Spaces:
Running
Running
| /* | |
| * Copyright (C) 2009-2011, Pino Toscano <pino@kde.org> | |
| * Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com> | |
| * Copyright (C) 2017, 2022, Albert Astals Cid <aacid@kde.org> | |
| * Copyright (C) 2018, 2020, Adam Reichold <adam.reichold@t-online.de> | |
| * Copyright (C) 2019, Masamichi Hosoda <trueroad@trueroad.jp> | |
| * Copyright (C) 2019, 2020, Oliver Sander <oliver.sander@tu-dresden.de> | |
| * | |
| * 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) | |
| * any later version. | |
| * | |
| * This program is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| * GNU General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU General Public License | |
| * along with this program; if not, write to the Free Software | |
| * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. | |
| */ | |
| /** | |
| \file poppler-document.h | |
| */ | |
| using namespace poppler; | |
| document_private::document_private(std::unique_ptr<GooString> &&file_path, const std::string &owner_password, const std::string &user_password) : document_private() | |
| { | |
| doc = new PDFDoc(std::move(file_path), GooString(owner_password.c_str()), GooString(user_password.c_str())); | |
| } | |
| document_private::document_private(byte_array *file_data, const std::string &owner_password, const std::string &user_password) : document_private() | |
| { | |
| file_data->swap(doc_data); | |
| MemStream *memstr = new MemStream(&doc_data[0], 0, doc_data.size(), Object(objNull)); | |
| doc = new PDFDoc(memstr, GooString(owner_password.c_str()), GooString(user_password.c_str())); | |
| } | |
| document_private::document_private(const char *file_data, int file_data_length, const std::string &owner_password, const std::string &user_password) : document_private() | |
| { | |
| raw_doc_data = file_data; | |
| raw_doc_data_length = file_data_length; | |
| MemStream *memstr = new MemStream(raw_doc_data, 0, raw_doc_data_length, Object(objNull)); | |
| doc = new PDFDoc(memstr, GooString(owner_password.c_str()), GooString(user_password.c_str())); | |
| } | |
| document_private::document_private() : GlobalParamsIniter(detail::error_function), doc(nullptr), raw_doc_data(nullptr), raw_doc_data_length(0), is_locked(false) { } | |
| document_private::~document_private() | |
| { | |
| delete_all(embedded_files); | |
| delete doc; | |
| } | |
| document *document_private::check_document(document_private *doc, byte_array *file_data) | |
| { | |
| if (doc->doc->isOk() || doc->doc->getErrorCode() == errEncrypted) { | |
| if (doc->doc->getErrorCode() == errEncrypted) { | |
| doc->is_locked = true; | |
| } | |
| return new document(*doc); | |
| } else { | |
| // put back the document data where it was before | |
| if (file_data) { | |
| file_data->swap(doc->doc_data); | |
| } | |
| delete doc; | |
| } | |
| return nullptr; | |
| } | |
| /** | |
| \class poppler::document poppler-document.h "poppler/cpp/poppler-document.h" | |
| Represents a PDF %document. | |
| */ | |
| /** | |
| \enum poppler::document::page_mode_enum | |
| The various page modes available in a PDF %document. | |
| */ | |
| /** | |
| \var poppler::document::page_mode_enum poppler::document::use_none | |
| The %document specifies no particular page mode. | |
| */ | |
| /** | |
| \var poppler::document::page_mode_enum poppler::document::use_outlines | |
| The %document specifies its TOC (table of contents) should be open. | |
| */ | |
| /** | |
| \var poppler::document::page_mode_enum poppler::document::use_thumbs | |
| The %document specifies that should be open a view of the thumbnails of its | |
| pages. | |
| */ | |
| /** | |
| \var poppler::document::page_mode_enum poppler::document::fullscreen | |
| The %document specifies it wants to be open in a fullscreen mode. | |
| */ | |
| /** | |
| \var poppler::document::page_mode_enum poppler::document::use_oc | |
| The %document specifies that should be open a view of its Optional Content | |
| (also known as layers). | |
| */ | |
| /** | |
| \var poppler::document::page_mode_enum poppler::document::use_attach | |
| The %document specifies that should be open a view of its %document-level | |
| attachments. | |
| */ | |
| document::document(document_private &dd) : d(&dd) { } | |
| document::~document() | |
| { | |
| delete d; | |
| } | |
| /** | |
| \returns whether the current %document is locked | |
| */ | |
| bool document::is_locked() const | |
| { | |
| return d->is_locked; | |
| } | |
| /** | |
| Unlocks the current document, if locked. | |
| \returns the new locking status of the document | |
| */ | |
| bool document::unlock(const std::string &owner_password, const std::string &user_password) | |
| { | |
| if (d->is_locked) { | |
| document_private *newdoc = nullptr; | |
| if (d->doc_data.size() > 0) { | |
| newdoc = new document_private(&d->doc_data, owner_password, user_password); | |
| } else if (d->raw_doc_data) { | |
| newdoc = new document_private(d->raw_doc_data, d->raw_doc_data_length, owner_password, user_password); | |
| } else { | |
| newdoc = new document_private(std::make_unique<GooString>(d->doc->getFileName()), owner_password, user_password); | |
| } | |
| if (!newdoc->doc->isOk()) { | |
| d->doc_data.swap(newdoc->doc_data); | |
| delete newdoc; | |
| } else { | |
| delete d; | |
| d = newdoc; | |
| d->is_locked = false; | |
| } | |
| } | |
| return d->is_locked; | |
| } | |
| /** | |
| \returns the eventual page mode specified by the current PDF %document | |
| */ | |
| document::page_mode_enum document::page_mode() const | |
| { | |
| switch (d->doc->getCatalog()->getPageMode()) { | |
| case Catalog::pageModeNone: | |
| return use_none; | |
| case Catalog::pageModeOutlines: | |
| return use_outlines; | |
| case Catalog::pageModeThumbs: | |
| return use_thumbs; | |
| case Catalog::pageModeFullScreen: | |
| return fullscreen; | |
| case Catalog::pageModeOC: | |
| return use_oc; | |
| case Catalog::pageModeAttach: | |
| return use_attach; | |
| default: | |
| return use_none; | |
| } | |
| } | |
| /** | |
| \returns the eventual page layout specified by the current PDF %document | |
| */ | |
| document::page_layout_enum document::page_layout() const | |
| { | |
| switch (d->doc->getCatalog()->getPageLayout()) { | |
| case Catalog::pageLayoutNone: | |
| return no_layout; | |
| case Catalog::pageLayoutSinglePage: | |
| return single_page; | |
| case Catalog::pageLayoutOneColumn: | |
| return one_column; | |
| case Catalog::pageLayoutTwoColumnLeft: | |
| return two_column_left; | |
| case Catalog::pageLayoutTwoColumnRight: | |
| return two_column_right; | |
| case Catalog::pageLayoutTwoPageLeft: | |
| return two_page_left; | |
| case Catalog::pageLayoutTwoPageRight: | |
| return two_page_right; | |
| default: | |
| return no_layout; | |
| } | |
| } | |
| /** | |
| Gets the version of the current PDF %document. | |
| Example: | |
| \code | |
| poppler::document *doc = ...; | |
| // for example, if the document is PDF 1.6: | |
| int major = 0, minor = 0; | |
| doc->get_pdf_version(&major, &minor); | |
| // major == 1 | |
| // minor == 6 | |
| \endcode | |
| \param major if not NULL, will be set to the "major" number of the version | |
| \param minor if not NULL, will be set to the "minor" number of the version | |
| */ | |
| void document::get_pdf_version(int *major, int *minor) const | |
| { | |
| if (major) { | |
| *major = d->doc->getPDFMajorVersion(); | |
| } | |
| if (minor) { | |
| *minor = d->doc->getPDFMinorVersion(); | |
| } | |
| } | |
| /** | |
| \returns all the information keys available in the %document | |
| \see info_key, info_date | |
| */ | |
| std::vector<std::string> document::info_keys() const | |
| { | |
| if (d->is_locked) { | |
| return std::vector<std::string>(); | |
| } | |
| Object info = d->doc->getDocInfo(); | |
| if (!info.isDict()) { | |
| return std::vector<std::string>(); | |
| } | |
| Dict *info_dict = info.getDict(); | |
| std::vector<std::string> keys(info_dict->getLength()); | |
| for (int i = 0; i < info_dict->getLength(); ++i) { | |
| keys[i] = std::string(info_dict->getKey(i)); | |
| } | |
| return keys; | |
| } | |
| /** | |
| Gets the value of the specified \p key of the document information. | |
| \returns the value for the \p key, or an empty string if not available | |
| \see info_keys, info_date | |
| */ | |
| ustring document::info_key(const std::string &key) const | |
| { | |
| if (d->is_locked) { | |
| return ustring(); | |
| } | |
| std::unique_ptr<GooString> goo_value(d->doc->getDocInfoStringEntry(key.c_str())); | |
| if (!goo_value.get()) { | |
| return ustring(); | |
| } | |
| return detail::unicode_GooString_to_ustring(goo_value.get()); | |
| } | |
| /** | |
| Sets the value of the specified \p key of the %document information to \p val. | |
| If \p val is empty, the entry specified by \p key is removed. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::set_info_key(const std::string &key, const ustring &val) | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString *goo_val; | |
| if (val.empty()) { | |
| goo_val = nullptr; | |
| } else { | |
| goo_val = detail::ustring_to_unicode_GooString(val); | |
| } | |
| d->doc->setDocInfoStringEntry(key.c_str(), goo_val); | |
| return true; | |
| } | |
| /** | |
| Gets the time_type value of the specified \p key of the document | |
| information. | |
| \returns the time_t value for the \p key | |
| \see info_keys, info_date | |
| */ | |
| time_type document::info_date(const std::string &key) const | |
| { | |
| if (d->is_locked) { | |
| return time_type(-1); | |
| } | |
| std::unique_ptr<GooString> goo_date(d->doc->getDocInfoStringEntry(key.c_str())); | |
| if (!goo_date.get()) { | |
| return time_type(-1); | |
| } | |
| return static_cast<time_type>(dateStringToTime(goo_date.get())); | |
| } | |
| /** | |
| Gets the time_t value of the specified \p key of the document | |
| information. | |
| \returns the time_t value for the \p key | |
| \see info_keys, info_date | |
| */ | |
| time_t document::info_date_t(const std::string &key) const | |
| { | |
| if (d->is_locked) { | |
| return time_t(-1); | |
| } | |
| std::unique_ptr<GooString> goo_date(d->doc->getDocInfoStringEntry(key.c_str())); | |
| if (!goo_date.get()) { | |
| return time_t(-1); | |
| } | |
| return dateStringToTime(goo_date.get()); | |
| } | |
| /** | |
| Sets the time_type value of the specified \p key of the %document information | |
| to \p val. | |
| If \p val == time_type(-1), the entry specified by \p key is removed. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::set_info_date(const std::string &key, time_type val) | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString *goo_date; | |
| if (val == time_type(-1)) { | |
| goo_date = nullptr; | |
| } else { | |
| time_t t = static_cast<time_t>(val); | |
| goo_date = timeToDateString(&t); | |
| } | |
| d->doc->setDocInfoStringEntry(key.c_str(), goo_date); | |
| return true; | |
| } | |
| /** | |
| Sets the time_t value of the specified \p key of the %document information | |
| to \p val. | |
| If \p val == time_t(-1), the entry specified by \p key is removed. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::set_info_date_t(const std::string &key, time_t val) | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString *goo_date; | |
| if (val == time_t(-1)) { | |
| goo_date = nullptr; | |
| } else { | |
| goo_date = timeToDateString(&val); | |
| } | |
| d->doc->setDocInfoStringEntry(key.c_str(), goo_date); | |
| return true; | |
| } | |
| /** | |
| Gets the %document's title. | |
| \returns the document's title, or an empty string if not available | |
| \see set_title, info_key | |
| */ | |
| ustring document::get_title() const | |
| { | |
| if (d->is_locked) { | |
| return ustring(); | |
| } | |
| std::unique_ptr<GooString> goo_title(d->doc->getDocInfoTitle()); | |
| if (!goo_title.get()) { | |
| return ustring(); | |
| } | |
| return detail::unicode_GooString_to_ustring(goo_title.get()); | |
| } | |
| /** | |
| Sets the %document's title to \p title. | |
| If \p title is empty, the %document's title is removed. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::set_title(const ustring &title) | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString *goo_title; | |
| if (title.empty()) { | |
| goo_title = nullptr; | |
| } else { | |
| goo_title = detail::ustring_to_unicode_GooString(title); | |
| } | |
| d->doc->setDocInfoTitle(goo_title); | |
| return true; | |
| } | |
| /** | |
| Gets the document's author. | |
| \returns the document's author, or an empty string if not available | |
| \see set_author, info_key | |
| */ | |
| ustring document::get_author() const | |
| { | |
| if (d->is_locked) { | |
| return ustring(); | |
| } | |
| std::unique_ptr<GooString> goo_author(d->doc->getDocInfoAuthor()); | |
| if (!goo_author.get()) { | |
| return ustring(); | |
| } | |
| return detail::unicode_GooString_to_ustring(goo_author.get()); | |
| } | |
| /** | |
| Sets the %document's author to \p author. | |
| If \p author is empty, the %document's author is removed. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::set_author(const ustring &author) | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString *goo_author; | |
| if (author.empty()) { | |
| goo_author = nullptr; | |
| } else { | |
| goo_author = detail::ustring_to_unicode_GooString(author); | |
| } | |
| d->doc->setDocInfoAuthor(goo_author); | |
| return true; | |
| } | |
| /** | |
| Gets the document's subject. | |
| \returns the document's subject, or an empty string if not available | |
| \see set_subject, info_key | |
| */ | |
| ustring document::get_subject() const | |
| { | |
| if (d->is_locked) { | |
| return ustring(); | |
| } | |
| std::unique_ptr<GooString> goo_subject(d->doc->getDocInfoSubject()); | |
| if (!goo_subject.get()) { | |
| return ustring(); | |
| } | |
| return detail::unicode_GooString_to_ustring(goo_subject.get()); | |
| } | |
| /** | |
| Sets the %document's subject to \p subject. | |
| If \p subject is empty, the %document's subject is removed. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::set_subject(const ustring &subject) | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString *goo_subject; | |
| if (subject.empty()) { | |
| goo_subject = nullptr; | |
| } else { | |
| goo_subject = detail::ustring_to_unicode_GooString(subject); | |
| } | |
| d->doc->setDocInfoSubject(goo_subject); | |
| return true; | |
| } | |
| /** | |
| Gets the document's keywords. | |
| \returns the document's keywords, or an empty string if not available | |
| \see set_keywords, info_key | |
| */ | |
| ustring document::get_keywords() const | |
| { | |
| if (d->is_locked) { | |
| return ustring(); | |
| } | |
| std::unique_ptr<GooString> goo_keywords(d->doc->getDocInfoKeywords()); | |
| if (!goo_keywords.get()) { | |
| return ustring(); | |
| } | |
| return detail::unicode_GooString_to_ustring(goo_keywords.get()); | |
| } | |
| /** | |
| Sets the %document's keywords to \p keywords. | |
| If \p keywords is empty, the %document's keywords are removed. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::set_keywords(const ustring &keywords) | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString *goo_keywords; | |
| if (keywords.empty()) { | |
| goo_keywords = nullptr; | |
| } else { | |
| goo_keywords = detail::ustring_to_unicode_GooString(keywords); | |
| } | |
| d->doc->setDocInfoKeywords(goo_keywords); | |
| return true; | |
| } | |
| /** | |
| Gets the document's creator. | |
| \returns the document's creator, or an empty string if not available | |
| \see set_creator, info_key | |
| */ | |
| ustring document::get_creator() const | |
| { | |
| if (d->is_locked) { | |
| return ustring(); | |
| } | |
| std::unique_ptr<GooString> goo_creator(d->doc->getDocInfoCreator()); | |
| if (!goo_creator.get()) { | |
| return ustring(); | |
| } | |
| return detail::unicode_GooString_to_ustring(goo_creator.get()); | |
| } | |
| /** | |
| Sets the %document's creator to \p creator. | |
| If \p creator is empty, the %document's creator is removed. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::set_creator(const ustring &creator) | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString *goo_creator; | |
| if (creator.empty()) { | |
| goo_creator = nullptr; | |
| } else { | |
| goo_creator = detail::ustring_to_unicode_GooString(creator); | |
| } | |
| d->doc->setDocInfoCreator(goo_creator); | |
| return true; | |
| } | |
| /** | |
| Gets the document's producer. | |
| \returns the document's producer, or an empty string if not available | |
| \see set_producer, info_key | |
| */ | |
| ustring document::get_producer() const | |
| { | |
| if (d->is_locked) { | |
| return ustring(); | |
| } | |
| std::unique_ptr<GooString> goo_producer(d->doc->getDocInfoProducer()); | |
| if (!goo_producer.get()) { | |
| return ustring(); | |
| } | |
| return detail::unicode_GooString_to_ustring(goo_producer.get()); | |
| } | |
| /** | |
| Sets the %document's producer to \p producer. | |
| If \p producer is empty, the %document's producer is removed. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::set_producer(const ustring &producer) | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString *goo_producer; | |
| if (producer.empty()) { | |
| goo_producer = nullptr; | |
| } else { | |
| goo_producer = detail::ustring_to_unicode_GooString(producer); | |
| } | |
| d->doc->setDocInfoProducer(goo_producer); | |
| return true; | |
| } | |
| /** | |
| Gets the document's creation date as a time_type value. | |
| \returns the document's creation date as a time_type value | |
| \see set_creation_date, info_date | |
| */ | |
| time_type document::get_creation_date() const | |
| { | |
| if (d->is_locked) { | |
| return time_type(-1); | |
| } | |
| std::unique_ptr<GooString> goo_creation_date(d->doc->getDocInfoCreatDate()); | |
| if (!goo_creation_date.get()) { | |
| return time_type(-1); | |
| } | |
| return static_cast<time_type>(dateStringToTime(goo_creation_date.get())); | |
| } | |
| /** | |
| Gets the document's creation date as a time_t value. | |
| \returns the document's creation date as a time_t value | |
| \see set_creation_date, info_date | |
| */ | |
| time_t document::get_creation_date_t() const | |
| { | |
| if (d->is_locked) { | |
| return time_t(-1); | |
| } | |
| std::unique_ptr<GooString> goo_creation_date(d->doc->getDocInfoCreatDate()); | |
| if (!goo_creation_date.get()) { | |
| return time_t(-1); | |
| } | |
| return dateStringToTime(goo_creation_date.get()); | |
| } | |
| /** | |
| Sets the %document's creation date to \p creation_date. | |
| If \p creation_date == time_type(-1), the %document's creation date is removed. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::set_creation_date(time_type creation_date) | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString *goo_creation_date; | |
| if (creation_date == time_type(-1)) { | |
| goo_creation_date = nullptr; | |
| } else { | |
| time_t t = static_cast<time_t>(creation_date); | |
| goo_creation_date = timeToDateString(&t); | |
| } | |
| d->doc->setDocInfoCreatDate(goo_creation_date); | |
| return true; | |
| } | |
| /** | |
| Sets the %document's creation date to \p creation_date. | |
| If \p creation_date == time_t(-1), the %document's creation date is removed. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::set_creation_date_t(time_t creation_date) | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString *goo_creation_date; | |
| if (creation_date == time_t(-1)) { | |
| goo_creation_date = nullptr; | |
| } else { | |
| goo_creation_date = timeToDateString(&creation_date); | |
| } | |
| d->doc->setDocInfoCreatDate(goo_creation_date); | |
| return true; | |
| } | |
| /** | |
| Gets the document's modification date as a time_type value. | |
| \returns the document's modification date as a time_type value | |
| \see set_modification_date, info_date | |
| */ | |
| time_type document::get_modification_date() const | |
| { | |
| if (d->is_locked) { | |
| return time_type(-1); | |
| } | |
| std::unique_ptr<GooString> goo_modification_date(d->doc->getDocInfoModDate()); | |
| if (!goo_modification_date.get()) { | |
| return time_type(-1); | |
| } | |
| return static_cast<time_type>(dateStringToTime(goo_modification_date.get())); | |
| } | |
| /** | |
| Gets the document's modification date as a time_t value. | |
| \returns the document's modification date as a time_t value | |
| \see set_modification_date, info_date | |
| */ | |
| time_t document::get_modification_date_t() const | |
| { | |
| if (d->is_locked) { | |
| return time_t(-1); | |
| } | |
| std::unique_ptr<GooString> goo_modification_date(d->doc->getDocInfoModDate()); | |
| if (!goo_modification_date.get()) { | |
| return time_t(-1); | |
| } | |
| return dateStringToTime(goo_modification_date.get()); | |
| } | |
| /** | |
| Sets the %document's modification date to \p mod_date. | |
| If \p mod_date == time_type(-1), the %document's modification date is removed. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::set_modification_date(time_type mod_date) | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString *goo_mod_date; | |
| if (mod_date == time_type(-1)) { | |
| goo_mod_date = nullptr; | |
| } else { | |
| time_t t = static_cast<time_t>(mod_date); | |
| goo_mod_date = timeToDateString(&t); | |
| } | |
| d->doc->setDocInfoModDate(goo_mod_date); | |
| return true; | |
| } | |
| /** | |
| Sets the %document's modification date to \p mod_date. | |
| If \p mod_date == time_t(-1), the %document's modification date is removed. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::set_modification_date_t(time_t mod_date) | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString *goo_mod_date; | |
| if (mod_date == time_t(-1)) { | |
| goo_mod_date = nullptr; | |
| } else { | |
| goo_mod_date = timeToDateString(&mod_date); | |
| } | |
| d->doc->setDocInfoModDate(goo_mod_date); | |
| return true; | |
| } | |
| /** | |
| Removes the %document's Info dictionary. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::remove_info() | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| d->doc->removeDocInfo(); | |
| return true; | |
| } | |
| /** | |
| \returns whether the document is encrypted | |
| */ | |
| bool document::is_encrypted() const | |
| { | |
| return d->doc->isEncrypted(); | |
| } | |
| /** | |
| \returns whether the document is linearized | |
| */ | |
| bool document::is_linearized() const | |
| { | |
| return d->doc->isLinearized(); | |
| } | |
| /** | |
| Check for available "document permission". | |
| \returns whether the specified permission is allowed | |
| */ | |
| bool document::has_permission(permission_enum which) const | |
| { | |
| switch (which) { | |
| case perm_print: | |
| return d->doc->okToPrint(); | |
| case perm_change: | |
| return d->doc->okToChange(); | |
| case perm_copy: | |
| return d->doc->okToCopy(); | |
| case perm_add_notes: | |
| return d->doc->okToAddNotes(); | |
| case perm_fill_forms: | |
| return d->doc->okToFillForm(); | |
| case perm_accessibility: | |
| return d->doc->okToAccessibility(); | |
| case perm_assemble: | |
| return d->doc->okToAssemble(); | |
| case perm_print_high_resolution: | |
| return d->doc->okToPrintHighRes(); | |
| } | |
| return true; | |
| } | |
| /** | |
| Reads the %document metadata string. | |
| \return the %document metadata string | |
| */ | |
| ustring document::metadata() const | |
| { | |
| std::unique_ptr<GooString> md(d->doc->getCatalog()->readMetadata()); | |
| if (md.get()) { | |
| return detail::unicode_GooString_to_ustring(md.get()); | |
| } | |
| return ustring(); | |
| } | |
| /** | |
| Gets the IDs of the current PDF %document, if available. | |
| \param permanent_id if not NULL, will be set to the permanent ID of the %document | |
| \param update_id if not NULL, will be set to the update ID of the %document | |
| \returns whether the document has the IDs | |
| \since 0.16 | |
| */ | |
| bool document::get_pdf_id(std::string *permanent_id, std::string *update_id) const | |
| { | |
| GooString goo_permanent_id; | |
| GooString goo_update_id; | |
| if (!d->doc->getID(permanent_id ? &goo_permanent_id : nullptr, update_id ? &goo_update_id : nullptr)) { | |
| return false; | |
| } | |
| if (permanent_id) { | |
| *permanent_id = goo_permanent_id.c_str(); | |
| } | |
| if (update_id) { | |
| *update_id = goo_update_id.c_str(); | |
| } | |
| return true; | |
| } | |
| /** | |
| Document page count. | |
| \returns the number of pages of the document | |
| */ | |
| int document::pages() const | |
| { | |
| return d->doc->getNumPages(); | |
| } | |
| /** | |
| Document page by label reading. | |
| This creates a new page representing the %document %page whose label is the | |
| specified \p label. If there is no page with that \p label, NULL is returned. | |
| \returns a new page object or NULL | |
| */ | |
| page *document::create_page(const ustring &label) const | |
| { | |
| std::unique_ptr<GooString> goolabel(detail::ustring_to_unicode_GooString(label)); | |
| int index = 0; | |
| if (!d->doc->getCatalog()->labelToIndex(goolabel.get(), &index)) { | |
| return nullptr; | |
| } | |
| return create_page(index); | |
| } | |
| /** | |
| Document page by index reading. | |
| This creates a new page representing the \p index -th %page of the %document. | |
| \note the page indexes are in the range [0, pages()[. | |
| \returns a new page object or NULL | |
| */ | |
| page *document::create_page(int index) const | |
| { | |
| if (index >= 0 && index < d->doc->getNumPages()) { | |
| page *p = new page(d, index); | |
| if (p->d->page) { | |
| return p; | |
| } else { | |
| delete p; | |
| return nullptr; | |
| } | |
| } else { | |
| return nullptr; | |
| } | |
| } | |
| /** | |
| Reads all the font information of the %document. | |
| \note this can be slow for big documents; prefer the use of a font_iterator | |
| to read incrementally page by page | |
| \see create_font_iterator | |
| */ | |
| std::vector<font_info> document::fonts() const | |
| { | |
| std::vector<font_info> result; | |
| font_iterator it(0, d); | |
| while (it.has_next()) { | |
| const std::vector<font_info> l = it.next(); | |
| std::copy(l.begin(), l.end(), std::back_inserter(result)); | |
| } | |
| return result; | |
| } | |
| /** | |
| Creates a new font iterator. | |
| This creates a new font iterator for reading the font information of the | |
| %document page by page, starting at the specified \p start_page (0 if not | |
| specified). | |
| \returns a new font iterator | |
| */ | |
| font_iterator *document::create_font_iterator(int start_page) const | |
| { | |
| return new font_iterator(start_page, d); | |
| } | |
| /** | |
| Reads the TOC (table of contents) of the %document. | |
| \returns a new toc object if a TOC is available, NULL otherwise | |
| */ | |
| toc *document::create_toc() const | |
| { | |
| return toc_private::load_from_outline(d->doc->getOutline()); | |
| } | |
| /** | |
| Reads whether the current document has %document-level embedded files | |
| (attachments). | |
| This is a very fast way to know whether there are embedded files (also known | |
| as "attachments") at the %document-level. Note this does not take into account | |
| files embedded in other ways (e.g. to annotations). | |
| \returns whether the document has embedded files | |
| */ | |
| bool document::has_embedded_files() const | |
| { | |
| return d->doc->getCatalog()->numEmbeddedFiles() > 0; | |
| } | |
| /** | |
| Reads all the %document-level embedded files of the %document. | |
| \returns the %document-level embedded files | |
| */ | |
| std::vector<embedded_file *> document::embedded_files() const | |
| { | |
| if (d->is_locked) { | |
| return std::vector<embedded_file *>(); | |
| } | |
| if (d->embedded_files.empty() && d->doc->getCatalog()->numEmbeddedFiles() > 0) { | |
| const int num = d->doc->getCatalog()->numEmbeddedFiles(); | |
| d->embedded_files.resize(num); | |
| for (int i = 0; i < num; ++i) { | |
| std::unique_ptr<FileSpec> fs = d->doc->getCatalog()->embeddedFile(i); | |
| d->embedded_files[i] = embedded_file_private::create(std::move(fs)); | |
| } | |
| } | |
| return d->embedded_files; | |
| } | |
| /** | |
| Creates a map of all the named destinations in the %document. | |
| \note The destination names may contain \\0 and other binary values | |
| so they are not printable and cannot convert to null-terminated C strings. | |
| \returns the map of the each name and destination | |
| \since 0.74 | |
| */ | |
| std::map<std::string, destination> document::create_destination_map() const | |
| { | |
| std::map<std::string, destination> m; | |
| Catalog *catalog = d->doc->getCatalog(); | |
| if (!catalog) { | |
| return m; | |
| } | |
| // Iterate from name-dict | |
| const int nDests = catalog->numDests(); | |
| for (int i = 0; i < nDests; ++i) { | |
| std::string key(catalog->getDestsName(i)); | |
| std::unique_ptr<LinkDest> link_dest = catalog->getDestsDest(i); | |
| if (link_dest) { | |
| destination dest(new destination_private(link_dest.get(), d->doc)); | |
| m.emplace(std::move(key), std::move(dest)); | |
| } | |
| } | |
| // Iterate from name-tree | |
| const int nDestsNameTree = catalog->numDestNameTree(); | |
| for (int i = 0; i < nDestsNameTree; ++i) { | |
| std::string key(catalog->getDestNameTreeName(i)->c_str(), catalog->getDestNameTreeName(i)->getLength()); | |
| std::unique_ptr<LinkDest> link_dest = catalog->getDestNameTreeDest(i); | |
| if (link_dest) { | |
| destination dest(new destination_private(link_dest.get(), d->doc)); | |
| m.emplace(std::move(key), std::move(dest)); | |
| } | |
| } | |
| return m; | |
| } | |
| /** | |
| Saves the %document to file \p file_name. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::save(const std::string &file_name) const | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString fname(file_name.c_str()); | |
| return d->doc->saveAs(fname) == errNone; | |
| } | |
| /** | |
| Saves the original version of the %document to file \p file_name. | |
| \returns true on success, false on failure | |
| */ | |
| bool document::save_a_copy(const std::string &file_name) const | |
| { | |
| if (d->is_locked) { | |
| return false; | |
| } | |
| GooString fname(file_name.c_str()); | |
| return d->doc->saveWithoutChangesAs(fname) == errNone; | |
| } | |
| /** | |
| Tries to load a PDF %document from the specified file. | |
| \param file_name the file to open | |
| \returns a new document if the load succeeded (even if the document is locked), | |
| NULL otherwise | |
| */ | |
| document *document::load_from_file(const std::string &file_name, const std::string &owner_password, const std::string &user_password) | |
| { | |
| document_private *doc = new document_private(std::make_unique<GooString>(file_name.c_str()), owner_password, user_password); | |
| return document_private::check_document(doc, nullptr); | |
| } | |
| /** | |
| Tries to load a PDF %document from the specified data. | |
| \note if the loading succeeds, the document takes ownership of the | |
| \p file_data (swap()ing it) | |
| \param file_data the data representing a document to open | |
| \returns a new document if the load succeeded (even if the document is locked), | |
| NULL otherwise | |
| */ | |
| document *document::load_from_data(byte_array *file_data, const std::string &owner_password, const std::string &user_password) | |
| { | |
| if (!file_data || file_data->size() < 10) { | |
| return nullptr; | |
| } | |
| document_private *doc = new document_private(file_data, owner_password, user_password); | |
| return document_private::check_document(doc, file_data); | |
| } | |
| /** | |
| Tries to load a PDF %document from the specified data buffer. | |
| \note the buffer must remain valid for the whole lifetime of the returned | |
| document | |
| \param file_data the data buffer representing a document to open | |
| \param file_data_length the length of the data buffer | |
| \returns a new document if the load succeeded (even if the document is locked), | |
| NULL otherwise | |
| \since 0.16 | |
| */ | |
| document *document::load_from_raw_data(const char *file_data, int file_data_length, const std::string &owner_password, const std::string &user_password) | |
| { | |
| if (!file_data || file_data_length < 10) { | |
| return nullptr; | |
| } | |
| document_private *doc = new document_private(file_data, file_data_length, owner_password, user_password); | |
| return document_private::check_document(doc, nullptr); | |
| } | |