[poppler] 35 commits - CMakeLists.txt cmake/modules config.h.cmake configure.ac cpp/CMakeLists.txt cpp/.gitignore cpp/Makefile.am cpp/poppler-document.cpp cpp/poppler-document.h cpp/poppler-document-private.h cpp/poppler-embedded-file.cpp cpp/poppler-embedded-file.h cpp/poppler-embedded-file-private.h cpp/poppler-font.cpp cpp/poppler-font.h cpp/poppler-global.cpp cpp/poppler-global.h cpp/poppler-page.cpp cpp/poppler-page.h cpp/poppler-page-private.h cpp/poppler-page-transition.cpp cpp/poppler-page-transition.h cpp/poppler-private.cpp cpp/poppler-private.h cpp/poppler-rectangle.cpp cpp/poppler-rectangle.h cpp/poppler-toc.cpp cpp/poppler-toc.h cpp/poppler-toc-private.h cpp/poppler-version.cpp cpp/poppler-version.h.in cpp/tests .gitignore m4/iconv.m4 Makefile.am poppler-cpp.pc.cmake poppler-cpp.pc.in

Pino Toscano pino at kemper.freedesktop.org
Sun Feb 21 11:01:36 PST 2010


 .gitignore                          |    1 
 CMakeLists.txt                      |   14 +
 Makefile.am                         |   16 +
 cmake/modules/FindIconv.cmake       |   57 +++++
 config.h.cmake                      |    6 
 configure.ac                        |   27 ++
 cpp/.gitignore                      |    7 
 cpp/CMakeLists.txt                  |   42 +++
 cpp/Makefile.am                     |   37 +++
 cpp/poppler-document-private.h      |   60 +++++
 cpp/poppler-document.cpp            |  391 ++++++++++++++++++++++++++++++++++++
 cpp/poppler-document.h              |   99 +++++++++
 cpp/poppler-embedded-file-private.h |   40 +++
 cpp/poppler-embedded-file.cpp       |  116 ++++++++++
 cpp/poppler-embedded-file.h         |   55 +++++
 cpp/poppler-font.cpp                |  166 +++++++++++++++
 cpp/poppler-font.h                  |   91 ++++++++
 cpp/poppler-global.cpp              |  215 +++++++++++++++++++
 cpp/poppler-global.h                |   96 ++++++++
 cpp/poppler-page-private.h          |   44 ++++
 cpp/poppler-page-transition.cpp     |   95 ++++++++
 cpp/poppler-page-transition.h       |   82 +++++++
 cpp/poppler-page.cpp                |  121 +++++++++++
 cpp/poppler-page.h                  |   62 +++++
 cpp/poppler-private.cpp             |  107 +++++++++
 cpp/poppler-private.h               |   66 ++++++
 cpp/poppler-rectangle.cpp           |   35 +++
 cpp/poppler-rectangle.h             |   66 ++++++
 cpp/poppler-toc-private.h           |   62 +++++
 cpp/poppler-toc.cpp                 |  142 +++++++++++++
 cpp/poppler-toc.h                   |   74 ++++++
 cpp/poppler-version.cpp             |   41 +++
 cpp/poppler-version.h.in            |   39 +++
 cpp/tests/.gitignore                |    1 
 cpp/tests/CMakeLists.txt            |   24 ++
 cpp/tests/Makefile.am               |   17 +
 cpp/tests/poppler-dump.cpp          |  343 +++++++++++++++++++++++++++++++
 m4/iconv.m4                         |  180 ++++++++++++++++
 poppler-cpp.pc.cmake                |    9 
 poppler-cpp.pc.in                   |    9 
 40 files changed, 3151 insertions(+), 4 deletions(-)

New commits:
commit a18dab9e53a20a76eb46fa3a868fffdd3c754ce2
Merge: fa09892... f3862f7...
Author: Pino Toscano <pino at kde.org>
Date:   Sun Feb 21 19:56:38 2010 +0100

    Merge remote branch 'origin/cpp-frontend'
    
    * origin/cpp-frontend: (34 commits)
      [cpp/tests] poppler-dump: show a string for the font type
      [cpp/tests] poppler-dump: show the orientation of the pages
      [cpp/tests] poppler-dump: a bit less output in permissions lines
      [cpp/tests] poppler-dump: add --show-all to show all the information
      [cpp] use iconv for the utf8 <-> utf16 conversions
      [cpp] add the build system stuff for iconv, mandatory for cpp
      [cpp] fixup unicode GooString <-> ustring conversions
      [cpp] fix installation of poppler-version.h with autotools and builddir != srcdir
      simplify
      [cpp/tests] add a simple poppler-dump test
      [cpp] use the correct index (instead of an uninitialized variable)
      [cpp] properly delete the children of a toc item
      [cpp] actually implement toc::root()
      [cpp] fix the reference to the vector data
      [cpp] fix the reference to the vector data
      [cpp] add destructor for 'rectangle'
      [cpp] add out stream operators for rect and rectf
      [cpp] add namespace to namespace functiond to link properly
      [cpp] add default empty parameters for the passwords of the document loading functions
      [cpp] add "human friendly" output representation for byte_array
      ...
    
    Conflicts:
    	config.h.cmake

diff --cc config.h.cmake
index 0097d8d,253e730..ec12045
--- a/config.h.cmake
+++ b/config.h.cmake
@@@ -46,9 -36,9 +46,12 @@@
  /* Defines if gettimeofday is available on your system */
  #cmakedefine HAVE_GETTIMEOFDAY 1
  
 +/* Defines if gmtime_r is available on your system */
 +#cmakedefine HAVE_GMTIME_R 1
 +
+ /* Define if you have the iconv() function and it works. */
+ #cmakedefine HAVE_ICONV 1
+ 
  /* Define to 1 if you have the <inttypes.h> header file. */
  #cmakedefine HAVE_INTTYPES_H 1
  
@@@ -120,6 -93,12 +123,9 @@@
  /* Define to 1 if you have the <zlib.h> header file. */
  #cmakedefine HAVE_ZLIB_H 1
  
+ /* Define as const if the declaration of iconv() needs const. */
+ #cmakedefine ICONV_CONST 1
+ 
 -/* Define to 1 if gdk was found */
 -#cmakedefine POPPLER_WITH_GDK 1
 -
  /* Enable multithreading support. */
  #cmakedefine MULTITHREADED 1
  
commit f3862f7d987aae52a1fd2bb0af27d1cd803a5b84
Author: Pino Toscano <pino at kde.org>
Date:   Thu Dec 31 00:20:11 2009 +0100

    [cpp/tests] poppler-dump: show a string for the font type

diff --git a/cpp/tests/poppler-dump.cpp b/cpp/tests/poppler-dump.cpp
index ef96ca7..745d038 100644
--- a/cpp/tests/poppler-dump.cpp
+++ b/cpp/tests/poppler-dump.cpp
@@ -132,6 +132,27 @@ static std::string out_page_orientation(poppler::page::orientation_enum o)
     return "<unknown orientation>";
 }
 
+static std::string out_font_info_type(poppler::font_info::type_enum t)
+{
+#define OUT_FONT_TYPE(thetype) case poppler::font_info::thetype: return #thetype
+    switch (t) {
+    OUT_FONT_TYPE(unknown);
+    OUT_FONT_TYPE(type1);
+    OUT_FONT_TYPE(type1c);
+    OUT_FONT_TYPE(type1c_ot);
+    OUT_FONT_TYPE(type3);
+    OUT_FONT_TYPE(truetype);
+    OUT_FONT_TYPE(truetype_ot);
+    OUT_FONT_TYPE(cid_type0);
+    OUT_FONT_TYPE(cid_type0c);
+    OUT_FONT_TYPE(cid_type0c_ot);
+    OUT_FONT_TYPE(cid_truetype);
+    OUT_FONT_TYPE(cid_truetype_ot);
+    }
+    return "<unknown font type>";
+#undef OUT_FONT_TYPE
+}
+
 static void print_info(poppler::document *doc)
 {
     std::cout << "Document information:" << std::endl;
@@ -209,7 +230,7 @@ static void print_fonts(poppler::document *doc)
         for (; it != it_end; ++it) {
             std::cout
                 << " " << std::setw(out_width + 10) << it->name()
-                << " " << std::setw(15) << it->type()
+                << " " << std::setw(15) << out_font_info_type(it->type())
                 << " " << std::setw(5) << it->is_embedded()
                 << " " << std::setw(5) << it->is_subset()
                 << " " << it->file()
commit 9c343c821593ebae51ac47b58ad007a82f198652
Author: Pino Toscano <pino at kde.org>
Date:   Thu Dec 31 00:13:09 2009 +0100

    [cpp/tests] poppler-dump: show the orientation of the pages

diff --git a/cpp/tests/poppler-dump.cpp b/cpp/tests/poppler-dump.cpp
index 8e2b6cf..ef96ca7 100644
--- a/cpp/tests/poppler-dump.cpp
+++ b/cpp/tests/poppler-dump.cpp
@@ -117,6 +117,21 @@ static std::string out_hex_string(const std::string &str)
     return ret;
 }
 
+static std::string out_page_orientation(poppler::page::orientation_enum o)
+{
+    switch (o) {
+    case poppler::page::landscape:
+        return "landscape (90)";
+    case poppler::page::portrait:
+        return "portrait (0)";
+    case poppler::page::seascape:
+        return "seascape (270)";
+    case poppler::page::upside_down:
+        return "upside_downs (180)";
+    };
+    return "<unknown orientation>";
+}
+
 static void print_info(poppler::document *doc)
 {
     std::cout << "Document information:" << std::endl;
@@ -241,6 +256,7 @@ static void print_page(poppler::page *p)
     std::cout << std::setw(out_width) << "Rect" << ": " << p->page_rect() << std::endl;
     std::cout << std::setw(out_width) << "Label" << ": " << out_ustring(p->label()) << std::endl;
     std::cout << std::setw(out_width) << "Duration" << ": " << p->duration() << std::endl;
+    std::cout << std::setw(out_width) << "Orientation" << ": " << out_page_orientation(p->orientation()) << std::endl;
     std::cout << std::endl;
 }
 
commit bc91fe3824f37cd17a38aac85c817e8ada1b2f43
Author: Pino Toscano <pino at kde.org>
Date:   Wed Dec 30 23:53:31 2009 +0100

    [cpp/tests] poppler-dump: a bit less output in permissions lines

diff --git a/cpp/tests/poppler-dump.cpp b/cpp/tests/poppler-dump.cpp
index 5e3d33e..8e2b6cf 100644
--- a/cpp/tests/poppler-dump.cpp
+++ b/cpp/tests/poppler-dump.cpp
@@ -140,7 +140,7 @@ static void print_perm(poppler::document *doc)
 {
     std::cout << "Document permissions:" << std::endl;
 #define OUT_PERM(theperm) \
-    std::cout << std::setw(out_width) << "Perm (" #theperm ")" << ": " \
+    std::cout << std::setw(out_width) << #theperm << ": " \
               << doc->has_permission(poppler::perm_##theperm) << std::endl
     OUT_PERM(print);
     OUT_PERM(change);
commit 1199de8f097a78edb831313841ac0ed3f9ec9905
Author: Pino Toscano <pino at kde.org>
Date:   Wed Dec 30 23:50:36 2009 +0100

    [cpp/tests] poppler-dump: add --show-all to show all the information

diff --git a/cpp/tests/poppler-dump.cpp b/cpp/tests/poppler-dump.cpp
index de50244..5e3d33e 100644
--- a/cpp/tests/poppler-dump.cpp
+++ b/cpp/tests/poppler-dump.cpp
@@ -33,6 +33,7 @@
 
 static const int out_width = 30;
 
+bool show_all = false;
 bool show_info = false;
 bool show_perm = false;
 bool show_metadata = false;
@@ -43,6 +44,8 @@ bool show_pages = false;
 bool show_help = false;
 
 static const ArgDesc the_args[] = {
+    { "--show-all",            argFlag,  &show_all,            0,
+      "show all the available information" },
     { "--show-info",           argFlag,  &show_info,           0,
       "show general document information" },
     { "--show-perm",           argFlag,  &show_perm,           0,
@@ -261,6 +264,16 @@ int main(int argc, char *argv[])
 
     std::cout.setf(std::ios_base::boolalpha);
 
+    if (show_all) {
+        show_info = true;
+        show_perm = true;
+        show_metadata = true;
+        show_toc = true;
+        show_fonts = true;
+        show_embedded_files = true;
+        show_pages = true;
+    }
+
     if (show_info) {
         print_info(doc.get());
     }
commit 9522f830b59942adfc91d5f03c274415a4737ccc
Author: Pino Toscano <pino at kde.org>
Date:   Wed Dec 30 23:38:40 2009 +0100

    [cpp] use iconv for the utf8 <-> utf16 conversions

diff --git a/cpp/poppler-global.cpp b/cpp/poppler-global.cpp
index 424f947..deae74b 100644
--- a/cpp/poppler-global.cpp
+++ b/cpp/poppler-global.cpp
@@ -20,10 +20,32 @@
 
 #include "DateInfo.h"
 
+#include <cerrno>
 #include <ctime>
 #include <cstring>
 #include <iostream>
 
+#include <iconv.h>
+
+namespace
+{
+
+struct MiniIconv
+{
+    MiniIconv(const char *to_code, const char *from_code)
+        : i_(iconv_open(to_code, from_code))
+    {}
+    ~MiniIconv()
+    { if (is_valid()) iconv_close(i_); }
+    bool is_valid() const
+    { return i_ != (iconv_t)-1; }
+    operator iconv_t() const
+    { return i_; }
+    iconv_t i_;
+};
+
+}
+
 using namespace poppler;
 
 noncopyable::noncopyable()
@@ -54,14 +76,28 @@ byte_array ustring::to_utf_8() const
         return byte_array();
     }
 
-    const value_type *me = data();
-    const size_t len = size() * 2 + 2;
-    byte_array str(len);
-    str[0] = 0xfe;
-    str[1] = 0xff;
-    for (size_t i = 0; i < size(); ++i, ++me) {
-        str[i * 2 + 2] = (*me & 0xff);
-        str[i * 2 + 3] = ((*me >> 8) & 0xff);
+    MiniIconv ic("UTF-8", "UTF-16");
+    if (!ic.is_valid()) {
+        return byte_array();
+    }
+    const value_type *me_data = data();
+    byte_array str(size());
+    char *str_data = &str[0];
+    size_t me_len_char = size() * 2;
+    size_t str_len_left = str.size();
+    size_t ir = iconv(ic, (char **)&me_data, &me_len_char, &str_data, &str_len_left);
+    if ((ir == (size_t)-1) && (errno == E2BIG)) {
+        const size_t delta = str_data - &str[0];
+        str_len_left += str.size();
+        str.resize(str.size() * 2);
+        str_data = &str[delta];
+        ir = iconv(ic, (char **)&me_data, &me_len_char, &str_data, &str_len_left);
+        if (ir == (size_t)-1) {
+            return byte_array();
+        }
+    }
+    if (str_len_left >= 0) {
+        str.resize(str.size() - str_len_left);
     }
     return str;
 }
@@ -90,30 +126,30 @@ ustring ustring::from_utf_8(const char *str, int len)
         }
     }
 
-    int i = 0;
-    bool is_unicode = false;
-    if ((str[0] & 0xff) == 0xfe && (len > 1 && (str[1] & 0xff) == 0xff)) {
-        is_unicode = true;
-        i = 2;
+    MiniIconv ic("UTF-16", "UTF-8");
+    if (!ic.is_valid()) {
+        return ustring();
     }
 
-    const ustring::size_type ret_len = (len - i) / (is_unicode ? 2 : 1);
-    ustring ret(ret_len, 0);
-    size_t ret_index = 0;
-    ustring::value_type u;
-    if (is_unicode) {
-        while (i < len) {
-            u = ((str[i] & 0xff) << 8) | (str[i + 1] & 0xff);
-            i += 2;
-            ret[ret_index++] = u;
-        }
-    } else {
-        while (i < len) {
-            u = str[i] & 0xff;
-            ++i;
-            ret[ret_index++] = u;
+    ustring ret(len, 0);
+    char *ret_data = reinterpret_cast<char *>(&ret[0]);
+    char *str_data = const_cast<char *>(str);
+    size_t str_len_char = len;
+    size_t ret_len_left = ret.size();
+    size_t ir = iconv(ic, &str_data, &str_len_char, &ret_data, &ret_len_left);
+    if ((ir == (size_t)-1) && (errno == E2BIG)) {
+        const size_t delta = ret_data - reinterpret_cast<char *>(&ret[0]);
+        ret_len_left += ret.size();
+        ret.resize(ret.size() * 2);
+        ret_data = reinterpret_cast<char *>(&ret[delta]);
+        ir = iconv(ic, (char **)&str_data, &str_len_char, &ret_data, &ret_len_left);
+        if (ir == (size_t)-1) {
+            return ustring();
         }
     }
+    if (ret_len_left >= 0) {
+        ret.resize(ret.size() - ret_len_left);
+    }
 
     return ret;
 }
commit b156b4031f5daf658f40db8efa2a3016d95b98b5
Author: Pino Toscano <pino at kde.org>
Date:   Wed Dec 30 23:24:23 2009 +0100

    [cpp] add the build system stuff for iconv, mandatory for cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 023229c..18b6a8e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -62,6 +62,12 @@ if(GLIB_FOUND)
     set(CAIRO_REQ "cairo")
   endif(CAIRO_FOUND)
 endif(GLIB_FOUND)
+if(ENABLE_CPP)
+  macro_optional_find_package(Iconv)
+  set(ENABLE_CPP ${ICONV_FOUND})
+  set(HAVE_ICONV ${ICONV_FOUND})
+  set(ICONV_CONST ${ICONV_SECOND_ARGUMENT_IS_CONST})
+endif(ENABLE_CPP)
 if(ENABLE_ZLIB)
   find_package(ZLIB)
   if(ZLIB_FOUND)
diff --git a/Makefile.am b/Makefile.am
index 6d279ad..aedf60f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -73,6 +73,7 @@ EXTRA_DIST +=							\
 	cmake/modules/FindCairo.cmake				\
 	cmake/modules/FindFontconfig.cmake			\
 	cmake/modules/FindGTK.cmake				\
+	cmake/modules/FindIconv.cmake				\
 	cmake/modules/FindLCMS.cmake				\
 	cmake/modules/FindQt3.cmake				\
 	cmake/modules/FindQt4.cmake				\
diff --git a/cmake/modules/FindIconv.cmake b/cmake/modules/FindIconv.cmake
new file mode 100644
index 0000000..ce40ab2
--- /dev/null
+++ b/cmake/modules/FindIconv.cmake
@@ -0,0 +1,57 @@
+# - Try to find Iconv 
+# Once done this will define 
+# 
+#  ICONV_FOUND - system has Iconv 
+#  ICONV_INCLUDE_DIR - the Iconv include directory 
+#  ICONV_LIBRARIES - Link these to use Iconv 
+#  ICONV_SECOND_ARGUMENT_IS_CONST - the second argument for iconv() is const
+# 
+include(CheckCXXSourceCompiles)
+
+IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
+  # Already in cache, be silent
+  SET(ICONV_FIND_QUIETLY TRUE)
+ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
+
+FIND_PATH(ICONV_INCLUDE_DIR iconv.h) 
+ 
+FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c)
+ 
+IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 
+   SET(ICONV_FOUND TRUE) 
+ENDIF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) 
+
+set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
+set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES})
+IF(ICONV_FOUND)
+  check_cxx_source_compiles("
+  #include <iconv.h>
+  int main(){
+    iconv_t conv = 0;
+    const char* in = 0;
+    size_t ilen = 0;
+    char* out = 0;
+    size_t olen = 0;
+    iconv(conv, &in, &ilen, &out, &olen);
+    return 0;
+  }
+" ICONV_SECOND_ARGUMENT_IS_CONST )
+ENDIF(ICONV_FOUND)
+set(CMAKE_REQUIRED_INCLUDES)
+set(CMAKE_REQUIRED_LIBRARIES)
+
+IF(ICONV_FOUND) 
+  IF(NOT ICONV_FIND_QUIETLY) 
+    MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}") 
+  ENDIF(NOT ICONV_FIND_QUIETLY) 
+ELSE(ICONV_FOUND) 
+  IF(Iconv_FIND_REQUIRED) 
+    MESSAGE(FATAL_ERROR "Could not find Iconv") 
+  ENDIF(Iconv_FIND_REQUIRED) 
+ENDIF(ICONV_FOUND) 
+
+MARK_AS_ADVANCED(
+  ICONV_INCLUDE_DIR
+  ICONV_LIBRARIES
+  ICONV_SECOND_ARGUMENT_IS_CONST
+)
diff --git a/config.h.cmake b/config.h.cmake
index 7b57de0..253e730 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -36,6 +36,9 @@
 /* Defines if gettimeofday is available on your system */
 #cmakedefine HAVE_GETTIMEOFDAY 1
 
+/* Define if you have the iconv() function and it works. */
+#cmakedefine HAVE_ICONV 1
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 #cmakedefine HAVE_INTTYPES_H 1
 
@@ -90,6 +93,9 @@
 /* Define to 1 if you have the <zlib.h> header file. */
 #cmakedefine HAVE_ZLIB_H 1
 
+/* Define as const if the declaration of iconv() needs const. */
+#cmakedefine ICONV_CONST 1
+
 /* Define to 1 if gdk was found */
 #cmakedefine POPPLER_WITH_GDK 1
 
diff --git a/configure.ac b/configure.ac
index a51eede..102a0b2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -453,6 +453,12 @@ AC_ARG_ENABLE(poppler-cpp,
                              [Don't compile poppler cpp wrapper.]),
               enable_poppler_cpp=$enableval,
               enable_poppler_cpp="yes")
+if test x$enable_poppler_cpp = xyes; then
+  AM_ICONV()
+  if test x$am_func_iconv != xyes; then
+    enable_poppler_cpp=no
+  fi
+fi
 
 AM_CONDITIONAL(BUILD_POPPLER_CPP, test "x$enable_poppler_cpp" = "xyes")
 
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index b5880de..4c1d7c4 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -22,7 +22,7 @@ set(poppler_cpp_SRCS
 
 add_library(poppler-cpp SHARED ${poppler_cpp_SRCS})
 set_target_properties(poppler-cpp PROPERTIES VERSION 0.1.0 SOVERSION 0)
-target_link_libraries(poppler-cpp poppler)
+target_link_libraries(poppler-cpp poppler ${ICONV_LIBRARIES})
 if(MSVC)
 target_link_libraries(poppler-cpp ${poppler_LIBS})
 endif(MSVC)
diff --git a/cpp/Makefile.am b/cpp/Makefile.am
index 4fb1874..2e3f56d 100644
--- a/cpp/Makefile.am
+++ b/cpp/Makefile.am
@@ -31,6 +31,7 @@ libpoppler_cpp_la_SOURCES =			\
 	poppler-version.cpp
 
 libpoppler_cpp_la_LIBADD = 			\
-	$(top_builddir)/poppler/libpoppler.la
+	$(top_builddir)/poppler/libpoppler.la	\
+	$(LIBICONV)
 
 libpoppler_cpp_la_LDFLAGS = -version-info 1:0:1 @create_shared_lib@
diff --git a/m4/iconv.m4 b/m4/iconv.m4
new file mode 100644
index 0000000..b2156eb
--- /dev/null
+++ b/m4/iconv.m4
@@ -0,0 +1,180 @@
+# iconv.m4 serial AM6 (gettext-0.17)
+dnl Copyright (C) 2000-2002, 2007 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
+[
+  dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+  dnl AC_REQUIRE([AC_LIB_RPATH])
+
+  dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+  dnl accordingly.
+  AC_LIB_LINKFLAGS_BODY([iconv])
+])
+
+AC_DEFUN([AM_ICONV_LINK],
+[
+  dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
+  dnl those with the standalone portable GNU libiconv installed).
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+  dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+  dnl accordingly.
+  AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+
+  dnl Add $INCICONV to CPPFLAGS before performing the following checks,
+  dnl because if the user has installed libiconv and not disabled its use
+  dnl via --without-libiconv-prefix, he wants to use it. The first
+  dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed.
+  am_save_CPPFLAGS="$CPPFLAGS"
+  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
+
+  AC_CACHE_CHECK([for iconv], am_cv_func_iconv, [
+    am_cv_func_iconv="no, consider installing GNU libiconv"
+    am_cv_lib_iconv=no
+    AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],
+      [iconv_t cd = iconv_open("","");
+       iconv(cd,NULL,NULL,NULL,NULL);
+       iconv_close(cd);],
+      am_cv_func_iconv=yes)
+    if test "$am_cv_func_iconv" != yes; then
+      am_save_LIBS="$LIBS"
+      LIBS="$LIBS $LIBICONV"
+      AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],
+        [iconv_t cd = iconv_open("","");
+         iconv(cd,NULL,NULL,NULL,NULL);
+         iconv_close(cd);],
+        am_cv_lib_iconv=yes
+        am_cv_func_iconv=yes)
+      LIBS="$am_save_LIBS"
+    fi
+  ])
+  if test "$am_cv_func_iconv" = yes; then
+    AC_CACHE_CHECK([for working iconv], am_cv_func_iconv_works, [
+      dnl This tests against bugs in AIX 5.1 and HP-UX 11.11.
+      am_save_LIBS="$LIBS"
+      if test $am_cv_lib_iconv = yes; then
+        LIBS="$LIBS $LIBICONV"
+      fi
+      AC_TRY_RUN([
+#include <iconv.h>
+#include <string.h>
+int main ()
+{
+  /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
+     returns.  */
+  {
+    iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
+    if (cd_utf8_to_88591 != (iconv_t)(-1))
+      {
+        static const char input[] = "\342\202\254"; /* EURO SIGN */
+        char buf[10];
+        const char *inptr = input;
+        size_t inbytesleft = strlen (input);
+        char *outptr = buf;
+        size_t outbytesleft = sizeof (buf);
+        size_t res = iconv (cd_utf8_to_88591,
+                            (char **) &inptr, &inbytesleft,
+                            &outptr, &outbytesleft);
+        if (res == 0)
+          return 1;
+      }
+  }
+#if 0 /* This bug could be worked around by the caller.  */
+  /* Test against HP-UX 11.11 bug: Positive return value instead of 0.  */
+  {
+    iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
+    if (cd_88591_to_utf8 != (iconv_t)(-1))
+      {
+        static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+        char buf[50];
+        const char *inptr = input;
+        size_t inbytesleft = strlen (input);
+        char *outptr = buf;
+        size_t outbytesleft = sizeof (buf);
+        size_t res = iconv (cd_88591_to_utf8,
+                            (char **) &inptr, &inbytesleft,
+                            &outptr, &outbytesleft);
+        if ((int)res > 0)
+          return 1;
+      }
+  }
+#endif
+  /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
+     provided.  */
+  if (/* Try standardized names.  */
+      iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
+      /* Try IRIX, OSF/1 names.  */
+      && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
+      /* Try AIX names.  */
+      && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
+      /* Try HP-UX names.  */
+      && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
+    return 1;
+  return 0;
+}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no],
+        [case "$host_os" in
+           aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
+           *)            am_cv_func_iconv_works="guessing yes" ;;
+         esac])
+      LIBS="$am_save_LIBS"
+    ])
+    case "$am_cv_func_iconv_works" in
+      *no) am_func_iconv=no am_cv_lib_iconv=no ;;
+      *)   am_func_iconv=yes ;;
+    esac
+  else
+    am_func_iconv=no am_cv_lib_iconv=no
+  fi
+  if test "$am_func_iconv" = yes; then
+    AC_DEFINE(HAVE_ICONV, 1,
+      [Define if you have the iconv() function and it works.])
+  fi
+  if test "$am_cv_lib_iconv" = yes; then
+    AC_MSG_CHECKING([how to link with libiconv])
+    AC_MSG_RESULT([$LIBICONV])
+  else
+    dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
+    dnl either.
+    CPPFLAGS="$am_save_CPPFLAGS"
+    LIBICONV=
+    LTLIBICONV=
+  fi
+  AC_SUBST(LIBICONV)
+  AC_SUBST(LTLIBICONV)
+])
+
+AC_DEFUN([AM_ICONV],
+[
+  AM_ICONV_LINK
+  if test "$am_cv_func_iconv" = yes; then
+    AC_MSG_CHECKING([for iconv declaration])
+    AC_CACHE_VAL(am_cv_proto_iconv, [
+      AC_TRY_COMPILE([
+#include <stdlib.h>
+#include <iconv.h>
+extern
+#ifdef __cplusplus
+"C"
+#endif
+#if defined(__STDC__) || defined(__cplusplus)
+size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
+#else
+size_t iconv();
+#endif
+], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const")
+      am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
+    am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
+    AC_MSG_RESULT([$]{ac_t:-
+         }[$]am_cv_proto_iconv)
+    AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
+      [Define as const if the declaration of iconv() needs const.])
+  fi
+])
commit a0cffb8b69e0595a2afe15ecc4928e0df1eeb063
Author: Pino Toscano <pino at kde.org>
Date:   Wed Dec 30 18:57:09 2009 +0100

    [cpp] fixup unicode GooString <-> ustring conversions
    
    better make them use the "hand-made" code, it is more correct for them

diff --git a/cpp/poppler-private.cpp b/cpp/poppler-private.cpp
index 1ba3433..51d557c 100644
--- a/cpp/poppler-private.cpp
+++ b/cpp/poppler-private.cpp
@@ -47,7 +47,37 @@ rectf detail::pdfrectangle_to_rectf(const PDFRectangle &pdfrect)
 
 ustring detail::unicode_GooString_to_ustring(GooString *str)
 {
-    return ustring::from_utf_8(str->getCString(), str->getLength());
+    const char *data = str->getCString();
+    const int len = str->getLength();
+
+    int i = 0;
+    bool is_unicode = false;
+    if ((data[0] & 0xff) == 0xfe && (len > 1 && (data[1] & 0xff) == 0xff)) {
+        is_unicode = true;
+        i = 2;
+    }
+    ustring::size_type ret_len = len - i;
+    if (is_unicode) {
+        ret_len >>= 1;
+    }
+    ustring ret(ret_len, 0);
+    size_t ret_index = 0;
+    ustring::value_type u;
+    if (is_unicode) {
+        while (i < len) {
+            u = ((data[i] & 0xff) << 8) | (data[i + 1] & 0xff);
+            i += 2;
+            ret[ret_index++] = u;
+        }
+    } else {
+        while (i < len) {
+            u = data[i] & 0xff;
+            ++i;
+            ret[ret_index++] = u;
+        }
+    }
+
+    return ret;
 }
 
 ustring detail::unicode_to_ustring(const Unicode *u, int length)
@@ -63,7 +93,15 @@ ustring detail::unicode_to_ustring(const Unicode *u, int length)
 
 GooString* detail::ustring_to_unicode_GooString(const ustring &str)
 {
-    const byte_array utf8_data = str.to_utf_8();
-    GooString *goo = new GooString(&utf8_data[0]);
+    const size_t len = str.size() * 2 + 2;
+    const ustring::value_type *me = str.data();
+    byte_array ba(len);
+    ba[0] = 0xfe;
+    ba[1] = 0xff;
+    for (size_t i = 0; i < str.size(); ++i, ++me) {
+        ba[i * 2 + 2] = ((*me >> 8) & 0xff);
+        ba[i * 2 + 3] = (*me & 0xff);
+    }
+    GooString *goo = new GooString(&ba[0]);
     return goo;
 }
commit 283dd326a00c804b6332ee3ca1aaa0d86377b3f3
Author: Pino Toscano <pino at kde.org>
Date:   Sat Dec 19 12:50:10 2009 +0100

    [cpp] fix installation of poppler-version.h with autotools and builddir != srcdir

diff --git a/cpp/Makefile.am b/cpp/Makefile.am
index 8890f83..4fb1874 100644
--- a/cpp/Makefile.am
+++ b/cpp/Makefile.am
@@ -15,7 +15,7 @@ poppler_include_HEADERS =			\
 	poppler-page-transition.h		\
 	poppler-rectangle.h			\
 	poppler-toc.h				\
-	poppler-version.h
+	$(builddir)/poppler-version.h
 
 lib_LTLIBRARIES = libpoppler-cpp.la
 libpoppler_cpp_la_SOURCES =			\
commit 752b14857cfb0669fd6d7dfef2ea73c13a2369fc
Author: Pino Toscano <pino at kde.org>
Date:   Thu Dec 17 17:16:01 2009 +0100

    simplify

diff --git a/cpp/poppler-toc.cpp b/cpp/poppler-toc.cpp
index 5d58d7b..1fc0f4d 100644
--- a/cpp/poppler-toc.cpp
+++ b/cpp/poppler-toc.cpp
@@ -47,7 +47,7 @@ toc* toc_private::load_from_outline(Outline *outline)
 
     toc *newtoc = new toc();
     newtoc->d->root.d->is_open = true;
-    newtoc->d->root.d->load_children(outline->getItems());
+    newtoc->d->root.d->load_children(items);
 
     return newtoc;
 }
commit a26e4b7903fabc667d7d16c23ca2c7a535dd05fa
Author: Pino Toscano <pino at kde.org>
Date:   Thu Dec 17 17:09:35 2009 +0100

    [cpp/tests] add a simple poppler-dump test
    
    this small test executable can dump various features of the document,
    like the general info, permissions, metadata, toc, fonts,
    embedded files, pages, etc
    
    also add the necessary autotools+cmake machinery to compile it

diff --git a/configure.ac b/configure.ac
index 70bac6c..a51eede 100644
--- a/configure.ac
+++ b/configure.ac
@@ -568,6 +568,7 @@ qt4/tests/Makefile
 qt4/demos/Makefile
 cpp/Makefile
 cpp/poppler-version.h
+cpp/tests/Makefile
 poppler.pc
 poppler-cairo.pc
 poppler-splash.pc
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index 0a0c6f0..b5880de 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -5,6 +5,8 @@ include_directories(
 
 configure_file(poppler-version.h.in ${CMAKE_CURRENT_BINARY_DIR}/poppler-version.h @ONLY)
 
+add_subdirectory(tests)
+
 set(poppler_cpp_SRCS
   poppler-document.cpp
   poppler-embedded-file.cpp
diff --git a/cpp/Makefile.am b/cpp/Makefile.am
index 6259770..8890f83 100644
--- a/cpp/Makefile.am
+++ b/cpp/Makefile.am
@@ -3,6 +3,7 @@ INCLUDES =					\
 	-I$(top_srcdir)/goo			\
 	-I$(top_srcdir)/poppler
 
+SUBDIRS = . tests
 
 poppler_includedir = $(includedir)/poppler/cpp
 poppler_include_HEADERS =			\
diff --git a/cpp/tests/.gitignore b/cpp/tests/.gitignore
new file mode 100644
index 0000000..737f30a
--- /dev/null
+++ b/cpp/tests/.gitignore
@@ -0,0 +1 @@
+poppler-dump
diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt
new file mode 100644
index 0000000..a083afd
--- /dev/null
+++ b/cpp/tests/CMakeLists.txt
@@ -0,0 +1,24 @@
+include_directories(
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/..
+  ${CMAKE_CURRENT_BINARY_DIR}/..
+  ${CMAKE_SOURCE_DIR}/utils
+)
+
+# ### temporary
+set(BUILD_CPP_TESTS TRUE)
+
+macro(CPP_ADD_SIMPLETEST exe)
+  string(REPLACE "-" "" test_name ${exe})
+  set(${test_name}_SOURCES
+    ${ARGN}
+  )
+  poppler_add_test(${exe} BUILD_CPP_TESTS ${${test_name}_SOURCES})
+  target_link_libraries(${exe} poppler-cpp)
+  if(MSVC)
+    target_link_libraries(${exe} poppler ${poppler_LIBS})
+  endif(MSVC)
+endmacro(CPP_ADD_SIMPLETEST)
+
+
+cpp_add_simpletest(poppler-dump poppler-dump.cpp ${CMAKE_SOURCE_DIR}/utils/parseargs.c)
diff --git a/cpp/tests/Makefile.am b/cpp/tests/Makefile.am
new file mode 100644
index 0000000..b01d3b9
--- /dev/null
+++ b/cpp/tests/Makefile.am
@@ -0,0 +1,17 @@
+INCLUDES =					\
+	-I$(top_srcdir)				\
+	-I$(top_srcdir)/utils			\
+	-I$(top_srcdir)/cpp
+
+LDADDS =					\
+	$(top_builddir)/cpp/libpoppler-cpp.la
+
+
+noinst_PROGRAMS =				\
+	poppler-dump
+
+poppler_dump_SOURCES = \
+	$(top_srcdir)/utils/parseargs.c		\
+	poppler-dump.cpp
+poppler_dump_LDADD = $(LDADDS)
+
diff --git a/cpp/tests/poppler-dump.cpp b/cpp/tests/poppler-dump.cpp
new file mode 100644
index 0000000..de50244
--- /dev/null
+++ b/cpp/tests/poppler-dump.cpp
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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-document.h>
+#include <poppler-embedded-file.h>
+#include <poppler-font.h>
+#include <poppler-page.h>
+#include <poppler-toc.h>
+
+#include <cstdlib>
+#include <ctime>
+#include <iomanip>
+#include <iostream>
+#include <memory>
+#include <sstream>
+
+#include "parseargs.h"
+
+static const int out_width = 30;
+
+bool show_info = false;
+bool show_perm = false;
+bool show_metadata = false;
+bool show_toc = false;
+bool show_fonts = false;
+bool show_embedded_files = false;
+bool show_pages = false;
+bool show_help = false;
+
+static const ArgDesc the_args[] = {
+    { "--show-info",           argFlag,  &show_info,           0,
+      "show general document information" },
+    { "--show-perm",           argFlag,  &show_perm,           0,
+      "show document permissions" },
+    { "--show-metadata",       argFlag,  &show_metadata,       0,
+      "show document metadata" },
+    { "--show-toc",            argFlag,  &show_toc,            0,
+      "show the TOC" },
+    { "--show-fonts",          argFlag,  &show_fonts,          0,
+      "show the document fonts" },
+    { "--show-embedded-files", argFlag,  &show_embedded_files, 0,
+      "show the document-level embedded files" },
+    { "--show-pages",          argFlag,  &show_pages,          0,
+      "show pages information" },
+    { "-h",                    argFlag,  &show_help,           0,
+      "print usage information" },
+    { "--help",                argFlag,  &show_help,           0,
+      "print usage information" },
+    { NULL, argFlag, 0, 0, NULL }
+};
+
+static void error(const std::string &msg)
+{
+    std::cerr << "Error: " << msg << std::endl;
+    std::cerr << "Exiting..." << std::endl;
+    exit(1);
+}
+
+static std::string out_ustring(const poppler::ustring &str)
+{
+    return str.to_latin1();
+}
+
+static std::string out_date(std::time_t date)
+{
+    if (date != std::time_t(-1)) {
+        struct tm time;
+        gmtime_r(&date, &time);
+        char buf[32];
+        strftime(buf, sizeof(buf) - 1, "%d/%m/%Y %H:%M:%S", &time);
+        return std::string(buf);
+    }
+    return std::string("n/a");
+}
+
+static std::string out_size(int size)
+{
+    if (size >= 0) {
+        std::ostringstream ss;
+        ss << size;
+        return ss.str();
+    }
+    return std::string("n/a");
+}
+
+static char charToHex(int x)
+{
+    return x < 10 ? x + '0' : x - 10 + 'a';
+}
+
+static std::string out_hex_string(const std::string &str)
+{
+    std::string ret(str.size() * 2, '\0');
+    const char *str_p = str.data();
+    for (unsigned int i = 0; i < str.size(); ++i, ++str_p) {
+        ret[i * 2] = charToHex((*str_p & 0xf0) >> 4);
+        ret[i * 2 + 1] = charToHex(*str_p & 0xf);
+    }
+    return ret;
+}
+
+static void print_info(poppler::document *doc)
+{
+    std::cout << "Document information:" << std::endl;
+    int major = 0, minor = 0;
+    doc->get_pdf_version(&major, &minor);
+    std::cout << std::setw(out_width) << "PDF version" << ": " << major << "." << minor << std::endl;
+    const std::vector<std::string> keys = doc->info_keys();
+    std::vector<std::string>::const_iterator key_it = keys.begin(), key_end = keys.end();
+    for (; key_it != key_end; ++key_it) {
+        std::cout << std::setw(out_width) << *key_it << ": " << out_ustring(doc->info_key(*key_it)) << std::endl;
+    }
+    std::cout << std::setw(out_width) << "Date (creation)" << ": " << out_date(doc->info_date("CreationDate")) << std::endl;
+    std::cout << std::setw(out_width) << "Date (modification)" << ": " << out_date(doc->info_date("ModDate")) << std::endl;
+    std::cout << std::setw(out_width) << "Number of pages" << ": " << doc->pages() << std::endl;
+    std::cout << std::setw(out_width) << "Linearized" << ": " << doc->is_linearized() << std::endl;
+    std::cout << std::setw(out_width) << "Encrypted" << ": " << doc->is_encrypted() << std::endl;
+    std::cout << std::endl;
+}
+
+static void print_perm(poppler::document *doc)
+{
+    std::cout << "Document permissions:" << std::endl;
+#define OUT_PERM(theperm) \
+    std::cout << std::setw(out_width) << "Perm (" #theperm ")" << ": " \
+              << doc->has_permission(poppler::perm_##theperm) << std::endl
+    OUT_PERM(print);
+    OUT_PERM(change);
+    OUT_PERM(copy);
+    OUT_PERM(add_notes);
+    OUT_PERM(fill_forms);
+    OUT_PERM(accessibility);
+    OUT_PERM(assemble);
+    OUT_PERM(print_high_resolution);
+    std::cout << std::endl;
+#undef OUT_PERM
+}
+
+static void print_metadata(poppler::document *doc)
+{
+    std::cout << std::setw(out_width) << "Metadata" << ":" << std::endl
+              << out_ustring(doc->metadata()) << std::endl;
+    std::cout << std::endl;
+}
+
+static void print_toc_item(poppler::toc_item *item, int indent)
+{
+    std::cout << std::setw(indent * 2) << " "
+              << "+ " << out_ustring(item->title()) << " (" << item->is_open() << ")"
+              << std::endl;
+    poppler::toc_item::iterator it = item->children_begin(), it_end = item->children_end();
+    for (; it != it_end; ++it) {
+        print_toc_item(*it, indent + 1);
+    }
+}
+
+static void print_toc(poppler::toc *doctoc)
+{
+    std::cout << "Document TOC:" << std::endl;
+    if (doctoc) {
+        print_toc_item(doctoc->root(), 0);
+    } else {
+        std::cout << "<no TOC>" << std::endl;
+    }
+    std::cout << std::endl;
+}
+
+static void print_fonts(poppler::document *doc)
+{
+    std::cout << "Document fonts:" << std::endl;
+    std::vector<poppler::font_info> fl = doc->fonts();
+    if (!fl.empty()) {
+        std::vector<poppler::font_info>::const_iterator it = fl.begin(), it_end = fl.end();
+        const std::ios_base::fmtflags f = std::cout.flags();
+        std::left(std::cout);
+        for (; it != it_end; ++it) {
+            std::cout
+                << " " << std::setw(out_width + 10) << it->name()
+                << " " << std::setw(15) << it->type()
+                << " " << std::setw(5) << it->is_embedded()
+                << " " << std::setw(5) << it->is_subset()
+                << " " << it->file()
+                << std::endl;
+        }
+        std::cout.flags(f);
+    } else {
+        std::cout << "<no fonts>" << std::endl;
+    }
+    std::cout << std::endl;
+}
+
+static void print_embedded_files(poppler::document *doc)
+{
+    std::cout << "Document embedded files:" << std::endl;
+    std::vector<poppler::embedded_file *> ef = doc->embedded_files();
+    if (!ef.empty()) {
+        std::vector<poppler::embedded_file *>::const_iterator it = ef.begin(), it_end = ef.end();
+        const std::ios_base::fmtflags f = std::cout.flags();
+        std::left(std::cout);
+        for (; it != it_end; ++it) {
+            poppler::embedded_file *f = *it;
+            std::cout
+                << " " << std::setw(out_width + 10) << f->name()
+                << " " << std::setw(10) << out_size(f->size())
+                << " " << std::setw(20) << out_date(f->creation_date())
+                << " " << std::setw(20) << out_date(f->modification_date())
+                << std::endl
+                << "     " << (f->description().empty() ? std::string("<no description>") : out_ustring(f->description()))
+                << std::endl
+                << "     " << std::setw(35) << (f->checksum().empty() ? std::string("<no checksum>") : out_hex_string(f->checksum()))
+                << " " << (f->mime_type().empty() ? std::string("<no mime type>") : f->mime_type())
+                << std::endl;
+        }
+        std::cout.flags(f);
+    } else {
+        std::cout << "<no embedded files>" << std::endl;
+    }
+    std::cout << std::endl;
+}
+
+static void print_page(poppler::page *p)
+{
+    std::cout << std::setw(out_width) << "Rect" << ": " << p->page_rect() << std::endl;
+    std::cout << std::setw(out_width) << "Label" << ": " << out_ustring(p->label()) << std::endl;
+    std::cout << std::setw(out_width) << "Duration" << ": " << p->duration() << std::endl;
+    std::cout << std::endl;
+}
+
+int main(int argc, char *argv[])
+{
+    if (!parseArgs(the_args, &argc, argv)
+        || argc < 2 || show_help) {
+        printUsage(argv[0], "DOCUMENT", the_args);
+        exit(1);
+    }
+
+    std::string file_name(argv[1]);
+
+    std::auto_ptr<poppler::document> doc(poppler::document::load_from_file(file_name));
+    if (!doc.get()) {
+        error("loading error");
+    }
+    if (doc->is_locked()) {
+        error("encrypted document");
+    }
+
+    std::cout.setf(std::ios_base::boolalpha);
+
+    if (show_info) {
+        print_info(doc.get());
+    }
+    if (show_perm) {
+        print_perm(doc.get());
+    }
+    if (show_metadata) {
+        print_metadata(doc.get());
+    }
+    if (show_toc) {
+        std::auto_ptr<poppler::toc> doctoc(doc->create_toc());
+        print_toc(doctoc.get());
+    }
+    if (show_fonts) {
+        print_fonts(doc.get());
+    }
+    if (show_embedded_files) {
+        print_embedded_files(doc.get());
+    }
+    if (show_pages) {
+        const int pages = doc->pages();
+        for (int i = 0; i < pages; ++i) {
+            std::cout << "Page " << (i + 1) << "/" << pages << ":" << std::endl;
+            std::auto_ptr<poppler::page> p(doc->create_page(i));
+            print_page(p.get());
+        }
+    }
+
+    return 0;
+}
commit ef7954b86f9b1a762c4f77a48d5f42f8db4bbed7
Author: Pino Toscano <pino at kde.org>
Date:   Tue Dec 15 02:20:18 2009 +0100

    [cpp] use the correct index (instead of an uninitialized variable)

diff --git a/cpp/poppler-page.cpp b/cpp/poppler-page.cpp
index b10cc5b..c8ce706 100644
--- a/cpp/poppler-page.cpp
+++ b/cpp/poppler-page.cpp
@@ -27,7 +27,7 @@ using namespace poppler;
 
 page_private::page_private(document_private *_doc, int _index)
     : doc(_doc)
-    , page(doc->doc->getCatalog()->getPage(index + 1))
+    , page(doc->doc->getCatalog()->getPage(_index + 1))
     , index(_index)
     , transition(0)
 {
commit 2547b5e53e7799cf7299838ae9bd882c21a228ae
Author: Pino Toscano <pino at kde.org>
Date:   Tue Dec 15 02:14:57 2009 +0100

    [cpp] properly delete the children of a toc item

diff --git a/cpp/poppler-toc.cpp b/cpp/poppler-toc.cpp
index 73a97dc..5d58d7b 100644
--- a/cpp/poppler-toc.cpp
+++ b/cpp/poppler-toc.cpp
@@ -59,6 +59,7 @@ toc_item_private::toc_item_private()
 
 toc_item_private::~toc_item_private()
 {
+    delete_all(children);
 }
 
 void toc_item_private::load(OutlineItem *item)
commit 771bd3594740fe16bd030dbe73928a8b1d4d113f
Author: Pino Toscano <pino at kde.org>
Date:   Tue Dec 15 02:04:24 2009 +0100

    [cpp] actually implement toc::root()

diff --git a/cpp/poppler-toc.cpp b/cpp/poppler-toc.cpp
index 6f05f21..73a97dc 100644
--- a/cpp/poppler-toc.cpp
+++ b/cpp/poppler-toc.cpp
@@ -99,6 +99,11 @@ toc::~toc()
     delete d;
 }
 
+toc_item* toc::root() const
+{
+    return &d->root;
+}
+
 
 toc_item::toc_item()
     : d(new toc_item_private())
commit ca1d2ec4588b2437b58b4448ae2fc5ebd0f130d3
Author: Pino Toscano <pino at kde.org>
Date:   Tue Dec 15 00:54:29 2009 +0100

    [cpp] fix the reference to the vector data

diff --git a/cpp/poppler-global.cpp b/cpp/poppler-global.cpp
index cc52b55..424f947 100644
--- a/cpp/poppler-global.cpp
+++ b/cpp/poppler-global.cpp
@@ -161,7 +161,7 @@ std::ostream& poppler::operator<<(std::ostream& stream, const byte_array &array)
     stream << "[";
     const std::ios_base::fmtflags f = stream.flags();
     std::hex(stream);
-    const char *data = array.data();
+    const char *data = &array[0];
     const byte_array::size_type out_len = std::min<byte_array::size_type>(array.size(), 50);
     for (byte_array::size_type i = 0; i < out_len; ++i)
     {
diff --git a/cpp/poppler-private.cpp b/cpp/poppler-private.cpp
index 6ab3b6c..1ba3433 100644
--- a/cpp/poppler-private.cpp
+++ b/cpp/poppler-private.cpp
@@ -64,6 +64,6 @@ ustring detail::unicode_to_ustring(const Unicode *u, int length)
 GooString* detail::ustring_to_unicode_GooString(const ustring &str)
 {
     const byte_array utf8_data = str.to_utf_8();
-    GooString *goo = new GooString(utf8_data.data());
+    GooString *goo = new GooString(&utf8_data[0]);
     return goo;
 }
commit 16c946e7658b0e9cff701ce1d6bbf7d3828cbe08
Author: Pino Toscano <pino at kde.org>
Date:   Tue Dec 15 00:35:25 2009 +0100

    [cpp] fix the reference to the vector data

diff --git a/cpp/poppler-document.cpp b/cpp/poppler-document.cpp
index 0ff526f..ab3939b 100644
--- a/cpp/poppler-document.cpp
+++ b/cpp/poppler-document.cpp
@@ -58,7 +58,7 @@ document_private::document_private(byte_array *file_data,
     Object obj;
     obj.initNull();
     file_data->swap(doc_data);
-    MemStream *memstr = new MemStream(doc_data.data(), 0, doc_data.size(), &obj);
+    MemStream *memstr = new MemStream(&doc_data[0], 0, doc_data.size(), &obj);
     GooString goo_owner_password(owner_password.c_str());
     GooString goo_user_password(user_password.c_str());
     doc = new PDFDoc(memstr, &goo_owner_password, &goo_user_password);
commit 9bb90c99b65e0e9d9b65c7dbeb5b4d66377ceb21
Author: Pino Toscano <pino at kde.org>
Date:   Mon Dec 14 23:43:12 2009 +0100

    [cpp] add destructor for 'rectangle'

diff --git a/cpp/poppler-rectangle.h b/cpp/poppler-rectangle.h
index a2b7c10..18674b2 100644
--- a/cpp/poppler-rectangle.h
+++ b/cpp/poppler-rectangle.h
@@ -33,7 +33,8 @@ public:
     rectangle(T _x, T _y, T w, T h)
         : x1(_x), y1(_y), x2(x1 + w), y2(y1 + h)
     {}
-    ~rectangle();
+    ~rectangle()
+    {}
 
     bool is_empty() const
     { return (x1 == x2) && (y1 == y2); }
commit 61ccdc9ab3b816174896fcae0899ff34f11eee80
Author: Pino Toscano <pino at kde.org>
Date:   Mon Dec 14 23:40:51 2009 +0100

    [cpp] add out stream operators for rect and rectf

diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index 3f8e9d9..0a0c6f0 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -13,6 +13,7 @@ set(poppler_cpp_SRCS
   poppler-page.cpp
   poppler-page-transition.cpp
   poppler-private.cpp
+  poppler-rectangle.cpp
   poppler-toc.cpp
   poppler-version.cpp
 )
diff --git a/cpp/Makefile.am b/cpp/Makefile.am
index b6c2d8e..6259770 100644
--- a/cpp/Makefile.am
+++ b/cpp/Makefile.am
@@ -25,6 +25,7 @@ libpoppler_cpp_la_SOURCES =			\
 	poppler-page.cpp			\
 	poppler-page-transition.cpp		\
 	poppler-private.cpp			\
+	poppler-rectangle.cpp			\
 	poppler-toc.cpp				\
 	poppler-version.cpp
 
diff --git a/cpp/poppler-rectangle.cpp b/cpp/poppler-rectangle.cpp
new file mode 100644
index 0000000..57fd859
--- /dev/null
+++ b/cpp/poppler-rectangle.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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-rectangle.h"
+
+#include <iostream>
+
+using namespace poppler;
+
+std::ostream& poppler::operator<<(std::ostream& stream, const rect &r)
+{
+    stream << "[" << r.x() << "," << r.y() << " " << r.width() << "+" << r.height() << "]";
+    return stream;
+}
+
+std::ostream& poppler::operator<<(std::ostream& stream, const rectf &r)
+{
+    stream << "[" << r.x() << "," << r.y() << " " << r.width() << "+" << r.height() << "]";
+    return stream;
+}
diff --git a/cpp/poppler-rectangle.h b/cpp/poppler-rectangle.h
index 7465edc..a2b7c10 100644
--- a/cpp/poppler-rectangle.h
+++ b/cpp/poppler-rectangle.h
@@ -19,6 +19,8 @@
 #ifndef POPPLER_RECTANGLE_H
 #define POPPLER_RECTANGLE_H
 
+#include "poppler-global.h"
+
 namespace poppler
 {
 
@@ -55,6 +57,9 @@ private:
 typedef rectangle<int> rect;
 typedef rectangle<double> rectf;
 
+POPPLER_CPP_EXPORT std::ostream& operator<<(std::ostream& stream, const rect &r);
+POPPLER_CPP_EXPORT std::ostream& operator<<(std::ostream& stream, const rectf &r);
+
 }
 
 #endif
commit 69dd51fed3de41f8b799b811ae5ee59c0d5f59c2
Author: Pino Toscano <pino at kde.org>
Date:   Mon Dec 14 22:24:07 2009 +0100

    [cpp] add namespace to namespace functiond to link properly

diff --git a/cpp/poppler-global.cpp b/cpp/poppler-global.cpp
index 9ce7641..cc52b55 100644
--- a/cpp/poppler-global.cpp
+++ b/cpp/poppler-global.cpp
@@ -133,7 +133,7 @@ ustring ustring::from_latin1(const std::string &str)
 }
 
 
-unsigned int convert_date(const std::string &date)
+unsigned int poppler::convert_date(const std::string &date)
 {
     int year, mon, day, hour, min, sec, tzHours, tzMins;
     char tz;
@@ -156,7 +156,7 @@ unsigned int convert_date(const std::string &date)
     return mktime(&time);
 }
 
-std::ostream& operator<<(std::ostream& stream, const byte_array &array)
+std::ostream& poppler::operator<<(std::ostream& stream, const byte_array &array)
 {
     stream << "[";
     const std::ios_base::fmtflags f = stream.flags();
diff --git a/cpp/poppler-version.cpp b/cpp/poppler-version.cpp
index 89f95a3..b39af53 100644
--- a/cpp/poppler-version.cpp
+++ b/cpp/poppler-version.cpp
@@ -20,22 +20,22 @@
 
 using namespace poppler;
 
-std::string version_string()
+std::string poppler::version_string()
 {
     return std::string(POPPLER_VERSION);
 }
 
-unsigned int version_major()
+unsigned int poppler::version_major()
 {
     return POPPLER_VERSION_MAJOR;
 }
 
-unsigned int version_minor()
+unsigned int poppler::version_minor()
 {
     return POPPLER_VERSION_MINOR;
 }
 
-unsigned int version_micro()
+unsigned int poppler::version_micro()
 {
     return POPPLER_VERSION_MICRO;
 }
commit 3923fa4890984d8616d86016f4f4a94e8ef3e992
Author: Pino Toscano <pino at kde.org>
Date:   Mon Dec 14 22:23:15 2009 +0100

    [cpp] add default empty parameters for the passwords of the document loading functions

diff --git a/cpp/poppler-document.h b/cpp/poppler-document.h
index ab6eb27..5d394bb 100644
--- a/cpp/poppler-document.h
+++ b/cpp/poppler-document.h
@@ -81,11 +81,11 @@ public:
     std::vector<embedded_file *> embedded_files() const;
 
     static document* load_from_file(const std::string &file_name,
-                                    const std::string &owner_password,
-                                    const std::string &user_password);
+                                    const std::string &owner_password = std::string(),
+                                    const std::string &user_password = std::string());
     static document* load_from_data(byte_array *file_data,
-                                    const std::string &owner_password,
-                                    const std::string &user_password);
+                                    const std::string &owner_password = std::string(),
+                                    const std::string &user_password = std::string());
 
 private:
     document(document_private &dd);
commit 1d23cc677e9b0a9f61c53e0ea365537f33abe5bf
Author: Pino Toscano <pino at kde.org>
Date:   Mon Dec 14 21:44:56 2009 +0100

    [cpp] add "human friendly" output representation for byte_array

diff --git a/cpp/poppler-global.cpp b/cpp/poppler-global.cpp
index cc15bce..9ce7641 100644
--- a/cpp/poppler-global.cpp
+++ b/cpp/poppler-global.cpp
@@ -22,6 +22,7 @@
 
 #include <ctime>
 #include <cstring>
+#include <iostream>
 
 using namespace poppler;
 
@@ -154,3 +155,25 @@ unsigned int convert_date(const std::string &date)
     time.tm_isdst = -1;
     return mktime(&time);
 }
+
+std::ostream& operator<<(std::ostream& stream, const byte_array &array)
+{
+    stream << "[";
+    const std::ios_base::fmtflags f = stream.flags();
+    std::hex(stream);
+    const char *data = array.data();
+    const byte_array::size_type out_len = std::min<byte_array::size_type>(array.size(), 50);
+    for (byte_array::size_type i = 0; i < out_len; ++i)
+    {
+        if (i != 0) {
+            stream << " ";
+        }
+        stream << ((data[i] & 0xf0) >> 4) << (data[i] & 0xf);
+    }
+    stream.flags(f);
+    if (out_len < array.size()) {
+        stream << " ...";
+    }
+    stream << "]";
+    return stream;
+}
diff --git a/cpp/poppler-global.h b/cpp/poppler-global.h
index da7c295..4b08e8d 100644
--- a/cpp/poppler-global.h
+++ b/cpp/poppler-global.h
@@ -33,6 +33,7 @@
 #  define POPPLER_CPP_EXPORT LIB_IMPORT
 #endif
 
+#include <iosfwd>
 #include <string>
 #include <vector>
 
@@ -88,6 +89,8 @@ private:
 
 POPPLER_CPP_EXPORT unsigned int /*time_t*/ convert_date(const std::string &date);
 
+POPPLER_CPP_EXPORT std::ostream& operator<<(std::ostream& stream, const byte_array &array);
+
 }
 
 #endif
commit a337c1d757d52c1c238229d2f0cd3a41694b0e08
Author: Pino Toscano <pino at kde.org>
Date:   Mon Dec 14 16:18:22 2009 +0100

    [cpp] add document metadata reading

diff --git a/cpp/poppler-document.cpp b/cpp/poppler-document.cpp
index ab14bf9..0ff526f 100644
--- a/cpp/poppler-document.cpp
+++ b/cpp/poppler-document.cpp
@@ -294,6 +294,15 @@ bool document::has_permission(permission_enum which) const
     return true;
 }
 
+ustring document::metadata() const
+{
+    std::auto_ptr<GooString> md(d->doc->getCatalog()->readMetadata());
+    if (md.get()) {
+        return detail::unicode_GooString_to_ustring(md.get());
+    }
+    return ustring();
+}
+
 int document::pages() const
 {
     return d->doc->getNumPages();
diff --git a/cpp/poppler-document.h b/cpp/poppler-document.h
index 66abe87..ab6eb27 100644
--- a/cpp/poppler-document.h
+++ b/cpp/poppler-document.h
@@ -66,6 +66,7 @@ public:
     bool is_encrypted() const;
     bool is_linearized() const;
     bool has_permission(permission_enum which) const;
+    ustring metadata() const;
 
     int pages() const;
     page* create_page(const ustring &label) const;
commit c9cb6353ad5279d09615eb2c944b2b053cdf5ccc
Author: Pino Toscano <pino at kde.org>
Date:   Mon Dec 14 15:52:25 2009 +0100

    [cpp] add function to query for document "permissions"

diff --git a/cpp/poppler-document.cpp b/cpp/poppler-document.cpp
index 908d4d2..ab14bf9 100644
--- a/cpp/poppler-document.cpp
+++ b/cpp/poppler-document.cpp
@@ -271,6 +271,29 @@ bool document::is_linearized() const
     return d->doc->isLinearized();
 }
 
+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;
+}
+
 int document::pages() const
 {
     return d->doc->getNumPages();
diff --git a/cpp/poppler-document.h b/cpp/poppler-document.h
index cc3c10d..66abe87 100644
--- a/cpp/poppler-document.h
+++ b/cpp/poppler-document.h
@@ -65,6 +65,7 @@ public:
     unsigned int /*time_t*/ info_date(const std::string &key) const;
     bool is_encrypted() const;
     bool is_linearized() const;
+    bool has_permission(permission_enum which) const;
 
     int pages() const;
     page* create_page(const ustring &label) const;
diff --git a/cpp/poppler-global.h b/cpp/poppler-global.h
index a6a9146..da7c295 100644
--- a/cpp/poppler-global.h
+++ b/cpp/poppler-global.h
@@ -60,6 +60,10 @@ enum rotation_enum { rotate_0, rotate_90, rotate_180, rotate_270 };
 
 enum page_box_enum { media_box, crop_box, bleed_box, trim_box, art_box };
 
+enum permission_enum { perm_print, perm_change, perm_copy, perm_add_notes,
+                       perm_fill_forms, perm_accessibility, perm_assemble,
+                       perm_print_high_resolution };
+
 typedef std::vector<char> byte_array;
 
 class POPPLER_CPP_EXPORT ustring : public std::basic_string<unsigned short>
commit 30e90c7c1b41c62ddc21905e7ccdea4c95547e80
Author: Pino Toscano <pino at kde.org>
Date:   Mon Dec 14 15:33:36 2009 +0100

    [cpp] add is_encrypted and is_linearized for document

diff --git a/cpp/poppler-document.cpp b/cpp/poppler-document.cpp
index d1bc026..908d4d2 100644
--- a/cpp/poppler-document.cpp
+++ b/cpp/poppler-document.cpp
@@ -261,6 +261,16 @@ unsigned int document::info_date(const std::string &key) const
     return result;
 }
 
+bool document::is_encrypted() const
+{
+    return d->doc->isEncrypted();
+}
+
+bool document::is_linearized() const
+{
+    return d->doc->isLinearized();
+}
+
 int document::pages() const
 {
     return d->doc->getNumPages();
diff --git a/cpp/poppler-document.h b/cpp/poppler-document.h
index 213a81a..cc3c10d 100644
--- a/cpp/poppler-document.h
+++ b/cpp/poppler-document.h
@@ -63,6 +63,8 @@ public:
     std::vector<std::string> info_keys() const;
     ustring info_key(const std::string &key) const;
     unsigned int /*time_t*/ info_date(const std::string &key) const;
+    bool is_encrypted() const;
+    bool is_linearized() const;
 
     int pages() const;
     page* create_page(const ustring &label) const;
commit 93fd588c519958a1f66231c111ea8a6b0a759be1
Author: Pino Toscano <pino at kde.org>
Date:   Mon Dec 14 13:19:24 2009 +0100

    [cpp] add the possibility to load a document from raw data

diff --git a/cpp/poppler-document-private.h b/cpp/poppler-document-private.h
index 52ed935..9820603 100644
--- a/cpp/poppler-document-private.h
+++ b/cpp/poppler-document-private.h
@@ -19,6 +19,8 @@
 #ifndef POPPLER_DOCUMENT_PRIVATE_H
 #define POPPLER_DOCUMENT_PRIVATE_H
 
+#include "poppler-global.h"
+
 #include "poppler-config.h"
 #include "GooString.h"
 #include "PDFDoc.h"
@@ -36,11 +38,14 @@ class document_private
 public:
     document_private(GooString *file_path, const std::string &owner_password,
                      const std::string &user_password);
+    document_private(byte_array *file_data, const std::string &owner_password,
+                     const std::string &user_password);
     ~document_private();
 
     static document* check_document(document_private *doc);
 
     PDFDoc *doc;
+    byte_array doc_data;
     bool is_locked;
     std::vector<embedded_file *> embedded_files;
 
diff --git a/cpp/poppler-document.cpp b/cpp/poppler-document.cpp
index 46f52b9..d1bc026 100644
--- a/cpp/poppler-document.cpp
+++ b/cpp/poppler-document.cpp
@@ -49,6 +49,22 @@ document_private::document_private(GooString *file_path, const std::string &owne
     init();
 }
 
+document_private::document_private(byte_array *file_data,
+                                   const std::string &owner_password,
+                                   const std::string &user_password)
+    : doc(0)
+    , is_locked(false)
+{
+    Object obj;
+    obj.initNull();
+    file_data->swap(doc_data);
+    MemStream *memstr = new MemStream(doc_data.data(), 0, doc_data.size(), &obj);
+    GooString goo_owner_password(owner_password.c_str());
+    GooString goo_user_password(user_password.c_str());
+    doc = new PDFDoc(memstr, &goo_owner_password, &goo_user_password);
+    init();
+}
+
 document_private::~document_private()
 {
     delete_all(embedded_files);
@@ -106,11 +122,15 @@ bool document::unlock(const std::string &owner_password, const std::string &user
 {
     if (d->is_locked) {
         document_private *newdoc = 0;
-        {
+        if (d->doc_data.size() > 0) {
+            newdoc = new document_private(&d->doc_data,
+                                          owner_password, user_password);
+        } else {
             newdoc = new document_private(new GooString(d->doc->getFileName()),
                                           owner_password, user_password);
         }
         if (!newdoc->doc->isOk()) {
+            d->doc_data.swap(newdoc->doc_data);
             delete newdoc;
         } else {
             delete d;
@@ -314,3 +334,16 @@ document* document::load_from_file(const std::string &file_name,
                                 owner_password, user_password);
     return document_private::check_document(doc);
 }
+
+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 0;
+    }
+
+    document_private *doc = new document_private(
+                                file_data, owner_password, user_password);
+    return document_private::check_document(doc);
+}
diff --git a/cpp/poppler-document.h b/cpp/poppler-document.h
index 7ff4337..213a81a 100644
--- a/cpp/poppler-document.h
+++ b/cpp/poppler-document.h
@@ -79,6 +79,9 @@ public:
     static document* load_from_file(const std::string &file_name,
                                     const std::string &owner_password,
                                     const std::string &user_password);
+    static document* load_from_data(byte_array *file_data,
+                                    const std::string &owner_password,
+                                    const std::string &user_password);
 
 private:
     document(document_private &dd);
commit 53996365b159cf84adf2cac56c76b8bda8dfb12e
Author: Pino Toscano <pino at kde.org>
Date:   Mon Dec 14 12:57:41 2009 +0100

    [cpp] use the byte_array typedef

diff --git a/cpp/poppler-embedded-file.cpp b/cpp/poppler-embedded-file.cpp
index 487b32d..6dfe321 100644
--- a/cpp/poppler-embedded-file.cpp
+++ b/cpp/poppler-embedded-file.cpp
@@ -93,15 +93,15 @@ std::string embedded_file::mime_type() const
     return std::string(d->emb_file->mimeType()->getCString());
 }
 
-std::vector<char> embedded_file::data() const
+byte_array embedded_file::data() const
 {
     if (!is_valid()) {
-        return std::vector<char>();
+        return byte_array();
     }
 
     Stream *stream = d->emb_file->streamObject().getStream();
     stream->reset();
-    std::vector<char> ret(1024);
+    byte_array ret(1024);
     size_t data_len = 0;
     int i;
     while ((i = stream->getChar()) != EOF) {
diff --git a/cpp/poppler-embedded-file.h b/cpp/poppler-embedded-file.h
index 250b84a..04ad7be 100644
--- a/cpp/poppler-embedded-file.h
+++ b/cpp/poppler-embedded-file.h
@@ -41,7 +41,7 @@ public:
     unsigned int /*time_t*/ creation_date() const;
     std::string checksum() const;
     std::string mime_type() const;
-    std::vector<char> data() const;
+    byte_array data() const;
 
 private:
     embedded_file(embedded_file_private &dd);
commit cfb4f5dfabf31de22d68aa0d5796cb7a33d8b462
Author: Pino Toscano <pino at kde.org>
Date:   Mon Dec 14 11:06:36 2009 +0100

    [cpp] add a byte_array typedef, and use it for utf8 string data

diff --git a/cpp/poppler-global.cpp b/cpp/poppler-global.cpp
index ce27061..cc15bce 100644
--- a/cpp/poppler-global.cpp
+++ b/cpp/poppler-global.cpp
@@ -47,27 +47,21 @@ ustring::~ustring()
 {
 }
 
-char* ustring::to_utf_8(int *length) const
+byte_array ustring::to_utf_8() const
 {
     if (!size()) {
-        if (length) {
-            *length = 0;
-        }
-        return 0;
+        return byte_array();
     }
 
     const value_type *me = data();
     const size_t len = size() * 2 + 2;
-    char *str = new char[len];
+    byte_array str(len);
     str[0] = 0xfe;
     str[1] = 0xff;
     for (size_t i = 0; i < size(); ++i, ++me) {
         str[i * 2 + 2] = (*me & 0xff);
         str[i * 2 + 3] = ((*me >> 8) & 0xff);
     }
-    if (length) {
-        *length = len;
-    }
     return str;
 }
 
diff --git a/cpp/poppler-global.h b/cpp/poppler-global.h
index e51878c..a6a9146 100644
--- a/cpp/poppler-global.h
+++ b/cpp/poppler-global.h
@@ -34,6 +34,7 @@
 #endif
 
 #include <string>
+#include <vector>
 
 namespace poppler
 {
@@ -59,6 +60,8 @@ enum rotation_enum { rotate_0, rotate_90, rotate_180, rotate_270 };
 
 enum page_box_enum { media_box, crop_box, bleed_box, trim_box, art_box };
 
+typedef std::vector<char> byte_array;
+
 class POPPLER_CPP_EXPORT ustring : public std::basic_string<unsigned short>
 {
 public:
@@ -66,7 +69,7 @@ public:
     ustring(size_type len, value_type ch);
     ~ustring();
 
-    char* to_utf_8(int *length = 0) const;
+    byte_array to_utf_8() const;
     std::string to_latin1() const;
 
     static ustring from_utf_8(const char *str, int len = -1);
diff --git a/cpp/poppler-private.cpp b/cpp/poppler-private.cpp
index 16ba370..6ab3b6c 100644
--- a/cpp/poppler-private.cpp
+++ b/cpp/poppler-private.cpp
@@ -63,8 +63,7 @@ ustring detail::unicode_to_ustring(const Unicode *u, int length)
 
 GooString* detail::ustring_to_unicode_GooString(const ustring &str)
 {
-    char *u = str.to_utf_8();
-    GooString *goo = new GooString(u);
-    delete [] u;
+    const byte_array utf8_data = str.to_utf_8();
+    GooString *goo = new GooString(utf8_data.data());
     return goo;
 }
commit 2d13ac31671b2007e44a90f45a82cb3adfa9c80c
Author: Pino Toscano <pino at kde.org>
Date:   Mon Dec 14 02:30:06 2009 +0100

    update ignore files

diff --git a/.gitignore b/.gitignore
index 11d96b9..d000352 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,7 @@ libtool
 ltmain.sh
 missing
 poppler-cairo.pc
+poppler-cpp.pc
 poppler-glib.pc
 poppler-qt.pc
 poppler-qt4.pc
diff --git a/cpp/.gitignore b/cpp/.gitignore
index 62535c7..0556b92 100644
--- a/cpp/.gitignore
+++ b/cpp/.gitignore
@@ -4,3 +4,4 @@
 *.lo
 Makefile
 Makefile.in
+poppler-version.h
commit 01e902e40ca15acf0319e37d39a271d6875bfce9
Author: Pino Toscano <pino at kde.org>
Date:   Mon Dec 14 02:02:47 2009 +0100

    [cpp] add a version header+functions
    
    this way, it is possible to get (either at build time and at runtime)
    the version of the current poppler-cpp library
    
    poppler-config.h is generated by the build system (autotools or cmake)
    with the correct version information

diff --git a/configure.ac b/configure.ac
index a7d61f7..70bac6c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -547,6 +547,7 @@ AC_SUBST(PC_REQUIRES_PRIVATE)
 AC_SUBST([POPPLER_MAJOR_VERSION],[poppler_version_major])
 AC_SUBST([POPPLER_MINOR_VERSION],[poppler_version_minor])
 AC_SUBST([POPPLER_MICRO_VERSION],[poppler_version_micro])
+AC_SUBST([POPPLER_VERSION],[poppler_version])
 
 AC_OUTPUT([
 Makefile
@@ -566,6 +567,7 @@ qt4/src/Makefile
 qt4/tests/Makefile
 qt4/demos/Makefile
 cpp/Makefile
+cpp/poppler-version.h
 poppler.pc
 poppler-cairo.pc
 poppler-splash.pc
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index 42fbca2..3f8e9d9 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -1,7 +1,10 @@
 include_directories(
+  ${CMAKE_CURRENT_SOURCE_DIR}
   ${CMAKE_CURRENT_BINARY_DIR}
 )
 
+configure_file(poppler-version.h.in ${CMAKE_CURRENT_BINARY_DIR}/poppler-version.h @ONLY)
+
 set(poppler_cpp_SRCS
   poppler-document.cpp
   poppler-embedded-file.cpp
@@ -11,6 +14,7 @@ set(poppler_cpp_SRCS
   poppler-page-transition.cpp
   poppler-private.cpp
   poppler-toc.cpp
+  poppler-version.cpp
 )
 
 add_library(poppler-cpp SHARED ${poppler_cpp_SRCS})
@@ -30,5 +34,6 @@ install(FILES
   poppler-page-transition.h
   poppler-rectangle.h
   poppler-toc.h
+  ${CMAKE_CURRENT_BINARY_DIR}/poppler-version.h
   DESTINATION include/poppler/cpp)
 
diff --git a/cpp/Makefile.am b/cpp/Makefile.am
index 58b8dd1..b6c2d8e 100644
--- a/cpp/Makefile.am
+++ b/cpp/Makefile.am
@@ -13,7 +13,8 @@ poppler_include_HEADERS =			\
 	poppler-page.h				\
 	poppler-page-transition.h		\
 	poppler-rectangle.h			\
-	poppler-toc.h
+	poppler-toc.h				\
+	poppler-version.h
 
 lib_LTLIBRARIES = libpoppler-cpp.la
 libpoppler_cpp_la_SOURCES =			\
@@ -24,7 +25,8 @@ libpoppler_cpp_la_SOURCES =			\
 	poppler-page.cpp			\
 	poppler-page-transition.cpp		\
 	poppler-private.cpp			\
-	poppler-toc.cpp
+	poppler-toc.cpp				\
+	poppler-version.cpp
 
 libpoppler_cpp_la_LIBADD = 			\
 	$(top_builddir)/poppler/libpoppler.la
diff --git a/cpp/poppler-version.cpp b/cpp/poppler-version.cpp
new file mode 100644
index 0000000..89f95a3
--- /dev/null
+++ b/cpp/poppler-version.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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-version.h"
+
+using namespace poppler;
+
+std::string version_string()
+{
+    return std::string(POPPLER_VERSION);
+}
+
+unsigned int version_major()
+{
+    return POPPLER_VERSION_MAJOR;
+}
+
+unsigned int version_minor()
+{
+    return POPPLER_VERSION_MINOR;
+}
+
+unsigned int version_micro()
+{
+    return POPPLER_VERSION_MICRO;
+}
diff --git a/cpp/poppler-version.h.in b/cpp/poppler-version.h.in
new file mode 100644
index 0000000..cf6bce6
--- /dev/null
+++ b/cpp/poppler-version.h.in
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_VERSION_H
+#define POPPLER_VERSION_H
+
+#include "poppler-global.h"
+
+#define POPPLER_VERSION "@POPPLER_VERSION@"
+#define POPPLER_VERSION_MAJOR @POPPLER_MAJOR_VERSION@
+#define POPPLER_VERSION_MINOR @POPPLER_MINOR_VERSION@
+#define POPPLER_VERSION_MICRO @POPPLER_MICRO_VERSION@
+
+namespace poppler
+{
+
+POPPLER_CPP_EXPORT std::string version_string();
+POPPLER_CPP_EXPORT unsigned int version_major();
+POPPLER_CPP_EXPORT unsigned int version_minor();
+POPPLER_CPP_EXPORT unsigned int version_micro();
+
+}
+
+#endif
commit 9d0cf201e96044dd679c26bea6255d986a6cd246
Author: Pino Toscano <pino at kde.org>
Date:   Sun Dec 13 23:45:39 2009 +0100

    [cpp] add ignore file

diff --git a/cpp/.gitignore b/cpp/.gitignore
new file mode 100644
index 0000000..62535c7
--- /dev/null
+++ b/cpp/.gitignore
@@ -0,0 +1,6 @@
+.deps
+.libs
+*.la
+*.lo
+Makefile
+Makefile.in
commit d783e92b863d8b22de6ca326328115fec63193ed
Author: Pino Toscano <pino at kde.org>
Date:   Sun Dec 13 23:42:33 2009 +0100

    [cpp] don't forget the cmake stuff when packing with the autotools

diff --git a/Makefile.am b/Makefile.am
index 59544e4..6d279ad 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -56,6 +56,7 @@ pkgconfig_DATA =				\
 
 # Add CMake buildsystem files here so they get added on make dist
 EXTRA_DIST +=							\
+	cpp/CMakeLists.txt					\
 	glib/demo/CMakeLists.txt				\
 	glib/CMakeLists.txt					\
 	glib/poppler-features.h.cmake				\
@@ -85,6 +86,7 @@ EXTRA_DIST +=							\
 	config.h.cmake						\
 	poppler-cairo.pc.cmake					\
 	poppler-config.h.cmake					\
+	poppler-cpp.pc.cmake					\
 	poppler-glib.pc.cmake					\
 	poppler-qt.pc.cmake					\
 	poppler-qt4.pc.cmake					\
commit 0105caefe860e7a45fc7d3a1bd1162fe56bcfe6a
Author: Pino Toscano <pino at kde.org>
Date:   Sun Dec 13 23:40:55 2009 +0100

    [cpp] add the pkg-config stuff

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f6cf57c..023229c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -452,6 +452,9 @@ endif(GLIB_FOUND)
 if(CAIRO_FOUND)
   poppler_create_install_pkgconfig(poppler-cairo.pc lib${LIB_SUFFIX}/pkgconfig)
 endif(CAIRO_FOUND)
+if(ENABLE_CPP)
+  poppler_create_install_pkgconfig(poppler-cpp.pc lib${LIB_SUFFIX}/pkgconfig)
+endif(ENABLE_CPP)
 
 
 message("Building Poppler with support for:")
diff --git a/Makefile.am b/Makefile.am
index 87209a6..59544e4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,6 +27,7 @@ endif
 
 if BUILD_POPPLER_CPP
 cpp_subdir = cpp
+cpp_pc_file = poppler-cpp.pc
 endif
 
 if BUILD_UTILS
@@ -40,7 +41,8 @@ EXTRA_DIST =					\
 	poppler.pc.in				\
 	poppler-cairo.pc.in			\
 	poppler-splash.pc.in			\
-	poppler-qt.pc.in
+	poppler-qt.pc.in			\
+	poppler-cpp.pc.in
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA =				\
@@ -49,7 +51,8 @@ pkgconfig_DATA =				\
 	$(splash_pc_file)			\
 	$(glib_pc_file)				\
 	$(qt_pc_file)                           \
-	$(qt4_pc_file)
+	$(qt4_pc_file)				\
+	$(cpp_pc_file)
 
 # Add CMake buildsystem files here so they get added on make dist
 EXTRA_DIST +=							\
diff --git a/configure.ac b/configure.ac
index 28d1b67..a7d61f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -571,7 +571,8 @@ poppler-cairo.pc
 poppler-splash.pc
 poppler-glib.pc
 poppler-qt.pc
-poppler-qt4.pc])
+poppler-qt4.pc
+poppler-cpp.pc])
 
 
 echo ""
diff --git a/poppler-cpp.pc.cmake b/poppler-cpp.pc.cmake
new file mode 100644
index 0000000..eeb11cc
--- /dev/null
+++ b/poppler-cpp.pc.cmake
@@ -0,0 +1,9 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib at LIB_SUFFIX@
+includedir=${prefix}/include
+
+Name: poppler-cpp
+Description: cpp backend for Poppler PDF rendering library
+Version: @POPPLER_VERSION@
+Requires: poppler = @POPPLER_VERSION@
diff --git a/poppler-cpp.pc.in b/poppler-cpp.pc.in
new file mode 100644
index 0000000..309f070
--- /dev/null
+++ b/poppler-cpp.pc.in
@@ -0,0 +1,9 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: poppler-cpp
+Description: cpp backend for Poppler PDF rendering library
+Version: @VERSION@
+Requires: poppler = @VERSION@
commit d5a74f78df0dca24fd537b30424fd2ebb3efe3e2
Author: Pino Toscano <pino at kde.org>
Date:   Sun Dec 13 23:35:06 2009 +0100

    [cpp] add the (rest of the) CMake build system for it

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ae5f8d6..f6cf57c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,6 +23,7 @@ option(BUILD_QT3_TESTS "Whether compile the Qt3 test programs." ON)
 option(BUILD_QT4_TESTS "Whether compile the Qt4 test programs." ON)
 option(ENABLE_SPLASH "Build the Splash graphics backend." ON)
 option(ENABLE_UTILS "Compile poppler command line utils." ON)
+option(ENABLE_CPP "Compile poppler cpp wrapper." ON)
 option(ENABLE_ABIWORD "Build the Abiword backend." ON)
 option(ENABLE_LIBOPENJPEG "Use libopenjpeg for JPX streams." ON)
 option(ENABLE_LCMS "Use liblcms for color management." ON)
@@ -418,6 +419,9 @@ add_subdirectory(test)
 if(QT4_FOUND)
   add_subdirectory(qt4)
 endif(QT4_FOUND)
+if(ENABLE_CPP)
+  add_subdirectory(cpp)
+endif(ENABLE_CPP)
 
 set(PKG_CONFIG_VERSION_0_18 TRUE)
 if(PKGCONFIG_EXECUTABLE)
@@ -458,6 +462,7 @@ show_end_message("qt wrapper" QT3_FOUND)
 show_end_message("qt4 wrapper" QT4_FOUND)
 show_end_message("glib wrapper" GLIB_FOUND)
 # message("  use gtk-doc:        $enable_gtk_doc") # TODO
+show_end_message("cpp wrapper" ENABLE_CPP)
 show_end_message("use libjpeg" ENABLE_LIBJPEG)
 show_end_message("use libpng" ENABLE_LIBPNG)
 show_end_message("use zlib" ENABLE_ZLIB)
commit 0e41f937946e4e4c1b660406bd74e4afe8825b5f
Author: Pino Toscano <pino at kde.org>
Date:   Sun Dec 13 23:31:46 2009 +0100

    [cpp] add the autotools buildsystem for it

diff --git a/Makefile.am b/Makefile.am
index 2a75262..87209a6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -25,11 +25,15 @@ qt4_subdir = qt4
 qt4_pc_file = poppler-qt4.pc
 endif
 
+if BUILD_POPPLER_CPP
+cpp_subdir = cpp
+endif
+
 if BUILD_UTILS
 utils_subdir = utils
 endif
 
-SUBDIRS = goo fofi $(splash_subdir) poppler $(utils_subdir) $(glib_subdir) $(qt_subdir) test $(qt4_subdir)
+SUBDIRS = goo fofi $(splash_subdir) poppler $(utils_subdir) $(glib_subdir) $(qt_subdir) test $(qt4_subdir) $(cpp_subdir)
 
 EXTRA_DIST =					\
 	README-XPDF				\
diff --git a/configure.ac b/configure.ac
index 7a8ca19..28d1b67 100644
--- a/configure.ac
+++ b/configure.ac
@@ -444,6 +444,19 @@ fi
 
 AM_CONDITIONAL(BUILD_POPPLER_QT4, test "x$enable_poppler_qt4" = "xyes")
 
+dnl
+dnl CPP frontend
+dnl
+
+AC_ARG_ENABLE(poppler-cpp,
+              AC_HELP_STRING([--disable-poppler-cpp],
+                             [Don't compile poppler cpp wrapper.]),
+              enable_poppler_cpp=$enableval,
+              enable_poppler_cpp="yes")
+
+AM_CONDITIONAL(BUILD_POPPLER_CPP, test "x$enable_poppler_cpp" = "xyes")
+
+
 AC_ARG_ENABLE(gtk-test,
               AC_HELP_STRING([--disable-gtk-test],
 	                     [Don't compile GTK+ test program.]),
@@ -552,6 +565,7 @@ qt4/Makefile
 qt4/src/Makefile
 qt4/tests/Makefile
 qt4/demos/Makefile
+cpp/Makefile
 poppler.pc
 poppler-cairo.pc
 poppler-splash.pc
@@ -569,6 +583,7 @@ echo "  qt wrapper:         $enable_poppler_qt"
 echo "  qt4 wrapper:        $enable_poppler_qt4"
 echo "  glib wrapper:       $enable_poppler_glib"
 echo "    use GDK:          $enable_gdk"
+echo "  cpp wrapper:        $enable_poppler_cpp"
 echo "  use gtk-doc:        $enable_gtk_doc"
 echo "  use libjpeg:        $enable_libjpeg"
 echo "  use libpng:         $enable_libpng"
diff --git a/cpp/Makefile.am b/cpp/Makefile.am
new file mode 100644
index 0000000..58b8dd1
--- /dev/null
+++ b/cpp/Makefile.am
@@ -0,0 +1,32 @@
+INCLUDES =					\
+	-I$(top_srcdir)				\
+	-I$(top_srcdir)/goo			\
+	-I$(top_srcdir)/poppler
+
+
+poppler_includedir = $(includedir)/poppler/cpp
+poppler_include_HEADERS =			\
+	poppler-document.h			\
+	poppler-embedded-file.h			\
+	poppler-font.h				\
+	poppler-global.h			\
+	poppler-page.h				\
+	poppler-page-transition.h		\
+	poppler-rectangle.h			\
+	poppler-toc.h
+
+lib_LTLIBRARIES = libpoppler-cpp.la
+libpoppler_cpp_la_SOURCES =			\
+	poppler-document.cpp			\
+	poppler-embedded-file.cpp		\
+	poppler-font.cpp			\
+	poppler-global.cpp			\
+	poppler-page.cpp			\
+	poppler-page-transition.cpp		\
+	poppler-private.cpp			\
+	poppler-toc.cpp
+
+libpoppler_cpp_la_LIBADD = 			\
+	$(top_builddir)/poppler/libpoppler.la
+
+libpoppler_cpp_la_LDFLAGS = -version-info 1:0:1 @create_shared_lib@
commit 9727fdc0c682742335e44ddc2f32d60e4c59983a
Author: Pino Toscano <pino at kde.org>
Date:   Sun Dec 13 22:55:28 2009 +0100

    Start of a pure C++ frontend for Poppler.
    
    This initial version (called 'poppler-cpp') includes preliminary support for:
    - document (loading from file name, some query methods, unlocking, font listing, embedded files)
    - page (some query methods) with page transitions
    - TOC
    
    Modelled a bit on the Qt4 API, it provides also an own "ustring" typedef representing UTF-16 strings,
    with methods to convert back/to UTF-8 and Latin 1.
    
    Most probably it has bugs, but nevertheless worth testing and developing.

diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
new file mode 100644
index 0000000..42fbca2
--- /dev/null
+++ b/cpp/CMakeLists.txt
@@ -0,0 +1,34 @@
+include_directories(
+  ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+set(poppler_cpp_SRCS
+  poppler-document.cpp
+  poppler-embedded-file.cpp
+  poppler-font.cpp
+  poppler-global.cpp
+  poppler-page.cpp
+  poppler-page-transition.cpp
+  poppler-private.cpp
+  poppler-toc.cpp
+)
+
+add_library(poppler-cpp SHARED ${poppler_cpp_SRCS})
+set_target_properties(poppler-cpp PROPERTIES VERSION 0.1.0 SOVERSION 0)
+target_link_libraries(poppler-cpp poppler)
+if(MSVC)
+target_link_libraries(poppler-cpp ${poppler_LIBS})
+endif(MSVC)
+install(TARGETS poppler-cpp RUNTIME DESTINATION bin LIBRARY DESTINATION lib${LIB_SUFFIX} ARCHIVE DESTINATION lib${LIB_SUFFIX})
+
+install(FILES
+  poppler-document.h
+  poppler-embedded-file.h
+  poppler-font.h
+  poppler-global.h
+  poppler-page.h
+  poppler-page-transition.h
+  poppler-rectangle.h
+  poppler-toc.h
+  DESTINATION include/poppler/cpp)
+
diff --git a/cpp/poppler-document-private.h b/cpp/poppler-document-private.h
new file mode 100644
index 0000000..52ed935
--- /dev/null
+++ b/cpp/poppler-document-private.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_DOCUMENT_PRIVATE_H
+#define POPPLER_DOCUMENT_PRIVATE_H
+
+#include "poppler-config.h"
+#include "GooString.h"
+#include "PDFDoc.h"
+
+#include <vector>
+
+namespace poppler
+{
+
+class document;
+class embedded_file;
+
+class document_private
+{
+public:
+    document_private(GooString *file_path, const std::string &owner_password,
+                     const std::string &user_password);
+    ~document_private();
+
+    static document* check_document(document_private *doc);
+
+    PDFDoc *doc;
+    bool is_locked;
+    std::vector<embedded_file *> embedded_files;
+
+private:
+    void init();
+
+    static unsigned int count;
+};
+
+}
+
+#endif
diff --git a/cpp/poppler-document.cpp b/cpp/poppler-document.cpp
new file mode 100644
index 0000000..46f52b9
--- /dev/null
+++ b/cpp/poppler-document.cpp
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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-document.h"
+#include "poppler-embedded-file.h"
+#include "poppler-page.h"
+#include "poppler-toc.h"
+
+#include "poppler-document-private.h"
+#include "poppler-embedded-file-private.h"
+#include "poppler-private.h"
+#include "poppler-toc-private.h"
+
+#include "Catalog.h"
+#include "ErrorCodes.h"
+#include "GlobalParams.h"
+#include "Outline.h"
+
+#include <algorithm>
+#include <memory>
+
+using namespace poppler;
+
+unsigned int poppler::document_private::count = 0U;
+
+document_private::document_private(GooString *file_path, const std::string &owner_password,
+                                   const std::string &user_password)
+    : doc(0)
+    , is_locked(false)
+{
+    GooString goo_owner_password(owner_password.c_str());
+    GooString goo_user_password(user_password.c_str());
+    doc = new PDFDoc(file_path, &goo_owner_password, &goo_user_password);
+    init();
+}
+
+document_private::~document_private()
+{
+    delete_all(embedded_files);
+
+    delete doc;
+
+    if (count > 0) {
+        --count;
+        if (!count) {
+            delete globalParams;
+            globalParams = 0;
+        }
+    }
+}
+
+void document_private::init()
+{
+    if (!count) {
+        globalParams = new GlobalParams();
+        setErrorFunction(detail::error_function);
+    }
+    count++;
+}
+
+document* document_private::check_document(document_private *doc)
+{
+    if (doc->doc->isOk() || doc->doc->getErrorCode() == errEncrypted) {
+        if (doc->doc->getErrorCode() == errEncrypted) {
+            doc->is_locked = true;
+        }
+        return new document(*doc);
+    } else {
+        delete doc;
+    }
+    return 0;
+}
+
+
+document::document(document_private &dd)
+    : d(&dd)
+{
+}
+
+document::~document()
+{
+    delete d;
+}
+
+bool document::is_locked() const
+{
+    return d->is_locked;
+}
+
+bool document::unlock(const std::string &owner_password, const std::string &user_password)
+{
+    if (d->is_locked) {
+        document_private *newdoc = 0;
+        {
+            newdoc = new document_private(new GooString(d->doc->getFileName()),
+                                          owner_password, user_password);
+        }
+        if (!newdoc->doc->isOk()) {
+            delete newdoc;
+        } else {
+            delete d;
+            d = newdoc;
+            d->is_locked = false;
+        }
+    }
+    return d->is_locked;
+}
+
+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;
+    }
+}
+
+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;
+    }
+}
+
+void document::get_pdf_version(int *major, int *minor) const
+{
+    if (major) {
+        *major = d->doc->getPDFMajorVersion();
+    }
+    if (minor) {
+        *minor = d->doc->getPDFMinorVersion();
+    }
+}
+
+std::vector<std::string> document::info_keys() const
+{
+    if (d->is_locked) {
+        return std::vector<std::string>();
+    }
+
+    Object info;
+    if (!d->doc->getDocInfo(&info)->isDict()) {
+        info.free();
+        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));
+    }
+
+    info.free();
+    return keys;
+}
+
+ustring document::info_key(const std::string &key) const
+{
+    if (d->is_locked) {
+        return ustring();
+    }
+
+    Object info;
+    if (!d->doc->getDocInfo(&info)->isDict()) {
+        info.free();
+        return ustring();
+    }
+
+    Dict *info_dict = info.getDict();
+    Object obj;
+    ustring result;
+    if (info_dict->lookup(PSTR(key.c_str()), &obj)->isString()) {
+        result = detail::unicode_GooString_to_ustring(obj.getString());
+    }
+    obj.free();
+    info.free();
+    return result;
+}
+
+unsigned int document::info_date(const std::string &key) const
+{
+    if (d->is_locked) {
+        return (unsigned int)(-1);
+    }
+
+    Object info;
+    if (!d->doc->getDocInfo(&info)->isDict()) {
+        info.free();
+        return (unsigned int)(-1);
+    }
+
+    Dict *info_dict = info.getDict();
+    Object obj;
+    unsigned int result = (unsigned int)(-1);
+    if (info_dict->lookup(PSTR(key.c_str()), &obj)->isString()) {
+        result = convert_date(obj.getString()->getCString());
+    }
+    obj.free();
+    info.free();
+    return result;
+}
+
+int document::pages() const
+{
+    return d->doc->getNumPages();
+}
+
+page* document::create_page(const ustring &label) const
+{
+    std::auto_ptr<GooString> goolabel(detail::ustring_to_unicode_GooString(label));
+    int index = 0;
+
+    if (!d->doc->getCatalog()->labelToIndex(goolabel.get(), &index)) {
+        return 0;
+    }
+    return create_page(index);
+}
+
+page* document::create_page(int index) const
+{
+    return index >= 0 && index < d->doc->getNumPages() ? new page(d, index) : 0;
+}
+
+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;
+}
+
+font_iterator* document::create_font_iterator(int start_page) const
+{
+    return new font_iterator(start_page, d);
+}
+
+toc* document::create_toc() const
+{
+    return toc_private::load_from_outline(d->doc->getOutline());
+}
+
+bool document::has_embedded_files() const
+{
+    return d->doc->getCatalog()->numEmbeddedFiles() > 0;
+}
+
+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) {
+            EmbFile *ef = d->doc->getCatalog()->embeddedFile(i);
+            d->embedded_files[i] = embedded_file_private::create(ef);
+        }
+    }
+    return d->embedded_files;
+}
+
+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(
+                                new GooString(file_name.c_str()),
+                                owner_password, user_password);
+    return document_private::check_document(doc);
+}
diff --git a/cpp/poppler-document.h b/cpp/poppler-document.h
new file mode 100644
index 0000000..7ff4337
--- /dev/null
+++ b/cpp/poppler-document.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_DOCUMENT_H
+#define POPPLER_DOCUMENT_H
+
+#include "poppler-global.h"
+#include "poppler-font.h"
+
+namespace poppler
+{
+
+class document_private;
+class embedded_file;
+class page;
+class toc;
+
+class POPPLER_CPP_EXPORT document : public poppler::noncopyable
+{
+public:
+    enum page_mode_enum {
+        use_none,
+        use_outlines,
+        use_thumbs,
+        fullscreen,
+        use_oc,
+        use_attach
+    };
+
+    enum page_layout_enum {
+        no_layout,
+        single_page,
+        one_column,
+        two_column_left,
+        two_column_right,
+        two_page_left,
+        two_page_right
+    };
+
+    ~document();
+
+    bool is_locked() const;
+    bool unlock(const std::string &owner_password, const std::string &user_password);
+
+    page_mode_enum page_mode() const;
+    page_layout_enum page_layout() const;
+    void get_pdf_version(int *major, int *minor) const;
+    std::vector<std::string> info_keys() const;
+    ustring info_key(const std::string &key) const;
+    unsigned int /*time_t*/ info_date(const std::string &key) const;
+
+    int pages() const;
+    page* create_page(const ustring &label) const;
+    page* create_page(int index) const;
+
+    std::vector<font_info> fonts() const;
+    font_iterator* create_font_iterator(int start_page = 0) const;
+
+    toc* create_toc() const;
+
+    bool has_embedded_files() const;
+    std::vector<embedded_file *> embedded_files() const;
+
+    static document* load_from_file(const std::string &file_name,
+                                    const std::string &owner_password,
+                                    const std::string &user_password);
+
+private:
+    document(document_private &dd);
+
+    document_private *d;
+    friend class document_private;
+};
+
+}
+
+#endif
diff --git a/cpp/poppler-embedded-file-private.h b/cpp/poppler-embedded-file-private.h
new file mode 100644
index 0000000..2acea65
--- /dev/null
+++ b/cpp/poppler-embedded-file-private.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_EMBEDDED_FILE_PRIVATE_H
+#define POPPLER_EMBEDDED_FILE_PRIVATE_H
+
+class EmbFile;
+
+namespace poppler
+{
+
+class embedded_file_private
+{
+public:
+    embedded_file_private(EmbFile *ef);
+    ~embedded_file_private();
+
+    static embedded_file* create(EmbFile *ef);
+
+    EmbFile *emb_file;
+};
+
+}
+
+#endif
diff --git a/cpp/poppler-embedded-file.cpp b/cpp/poppler-embedded-file.cpp
new file mode 100644
index 0000000..487b32d
--- /dev/null
+++ b/cpp/poppler-embedded-file.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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-embedded-file.h"
+
+#include "poppler-embedded-file-private.h"
+#include "poppler-private.h"
+
+#include "Object.h"
+#include "Stream.h"
+#include "Catalog.h"
+
+using namespace poppler;
+
+embedded_file_private::embedded_file_private(EmbFile *ef)
+    : emb_file(ef)
+{
+}
+
+embedded_file_private::~embedded_file_private()
+{
+    delete emb_file;
+}
+
+embedded_file* embedded_file_private::create(EmbFile *ef)
+{
+    return new embedded_file(*new embedded_file_private(ef));
+}
+
+
+embedded_file::embedded_file(embedded_file_private &dd)
+    : d(&dd)
+{
+}
+
+embedded_file::~embedded_file()
+{
+    delete d;
+}
+
+bool embedded_file::is_valid() const
+{
+    return d->emb_file->isOk();
+}
+
+std::string embedded_file::name() const
+{
+    return std::string(d->emb_file->name()->getCString());
+}
+
+ustring embedded_file::description() const
+{
+    return detail::unicode_GooString_to_ustring(d->emb_file->description());
+}
+
+int embedded_file::size() const
+{
+    return d->emb_file->size();
+}
+
+unsigned int embedded_file::modification_date() const
+{
+    return convert_date(d->emb_file->modDate()->getCString());
+}
+
+unsigned int embedded_file::creation_date() const
+{
+    return convert_date(d->emb_file->createDate()->getCString());
+}
+
+std::string embedded_file::checksum() const
+{
+    return std::string(d->emb_file->checksum()->getCString());
+}
+
+std::string embedded_file::mime_type() const
+{
+    return std::string(d->emb_file->mimeType()->getCString());
+}
+
+std::vector<char> embedded_file::data() const
+{
+    if (!is_valid()) {
+        return std::vector<char>();
+    }
+
+    Stream *stream = d->emb_file->streamObject().getStream();
+    stream->reset();
+    std::vector<char> ret(1024);
+    size_t data_len = 0;
+    int i;
+    while ((i = stream->getChar()) != EOF) {
+        if (data_len == ret.size()) {
+            ret.resize(ret.size() * 2);
+        }
+        ret[data_len] = (char)i;
+        ++data_len;
+    }
+    ret.resize(data_len);
+    return ret;
+}
diff --git a/cpp/poppler-embedded-file.h b/cpp/poppler-embedded-file.h
new file mode 100644
index 0000000..250b84a
--- /dev/null
+++ b/cpp/poppler-embedded-file.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_EMBEDDED_FILE_H
+#define POPPLER_EMBEDDED_FILE_H
+
+#include "poppler-global.h"
+
+#include <vector>
+
+namespace poppler
+{
+
+class embedded_file_private;
+
+class POPPLER_CPP_EXPORT embedded_file : public poppler::noncopyable
+{
+public:
+    ~embedded_file();
+
+    bool is_valid() const;
+    std::string name() const;
+    ustring description() const;
+    int size() const;
+    unsigned int /*time_t*/ modification_date() const;
+    unsigned int /*time_t*/ creation_date() const;
+    std::string checksum() const;
+    std::string mime_type() const;
+    std::vector<char> data() const;
+
+private:
+    embedded_file(embedded_file_private &dd);
+
+    embedded_file_private *d;
+    friend class embedded_file_private;
+};
+
+}
+
+#endif
diff --git a/cpp/poppler-font.cpp b/cpp/poppler-font.cpp
new file mode 100644
index 0000000..5c3221b
--- /dev/null
+++ b/cpp/poppler-font.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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-font.h"
+
+#include "poppler-document-private.h"
+
+#include "FontInfo.h"
+
+using namespace poppler;
+
+class poppler::font_info_private
+{
+public:
+    font_info_private()
+        : type(font_info::unknown)
+        , is_embedded(false)
+        , is_subset(false)
+    {
+    }
+    font_info_private(FontInfo *fi)
+        : type((font_info::type_enum)fi->getType())
+        , is_embedded(fi->getEmbedded())
+        , is_subset(fi->getSubset())
+        , emb_ref(fi->getEmbRef())
+    {
+        if (fi->getName()) {
+            font_name = fi->getName()->getCString();
+        }
+        if (fi->getFile()) {
+            font_file = fi->getFile()->getCString();
+        }
+    }
+
+    std::string font_name;
+    std::string font_file;
+    font_info::type_enum type : 5;
+    bool is_embedded : 1;
+    bool is_subset : 1;
+    Ref emb_ref;
+};
+
+
+class poppler::font_iterator_private
+{
+public:
+    font_iterator_private(int start_page, document_private *dd)
+        : font_info_scanner(dd->doc, start_page)
+        , total_pages(dd->doc->getNumPages())
+        , current_page((std::max)(start_page, 0) - 1)
+    {
+    }
+    ~font_iterator_private()
+    {
+    }
+
+    FontInfoScanner font_info_scanner;
+    int total_pages;
+    int current_page;
+};
+
+
+font_info::font_info()
+    : d(new font_info_private())
+{
+}
+
+font_info::font_info(font_info_private &dd)
+    : d(&dd)
+{
+}
+
+font_info::font_info(const font_info &fi)
+    : d(new font_info_private(*fi.d))
+{
+}
+
+font_info::~font_info()
+{
+    delete d;
+}
+
+std::string font_info::name() const
+{
+    return d->font_name;
+}
+
+std::string font_info::file() const
+{
+    return d->font_file;
+}
+
+bool font_info::is_embedded() const
+{
+    return d->is_embedded;
+}
+
+bool font_info::is_subset() const
+{
+    return d->is_subset;
+}
+
+font_info::type_enum font_info::type() const
+{
+    return d->type;
+}
+
+font_info& font_info::operator=(const font_info &fi)
+{
+    if (this != &fi) {
+        *d = *fi.d;
+    }
+    return *this;
+}
+
+
+font_iterator::font_iterator(int start_page, document_private *dd)
+    : d(new font_iterator_private(start_page, dd))
+{
+}
+
+font_iterator::~font_iterator()
+{
+    delete d;
+}
+
+std::vector<font_info> font_iterator::next()
+{
+    ++d->current_page;
+
+    GooList *items = d->font_info_scanner.scan(1);
+    if (!items) {
+        return std::vector<font_info>();
+    }
+    std::vector<font_info> fonts(items->getLength());
+    for (int i = 0; i < items->getLength(); ++i) {
+        fonts[i] = font_info(*new font_info_private((FontInfo *)items->get(i)));
+    }
+    deleteGooList(items, FontInfo);
+    return fonts;
+}
+
+bool font_iterator::has_next() const
+{
+    return (d->current_page + 1) < d->total_pages;
+}
+
+int font_iterator::current_page() const
+{
+    return d->current_page;
+}
diff --git a/cpp/poppler-font.h b/cpp/poppler-font.h
new file mode 100644
index 0000000..854b7a4
--- /dev/null
+++ b/cpp/poppler-font.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_FONT_H
+#define POPPLER_FONT_H
+
+#include "poppler-global.h"
+
+#include <vector>
+
+namespace poppler
+{
+
+class document;
+class document_private;
+class font_info_private;
+class font_iterator;
+class font_iterator_private;
+
+class POPPLER_CPP_EXPORT font_info
+{
+public:
+    enum type_enum {
+        unknown,
+        type1,
+        type1c,
+        type1c_ot,
+        type3,
+        truetype,
+        truetype_ot,
+        cid_type0,
+        cid_type0c,
+        cid_type0c_ot,
+        cid_truetype,
+        cid_truetype_ot
+    };
+
+    font_info();
+    font_info(const font_info &fi);
+    ~font_info();
+
+    std::string name() const;
+    std::string file() const;
+    bool is_embedded() const;
+    bool is_subset() const;
+    type_enum type() const;
+
+    font_info& operator=(const font_info &fi);
+
+private:
+    font_info(font_info_private &dd);
+
+    font_info_private *d;
+    friend class font_iterator;
+};
+
+
+class POPPLER_CPP_EXPORT font_iterator : public poppler::noncopyable
+{
+public:
+    ~font_iterator();
+
+    std::vector<font_info> next();
+    bool has_next() const;
+    int current_page() const;
+
+private:
+    font_iterator(int, document_private *dd);
+
+    font_iterator_private *d;
+    friend class document;
+};
+
+}
+
+#endif
diff --git a/cpp/poppler-global.cpp b/cpp/poppler-global.cpp
new file mode 100644
index 0000000..ce27061
--- /dev/null
+++ b/cpp/poppler-global.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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-global.h"
+
+#include "DateInfo.h"
+
+#include <ctime>
+#include <cstring>
+
+using namespace poppler;
+
+noncopyable::noncopyable()
+{
+}
+
+noncopyable::~noncopyable()
+{
+}
+
+
+ustring::ustring()
+{
+}
+
+ustring::ustring(size_type len, value_type ch)
+    : std::basic_string<value_type>(len, ch)
+{
+}
+
+ustring::~ustring()
+{
+}
+
+char* ustring::to_utf_8(int *length) const
+{
+    if (!size()) {
+        if (length) {
+            *length = 0;
+        }
+        return 0;
+    }
+
+    const value_type *me = data();
+    const size_t len = size() * 2 + 2;
+    char *str = new char[len];
+    str[0] = 0xfe;
+    str[1] = 0xff;
+    for (size_t i = 0; i < size(); ++i, ++me) {
+        str[i * 2 + 2] = (*me & 0xff);
+        str[i * 2 + 3] = ((*me >> 8) & 0xff);
+    }
+    if (length) {
+        *length = len;
+    }
+    return str;
+}
+
+std::string ustring::to_latin1() const
+{
+    if (!size()) {
+        return std::string();
+    }
+
+    const size_type mylength = size();
+    std::string ret(mylength, '\0');
+    const value_type *me = data();
+    for (size_type i = 0; i < mylength; ++i) {
+        ret[i] = (char)*me++;
+    }
+    return ret;
+}
+
+ustring ustring::from_utf_8(const char *str, int len)
+{
+    if (len <= 0) {
+        len = std::strlen(str);
+        if (len <= 0) {
+            return ustring();
+        }
+    }
+
+    int i = 0;
+    bool is_unicode = false;
+    if ((str[0] & 0xff) == 0xfe && (len > 1 && (str[1] & 0xff) == 0xff)) {
+        is_unicode = true;
+        i = 2;
+    }
+
+    const ustring::size_type ret_len = (len - i) / (is_unicode ? 2 : 1);
+    ustring ret(ret_len, 0);
+    size_t ret_index = 0;
+    ustring::value_type u;
+    if (is_unicode) {
+        while (i < len) {
+            u = ((str[i] & 0xff) << 8) | (str[i + 1] & 0xff);
+            i += 2;
+            ret[ret_index++] = u;
+        }
+    } else {
+        while (i < len) {
+            u = str[i] & 0xff;
+            ++i;
+            ret[ret_index++] = u;
+        }
+    }
+
+    return ret;
+}
+
+ustring ustring::from_latin1(const std::string &str)
+{
+    const size_type l = str.size();
+    if (!l) {
+        return ustring();
+    }
+    const char *c = str.data();
+    ustring ret(l, 0);
+    for (size_type i = 0; i < l; ++i) {
+        ret[i] = *c++;
+    }
+    return ret;
+}
+
+
+unsigned int convert_date(const std::string &date)
+{
+    int year, mon, day, hour, min, sec, tzHours, tzMins;
+    char tz;
+
+    if (!parseDateString(date.c_str(), &year, &mon, &day, &hour, &min, &sec,
+                                       &tz, &tzHours, &tzMins)) {
+        return (unsigned int)(-1);
+    }
+
+    struct tm time;
+    time.tm_sec = sec;
+    time.tm_min = min;
+    time.tm_hour = hour;
+    time.tm_mday = day;
+    time.tm_mon = mon - 1;
+    time.tm_year = year - 1900;
+    time.tm_wday = -1;
+    time.tm_yday = -1;
+    time.tm_isdst = -1;
+    return mktime(&time);
+}
diff --git a/cpp/poppler-global.h b/cpp/poppler-global.h
new file mode 100644
index 0000000..e51878c
--- /dev/null
+++ b/cpp/poppler-global.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_GLOBAL_H
+#define POPPLER_GLOBAL_H
+
+#if defined(_WIN32)
+#  define LIB_EXPORT __declspec(dllexport)
+#  define LIB_IMPORT __declspec(dllimport)
+#else
+#  define LIB_EXPORT
+#  define LIB_IMPORT
+#endif
+
+#if defined(poppler_cpp_EXPORTS)
+#  define POPPLER_CPP_EXPORT LIB_EXPORT
+#else
+#  define POPPLER_CPP_EXPORT LIB_IMPORT
+#endif
+
+#include <string>
+
+namespace poppler
+{
+
+namespace detail
+{
+
+class POPPLER_CPP_EXPORT noncopyable
+{
+protected:
+    noncopyable();
+    ~noncopyable();
+private:
+    noncopyable(const noncopyable &);
+    const noncopyable& operator=(const noncopyable &);
+};
+
+}
+
+typedef detail::noncopyable noncopyable;
+
+enum rotation_enum { rotate_0, rotate_90, rotate_180, rotate_270 };
+
+enum page_box_enum { media_box, crop_box, bleed_box, trim_box, art_box };
+
+class POPPLER_CPP_EXPORT ustring : public std::basic_string<unsigned short>
+{
+public:
+    ustring();
+    ustring(size_type len, value_type ch);
+    ~ustring();
+
+    char* to_utf_8(int *length = 0) const;
+    std::string to_latin1() const;
+
+    static ustring from_utf_8(const char *str, int len = -1);
+    static ustring from_latin1(const std::string &str);
+
+private:
+    // forbid implicit std::string conversions
+    ustring(const std::string &);
+    operator std::string() const;
+    ustring& operator=(const std::string &);
+};
+
+POPPLER_CPP_EXPORT unsigned int /*time_t*/ convert_date(const std::string &date);
+
+}
+
+#endif
diff --git a/cpp/poppler-page-private.h b/cpp/poppler-page-private.h
new file mode 100644
index 0000000..654478b
--- /dev/null
+++ b/cpp/poppler-page-private.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_PAGE_PRIVATE_H
+#define POPPLER_PAGE_PRIVATE_H
+
+class Page;
+
+namespace poppler
+{
+
+class document_private;
+class page_transition;
+
+class page_private
+{
+public:
+    page_private(document_private *doc, int index);
+    ~page_private();
+
+    document_private *doc;
+    Page *page;
+    int index;
+    page_transition *transition;
+};
+
+}
+
+#endif
diff --git a/cpp/poppler-page-transition.cpp b/cpp/poppler-page-transition.cpp
new file mode 100644
index 0000000..92ae4fc
--- /dev/null
+++ b/cpp/poppler-page-transition.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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-page-transition.h"
+
+#include "PageTransition.h"
+
+using namespace poppler;
+
+class poppler::page_transition_private
+{
+public:
+    page_transition_private(Object *trans)
+        : pt(trans)
+    {
+    }
+
+    PageTransition pt;
+};
+
+
+page_transition::page_transition(Object *params)
+    : d(new page_transition_private(params))
+{
+}
+
+page_transition::page_transition(const page_transition &pt)
+    : d(new page_transition_private(*pt.d))
+{
+}
+
+page_transition::~page_transition()
+{
+    delete d;
+}
+
+page_transition::type_enum page_transition::type() const
+{
+    return (page_transition::type_enum)d->pt.getType();
+}
+
+int page_transition::duration() const
+{
+    return d->pt.getDuration();
+}
+
+page_transition::alignment_enum page_transition::alignment() const
+{
+    return (page_transition::alignment_enum)d->pt.getAlignment();
+}
+
+page_transition::direction_enum page_transition::direction() const
+{
+    return (page_transition::direction_enum)d->pt.getDirection();
+}
+
+int page_transition::angle() const
+{
+    return d->pt.getAngle();
+}
+
+double page_transition::scale() const
+{
+    return d->pt.getScale();
+}
+
+bool page_transition::is_rectangular() const
+{
+    return d->pt.isRectangular();
+}
+
+page_transition& page_transition::operator=(const page_transition &pt)
+{
+    if (&pt != this) {
+        page_transition_private *new_d = new page_transition_private(*pt.d);
+        delete d;
+        new_d = d;
+    }
+    return *this;
+}
diff --git a/cpp/poppler-page-transition.h b/cpp/poppler-page-transition.h
new file mode 100644
index 0000000..4ecb179
--- /dev/null
+++ b/cpp/poppler-page-transition.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_PAGE_TRANSITION_H
+#define POPPLER_PAGE_TRANSITION_H
+
+#include "poppler-global.h"
+
+class Object;
+
+namespace poppler
+{
+
+class page;
+class page_transition_private;
+
+class POPPLER_CPP_EXPORT page_transition
+{
+public:
+    enum type_enum {
+        replace = 0,
+        split,
+        blinds,
+        box,
+        wipe,
+        dissolve,
+        glitter,
+        fly,
+        push,
+        cover,
+        uncover,
+        fade
+    };
+
+    enum alignment_enum {
+        horizontal = 0,
+        vertical
+    };
+
+    enum direction_enum {
+        inward = 0,
+        outward
+    };
+
+    page_transition(const page_transition &pt);
+    ~page_transition();
+
+    type_enum type() const;
+    int duration() const;
+    alignment_enum alignment() const;
+    direction_enum direction() const;
+    int angle() const;
+    double scale() const;
+    bool is_rectangular() const;
+
+    page_transition& operator=(const page_transition &pt);
+
+private:
+    page_transition(Object *params);
+
+    page_transition_private *d;
+    friend class page;
+};
+
+}
+
+#endif
diff --git a/cpp/poppler-page.cpp b/cpp/poppler-page.cpp
new file mode 100644
index 0000000..b10cc5b
--- /dev/null
+++ b/cpp/poppler-page.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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-page.h"
+#include "poppler-page-transition.h"
+
+#include "poppler-document-private.h"
+#include "poppler-page-private.h"
+#include "poppler-private.h"
+
+using namespace poppler;
+
+page_private::page_private(document_private *_doc, int _index)
+    : doc(_doc)
+    , page(doc->doc->getCatalog()->getPage(index + 1))
+    , index(_index)
+    , transition(0)
+{
+}
+
+page_private::~page_private()
+{
+    delete transition;
+}
+
+
+page::page(document_private *doc, int index)
+    : d(new page_private(doc, index))
+{
+}
+
+page::~page()
+{
+    delete d;
+}
+
+page::orientation_enum page::orientation() const
+{
+    const int rotation = d->page->getRotate();
+    switch (rotation) {
+    case 90:
+        return landscape;
+        break;
+    case 180:
+        return upside_down;
+        break;
+    case 270:
+        return seascape;
+        break;
+    default:
+        return portrait;
+    }
+}
+
+double page::duration() const
+{
+    return d->page->getDuration();
+}
+
+rectf page::page_rect(page_box_enum box) const
+{
+    PDFRectangle *r = 0;
+    switch (box) {
+    case media_box:
+        r = d->page->getMediaBox();
+        break;
+    case crop_box:
+        r = d->page->getCropBox();
+        break;
+    case bleed_box:
+        r = d->page->getBleedBox();
+        break;
+    case trim_box:
+        r = d->page->getTrimBox();
+        break;
+    case art_box:
+        r = d->page->getArtBox();
+        break;
+    }
+    if (r) {
+        return detail::pdfrectangle_to_rectf(*r);
+    }
+    return rectf();
+}
+
+ustring page::label() const
+{
+    GooString goo;
+    if (!d->doc->doc->getCatalog()->indexToLabel(d->index, &goo)) {
+        return ustring();
+    }
+
+    return detail::unicode_GooString_to_ustring(&goo);
+}
+
+page_transition* page::transition() const
+{
+    if (!d->transition) {
+        Object o;
+        if (d->page->getTrans(&o)->isDict()) {
+            d->transition = new page_transition(&o);
+        }
+        o.free();
+    }
+    return d->transition;
+}
diff --git a/cpp/poppler-page.h b/cpp/poppler-page.h
new file mode 100644
index 0000000..65cea52
--- /dev/null
+++ b/cpp/poppler-page.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_PAGE_H
+#define POPPLER_PAGE_H
+
+#include "poppler-global.h"
+#include "poppler-rectangle.h"
+
+namespace poppler
+{
+
+class document;
+class document_private;
+class page_private;
+class page_transition;
+
+class POPPLER_CPP_EXPORT page : public poppler::noncopyable
+{
+public:
+    enum orientation_enum {
+        landscape,
+        portrait,
+        seascape,
+        upside_down
+    };
+
+    ~page();
+
+    orientation_enum orientation() const;
+    double duration() const;
+    rectf page_rect(page_box_enum box = crop_box) const;
+    ustring label() const;
+
+    page_transition* transition() const;
+
+private:
+    page(document_private *doc, int index);
+
+    page_private *d;
+    friend class page_private;
+    friend class document;
+};
+
+}
+
+#endif
diff --git a/cpp/poppler-private.cpp b/cpp/poppler-private.cpp
new file mode 100644
index 0000000..16ba370
--- /dev/null
+++ b/cpp/poppler-private.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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-private.h"
+
+#include "GooString.h"
+#include "Page.h"
+
+#include <iostream>
+#include <sstream>
+
+using namespace poppler;
+
+void detail::error_function(int pos, char *msg, va_list args)
+{
+    std::ostringstream oss;
+    if (pos >= 0) {
+        oss << "poppler/error (" << pos << "): ";
+    } else {
+        oss << "poppler/error: ";
+    }
+    char buffer[4096]; // should be big enough
+    vsnprintf(buffer, sizeof(buffer) - 1, msg, args);
+    oss << buffer;
+    std::cerr << oss.str();
+}
+
+rectf detail::pdfrectangle_to_rectf(const PDFRectangle &pdfrect)
+{
+    return rectf(pdfrect.x1, pdfrect.y1, pdfrect.x2 - pdfrect.x1, pdfrect.y2 - pdfrect.y1);
+}
+
+ustring detail::unicode_GooString_to_ustring(GooString *str)
+{
+    return ustring::from_utf_8(str->getCString(), str->getLength());
+}
+
+ustring detail::unicode_to_ustring(const Unicode *u, int length)
+{
+    ustring str(length, 0);
+    ustring::iterator it = str.begin(), it_end = str.end();
+    const Unicode *uu = u;
+    for (; it != it_end; ++it) {
+        *it = ustring::value_type(*uu++);
+    }
+    return str;
+}
+
+GooString* detail::ustring_to_unicode_GooString(const ustring &str)
+{
+    char *u = str.to_utf_8();
+    GooString *goo = new GooString(u);
+    delete [] u;
+    return goo;
+}
diff --git a/cpp/poppler-private.h b/cpp/poppler-private.h
new file mode 100644
index 0000000..fb3bc6c
--- /dev/null
+++ b/cpp/poppler-private.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_PRIVATE_H
+#define POPPLER_PRIVATE_H
+
+#include "poppler-global.h"
+#include "poppler-rectangle.h"
+
+#include "CharTypes.h"
+
+#include <stdarg.h>
+
+class GooString;
+class PDFRectangle;
+
+#define PSTR(str) const_cast<char *>(str)
+
+namespace poppler
+{
+
+namespace detail
+{
+
+void error_function(int pos, char *msg, va_list args);
+
+rectf pdfrectangle_to_rectf(const PDFRectangle &pdfrect);
+
+ustring unicode_GooString_to_ustring(GooString *str);
+ustring unicode_to_ustring(const Unicode *u, int length);
+GooString* ustring_to_unicode_GooString(const ustring &str);
+
+}
+
+template <typename ConstIterator>
+void delete_all(ConstIterator it, ConstIterator end)
+{
+    while (it != end) {
+        delete *it++;
+    }
+}
+
+template <typename Collection>
+void delete_all(const Collection &c)
+{
+    delete_all(c.begin(), c.end());
+}
+
+}
+
+#endif
diff --git a/cpp/poppler-rectangle.h b/cpp/poppler-rectangle.h
new file mode 100644
index 0000000..7465edc
--- /dev/null
+++ b/cpp/poppler-rectangle.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_RECTANGLE_H
+#define POPPLER_RECTANGLE_H
+
+namespace poppler
+{
+
+template <typename T> class rectangle
+{
+public:
+    rectangle()
+        : x1(), y1(), x2(), y2()
+    {}
+    rectangle(T _x, T _y, T w, T h)
+        : x1(_x), y1(_y), x2(x1 + w), y2(y1 + h)
+    {}
+    ~rectangle();
+
+    bool is_empty() const
+    { return (x1 == x2) && (y1 == y2); }
+
+    T x() const
+    { return x1; }
+
+    T y() const
+    { return y1; }
+
+    T width() const
+    { return x2 - x1; }
+
+    T height() const
+    { return y2 - y1; }
+
+private:
+    T x1, y1, x2, y2;
+};
+
+typedef rectangle<int> rect;
+typedef rectangle<double> rectf;
+
+}
+
+#endif
diff --git a/cpp/poppler-toc-private.h b/cpp/poppler-toc-private.h
new file mode 100644
index 0000000..e8841ff
--- /dev/null
+++ b/cpp/poppler-toc-private.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_TOC_PRIVATE_H
+#define POPPLER_TOC_PRIVATE_H
+
+#include "poppler-global.h"
+#include "poppler-toc.h"
+
+#include <vector>
+
+class GooList;
+class Outline;
+class OutlineItem;
+
+namespace poppler
+{
+
+class toc_private
+{
+public:
+    toc_private();
+    ~toc_private();
+
+    static toc* load_from_outline(Outline *outline);
+
+    toc_item root;
+};
+
+
+class toc_item_private
+{
+public:
+    toc_item_private();
+    ~toc_item_private();
+
+    void load(OutlineItem *item);
+    void load_children(GooList *items);
+
+    std::vector<toc_item*> children;
+    ustring title;
+    bool is_open;
+};
+
+}
+
+#endif
diff --git a/cpp/poppler-toc.cpp b/cpp/poppler-toc.cpp
new file mode 100644
index 0000000..6f05f21
--- /dev/null
+++ b/cpp/poppler-toc.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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-toc.h"
+
+#include "poppler-toc-private.h"
+#include "poppler-private.h"
+
+#include "GooList.h"
+#include "Outline.h"
+
+using namespace poppler;
+
+toc_private::toc_private()
+{
+}
+
+toc_private::~toc_private()
+{
+}
+
+toc* toc_private::load_from_outline(Outline *outline)
+{
+    if (!outline) {
+        return 0;
+    }
+
+    GooList *items = outline->getItems();
+    if (!items || items->getLength() < 1) {
+        return 0;
+    }
+
+    toc *newtoc = new toc();
+    newtoc->d->root.d->is_open = true;
+    newtoc->d->root.d->load_children(outline->getItems());
+
+    return newtoc;
+}
+
+toc_item_private::toc_item_private()
+    : is_open(false)
+{
+}
+
+toc_item_private::~toc_item_private()
+{
+}
+
+void toc_item_private::load(OutlineItem *item)
+{
+    const Unicode *title_unicode = item->getTitle();
+    const int title_length = item->getTitleLength();
+    title = detail::unicode_to_ustring(title_unicode, title_length);
+    is_open = item->isOpen();
+}
+
+void toc_item_private::load_children(GooList *items)
+{
+    const int num_items = items->getLength();
+    children.resize(num_items);
+    for (int i = 0; i < num_items; ++i) {
+        OutlineItem *item = (OutlineItem *)items->get(i);
+
+        toc_item *new_item = new toc_item();
+        new_item->d->load(item);
+        children[i] = new_item;
+
+        item->open();
+        GooList *item_children = item->getKids();
+        if (item_children) {
+            new_item->d->load_children(item_children);
+        }
+    }
+}
+
+
+toc::toc()
+    : d(new toc_private())
+{
+}
+
+toc::~toc()
+{
+    delete d;
+}
+
+
+toc_item::toc_item()
+    : d(new toc_item_private())
+{
+}
+
+toc_item::~toc_item()
+{
+    delete d;
+}
+
+ustring toc_item::title() const
+{
+    return d->title;
+}
+
+bool toc_item::is_open() const
+{
+    return d->is_open;
+}
+
+std::vector<toc_item *> toc_item::children() const
+{
+    return d->children;
+}
+
+toc_item::iterator toc_item::children_begin() const
+{
+    return d->children.begin();
+}
+
+toc_item::iterator toc_item::children_end() const
+{
+    return d->children.end();
+}
diff --git a/cpp/poppler-toc.h b/cpp/poppler-toc.h
new file mode 100644
index 0000000..8b09736
--- /dev/null
+++ b/cpp/poppler-toc.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2009, Pino Toscano <pino at kde.org>
+ *
+ * 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_TOC_H
+#define POPPLER_TOC_H
+
+#include "poppler-global.h"
+
+#include <vector>
+
+namespace poppler
+{
+
+class toc_private;
+class toc_item;
+class toc_item_private;
+
+class POPPLER_CPP_EXPORT toc : public poppler::noncopyable
+{
+public:
+    ~toc();
+
+    toc_item* root() const;
+
+private:
+    toc();
+
+    toc_private *d;
+
+    friend class toc_private;
+};
+
+
+class POPPLER_CPP_EXPORT toc_item : public poppler::noncopyable
+{
+public:
+    typedef std::vector<toc_item *>::const_iterator iterator;
+
+    ~toc_item();
+
+    ustring title() const;
+    bool is_open() const;
+
+    std::vector<toc_item *> children() const;
+    iterator children_begin() const;
+    iterator children_end() const;
+
+private:
+    toc_item();
+
+    toc_item_private *d;
+    friend class toc;
+    friend class toc_private;
+    friend class toc_item_private;
+};
+
+}
+
+#endif


More information about the poppler mailing list