summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/pdfinput
diff options
context:
space:
mode:
Diffstat (limited to 'src/extension/internal/pdfinput')
-rw-r--r--src/extension/internal/pdfinput/pdf-input.cpp259
-rw-r--r--src/extension/internal/pdfinput/pdf-input.h4
-rw-r--r--src/extension/internal/pdfinput/pdf-parser.cpp236
-rw-r--r--src/extension/internal/pdfinput/pdf-parser.h30
-rw-r--r--src/extension/internal/pdfinput/svg-builder.cpp11
5 files changed, 374 insertions, 166 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;
diff --git a/src/extension/internal/pdfinput/pdf-input.h b/src/extension/internal/pdfinput/pdf-input.h
index f22a783ff..d57c3e993 100644
--- a/src/extension/internal/pdfinput/pdf-input.h
+++ b/src/extension/internal/pdfinput/pdf-input.h
@@ -75,6 +75,7 @@ public:
bool showDialog();
int getSelectedPage();
+ int getImportMethod();
void getImportSettings(Inkscape::XML::Node *prefs);
private:
@@ -103,6 +104,9 @@ private:
class Inkscape::UI::Widget::Frame * _pageSettingsFrame;
class Gtk::Label * _labelPrecision;
class Gtk::Label * _labelPrecisionWarning;
+#ifdef HAVE_POPPLER_CAIRO
+ class Gtk::CheckButton * _importviaPopplerCheck; // using poppler_cairo for importing
+#endif
#if WITH_GTKMM_3_0
class Gtk::Scale * _fallbackPrecisionSlider;
Glib::RefPtr<Gtk::Adjustment> _fallbackPrecisionSlider_adj;
diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp
index b398486e6..0b7dc7905 100644
--- a/src/extension/internal/pdfinput/pdf-parser.cpp
+++ b/src/extension/internal/pdfinput/pdf-parser.cpp
@@ -247,30 +247,74 @@ PdfOperator PdfParser::opTab[] = {
#define numOps (sizeof(opTab) / sizeof(PdfOperator))
+namespace {
+
+GfxPatch blankPatch()
+{
+ GfxPatch patch;
+ memset(&patch, 0, sizeof(patch)); // quick-n-dirty
+ return patch;
+}
+
+} // namespace
+
//------------------------------------------------------------------------
-// PdfParser
+// ClipHistoryEntry
//------------------------------------------------------------------------
-PdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *builderA,
- int /*pageNum*/, int rotate, Dict *resDict,
- PDFRectangle *box, PDFRectangle *cropBox)
-{
- xref = xrefA;
- subPage = gFalse;
- printCommands = false;
+class ClipHistoryEntry {
+public:
+
+ ClipHistoryEntry(GfxPath *clipPath = NULL, GfxClipType clipType = clipNormal);
+ virtual ~ClipHistoryEntry();
- // start the resource stack
- res = new GfxResources(xref, resDict, NULL);
+ // Manipulate clip path stack
+ ClipHistoryEntry *save();
+ ClipHistoryEntry *restore();
+ GBool hasSaves() { return saved != NULL; }
+ void setClip(GfxPath *newClipPath, GfxClipType newClipType = clipNormal);
+ GfxPath *getClipPath() { return clipPath; }
+ GfxClipType getClipType() { return clipType; }
- // initialize
- state = new GfxState(72.0, 72.0, box, rotate, gTrue);
- clipHistory = new ClipHistoryEntry();
+private:
+
+ ClipHistoryEntry *saved; // next clip path on stack
+
+ GfxPath *clipPath; // used as the path to be filled for an 'sh' operator
+ GfxClipType clipType;
+
+ ClipHistoryEntry(ClipHistoryEntry *other);
+};
+
+//------------------------------------------------------------------------
+// PdfParser
+//------------------------------------------------------------------------
+
+PdfParser::PdfParser(XRef *xrefA,
+ Inkscape::Extension::Internal::SvgBuilder *builderA,
+ int /*pageNum*/,
+ int rotate,
+ Dict *resDict,
+ PDFRectangle *box,
+ PDFRectangle *cropBox) :
+ xref(xrefA),
+ builder(builderA),
+ subPage(gFalse),
+ printCommands(false),
+ res(new GfxResources(xref, resDict, NULL)), // start the resource stack
+ state(new GfxState(72.0, 72.0, box, rotate, gTrue)),
+ fontChanged(gFalse),
+ clip(clipNone),
+ ignoreUndef(0),
+ baseMatrix(),
+ formDepth(0),
+ parser(NULL),
+ colorDeltas(),
+ maxDepths(),
+ clipHistory(new ClipHistoryEntry()),
+ operatorHistory(NULL)
+{
setDefaultApproximationPrecision();
- fontChanged = gFalse;
- clip = clipNone;
- ignoreUndef = 0;
- operatorHistory = NULL;
- builder = builderA;
builder->setDocumentSize(Inkscape::Util::Quantity::convert(state->getPageWidth(), "pt", "px"),
Inkscape::Util::Quantity::convert(state->getPageHeight(), "pt", "px"));
@@ -306,50 +350,62 @@ PdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *bui
pushOperator("startPage");
}
-PdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *builderA,
- Dict *resDict, PDFRectangle *box) {
-
- int i;
- parser = NULL;
-
- xref = xrefA;
- subPage = gTrue;
- printCommands = false;
-
- // start the resource stack
- res = new GfxResources(xref, resDict, NULL);
-
- // initialize
- operatorHistory = NULL;
- builder = builderA;
- state = new GfxState(72, 72, box, 0, gFalse);
- clipHistory = new ClipHistoryEntry();
+PdfParser::PdfParser(XRef *xrefA,
+ Inkscape::Extension::Internal::SvgBuilder *builderA,
+ Dict *resDict,
+ PDFRectangle *box) :
+ xref(xrefA),
+ builder(builderA),
+ subPage(gTrue),
+ printCommands(false),
+ res(new GfxResources(xref, resDict, NULL)), // start the resource stack
+ state(new GfxState(72, 72, box, 0, gFalse)),
+ fontChanged(gFalse),
+ clip(clipNone),
+ ignoreUndef(0),
+ baseMatrix(),
+ formDepth(0),
+ parser(NULL),
+ colorDeltas(),
+ maxDepths(),
+ clipHistory(new ClipHistoryEntry()),
+ operatorHistory(NULL)
+{
setDefaultApproximationPrecision();
- fontChanged = gFalse;
- clip = clipNone;
- ignoreUndef = 0;
- for (i = 0; i < 6; ++i) {
+ for (int i = 0; i < 6; ++i) {
baseMatrix[i] = state->getCTM()[i];
}
formDepth = 0;
}
PdfParser::~PdfParser() {
- while (state->hasSaves()) {
+ while(operatorHistory) {
+ OpHistoryEntry *tmp = operatorHistory->next;
+ delete operatorHistory;
+ operatorHistory = tmp;
+ }
+
+ while (state && state->hasSaves()) {
restoreState();
}
+
if (!subPage) {
//out->endPage();
}
+
while (res) {
popResources();
}
+
if (state) {
delete state;
+ state = NULL;
}
+
if (clipHistory) {
delete clipHistory;
+ clipHistory = NULL;
}
}
@@ -460,7 +516,8 @@ void PdfParser::go(GBool /*topLevel*/)
}
}
-void PdfParser::pushOperator(const char *name) {
+void PdfParser::pushOperator(const char *name)
+{
OpHistoryEntry *newEntry = new OpHistoryEntry;
newEntry->name = name;
newEntry->state = NULL;
@@ -866,7 +923,9 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/)
GBool isolated = gFalse;
GBool knockout = gFalse;
if (!obj4.dictLookup(const_cast<char*>("CS"), &obj5)->isNull()) {
-#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
+#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API)
+ blendingColorSpace = GfxColorSpace::parse(&obj5, NULL, NULL);
+#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
blendingColorSpace = GfxColorSpace::parse(&obj5, NULL);
#else
blendingColorSpace = GfxColorSpace::parse(&obj5);
@@ -1100,7 +1159,13 @@ void PdfParser::opSetFillColorSpace(Object args[], int /*numArgs*/)
res->lookupColorSpace(args[0].getName(), &obj);
GfxColorSpace *colorSpace = 0;
-#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
+#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API)
+ if (obj.isNull()) {
+ colorSpace = GfxColorSpace::parse(&args[0], NULL, NULL);
+ } else {
+ colorSpace = GfxColorSpace::parse(&obj, NULL, NULL);
+ }
+#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
if (obj.isNull()) {
colorSpace = GfxColorSpace::parse(&args[0], NULL);
} else {
@@ -1137,7 +1202,13 @@ void PdfParser::opSetStrokeColorSpace(Object args[], int /*numArgs*/)
state->setStrokePattern(NULL);
res->lookupColorSpace(args[0].getName(), &obj);
-#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
+#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API)
+ if (obj.isNull()) {
+ colorSpace = GfxColorSpace::parse(&args[0], NULL, NULL);
+ } else {
+ colorSpace = GfxColorSpace::parse(&obj, NULL, NULL);
+ }
+#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
if (obj.isNull()) {
colorSpace = GfxColorSpace::parse(&args[0], NULL);
} else {
@@ -1231,7 +1302,13 @@ void PdfParser::opSetFillColorN(Object args[], int numArgs) {
builder->updateStyle(state);
}
GfxPattern *pattern;
-#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
+#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API)
+ if (args[numArgs-1].isName() &&
+ (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL, NULL))) {
+ state->setFillPattern(pattern);
+ builder->updateStyle(state);
+ }
+#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
if (args[numArgs-1].isName() &&
(pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) {
state->setFillPattern(pattern);
@@ -1291,7 +1368,13 @@ void PdfParser::opSetStrokeColorN(Object args[], int numArgs) {
builder->updateStyle(state);
}
GfxPattern *pattern;
-#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
+#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API)
+ if (args[numArgs-1].isName() &&
+ (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL, NULL))) {
+ state->setStrokePattern(pattern);
+ builder->updateStyle(state);
+ }
+#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
if (args[numArgs-1].isName() &&
(pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) {
state->setStrokePattern(pattern);
@@ -1746,7 +1829,11 @@ void PdfParser::opShFill(Object args[], int /*numArgs*/)
double *matrix = NULL;
GBool savedState = gFalse;
-#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
+#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API)
+ if (!(shading = res->lookupShading(args[0].getName(), NULL, NULL))) {
+ return;
+ }
+#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
if (!(shading = res->lookupShading(args[0].getName(), NULL))) {
return;
}
@@ -2056,13 +2143,19 @@ void PdfParser::doPatchMeshShFill(GfxPatchMeshShading *shading) {
}
void PdfParser::fillPatch(GfxPatch *patch, int nComps, int depth) {
- GfxPatch patch00, patch01, patch10, patch11;
+ GfxPatch patch00 = blankPatch();
+ GfxPatch patch01 = blankPatch();
+ GfxPatch patch10 = blankPatch();
+ GfxPatch patch11 = blankPatch();
#ifdef POPPLER_NEW_GFXPATCH
- GfxColor color;
+ GfxColor color = {{0}};
#endif
- double xx[4][8], yy[4][8];
- double xxm, yym;
- double patchColorDelta = colorDeltas[pdfPatchMeshShading-1];
+ double xx[4][8];
+ double yy[4][8];
+ double xxm;
+ double yym;
+ double patchColorDelta = colorDeltas[pdfPatchMeshShading - 1];
+
int i;
for (i = 0; i < nComps; ++i) {
@@ -2817,7 +2910,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)
}
}
if (!obj1.isNull()) {
-#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
+#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API)
+ colorSpace = GfxColorSpace::parse(&obj1, NULL, NULL);
+#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
colorSpace = GfxColorSpace::parse(&obj1, NULL);
#else
colorSpace = GfxColorSpace::parse(&obj1);
@@ -2909,7 +3004,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg)
obj2.free();
}
}
-#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
+#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API)
+ GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1, NULL, NULL);
+#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1, NULL);
#else
GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1);
@@ -3099,7 +3196,9 @@ void PdfParser::doForm(Object *str) {
if (obj1.dictLookup(const_cast<char*>("S"), &obj2)->isName(const_cast<char*>("Transparency"))) {
transpGroup = gTrue;
if (!obj1.dictLookup(const_cast<char*>("CS"), &obj3)->isNull()) {
-#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
+#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API)
+ blendingColorSpace = GfxColorSpace::parse(&obj3, NULL, NULL);
+#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI)
blendingColorSpace = GfxColorSpace::parse(&obj3, NULL);
#else
blendingColorSpace = GfxColorSpace::parse(&obj3);
@@ -3427,9 +3526,7 @@ void PdfParser::popResources() {
}
void PdfParser::setDefaultApproximationPrecision() {
- int i;
-
- for (i = 1; i <= pdfNumShadingTypes; ++i) {
+ for (int i = 1; i <= pdfNumShadingTypes; ++i) {
setApproximationPrecision(i, defaultShadingColorDelta, defaultShadingMaxDepth);
}
}
@@ -3448,19 +3545,18 @@ void PdfParser::setApproximationPrecision(int shadingType, double colorDelta,
// ClipHistoryEntry
//------------------------------------------------------------------------
-ClipHistoryEntry::ClipHistoryEntry(GfxPath *clipPathA, GfxClipType clipTypeA) {
- if (clipPathA) {
- clipPath = clipPathA->copy();
- } else {
- clipPath = NULL;
- }
- clipType = clipTypeA;
- saved = NULL;
+ClipHistoryEntry::ClipHistoryEntry(GfxPath *clipPathA, GfxClipType clipTypeA) :
+ saved(NULL),
+ clipPath((clipPathA) ? clipPathA->copy() : NULL),
+ clipType(clipTypeA)
+{
}
-ClipHistoryEntry::~ClipHistoryEntry() {
+ClipHistoryEntry::~ClipHistoryEntry()
+{
if (clipPath) {
delete clipPath;
+ clipPath = NULL;
}
}
@@ -3474,6 +3570,7 @@ void ClipHistoryEntry::setClip(GfxPath *clipPathA, GfxClipType clipTypeA) {
clipType = clipTypeA;
} else {
clipPath = NULL;
+ clipType = clipNormal;
}
}
@@ -3490,7 +3587,7 @@ ClipHistoryEntry *ClipHistoryEntry::restore() {
if (saved) {
oldEntry = saved;
saved = NULL;
- delete this;
+ delete this; // TODO really should avoid deleting from inside.
} else {
oldEntry = this;
}
@@ -3504,6 +3601,7 @@ ClipHistoryEntry::ClipHistoryEntry(ClipHistoryEntry *other) {
this->clipType = other->clipType;
} else {
this->clipPath = NULL;
+ this->clipType = clipNormal;
}
saved = NULL;
}
diff --git a/src/extension/internal/pdfinput/pdf-parser.h b/src/extension/internal/pdfinput/pdf-parser.h
index a63d669c7..e28fecc2e 100644
--- a/src/extension/internal/pdfinput/pdf-parser.h
+++ b/src/extension/internal/pdfinput/pdf-parser.h
@@ -58,6 +58,8 @@ class AnnotBorderStyle;
class PdfParser;
+class ClipHistoryEntry;
+
//------------------------------------------------------------------------
#ifndef GFX_H
@@ -101,34 +103,6 @@ struct OpHistoryEntry {
};
//------------------------------------------------------------------------
-// ClipHistoryEntry
-//------------------------------------------------------------------------
-
-class ClipHistoryEntry {
-public:
-
- ClipHistoryEntry(GfxPath *clipPath=NULL, GfxClipType clipType=clipNormal);
- virtual ~ClipHistoryEntry();
-
- // Manipulate clip path stack
- ClipHistoryEntry *save();
- ClipHistoryEntry *restore();
- GBool hasSaves() { return saved != NULL; }
- void setClip(GfxPath *newClipPath, GfxClipType newClipType=clipNormal);
- GfxPath *getClipPath() { return clipPath; }
- GfxClipType getClipType() { return clipType; }
-
-private:
-
- ClipHistoryEntry *saved; // next clip path on stack
-
- GfxPath *clipPath; // used as the path to be filled for an 'sh' operator
- GfxClipType clipType;
-
- ClipHistoryEntry(ClipHistoryEntry *other);
-};
-
-//------------------------------------------------------------------------
// PdfParser
//------------------------------------------------------------------------
diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp
index 71e6dc6ae..7a504add0 100644
--- a/src/extension/internal/pdfinput/svg-builder.cpp
+++ b/src/extension/internal/pdfinput/svg-builder.cpp
@@ -123,12 +123,11 @@ void SvgBuilder::_init() {
_height = 0;
// Fill _availableFontNames (Bug LP #179589) (code cfr. FontLister)
- FamilyToStylesMap familyStyleMap;
- font_factory::Default()->GetUIFamiliesAndStyles(&familyStyleMap);
- for (FamilyToStylesMap::iterator iter = familyStyleMap.begin();
- iter != familyStyleMap.end();
- ++iter) {
- _availableFontNames.push_back(iter->first.c_str());
+ std::vector<PangoFontFamily *> families;
+ font_factory::Default()->GetUIFamilies(families);
+ for ( std::vector<PangoFontFamily *>::iterator iter = families.begin();
+ iter != families.end(); ++iter ) {
+ _availableFontNames.push_back(pango_font_family_get_name(*iter));
}
_transp_group_stack = NULL;