summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/pdfinput
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2015-06-25 16:15:05 +0000
committerJabiertxof <jtx@jtx.marker.es>2015-06-25 16:15:05 +0000
commit5c2d982cc636ee4e2bc12703c01c86e245dd821f (patch)
tree6e6f22800c7d38314e14eccd486b65c3c4286d81 /src/extension/internal/pdfinput
parentupdate to trunk (diff)
parentFix for the bug 1468396 (diff)
downloadinkscape-5c2d982cc636ee4e2bc12703c01c86e245dd821f.tar.gz
inkscape-5c2d982cc636ee4e2bc12703c01c86e245dd821f.zip
update to trunk
(bzr r13645.1.94)
Diffstat (limited to 'src/extension/internal/pdfinput')
-rw-r--r--src/extension/internal/pdfinput/pdf-input.cpp203
-rw-r--r--src/extension/internal/pdfinput/pdf-input.h13
-rw-r--r--src/extension/internal/pdfinput/pdf-parser.cpp47
-rw-r--r--src/extension/internal/pdfinput/svg-builder.cpp36
-rw-r--r--src/extension/internal/pdfinput/svg-builder.h17
5 files changed, 202 insertions, 114 deletions
diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp
index 148d2dcba..363061734 100644
--- a/src/extension/internal/pdfinput/pdf-input.cpp
+++ b/src/extension/internal/pdfinput/pdf-input.cpp
@@ -36,8 +36,14 @@
#include <gtkmm/comboboxtext.h>
#include <gtkmm/drawingarea.h>
#include <gtkmm/frame.h>
+#include <gtkmm/radiobutton.h>
#include <gtkmm/scale.h>
+#if WITH_GTKMM_3_0
+#include <glibmm/convert.h>
+#include <glibmm/miscutils.h>
+#endif
+
#include "extension/system.h"
#include "extension/input.h"
#include "svg-builder.h"
@@ -81,7 +87,6 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/)
_poppler_doc = NULL;
#endif // HAVE_POPPLER_CAIRO
_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:")));
@@ -125,8 +130,13 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/)
_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")));
+ Gtk::RadioButton::Group group;
+ _importViaPoppler = Gtk::manage(new class Gtk::RadioButton(group,_("Poppler/Cairo import")));
+ _labelViaPoppler = Gtk::manage(new class Gtk::Label(_("Import via external library. Text consists of groups containing cloned glyphs where each glyph is a path. Images are stored internally. Meshes cause entire document to be rendered as a raster image.")));
+ _importViaInternal = Gtk::manage(new class Gtk::RadioButton(group,_("Internal import")));
+ _labelViaInternal = Gtk::manage(new class Gtk::Label(_("Import via internal (Poppler derived) library. Text is stored as text but white space is missing. Meshes are converted to tiles, the number depends on the precision set below.")));
#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));
@@ -139,13 +149,15 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/)
hbox6 = Gtk::manage(new class Gtk::HBox(false, 4));
// Text options
- _labelText = Gtk::manage(new class Gtk::Label(_("Text handling:")));
- _textHandlingCombo = Gtk::manage(new class Gtk::ComboBoxText());
- _textHandlingCombo->append(_("Import text as text"));
- _textHandlingCombo->set_active_text(_("Import text as text"));
+ // _labelText = Gtk::manage(new class Gtk::Label(_("Text handling:")));
+ // _textHandlingCombo = Gtk::manage(new class Gtk::ComboBoxText());
+ // _textHandlingCombo->append(_("Import text as text"));
+ // _textHandlingCombo->set_active_text(_("Import text as text"));
+ // hbox5 = Gtk::manage(new class Gtk::HBox(false, 4));
+
+ // Font option
_localFontsCheck = Gtk::manage(new class Gtk::CheckButton(_("Replace PDF fonts by closest-named installed fonts")));
- hbox5 = Gtk::manage(new class Gtk::HBox(false, 4));
_embedImagesCheck = Gtk::manage(new class Gtk::CheckButton(_("Embed images")));
vbox3 = Gtk::manage(new class Gtk::VBox(false, 4));
_importSettingsFrame = Gtk::manage(new class Inkscape::UI::Widget::Frame(_("Import settings")));
@@ -202,12 +214,19 @@ 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);
+ _importViaPoppler->set_can_focus();
+ _importViaPoppler->set_relief(Gtk::RELIEF_NORMAL);
+ _importViaPoppler->set_mode(true);
+ _importViaPoppler->set_active(false);
+ _importViaInternal->set_can_focus();
+ _importViaInternal->set_relief(Gtk::RELIEF_NORMAL);
+ _importViaInternal->set_mode(true);
+ _labelViaPoppler->set_line_wrap(true);
+ _labelViaInternal->set_line_wrap(true);
#endif
+
_fallbackPrecisionSlider->set_size_request(180,-1);
_fallbackPrecisionSlider->set_can_focus();
_fallbackPrecisionSlider->set_inverted(false);
@@ -223,14 +242,14 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/)
_labelPrecisionComment->set_selectable(false);
hbox6->pack_start(*_fallbackPrecisionSlider, Gtk::PACK_SHRINK, 4);
hbox6->pack_start(*_labelPrecisionComment, Gtk::PACK_SHRINK, 0);
- _labelText->set_alignment(0.5,0.5);
- _labelText->set_padding(4,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);
+ // _labelText->set_alignment(0.5,0.5);
+ // _labelText->set_padding(4,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);
_localFontsCheck->set_can_focus();
_localFontsCheck->set_relief(Gtk::RELIEF_NORMAL);
_localFontsCheck->set_mode(true);
@@ -240,14 +259,17 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/)
_embedImagesCheck->set_mode(true);
_embedImagesCheck->set_active(true);
#ifdef HAVE_POPPLER_CAIRO
- vbox3->pack_start(*_importviaPopplerCheck, Gtk::PACK_SHRINK, 0);
+ vbox3->pack_start(*_importViaPoppler, Gtk::PACK_SHRINK, 0);
+ vbox3->pack_start(*_labelViaPoppler, Gtk::PACK_SHRINK, 0);
+ vbox3->pack_start(*_importViaInternal, Gtk::PACK_SHRINK, 0);
+ vbox3->pack_start(*_labelViaInternal, Gtk::PACK_SHRINK, 0);
#endif
+ vbox3->pack_start(*_localFontsCheck, Gtk::PACK_SHRINK, 0);
+ vbox3->pack_start(*_embedImagesCheck, Gtk::PACK_SHRINK, 0);
vbox3->pack_start(*_labelPrecision, Gtk::PACK_SHRINK, 0);
vbox3->pack_start(*hbox6, Gtk::PACK_SHRINK, 0);
vbox3->pack_start(*_labelPrecisionWarning, Gtk::PACK_SHRINK, 0);
- vbox3->pack_start(*hbox5, Gtk::PACK_SHRINK, 4);
- vbox3->pack_start(*_localFontsCheck, Gtk::PACK_SHRINK, 0);
- vbox3->pack_start(*_embedImagesCheck, Gtk::PACK_SHRINK, 0);
+ // vbox3->pack_start(*hbox5, Gtk::PACK_SHRINK, 4);
_importSettingsFrame->add(*vbox3);
_importSettingsFrame->set_border_width(4);
vbox1->pack_start(*_pageSettingsFrame, Gtk::PACK_EXPAND_PADDING, 0);
@@ -273,36 +295,9 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/)
this->property_destroy_with_parent().set_value(false);
this->add_action_widget(*cancelbutton, -6);
this->add_action_widget(*okbutton, -5);
- cancelbutton->show();
- okbutton->show();
- _labelSelect->show();
- _pageNumberSpin->show();
- _labelTotalPages->show();
- hbox2->show();
- _cropCheck->show();
- _cropTypeCombo->show();
- hbox3->show();
- vbox2->show();
- _pageSettingsFrame->show();
- _labelPrecision->show();
- _labelPrecisionWarning->show();
-#ifdef HAVE_POPPLER_CAIRO
- _importviaPopplerCheck->show();
-#endif
- _fallbackPrecisionSlider->show();
- _labelPrecisionComment->show();
- hbox6->show();
- _labelText->show();
- _textHandlingCombo->show();
- hbox5->show();
- _localFontsCheck->show();
- _embedImagesCheck->show();
- vbox3->show();
- _importSettingsFrame->show();
- vbox1->show();
- _previewArea->show();
- hbox1->show();
+ this->show_all();
+
// Connect signals
#if WITH_GTKMM_3_0
_previewArea->signal_draw().connect(sigc::mem_fun(*this, &PdfImportDialog::_onDraw));
@@ -313,17 +308,28 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/)
_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));
+#ifdef HAVE_POPPLER_CAIRO
+ _importViaPoppler->signal_toggled().connect(sigc::mem_fun(*this, &PdfImportDialog::_onToggleImport));
+#endif
_render_thumb = false;
#ifdef HAVE_POPPLER_CAIRO
_cairo_surface = NULL;
_render_thumb = true;
+
// Create PopplerDocument
- gchar *doc_uri = g_filename_to_uri(_pdf_doc->getFileName()->getCString(),NULL,NULL);
- if (doc_uri) {
- _poppler_doc = poppler_document_new_from_file(doc_uri, NULL, NULL);
- g_free(doc_uri);
+ Glib::ustring filename = _pdf_doc->getFileName()->getCString();
+ if (!Glib::path_is_absolute(filename)) {
+ filename = Glib::build_filename(Glib::get_current_dir(),filename);
+ }
+ Glib::ustring full_uri = Glib::filename_to_uri(filename);
+
+ if (!full_uri.empty()) {
+ _poppler_doc = poppler_document_new_from_file(full_uri.c_str(), NULL, NULL);
}
+
+ // Set sensitivity of some widgets based on selected import type.
+ _onToggleImport();
#endif
// Set default preview size
@@ -373,11 +379,11 @@ int PdfImportDialog::getSelectedPage() {
return _current_page;
}
-int PdfImportDialog::getImportMethod() {
+bool PdfImportDialog::getImportMethod() {
#ifdef HAVE_POPPLER_CAIRO
- return (_importviaPopplerCheck->get_active()) ? 1 : 0;
+ return _importViaPoppler->get_active();
#else
- return 0;
+ return false;
#endif
}
@@ -413,7 +419,7 @@ void PdfImportDialog::getImportSettings(Inkscape::XML::Node *prefs) {
prefs->setAttribute("embedImages", "0");
}
#ifdef HAVE_POPPLER_CAIRO
- if (_importviaPopplerCheck->get_active()) {
+ if (_importViaPoppler->get_active()) {
prefs->setAttribute("importviapoppler", "1");
} else {
prefs->setAttribute("importviapoppler", "0");
@@ -454,6 +460,23 @@ void PdfImportDialog::_onPageNumberChanged() {
}
#ifdef HAVE_POPPLER_CAIRO
+void PdfImportDialog::_onToggleImport() {
+ if( _importViaPoppler->get_active() ) {
+ hbox3->set_sensitive(false);
+ _localFontsCheck->set_sensitive(false);
+ _embedImagesCheck->set_sensitive(false);
+ hbox6->set_sensitive(false);
+ } else {
+ hbox3->set_sensitive();
+ _localFontsCheck->set_sensitive();
+ _embedImagesCheck->set_sensitive();
+ hbox6->set_sensitive();
+ }
+}
+#endif
+
+
+#ifdef HAVE_POPPLER_CAIRO
/**
* \brief Copies image data from a Cairo surface to a pixbuf
*
@@ -673,8 +696,13 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) {
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
+
+
+ // PDFDoc is from poppler. PDFDoc is used for preview and for native import.
+
#ifndef WIN32
+ // poppler does not use glib g_open. So on win32 we must use unicode call. code was copied from
+ // glib gstdio.c
GooString *filename_goo = new GooString(uri);
PDFDoc *pdf_doc = new PDFDoc(filename_goo, NULL, NULL, NULL); // TODO: Could ask for password
//delete filename_goo;
@@ -730,26 +758,20 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) {
}
}
- // Get needed page
- int page_num;
- if (dlg)
+ // Get options
+ int page_num = 1;
+ bool is_importvia_poppler = false;
+ if (dlg) {
page_num = dlg->getSelectedPage();
- else
- 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();
+ // printf("PDF import via %s.\n", is_importvia_poppler ? "poppler" : "native");
#endif
}
SPDocument *doc = NULL;
bool saved = false;
- if(is_importvia_poppler == 0)
+ if(!is_importvia_poppler)
{
// native importer
doc = SPDocument::createNewDoc(NULL, TRUE, TRUE);
@@ -769,12 +791,14 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) {
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);
+
+ Catalog *catalog = pdf_doc->getCatalog();
+ Page *page = catalog->getPage(page_num);
+
if ( crop_setting >= 0.0 ) { // Do page clipping
int crop_choice = (int)crop_setting;
switch (crop_choice) {
@@ -798,11 +822,11 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) {
}
}
- // Create parser
+ // Create parser (extension/internal/pdfinput/pdf-parser.h)
PdfParser *pdf_parser = new PdfParser(pdf_doc->getXRef(), builder, page_num-1, page->getRotate(),
page->getResourceDict(), page->getCropBox(), clipToBox);
- // Set up approximation precision for parser
+ // Set up approximation precision for parser. Used for convering Mesh Gradients into tiles.
double color_delta;
sp_repr_get_double(prefs, "approximationPrecision", &color_delta);
if ( color_delta <= 0.0 ) {
@@ -831,13 +855,20 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) {
{
#ifdef HAVE_POPPLER_CAIRO
// the poppler import
- gchar* filename_uri = g_filename_to_uri(uri, NULL, NULL);
+
+ Glib::ustring full_path = uri;
+ if (!Glib::path_is_absolute(uri)) {
+ full_path = Glib::build_filename(Glib::get_current_dir(),uri);
+ }
+ Glib::ustring full_uri = Glib::filename_to_uri(full_path);
+
GError *error = NULL;
- /// @todo handle passwort
+ /// @todo handle password
/// @todo check if win32 unicode needs special attention
- PopplerDocument* document = poppler_document_new_from_file(filename_uri, NULL, &error);
+ PopplerDocument* document = poppler_document_new_from_file(full_uri.c_str(), NULL, &error);
if(error != NULL) {
+ std::cerr << "PDFInput::open: error opening document: " << full_uri << std::endl;
g_error_free (error);
}
@@ -850,6 +881,13 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) {
Glib::ustring output;
cairo_surface_t* surface = cairo_svg_surface_create_for_stream(Inkscape::Extension::Internal::_write_ustring_cb,
&output, width, height);
+
+ // This magical function results in more fine-grain fallbacks. In particular, a mesh
+ // gradient won't necessarily result in the whole PDF being rasterized. Of course, SVG
+ // 1.2 never made it as a standard, but hey, we'll take what we can get. This trick was
+ // found by examining the 'pdftocairo' code.
+ cairo_svg_surface_restrict_to_version( surface, CAIRO_SVG_VERSION_1_2 );
+
cairo_t* cr = cairo_create(surface);
poppler_page_render_for_printing(page, cr);
@@ -867,13 +905,10 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) {
}
else
{
- doc = SPDocument::createNewDoc(NULL, TRUE, TRUE); // fallback create empthy document
+ doc = SPDocument::createNewDoc(NULL, TRUE, TRUE); // fallback create empty document
}
saved = DocumentUndo::getUndoSensitive(doc);
DocumentUndo::setUndoSensitive(doc, false); // No need to undo in this temporary document
-
- // Cleanup
- g_free(filename_uri);
#endif
}
diff --git a/src/extension/internal/pdfinput/pdf-input.h b/src/extension/internal/pdfinput/pdf-input.h
index 866db5d82..6e36603c3 100644
--- a/src/extension/internal/pdfinput/pdf-input.h
+++ b/src/extension/internal/pdfinput/pdf-input.h
@@ -44,6 +44,7 @@ namespace Gtk {
#else
class HScale;
#endif
+ class RadioButton;
class VBox;
class Label;
}
@@ -71,7 +72,7 @@ public:
bool showDialog();
int getSelectedPage();
- int getImportMethod();
+ bool getImportMethod();
void getImportSettings(Inkscape::XML::Node *prefs);
private:
@@ -86,7 +87,10 @@ private:
void _onPageNumberChanged();
void _onToggleCropping();
void _onPrecisionChanged();
-
+#ifdef HAVE_POPPLER_CAIRO
+ void _onToggleImport();
+#endif
+
class Gtk::Button * cancelbutton;
class Gtk::Button * okbutton;
class Gtk::Label * _labelSelect;
@@ -101,7 +105,10 @@ private:
class Gtk::Label * _labelPrecision;
class Gtk::Label * _labelPrecisionWarning;
#ifdef HAVE_POPPLER_CAIRO
- class Gtk::CheckButton * _importviaPopplerCheck; // using poppler_cairo for importing
+ class Gtk::RadioButton * _importViaPoppler; // Use poppler_cairo importing
+ class Gtk::Label * _labelViaPoppler;
+ class Gtk::RadioButton * _importViaInternal; // Use native (poppler based) importing
+ class Gtk::Label * _labelViaInternal;
#endif
#if WITH_GTKMM_3_0
class Gtk::Scale * _fallbackPrecisionSlider;
diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp
index cc0b38515..836c34c32 100644
--- a/src/extension/internal/pdfinput/pdf-parser.cpp
+++ b/src/extension/internal/pdfinput/pdf-parser.cpp
@@ -2780,12 +2780,14 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)
Dict *dict;
int width, height;
int bits;
+ GBool interpolate;
StreamColorSpaceMode csMode;
GBool mask;
GBool invert;
Object maskObj, smaskObj;
GBool haveColorKeyMask, haveExplicitMask, haveSoftMask;
GBool maskInvert;
+ GBool maskInterpolate;
Object obj1, obj2;
// get info from the stream
@@ -2828,6 +2830,19 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)
}
obj1.free();
+ // image interpolation
+ dict->lookup("Interpolate", &obj1);
+ if (obj1.isNull()) {
+ obj1.free();
+ dict->lookup("I", &obj1);
+ }
+ if (obj1.isBool())
+ interpolate = obj1.getBool();
+ else
+ interpolate = gFalse;
+ obj1.free();
+ maskInterpolate = gFalse;
+
// image or mask?
dict->lookup(const_cast<char*>("ImageMask"), &obj1);
if (obj1.isNull()) {
@@ -2884,7 +2899,7 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)
obj1.free();
// draw it
- builder->addImageMask(state, str, width, height, invert);
+ builder->addImageMask(state, str, width, height, invert, interpolate);
} else {
// get color space and color map
@@ -2986,6 +3001,16 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)
}
int maskBits = obj1.getInt();
obj1.free();
+ maskDict->lookup("Interpolate", &obj1);
+ if (obj1.isNull()) {
+ obj1.free();
+ maskDict->lookup("I", &obj1);
+ }
+ if (obj1.isBool())
+ maskInterpolate = obj1.getBool();
+ else
+ maskInterpolate = gFalse;
+ obj1.free();
maskDict->lookup(const_cast<char*>("ColorSpace"), &obj1);
if (obj1.isNull()) {
obj1.free();
@@ -3071,6 +3096,16 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)
goto err2;
}
obj1.free();
+ maskDict->lookup("Interpolate", &obj1);
+ if (obj1.isNull()) {
+ obj1.free();
+ maskDict->lookup("I", &obj1);
+ }
+ if (obj1.isBool())
+ maskInterpolate = obj1.getBool();
+ else
+ maskInterpolate = gFalse;
+ obj1.free();
maskInvert = gFalse;
maskDict->lookup(const_cast<char*>("Decode"), &obj1);
if (obj1.isNull()) {
@@ -3092,14 +3127,14 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)
// draw it
if (haveSoftMask) {
- builder->addSoftMaskedImage(state, str, width, height, colorMap,
- maskStr, maskWidth, maskHeight, maskColorMap);
+ builder->addSoftMaskedImage(state, str, width, height, colorMap, interpolate,
+ maskStr, maskWidth, maskHeight, maskColorMap, maskInterpolate);
delete maskColorMap;
} else if (haveExplicitMask) {
- builder->addMaskedImage(state, str, width, height, colorMap,
- maskStr, maskWidth, maskHeight, maskInvert);
+ builder->addMaskedImage(state, str, width, height, colorMap, interpolate,
+ maskStr, maskWidth, maskHeight, maskInvert, maskInterpolate);
} else {
- builder->addImage(state, str, width, height, colorMap,
+ builder->addImage(state, str, width, height, colorMap, interpolate,
haveColorKeyMask ? maskColors : static_cast<int *>(NULL));
}
delete colorMap;
diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp
index a3abb4045..58e2030d9 100644
--- a/src/extension/internal/pdfinput/svg-builder.cpp
+++ b/src/extension/internal/pdfinput/svg-builder.cpp
@@ -1485,7 +1485,9 @@ void png_flush_base64stream(png_structp png_ptr)
*
*/
Inkscape::XML::Node *SvgBuilder::_createImage(Stream *str, int width, int height,
- GfxImageColorMap *color_map, int *mask_colors, bool alpha_only, bool invert_alpha) {
+ GfxImageColorMap *color_map, bool interpolate,
+ int *mask_colors, bool alpha_only,
+ bool invert_alpha) {
// Create PNG write struct
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
@@ -1655,6 +1657,13 @@ Inkscape::XML::Node *SvgBuilder::_createImage(Stream *str, int width, int height
Inkscape::XML::Node *image_node = _xml_doc->createElement("svg:image");
sp_repr_set_svg_double(image_node, "width", 1);
sp_repr_set_svg_double(image_node, "height", 1);
+ if( !interpolate ) {
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ // This should be changed after CSS4 Images widely supported.
+ sp_repr_css_set_property(css, "image-rendering", "optimizeSpeed");
+ sp_repr_css_change(image_node, css, "style");
+ sp_repr_css_attr_unref(css);
+ }
// PS/PDF images are placed via a transformation matrix, no preserveAspectRatio used
image_node->setAttribute("preserveAspectRatio", "none");
@@ -1715,9 +1724,9 @@ Inkscape::XML::Node *SvgBuilder::_createMask(double width, double height) {
}
void SvgBuilder::addImage(GfxState * /*state*/, Stream *str, int width, int height,
- GfxImageColorMap *color_map, int *mask_colors) {
+ GfxImageColorMap *color_map, bool interpolate, int *mask_colors) {
- Inkscape::XML::Node *image_node = _createImage(str, width, height, color_map, mask_colors);
+ Inkscape::XML::Node *image_node = _createImage(str, width, height, color_map, interpolate, mask_colors);
if (image_node) {
_container->appendChild(image_node);
Inkscape::GC::release(image_node);
@@ -1725,7 +1734,7 @@ void SvgBuilder::addImage(GfxState * /*state*/, Stream *str, int width, int heig
}
void SvgBuilder::addImageMask(GfxState *state, Stream *str, int width, int height,
- bool invert) {
+ bool invert, bool interpolate) {
// Create a rectangle
Inkscape::XML::Node *rect = _xml_doc->createElement("svg:rect");
@@ -1742,7 +1751,8 @@ void SvgBuilder::addImageMask(GfxState *state, Stream *str, int width, int heigh
// Scaling 1x1 surfaces might not work so skip setting a mask with this size
if ( width > 1 || height > 1 ) {
- Inkscape::XML::Node *mask_image_node = _createImage(str, width, height, NULL, NULL, true, invert);
+ Inkscape::XML::Node *mask_image_node =
+ _createImage(str, width, height, NULL, interpolate, NULL, true, invert);
if (mask_image_node) {
// Create the mask
Inkscape::XML::Node *mask_node = _createMask(1.0, 1.0);
@@ -1762,13 +1772,13 @@ void SvgBuilder::addImageMask(GfxState *state, Stream *str, int width, int heigh
}
void SvgBuilder::addMaskedImage(GfxState * /*state*/, Stream *str, int width, int height,
- GfxImageColorMap *color_map,
+ GfxImageColorMap *color_map, bool interpolate,
Stream *mask_str, int mask_width, int mask_height,
- bool invert_mask) {
+ bool invert_mask, bool mask_interpolate) {
Inkscape::XML::Node *mask_image_node = _createImage(mask_str, mask_width, mask_height,
- NULL, NULL, true, invert_mask);
- Inkscape::XML::Node *image_node = _createImage(str, width, height, color_map, NULL);
+ NULL, mask_interpolate, NULL, true, invert_mask);
+ Inkscape::XML::Node *image_node = _createImage(str, width, height, color_map, interpolate, NULL);
if ( mask_image_node && image_node ) {
// Create mask for the image
Inkscape::XML::Node *mask_node = _createMask(1.0, 1.0);
@@ -1795,13 +1805,13 @@ void SvgBuilder::addMaskedImage(GfxState * /*state*/, Stream *str, int width, in
}
void SvgBuilder::addSoftMaskedImage(GfxState * /*state*/, Stream *str, int width, int height,
- GfxImageColorMap *color_map,
+ GfxImageColorMap *color_map, bool interpolate,
Stream *mask_str, int mask_width, int mask_height,
- GfxImageColorMap *mask_color_map) {
+ GfxImageColorMap *mask_color_map, bool mask_interpolate) {
Inkscape::XML::Node *mask_image_node = _createImage(mask_str, mask_width, mask_height,
- mask_color_map, NULL, true);
- Inkscape::XML::Node *image_node = _createImage(str, width, height, color_map, NULL);
+ mask_color_map, mask_interpolate, NULL, true);
+ Inkscape::XML::Node *image_node = _createImage(str, width, height, color_map, interpolate, NULL);
if ( mask_image_node && image_node ) {
// Create mask for the image
Inkscape::XML::Node *mask_node = _createMask(1.0, 1.0);
diff --git a/src/extension/internal/pdfinput/svg-builder.h b/src/extension/internal/pdfinput/svg-builder.h
index f1ce02cf0..ad15c9c06 100644
--- a/src/extension/internal/pdfinput/svg-builder.h
+++ b/src/extension/internal/pdfinput/svg-builder.h
@@ -112,17 +112,17 @@ public:
// Image handling
void addImage(GfxState *state, Stream *str, int width, int height,
- GfxImageColorMap *color_map, int *mask_colors);
+ GfxImageColorMap *color_map, bool interpolate, int *mask_colors);
void addImageMask(GfxState *state, Stream *str, int width, int height,
- bool invert);
+ bool invert, bool interpolate);
void addMaskedImage(GfxState *state, Stream *str, int width, int height,
- GfxImageColorMap *color_map,
+ GfxImageColorMap *color_map, bool interpolate,
Stream *mask_str, int mask_width, int mask_height,
- bool invert_mask);
+ bool invert_mask, bool mask_interpolate);
void addSoftMaskedImage(GfxState *state, Stream *str, int width, int height,
- GfxImageColorMap *color_map,
+ GfxImageColorMap *color_map, bool interpolate,
Stream *mask_str, int mask_width, int mask_height,
- GfxImageColorMap *mask_color_map);
+ GfxImageColorMap *mask_color_map, bool mask_interpolate);
// Transparency group and soft mask handling
void pushTransparencyGroup(GfxState *state, double *bbox,
@@ -180,8 +180,9 @@ private:
bool is_stroke=false);
// Image/mask creation
Inkscape::XML::Node *_createImage(Stream *str, int width, int height,
- GfxImageColorMap *color_map, int *mask_colors,
- bool alpha_only=false, bool invert_alpha=false);
+ GfxImageColorMap *color_map, bool interpolate,
+ int *mask_colors, bool alpha_only=false,
+ bool invert_alpha=false);
Inkscape::XML::Node *_createMask(double width, double height);
// Style setting
SPCSSAttr *_setStyle(GfxState *state, bool fill, bool stroke, bool even_odd=false);