[poppler] 3 commits - cpp/CMakeLists.txt cpp/poppler-destination.cpp cpp/poppler-destination.h cpp/poppler-destination-private.h cpp/poppler-document.cpp cpp/poppler-document.h cpp/tests
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Jan 15 23:24:32 UTC 2019
cpp/CMakeLists.txt | 2
cpp/poppler-destination-private.h | 55 +++++++
cpp/poppler-destination.cpp | 285 ++++++++++++++++++++++++++++++++++++++
cpp/poppler-destination.h | 68 +++++++++
cpp/poppler-document.cpp | 56 +++++++
cpp/poppler-document.h | 8 +
cpp/tests/poppler-dump.cpp | 97 ++++++++++++
7 files changed, 571 insertions(+)
New commits:
commit eae71a6b497f0bbafeaf3d8a09dc735e591cdf10
Author: Masamichi Hosoda <trueroad at trueroad.jp>
Date: Sat Jan 12 21:55:17 2019 +0900
cpp: Add named destination for poppler-dump
diff --git a/cpp/tests/poppler-dump.cpp b/cpp/tests/poppler-dump.cpp
index a1a68251..2451be2e 100644
--- a/cpp/tests/poppler-dump.cpp
+++ b/cpp/tests/poppler-dump.cpp
@@ -3,6 +3,7 @@
* Copyright (C) 2017, 2018, Albert Astals Cid <aacid at kde.org>
* Copyright (C) 2017, Jason Alan Palmer <jalanpalmer at gmail.com>
* Copyright (C) 2018, Suzuki Toshiya <mpsuzuki at hiroshima-u.ac.jp>
+ * Copyright (C) 2019, Masamichi Hosoda <trueroad at trueroad.jp>
*
* 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
@@ -20,6 +21,7 @@
*/
#include <goo/glibc.h>
+#include <poppler-destination.h>
#include <poppler-document.h>
#include <poppler-embedded-file.h>
#include <poppler-font.h>
@@ -29,9 +31,11 @@
#include <cstdlib>
#include <cstring>
#include <ctime>
+#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
+#include <map>
#include <memory>
#include <sstream>
@@ -49,6 +53,7 @@ bool show_toc = false;
bool show_fonts = false;
bool show_embedded_files = false;
bool show_pages = false;
+bool show_destinations = false;
bool show_help = false;
char show_text[32];
bool show_text_list = false;
@@ -71,6 +76,8 @@ static const ArgDesc the_args[] = {
"show the document-level embedded files" },
{ "--show-pages", argFlag, &show_pages, 0,
"show pages information" },
+ { "--show-destinations", argFlag, &show_destinations, 0,
+ "show named destinations" },
{ "--show-text", argString, &show_text, sizeof(show_text),
"show text (physical|raw) extracted from all pages" },
{ "--show-text-list", argFlag, &show_text_list, 0,
@@ -317,6 +324,84 @@ static void print_page(poppler::page *p)
std::cout << std::endl;
}
+static void print_destination(const poppler::destination *d)
+{
+ if (d) {
+ std::cout << std::setw(out_width) << "Type" << ": ";
+ switch (d->type()) {
+ case poppler::destination::unknown:
+ std::cout << "unknown" << std::endl;
+ break;
+ case poppler::destination::xyz:
+ std::cout << "xyz" << std::endl
+ << std::setw(out_width)
+ << "Page" << ": " << d->page_number() << std::endl
+ << std::setw(out_width)
+ << "Left" << ": " << d->left() << std::endl
+ << std::setw(out_width)
+ << "Top" << ": " << d->top() << std::endl
+ << std::setw(out_width)
+ << "Zoom" << ": " << d->zoom() << std::endl;
+ break;
+ case poppler::destination::fit:
+ std::cout << "fit" << std::endl
+ << std::setw(out_width)
+ << "Page" << ": " << d->page_number() << std::endl;
+ break;
+ case poppler::destination::fit_h:
+ std::cout << "fit_h" << std::endl
+ << std::setw(out_width)
+ << "Page" << ": " << d->page_number() << std::endl
+ << std::setw(out_width)
+ << "Top" << ": " << d->top() << std::endl;
+ break;
+ case poppler::destination::fit_v:
+ std::cout << "fit_v" << std::endl
+ << std::setw(out_width)
+ << "Page" << ": " << d->page_number() << std::endl
+ << std::setw(out_width)
+ << "Left" << ": " << d->left() << std::endl;
+ break;
+ case poppler::destination::fit_r:
+ std::cout << "fit_r" << std::endl
+ << std::setw(out_width)
+ << "Page" << ": " << d->page_number() << std::endl
+ << std::setw(out_width)
+ << "Left" << ": " << d->left() << std::endl
+ << std::setw(out_width)
+ << "Bottom" << ": " << d->bottom() << std::endl
+ << std::setw(out_width)
+ << "Right" << ": " << d->right() << std::endl
+ << std::setw(out_width)
+ << "Top" << ": " << d->top() << std::endl;
+ break;
+ case poppler::destination::fit_b:
+ std::cout << "fit_b" << std::endl
+ << std::setw(out_width)
+ << "Page" << ": " << d->page_number() << std::endl;
+ break;
+ case poppler::destination::fit_b_h:
+ std::cout << "fit_b_h" << std::endl
+ << std::setw(out_width)
+ << "Page" << ": " << d->page_number() << std::endl
+ << std::setw(out_width)
+ << "Top" << ": " << d->top() << std::endl;
+ break;
+ case poppler::destination::fit_b_v:
+ std::cout << "fit_b_v" << std::endl
+ << std::setw(out_width)
+ << "Page" << ": " << d->page_number() << std::endl
+ << std::setw(out_width)
+ << "Left" << ": " << d->left() << std::endl;
+ break;
+ default:
+ std::cout << "error" << std::endl;
+ break;
+ }
+ }
+ std::cout << std::endl;
+}
+
static void print_page_text(poppler::page *p)
{
if (p) {
@@ -416,6 +501,18 @@ int main(int argc, char *argv[])
print_page(p.get());
}
}
+ if (show_destinations) {
+ auto map = doc->create_destination_map();
+ for (const auto &pair: map) {
+ std::string s = pair.first;
+ for (auto &c: s) {
+ if (c < 0x20 || c>0x7e )
+ c = '.';
+ }
+ std::cout << "Named destination \"" << s << "\":" << std::endl;
+ print_destination(&pair.second);
+ }
+ }
if (show_text[0]) {
const int pages = doc->pages();
for (int i = 0; i < pages; ++i) {
commit ec67506c3d0b1c519bb3e2f0bee90fac328e7ddb
Author: Masamichi Hosoda <trueroad at trueroad.jp>
Date: Sat Jan 12 18:44:42 2019 +0900
cpp: Add document::create_destination_map()
Creates a map of all the named destinations in the document.
diff --git a/cpp/poppler-document.cpp b/cpp/poppler-document.cpp
index 4ce4f780..c58f9663 100644
--- a/cpp/poppler-document.cpp
+++ b/cpp/poppler-document.cpp
@@ -3,6 +3,7 @@
* Copyright (C) 2016 Jakub Alba <jakubalba at gmail.com>
* Copyright (C) 2017, Albert Astals Cid <aacid at kde.org>
* Copyright (C) 2018, Adam Reichold <adam.reichold at t-online.de>
+ * Copyright (C) 2019, Masamichi Hosoda <trueroad at trueroad.jp>
*
* 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
@@ -19,11 +20,13 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include "poppler-destination.h"
#include "poppler-document.h"
#include "poppler-embedded-file.h"
#include "poppler-page.h"
#include "poppler-toc.h"
+#include "poppler-destination-private.h"
#include "poppler-document-private.h"
#include "poppler-embedded-file-private.h"
#include "poppler-page-private.h"
@@ -34,6 +37,7 @@
#include "DateInfo.h"
#include "ErrorCodes.h"
#include "GlobalParams.h"
+#include "Link.h"
#include "Outline.h"
#include <algorithm>
@@ -1023,6 +1027,58 @@ std::vector<embedded_file *> document::embedded_files() const
}
/**
+ 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));
+ LinkDest *link_dest = catalog->getDestsDest (i);
+
+ if (link_dest) {
+ destination dest(new destination_private(link_dest, d->doc));
+
+ m.emplace(std::move(key), std::move(dest));
+
+ delete link_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 ());
+ LinkDest *link_dest = catalog->getDestNameTreeDest (i);
+
+ if (link_dest) {
+ destination dest(new destination_private(link_dest, d->doc));
+
+ m.emplace(std::move(key), std::move(dest));
+
+ delete link_dest;
+ }
+ }
+
+ return m;
+}
+
+/**
Saves the %document to file \p file_name.
\returns true on success, false on failure
diff --git a/cpp/poppler-document.h b/cpp/poppler-document.h
index c2322634..07bd6eef 100644
--- a/cpp/poppler-document.h
+++ b/cpp/poppler-document.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009-2010, Pino Toscano <pino at kde.org>
* Copyright (C) 2016 Jakub Alba <jakubalba at gmail.com>
+ * Copyright (C) 2019, Masamichi Hosoda <trueroad at trueroad.jp>
*
* 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
@@ -23,9 +24,12 @@
#include "poppler-global.h"
#include "poppler-font.h"
+#include <map>
+
namespace poppler
{
+class destination;
class document_private;
class embedded_file;
class page;
@@ -106,6 +110,10 @@ public:
bool has_embedded_files() const;
std::vector<embedded_file *> embedded_files() const;
+ // Named destinations are bytestrings, not string.
+ // So we use std::string instead of ustring.
+ std::map<std::string, destination> create_destination_map() const;
+
bool save(const std::string &filename) const;
bool save_a_copy(const std::string &filename) const;
commit dbed0702722336baf3ed9fc0e780e14fcdec6f3b
Author: Masamichi Hosoda <trueroad at trueroad.jp>
Date: Sat Jan 12 16:08:44 2019 +0900
cpp: Add destination class
The information about a destination used in a PDF document.
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index 4e049bbf..e8e8e9cc 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -9,6 +9,7 @@ configure_file(poppler-version.h.in ${CMAKE_CURRENT_BINARY_DIR}/poppler-version.
add_subdirectory(tests)
set(poppler_cpp_SRCS
+ poppler-destination.cpp
poppler-document.cpp
poppler-embedded-file.cpp
poppler-font.cpp
@@ -33,6 +34,7 @@ target_link_libraries(poppler-cpp poppler ${ICONV_LIBRARIES})
install(TARGETS poppler-cpp RUNTIME DESTINATION bin LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES
+ poppler-destination.h
poppler-document.h
poppler-embedded-file.h
poppler-font.h
diff --git a/cpp/poppler-destination-private.h b/cpp/poppler-destination-private.h
new file mode 100644
index 00000000..5e9b06cc
--- /dev/null
+++ b/cpp/poppler-destination-private.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019, Masamichi Hosoda <trueroad at trueroad.jp>
+ *
+ * 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.
+ */
+
+#ifndef POPPLER_DESTINATION_PRIVATE_H
+#define POPPLER_DESTINATION_PRIVATE_H
+
+#include "poppler-global.h"
+#include "poppler-destination.h"
+
+#include "Object.h"
+
+class PDFDoc;
+class LinkDest;
+
+namespace poppler
+{
+
+class destination_private
+{
+public:
+ destination_private(const LinkDest *ld, PDFDoc *doc);
+
+ destination::type_enum type;
+ bool page_number_unresolved;
+ union {
+ Ref page_ref;
+ int page_number;
+ };
+ double left, bottom;
+ double right, top;
+ double zoom;
+ bool change_left : 1, change_top : 1;
+ bool change_zoom : 1;
+
+ PDFDoc *pdf_doc;
+};
+
+}
+
+#endif
diff --git a/cpp/poppler-destination.cpp b/cpp/poppler-destination.cpp
new file mode 100644
index 00000000..2fcc98db
--- /dev/null
+++ b/cpp/poppler-destination.cpp
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2019, Masamichi Hosoda <trueroad at trueroad.jp>
+ *
+ * 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.
+ */
+
+#include "poppler-destination.h"
+
+#include "poppler-destination-private.h"
+
+#include "PDFDoc.h"
+#include "Link.h"
+
+#include <utility>
+
+using namespace poppler;
+
+destination_private::destination_private(const LinkDest *ld, PDFDoc *doc)
+ : pdf_doc(doc)
+{
+ if (!ld) {
+ type = destination::unknown;
+ return;
+ }
+
+ switch (ld->getKind()) {
+ case ::destXYZ:
+ type = destination::xyz;
+ break;
+ case ::destFit:
+ type = destination::fit;
+ break;
+ case ::destFitH:
+ type = destination::fit_h;
+ break;
+ case ::destFitV:
+ type = destination::fit_v;
+ break;
+ case ::destFitR:
+ type = destination::fit_r;
+ break;
+ case ::destFitB:
+ type = destination::fit_b;
+ break;
+ case ::destFitBH:
+ type = destination::fit_b_h;
+ break;
+ case ::destFitBV:
+ type = destination::fit_b_v;
+ break;
+ default:
+ type = destination::unknown;
+ break;
+ }
+
+ if (!ld->isPageRef()) {
+ // The page number has been resolved.
+ page_number_unresolved = false;
+ page_number = ld->getPageNum();
+ } else if (doc) {
+ // It is necessary to resolve the page number by its accessor.
+ page_number_unresolved = true;
+ page_ref = ld->getPageRef();
+ } else {
+ // The page number cannot be resolved because there is no PDFDoc.
+ page_number_unresolved = false;
+ page_number = 0;
+ }
+
+ left = ld->getLeft();
+ bottom = ld->getBottom();
+ right = ld->getRight();
+ top = ld->getTop();
+ zoom = ld->getZoom();
+ change_left = ld->getChangeLeft();
+ change_top = ld->getChangeTop();
+ change_zoom = ld->getChangeZoom();
+}
+
+/**
+ \class poppler::destination poppler-destination.h "poppler/cpp/poppler-destination.h"
+
+ The information about a destination used in a PDF %document.
+ */
+
+/**
+ \enum poppler::destination::type_enum
+
+ The various types of destinations available in a PDF %document.
+*/
+/**
+ \var poppler::destination::type_enum poppler::destination::unknown
+
+ unknown destination
+*/
+/**
+ \var poppler::destination::type_enum poppler::destination::xyz
+
+ go to page with coordinates (left, top) positioned at the upper-left
+ corner of the window and the contents of the page magnified
+ by the factor zoom
+*/
+/**
+ \var poppler::destination::type_enum poppler::destination::fit
+
+ go to page with its contents magnified just enough to fit the entire page
+ within the window both horizontally and vertically
+*/
+/**
+ \var poppler::destination::type_enum poppler::destination::fit_h
+
+ go to page with the vertical coordinate top positioned at the top edge
+ of the window and the contents of the page magnified just enough to fit
+ the entire width of the page within the window
+*/
+/**
+ \var poppler::destination::type_enum poppler::destination::fit_v
+
+ go to page with the horizontal coordinate left positioned at the left edge
+ of the window and the contents of the page magnified just enough to fit
+ the entire height of the page within the window
+*/
+/**
+ \var poppler::destination::type_enum poppler::destination::fit_r
+
+ go to page with its contents magnified just enough to fit the rectangle
+ specified by the coordinates left, bottom, right, and top entirely
+ within the window both horizontally and vertically
+*/
+/**
+ \var poppler::destination::type_enum poppler::destination::fit_b
+
+ go to page with its contents magnified just enough to fit its bounding box
+ entirely within the window both horizontally and vertically
+*/
+/**
+ \var poppler::destination::type_enum poppler::destination::fit_b_h
+
+ go to page with the vertical coordinate top positioned at the top edge
+ of the window and the contents of the page magnified just enough to fit
+ the entire width of its bounding box within the window
+*/
+/**
+ \var poppler::destination::type_enum poppler::destination::fit_b_v
+
+ go to page with the horizontal coordinate left positioned at the left edge
+ of the window and the contents of the page magnified just enough to fit
+ the entire height of its bounding box within the window
+*/
+
+
+destination::destination(destination_private *dd)
+ : d(dd)
+{
+}
+
+/**
+ Move constructor.
+ */
+destination::destination(destination &&other)
+{
+ *this = std::move(other);
+}
+
+/**
+ \returns the type of the destination
+ */
+destination::type_enum destination::type() const
+{
+ return d->type;
+}
+
+/**
+ \note It is necessary not to destruct parent poppler::document
+ before calling this function for the first time.
+
+ \returns the page number of the destination
+ */
+int destination::page_number() const
+{
+ if (d->page_number_unresolved) {
+ d->page_number_unresolved = false;
+ d->page_number =
+ d->pdf_doc->findPage(d->page_ref.num, d->page_ref.gen);
+ }
+
+ return d->page_number;
+}
+
+/**
+ \returns the left coordinate of the destination
+ */
+double destination::left() const
+{
+ return d->left;
+}
+
+/**
+ \returns the bottom coordinate of the destination
+ */
+double destination::bottom() const
+{
+ return d->bottom;
+}
+
+/**
+ \returns the right coordinate of the destination
+ */
+double destination::right() const
+{
+ return d->right;
+}
+
+/**
+ \returns the top coordinate of the destination
+ */
+double destination::top() const
+{
+ return d->top;
+}
+
+/**
+ \returns the scale factor of the destination
+ */
+double destination::zoom() const
+{
+ return d->zoom;
+}
+
+/**
+ \returns whether left coordinate should be changed
+ */
+bool destination::is_change_left() const
+{
+ return d->change_left;
+}
+
+/**
+ \returns whether top coordinate should be changed
+ */
+bool destination::is_change_top() const
+{
+ return d->change_top;
+}
+
+/**
+ \returns whether scale factor should be changed
+ */
+bool destination::is_change_zoom() const
+{
+ return d->change_zoom;
+}
+
+/**
+ Move assignment operator.
+ */
+destination& destination::operator=(destination &&other)
+{
+ if (this != &other) {
+ d = other.d;
+ other.d = nullptr;
+ }
+
+ return *this;
+}
+
+/**
+ Destructor.
+ */
+destination::~destination()
+{
+ delete d;
+}
diff --git a/cpp/poppler-destination.h b/cpp/poppler-destination.h
new file mode 100644
index 00000000..964c1b5f
--- /dev/null
+++ b/cpp/poppler-destination.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019, Masamichi Hosoda <trueroad at trueroad.jp>
+ *
+ * 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.
+ */
+
+#ifndef POPPLER_DESTINATION_H
+#define POPPLER_DESTINATION_H
+
+#include "poppler-global.h"
+
+namespace poppler
+{
+class destination_private;
+
+class POPPLER_CPP_EXPORT destination : public poppler::noncopyable
+{
+public:
+ enum type_enum {
+ unknown,
+ xyz,
+ fit,
+ fit_h,
+ fit_v,
+ fit_r,
+ fit_b,
+ fit_b_h,
+ fit_b_v
+ };
+
+ ~destination();
+ destination(destination &&other);
+
+ type_enum type() const;
+ int page_number() const;
+ double left() const;
+ double bottom() const;
+ double right() const;
+ double top() const;
+ double zoom() const;
+ bool is_change_left() const;
+ bool is_change_top() const;
+ bool is_change_zoom() const;
+
+ destination& operator=(destination &&other);
+
+private:
+ destination(destination_private *dd);
+
+ destination_private *d;
+ friend class document;
+};
+
+}
+
+#endif
More information about the poppler
mailing list