[poppler] 3 commits - glib/poppler-document.cc glib/poppler-document.h glib/reference poppler/Object.h poppler/PDFDoc.cc poppler/PDFDoc.h poppler/XRef.cc poppler/XRef.h
Carlos Garcia Campos
carlosgc at kemper.freedesktop.org
Sun Jul 3 09:03:43 UTC 2016
glib/poppler-document.cc | 347 ++++++++++++++++++++++++++----------
glib/poppler-document.h | 18 +
glib/reference/poppler-docs.sgml | 4
glib/reference/poppler-sections.txt | 8
poppler/Object.h | 7
poppler/PDFDoc.cc | 79 +++++++-
poppler/PDFDoc.h | 41 ++++
poppler/XRef.cc | 39 ++++
poppler/XRef.h | 14 +
9 files changed, 456 insertions(+), 101 deletions(-)
New commits:
commit 82476b0d6967ce5e61dce4666fe556edd63c16e6
Author: Jakub Kucharski <jakubkucharski97 at gmail.com>
Date: Mon Jun 6 22:17:57 2016 +0200
glib: Added document property setters & simplified getters
https://bugs.freedesktop.org/show_bug.cgi?id=36653
diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc
index 61d92e8..63eae7c 100644
--- a/glib/poppler-document.cc
+++ b/glib/poppler-document.cc
@@ -1,6 +1,8 @@
/* poppler-document.cc: glib wrapper for poppler
* Copyright (C) 2005, Red Hat, Inc.
*
+ * Copyright (C) 2016 Jakub Kucharski <jakubkucharski97 at gmail.com>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -22,6 +24,7 @@
#ifndef __GI_SCANNER__
#include <goo/GooList.h>
#include <splash/SplashBitmap.h>
+#include <DateInfo.h>
#include <GlobalParams.h>
#include <PDFDoc.h>
#include <Outline.h>
@@ -711,6 +714,10 @@ poppler_document_find_dest (PopplerDocument *document,
char *_poppler_goo_string_to_utf8(GooString *s)
{
+ if (s == NULL) {
+ return NULL;
+ }
+
char *result;
if (s->hasUnicodeMarker()) {
@@ -737,40 +744,28 @@ char *_poppler_goo_string_to_utf8(GooString *s)
return result;
}
-static gchar *
-info_dict_get_string (Dict *info_dict, const gchar *key)
+static GooString *
+_poppler_goo_string_from_utf8(const gchar *src)
{
- Object obj;
- GooString *goo_value;
- gchar *result;
-
- if (!info_dict->lookup ((gchar *)key, &obj)->isString ()) {
- obj.free ();
+ if (src == NULL) {
return NULL;
}
- goo_value = obj.getString ();
- result = _poppler_goo_string_to_utf8(goo_value);
- obj.free ();
+ gsize outlen;
- return result;
-}
+ gchar *utf16 = g_convert (src, -1, "UTF-16BE", "UTF-8", NULL, &outlen, NULL);
+ if (utf16 == NULL) {
+ return NULL;
+ }
-static time_t
-info_dict_get_date (Dict *info_dict, const gchar *key)
-{
- Object obj;
- time_t result;
+ GooString *result = new GooString (utf16, outlen);
+ g_free (utf16);
- if (!info_dict->lookup ((gchar *)key, &obj)->isString ()) {
- obj.free ();
- return (time_t)-1;
+ if (!result->hasUnicodeMarker()) {
+ result->insert(0, 0xff);
+ result->insert(0, 0xfe);
}
- if (!_poppler_convert_pdf_date_to_gtime (obj.getString (), &result))
- result = (time_t)-1;
- obj.free ();
-
return result;
}
@@ -879,17 +874,39 @@ poppler_document_get_pdf_version (PopplerDocument *document,
gchar *
poppler_document_get_title (PopplerDocument *document)
{
- Object obj;
- gchar *retval = NULL;
-
g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);
- document->doc->getDocInfo (&obj);
- if (obj.isDict ())
- retval = info_dict_get_string (obj.getDict(), "Title");
- obj.free ();
+ GooString *goo_title = document->doc->getDocInfoTitle();
+ gchar *utf8 = _poppler_goo_string_to_utf8(goo_title);
+ delete goo_title;
- return retval;
+ return utf8;
+}
+
+/**
+ * poppler_document_set_title:
+ * @document: A #PopplerDocument
+ * @title: A new title
+ *
+ * Sets the document's title. If @title is %NULL, Title entry
+ * is removed from the document's Info dictionary.
+ *
+ * Since: 0.46
+ **/
+void
+poppler_document_set_title (PopplerDocument *document, const gchar *title)
+{
+ g_return_if_fail (POPPLER_IS_DOCUMENT (document));
+
+ GooString *goo_title;
+ if (!title) {
+ goo_title = NULL;
+ } else {
+ goo_title = _poppler_goo_string_from_utf8(title);
+ if (!goo_title)
+ return;
+ }
+ document->doc->setDocInfoTitle(goo_title);
}
/**
@@ -906,17 +923,39 @@ poppler_document_get_title (PopplerDocument *document)
gchar *
poppler_document_get_author (PopplerDocument *document)
{
- Object obj;
- gchar *retval = NULL;
-
g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);
- document->doc->getDocInfo (&obj);
- if (obj.isDict ())
- retval = info_dict_get_string (obj.getDict(), "Author");
- obj.free ();
+ GooString *goo_author = document->doc->getDocInfoAuthor();
+ gchar *utf8 = _poppler_goo_string_to_utf8(goo_author);
+ delete goo_author;
- return retval;
+ return utf8;
+}
+
+/**
+ * poppler_document_set_author:
+ * @document: A #PopplerDocument
+ * @author: A new author
+ *
+ * Sets the document's author. If @author is %NULL, Author
+ * entry is removed from the document's Info dictionary.
+ *
+ * Since: 0.46
+ **/
+void
+poppler_document_set_author (PopplerDocument *document, const gchar *author)
+{
+ g_return_if_fail (POPPLER_IS_DOCUMENT (document));
+
+ GooString *goo_author;
+ if (!author) {
+ goo_author = NULL;
+ } else {
+ goo_author = _poppler_goo_string_from_utf8(author);
+ if (!goo_author)
+ return;
+ }
+ document->doc->setDocInfoAuthor(goo_author);
}
/**
@@ -933,17 +972,39 @@ poppler_document_get_author (PopplerDocument *document)
gchar *
poppler_document_get_subject (PopplerDocument *document)
{
- Object obj;
- gchar *retval = NULL;
-
g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);
- document->doc->getDocInfo (&obj);
- if (obj.isDict ())
- retval = info_dict_get_string (obj.getDict(), "Subject");
- obj.free ();
+ GooString *goo_subject = document->doc->getDocInfoSubject();
+ gchar *utf8 = _poppler_goo_string_to_utf8(goo_subject);
+ delete goo_subject;
- return retval;
+ return utf8;
+}
+
+/**
+ * poppler_document_set_subject:
+ * @document: A #PopplerDocument
+ * @subject: A new subject
+ *
+ * Sets the document's subject. If @subject is %NULL, Subject
+ * entry is removed from the document's Info dictionary.
+ *
+ * Since: 0.46
+ **/
+void
+poppler_document_set_subject (PopplerDocument *document, const gchar *subject)
+{
+ g_return_if_fail (POPPLER_IS_DOCUMENT (document));
+
+ GooString *goo_subject;
+ if (!subject) {
+ goo_subject = NULL;
+ } else {
+ goo_subject = _poppler_goo_string_from_utf8(subject);
+ if (!goo_subject)
+ return;
+ }
+ document->doc->setDocInfoSubject(goo_subject);
}
/**
@@ -960,17 +1021,39 @@ poppler_document_get_subject (PopplerDocument *document)
gchar *
poppler_document_get_keywords (PopplerDocument *document)
{
- Object obj;
- gchar *retval = NULL;
-
g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);
- document->doc->getDocInfo (&obj);
- if (obj.isDict ())
- retval = info_dict_get_string (obj.getDict(), "Keywords");
- obj.free ();
+ GooString *goo_keywords = document->doc->getDocInfoKeywords();
+ gchar *utf8 = _poppler_goo_string_to_utf8(goo_keywords);
+ delete goo_keywords;
- return retval;
+ return utf8;
+}
+
+/**
+ * poppler_document_set_keywords:
+ * @document: A #PopplerDocument
+ * @keywords: New keywords
+ *
+ * Sets the document's keywords. If @keywords is %NULL,
+ * Keywords entry is removed from the document's Info dictionary.
+ *
+ * Since: 0.46
+ **/
+void
+poppler_document_set_keywords (PopplerDocument *document, const gchar *keywords)
+{
+ g_return_if_fail (POPPLER_IS_DOCUMENT (document));
+
+ GooString *goo_keywords;
+ if (!keywords) {
+ goo_keywords = NULL;
+ } else {
+ goo_keywords = _poppler_goo_string_from_utf8(keywords);
+ if (!goo_keywords)
+ return;
+ }
+ document->doc->setDocInfoKeywords(goo_keywords);
}
/**
@@ -989,17 +1072,39 @@ poppler_document_get_keywords (PopplerDocument *document)
gchar *
poppler_document_get_creator (PopplerDocument *document)
{
- Object obj;
- gchar *retval = NULL;
-
g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);
- document->doc->getDocInfo (&obj);
- if (obj.isDict ())
- retval = info_dict_get_string (obj.getDict(), "Creator");
- obj.free ();
+ GooString *goo_creator = document->doc->getDocInfoCreator();
+ gchar *utf8 = _poppler_goo_string_to_utf8(goo_creator);
+ delete goo_creator;
- return retval;
+ return utf8;
+}
+
+/**
+ * poppler_document_set_creator:
+ * @document: A #PopplerDocument
+ * @creator: A new creator
+ *
+ * Sets the document's creator. If @creator is %NULL, Creator
+ * entry is removed from the document's Info dictionary.
+ *
+ * Since: 0.46
+ **/
+void
+poppler_document_set_creator (PopplerDocument *document, const gchar *creator)
+{
+ g_return_if_fail (POPPLER_IS_DOCUMENT (document));
+
+ GooString *goo_creator;
+ if (!creator) {
+ goo_creator = NULL;
+ } else {
+ goo_creator = _poppler_goo_string_from_utf8(creator);
+ if (!goo_creator)
+ return;
+ }
+ document->doc->setDocInfoCreator(goo_creator);
}
/**
@@ -1018,17 +1123,39 @@ poppler_document_get_creator (PopplerDocument *document)
gchar *
poppler_document_get_producer (PopplerDocument *document)
{
- Object obj;
- gchar *retval = NULL;
-
g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);
- document->doc->getDocInfo (&obj);
- if (obj.isDict ())
- retval = info_dict_get_string (obj.getDict(), "Producer");
- obj.free ();
+ GooString *goo_producer = document->doc->getDocInfoProducer();
+ gchar *utf8 = _poppler_goo_string_to_utf8(goo_producer);
+ delete goo_producer;
- return retval;
+ return utf8;
+}
+
+/**
+ * poppler_document_set_producer:
+ * @document: A #PopplerDocument
+ * @producer: A new producer
+ *
+ * Sets the document's producer. If @producer is %NULL,
+ * Producer entry is removed from the document's Info dictionary.
+ *
+ * Since: 0.46
+ **/
+void
+poppler_document_set_producer (PopplerDocument *document, const gchar *producer)
+{
+ g_return_if_fail (POPPLER_IS_DOCUMENT (document));
+
+ GooString *goo_producer;
+ if (!producer) {
+ goo_producer = NULL;
+ } else {
+ goo_producer = _poppler_goo_string_from_utf8(producer);
+ if (!goo_producer)
+ return;
+ }
+ document->doc->setDocInfoProducer(goo_producer);
}
/**
@@ -1044,17 +1171,38 @@ poppler_document_get_producer (PopplerDocument *document)
time_t
poppler_document_get_creation_date (PopplerDocument *document)
{
- Object obj;
- time_t retval = (time_t)-1;
-
g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), (time_t)-1);
- document->doc->getDocInfo (&obj);
- if (obj.isDict ())
- retval = info_dict_get_date (obj.getDict(), "CreationDate");
- obj.free ();
+ GooString *str = document->doc->getDocInfoCreatDate();
+ if (str == NULL) {
+ return (time_t)-1;
+ }
- return retval;
+ time_t date;
+ gboolean success = _poppler_convert_pdf_date_to_gtime (str, &date);
+ delete str;
+
+ return (success) ? date : (time_t)-1;
+}
+
+/**
+ * poppler_document_set_creation_date:
+ * @document: A #PopplerDocument
+ * @creation_date: A new creation date
+ *
+ * Sets the document's creation date. If @creation_date is -1, CreationDate
+ * entry is removed from the document's Info dictionary.
+ *
+ * Since: 0.46
+ **/
+void
+poppler_document_set_creation_date (PopplerDocument *document,
+ time_t creation_date)
+{
+ g_return_if_fail (POPPLER_IS_DOCUMENT (document));
+
+ GooString *str = creation_date == (time_t)-1 ? NULL : timeToDateString (&creation_date);
+ document->doc->setDocInfoCreatDate (str);
}
/**
@@ -1070,17 +1218,38 @@ poppler_document_get_creation_date (PopplerDocument *document)
time_t
poppler_document_get_modification_date (PopplerDocument *document)
{
- Object obj;
- time_t retval = (time_t)-1;
-
g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), (time_t)-1);
- document->doc->getDocInfo (&obj);
- if (obj.isDict ())
- retval = info_dict_get_date (obj.getDict(), "ModDate");
- obj.free ();
+ GooString *str = document->doc->getDocInfoModDate();
+ if (str == NULL) {
+ return (time_t)-1;
+ }
+
+ time_t date;
+ gboolean success = _poppler_convert_pdf_date_to_gtime (str, &date);
+ delete str;
- return retval;
+ return (success) ? date : (time_t)-1;
+}
+
+/**
+ * poppler_document_set_modification_date:
+ * @document: A #PopplerDocument
+ * @modification_date: A new modification date
+ *
+ * Sets the document's modification date. If @modification_date is -1, ModDate
+ * entry is removed from the document's Info dictionary.
+ *
+ * Since: 0.46
+ **/
+void
+poppler_document_set_modification_date (PopplerDocument *document,
+ time_t modification_date)
+{
+ g_return_if_fail (POPPLER_IS_DOCUMENT (document));
+
+ GooString *str = modification_date == (time_t)-1 ? NULL : timeToDateString (&modification_date);
+ document->doc->setDocInfoModDate (str);
}
/**
diff --git a/glib/poppler-document.h b/glib/poppler-document.h
index a34e88c..fb0ac72 100644
--- a/glib/poppler-document.h
+++ b/glib/poppler-document.h
@@ -1,6 +1,8 @@
/* poppler-document.h: glib interface to poppler
* Copyright (C) 2004, Red Hat, Inc.
*
+ * Copyright (C) 2016 Jakub Kucharski <jakubkucharski97 at gmail.com>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -201,13 +203,29 @@ void poppler_document_get_pdf_version (PopplerDocument *doc
guint *major_version,
guint *minor_version);
gchar *poppler_document_get_title (PopplerDocument *document);
+void poppler_document_set_title (PopplerDocument *document,
+ const gchar *title);
gchar *poppler_document_get_author (PopplerDocument *document);
+void poppler_document_set_author (PopplerDocument *document,
+ const gchar *author);
gchar *poppler_document_get_subject (PopplerDocument *document);
+void poppler_document_set_subject (PopplerDocument *document,
+ const gchar *subject);
gchar *poppler_document_get_keywords (PopplerDocument *document);
+void poppler_document_set_keywords (PopplerDocument *document,
+ const gchar *keywords);
gchar *poppler_document_get_creator (PopplerDocument *document);
+void poppler_document_set_creator (PopplerDocument *document,
+ const gchar *creator);
gchar *poppler_document_get_producer (PopplerDocument *document);
+void poppler_document_set_producer (PopplerDocument *document,
+ const gchar *producer);
time_t poppler_document_get_creation_date (PopplerDocument *document);
+void poppler_document_set_creation_date (PopplerDocument *document,
+ time_t creation_date);
time_t poppler_document_get_modification_date (PopplerDocument *document);
+void poppler_document_set_modification_date (PopplerDocument *document,
+ time_t modification_date);
gboolean poppler_document_is_linearized (PopplerDocument *document);
PopplerPageLayout poppler_document_get_page_layout (PopplerDocument *document);
PopplerPageMode poppler_document_get_page_mode (PopplerDocument *document);
diff --git a/glib/reference/poppler-docs.sgml b/glib/reference/poppler-docs.sgml
index ec8a3eb..5db818f 100644
--- a/glib/reference/poppler-docs.sgml
+++ b/glib/reference/poppler-docs.sgml
@@ -69,6 +69,10 @@
<title>Index of new symbols in 0.33</title>
<xi:include href="xml/api-index-0.33.xml"><xi:fallback /></xi:include>
</index>
+ <index id="api-index-0-46">
+ <title>Index of new symbols in 0.46</title>
+ <xi:include href="xml/api-index-0.46.xml"><xi:fallback /></xi:include>
+ </index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
</book>
diff --git a/glib/reference/poppler-sections.txt b/glib/reference/poppler-sections.txt
index 92bf432..d597c2d 100644
--- a/glib/reference/poppler-sections.txt
+++ b/glib/reference/poppler-sections.txt
@@ -134,13 +134,21 @@ poppler_document_get_id
poppler_document_get_pdf_version_string
poppler_document_get_pdf_version
poppler_document_get_title
+poppler_document_set_title
poppler_document_get_author
+poppler_document_set_author
poppler_document_get_subject
+poppler_document_set_subject
poppler_document_get_keywords
+poppler_document_set_keywords
poppler_document_get_creator
+poppler_document_set_creator
poppler_document_get_producer
+poppler_document_set_producer
poppler_document_get_creation_date
+poppler_document_set_creation_date
poppler_document_get_modification_date
+poppler_document_set_modification_date
poppler_document_get_page_layout
poppler_document_get_page_mode
poppler_document_get_permissions
commit 4f7c67b59b9c55b9b896378d3adbecbb73f6eb63
Author: Jakub Kucharski <jakubkucharski97 at gmail.com>
Date: Tue Feb 23 16:46:43 2016 +0100
Added DocInfo setters & getters
https://bugs.freedesktop.org/show_bug.cgi?id=36653
diff --git a/poppler/Object.h b/poppler/Object.h
index b9cae28..0c7767c 100644
--- a/poppler/Object.h
+++ b/poppler/Object.h
@@ -21,6 +21,7 @@
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag at alfa.de>
// Copyright (C) 2013 Adrian Johnson <ajohnson at redneon.com>
// Copyright (C) 2013 Adrian Perez de Castro <aperez at igalia.com>
+// Copyright (C) 2016 Jakub Kucharski <jakubkucharski97 at gmail.com>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
@@ -235,6 +236,7 @@ public:
int dictGetLength();
void dictAdd(char *key, Object *val);
void dictSet(const char *key, Object *val);
+ void dictRemove(const char *key);
GBool dictIs(const char *dictType);
Object *dictLookup(const char *key, Object *obj, int recursion = 0);
Object *dictLookupNF(const char *key, Object *obj);
@@ -318,7 +320,10 @@ inline void Object::dictAdd(char *key, Object *val)
{ OBJECT_TYPE_CHECK(objDict); dict->add(key, val); }
inline void Object::dictSet(const char *key, Object *val)
- { OBJECT_TYPE_CHECK(objDict); dict->set(key, val); }
+ { OBJECT_TYPE_CHECK(objDict); dict->set(key, val); }
+
+inline void Object::dictRemove(const char *key)
+ { OBJECT_TYPE_CHECK(objDict); dict->remove(key); }
inline GBool Object::dictIs(const char *dictType)
{ OBJECT_TYPE_CHECK(objDict); return dict->is(dictType); }
diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
index 703a4fd..c91d6e4 100644
--- a/poppler/PDFDoc.cc
+++ b/poppler/PDFDoc.cc
@@ -34,6 +34,7 @@
// Copyright (C) 2015 Li Junling <lijunling at sina.com>
// Copyright (C) 2015 André Guerreiro <aguerreiro1985 at gmail.com>
// Copyright (C) 2015 André Esser <bepandre at hotmail.com>
+// Copyright (C) 2016 Jakub Kucharski <jakubkucharski97 at gmail.com>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
@@ -600,6 +601,72 @@ GBool PDFDoc::isLinearized(GBool tryingToReconstruct) {
}
}
+void PDFDoc::setDocInfoModified(Object *infoObj)
+{
+ Object infoObjRef;
+ getDocInfoNF(&infoObjRef);
+ xref->setModifiedObject(infoObj, infoObjRef.getRef());
+ infoObjRef.free();
+}
+
+void PDFDoc::setDocInfoStringEntry(const char *key, GooString *value)
+{
+ GBool removeEntry = !value || value->getLength() == 0;
+
+ Object infoObj;
+ getDocInfo(&infoObj);
+
+ if (infoObj.isNull() && removeEntry) {
+ // No info dictionary, so no entry to remove.
+ return;
+ }
+
+ createDocInfoIfNoneExists(&infoObj);
+
+ Object gooStrObj;
+ if (removeEntry) {
+ gooStrObj.initNull();
+ } else {
+ gooStrObj.initString(value);
+ }
+
+ // gooStrObj is set to value or null by now. The latter will cause a removal.
+ infoObj.dictSet(key, &gooStrObj);
+
+ if (infoObj.dictGetLength() == 0) {
+ // Info dictionary is empty. Remove it altogether.
+ removeDocInfo();
+ } else {
+ setDocInfoModified(&infoObj);
+ }
+
+ infoObj.free();
+}
+
+GooString *PDFDoc::getDocInfoStringEntry(const char *key) {
+ Object infoObj;
+ getDocInfo(&infoObj);
+ if (infoObj.isNull()) {
+ return NULL;
+ }
+
+ Object entryObj;
+ infoObj.dictLookup(key, &entryObj);
+
+ GooString *result;
+
+ if (entryObj.isString()) {
+ result = entryObj.takeString();
+ } else {
+ result = NULL;
+ }
+
+ entryObj.free();
+ infoObj.free();
+
+ return result;
+}
+
static GBool
get_id (GooString *encodedidstring, GooString *id) {
const char *encodedid = encodedidstring->getCString();
diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h
index 3a65ecb..daff3f4 100644
--- a/poppler/PDFDoc.h
+++ b/poppler/PDFDoc.h
@@ -29,6 +29,7 @@
// Copyright (C) 2013 Adrian Perez de Castro <aperez at igalia.com>
// Copyright (C) 2015 André Guerreiro <aguerreiro1985 at gmail.com>
// Copyright (C) 2015 André Esser <bepandre at hotmail.com>
+// Copyright (C) 2016 Jakub Kucharski <jakubkucharski97 at gmail.com>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
@@ -231,6 +232,43 @@ public:
Object *getDocInfo(Object *obj) { return xref->getDocInfo(obj); }
Object *getDocInfoNF(Object *obj) { return xref->getDocInfoNF(obj); }
+ // Create and return the document's Info dictionary if none exists.
+ // Otherwise return the existing one.
+ Object *createDocInfoIfNoneExists(Object *obj) { return xref->createDocInfoIfNoneExists(obj); }
+
+ // Remove the document's Info dictionary and update the trailer dictionary.
+ void removeDocInfo() { xref->removeDocInfo(); }
+
+ // Set doc info string entry. NULL or empty value will cause a removal.
+ // Takes ownership of value.
+ void setDocInfoStringEntry(const char *key, GooString *value);
+
+ // Set document's properties in document's Info dictionary.
+ // NULL or empty value will cause a removal.
+ // Takes ownership of value.
+ void setDocInfoTitle(GooString *title) { setDocInfoStringEntry("Title", title); }
+ void setDocInfoAuthor(GooString *author) { setDocInfoStringEntry("Author", author); }
+ void setDocInfoSubject(GooString *subject) { setDocInfoStringEntry("Subject", subject); }
+ void setDocInfoKeywords(GooString *keywords) { setDocInfoStringEntry("Keywords", keywords); }
+ void setDocInfoCreator(GooString *creator) { setDocInfoStringEntry("Creator", creator); }
+ void setDocInfoProducer(GooString *producer) { setDocInfoStringEntry("Producer", producer); }
+ void setDocInfoCreatDate(GooString *creatDate) { setDocInfoStringEntry("CreationDate", creatDate); }
+ void setDocInfoModDate(GooString *modDate) { setDocInfoStringEntry("ModDate", modDate); }
+
+ // Get document's properties from document's Info dictionary.
+ // Returns NULL on fail.
+ // Returned GooStrings should be freed by the caller.
+ GooString *getDocInfoStringEntry(const char *key);
+
+ GooString *getDocInfoTitle() { return getDocInfoStringEntry("Title"); }
+ GooString *getDocInfoAuthor() { return getDocInfoStringEntry("Author"); }
+ GooString *getDocInfoSubject() { return getDocInfoStringEntry("Subject"); }
+ GooString *getDocInfoKeywords() { return getDocInfoStringEntry("Keywords"); }
+ GooString *getDocInfoCreator() { return getDocInfoStringEntry("Creator"); }
+ GooString *getDocInfoProducer() { return getDocInfoStringEntry("Producer"); }
+ GooString *getDocInfoCreatDate() { return getDocInfoStringEntry("CreationDate"); }
+ GooString *getDocInfoModDate() { return getDocInfoStringEntry("ModDate"); }
+
// Return the PDF version specified by the file.
int getPDFMajorVersion() { return pdfMajorVersion; }
int getPDFMinorVersion() { return pdfMinorVersion; }
@@ -315,6 +353,9 @@ private:
Goffset getMainXRefEntriesOffset(GBool tryingToReconstruct = gFalse);
long long strToLongLong(char *s);
+ // Mark the document's Info dictionary as modified.
+ void setDocInfoModified(Object *infoObj);
+
GooString *fileName;
#ifdef _WIN32
wchar_t *fileNameU;
diff --git a/poppler/XRef.cc b/poppler/XRef.cc
index 8570819..f88c632 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -1292,6 +1292,40 @@ Object *XRef::getDocInfoNF(Object *obj) {
return trailerDict.dictLookupNF("Info", obj);
}
+Object *XRef::createDocInfoIfNoneExists(Object *obj) {
+ getDocInfo(obj);
+
+ if (!obj->isNull()) {
+ return obj;
+ }
+
+ obj->initDict(this);
+
+ Ref ref = addIndirectObject(obj);
+
+ Object objRef;
+ objRef.initRef(ref.num, ref.gen);
+
+ trailerDict.dictSet("Info", &objRef);
+
+ objRef.free();
+
+ return obj;
+}
+
+void XRef::removeDocInfo() {
+ Object infoObjRef;
+ getDocInfoNF(&infoObjRef);
+ if (infoObjRef.isNull()) {
+ return;
+ }
+
+ trailerDict.dictRemove("Info");
+
+ removeIndirectObject(infoObjRef.getRef());
+ infoObjRef.free();
+}
+
GBool XRef::getStreamEnd(Goffset streamStart, Goffset *streamEnd) {
int a, b, m;
diff --git a/poppler/XRef.h b/poppler/XRef.h
index 739b537..245b14b 100644
--- a/poppler/XRef.h
+++ b/poppler/XRef.h
@@ -150,6 +150,13 @@ public:
Object *getDocInfo(Object *obj);
Object *getDocInfoNF(Object *obj);
+ // Create and return the document's Info dictionary if none exists.
+ // Otherwise return the existing one.
+ Object *createDocInfoIfNoneExists(Object *obj);
+
+ // Remove the document's Info dictionary and update the trailer dictionary.
+ void removeDocInfo();
+
// Return the number of objects in the xref table.
int getNumObjects() { return size; }
commit e2851dd8166fa5a1df0518959ad71c9d81bd9152
Author: Jakub Kucharski <jakubkucharski97 at gmail.com>
Date: Tue Feb 23 15:36:43 2016 +0100
Added XRef modification flag
https://bugs.freedesktop.org/show_bug.cgi?id=36653
diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
index 9fc43e5..703a4fd 100644
--- a/poppler/PDFDoc.cc
+++ b/poppler/PDFDoc.cc
@@ -865,17 +865,7 @@ int PDFDoc::saveAs(GooString *name, PDFWriteMode mode) {
}
int PDFDoc::saveAs(OutStream *outStr, PDFWriteMode mode) {
-
- // find if we have updated objects
- GBool updated = gFalse;
- for(int i=0; i<xref->getNumObjects(); i++) {
- if (xref->getEntry(i)->getFlag(XRefEntry::Updated)) {
- updated = gTrue;
- break;
- }
- }
-
- if (!updated && mode == writeStandard) {
+ if (!xref->isModified() && mode == writeStandard) {
// simply copy the original file
saveWithoutChangesAs (outStr);
} else if (mode == writeForceRewrite) {
diff --git a/poppler/XRef.cc b/poppler/XRef.cc
index 3d032bc..8570819 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -24,6 +24,7 @@
// Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso at hotmail.it>
// Copyright (C) 2013, 2014 Adrian Johnson <ajohnson at redneon.com>
// Copyright (C) 2013 Pino Toscano <pino at kde.org>
+// Copyright (C) 2016 Jakub Kucharski <jakubkucharski97 at gmail.com>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
@@ -286,6 +287,7 @@ void XRef::init() {
entries = NULL;
capacity = 0;
size = 0;
+ modified = gFalse;
streamEnds = NULL;
streamEndsLen = 0;
objStrs = new PopplerCache(5);
@@ -1373,6 +1375,7 @@ void XRef::setModifiedObject (Object* o, Ref r) {
e->obj.free();
o->copy(&(e->obj));
e->setFlag(XRefEntry::Updated, gTrue);
+ setModified();
}
Ref XRef::addIndirectObject (Object* o) {
@@ -1398,6 +1401,7 @@ Ref XRef::addIndirectObject (Object* o) {
e->type = xrefEntryUncompressed;
o->copy(&e->obj);
e->setFlag(XRefEntry::Updated, gTrue);
+ setModified();
Ref r;
r.num = entryIndexToUse;
@@ -1419,6 +1423,7 @@ void XRef::removeIndirectObject(Ref r) {
e->type = xrefEntryFree;
e->gen++;
e->setFlag(XRefEntry::Updated, gTrue);
+ setModified();
}
void XRef::writeXRef(XRef::XRefWriter *writer, GBool writeAllEntries) {
diff --git a/poppler/XRef.h b/poppler/XRef.h
index 8748cb4..739b537 100644
--- a/poppler/XRef.h
+++ b/poppler/XRef.h
@@ -22,6 +22,7 @@
// Copyright (C) 2012, 2013, 2016 Thomas Freitag <Thomas.Freitag at kabelmail.de>
// Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso at hotmail.it>
// Copyright (C) 2013 Adrian Johnson <ajohnson at redneon.com>
+// Copyright (C) 2016 Jakub Kucharski <jakubkucharski97 at gmail.com>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
@@ -175,6 +176,11 @@ public:
XRefEntry *getEntry(int i, GBool complainIfMissing = gTrue);
Object *getTrailerDict() { return &trailerDict; }
+ // Was the XRef modified?
+ GBool isModified() { return modified; }
+ // Set the modification flag for XRef to true.
+ void setModified() { modified = gTrue; }
+
// Write access
void setModifiedObject(Object* o, Ref r);
Ref addIndirectObject (Object* o);
@@ -203,6 +209,7 @@ private:
int errCode; // error code (if <ok> is false)
GBool xrefReconstructed; // marker, true if xref was already reconstructed
Object trailerDict; // trailer dictionary
+ GBool modified;
Goffset *streamEnds; // 'endstream' positions - only used in
// damaged files
int streamEndsLen; // number of valid entries in streamEnds
More information about the poppler
mailing list