[poppler] 3 commits - cpp/CMakeLists.txt cpp/Makefile.am cpp/poppler-page-private.h cpp/poppler-page-renderer.cpp cpp/poppler-page-renderer.h cpp/tests

Pino Toscano pino at kemper.freedesktop.org
Sun Nov 7 07:31:56 PST 2010


 cpp/CMakeLists.txt            |    2 
 cpp/Makefile.am               |    2 
 cpp/poppler-page-private.h    |    5 
 cpp/poppler-page-renderer.cpp |  212 ++++++++++++++++++++++++++++++++++++++++++
 cpp/poppler-page-renderer.h   |   66 +++++++++++++
 cpp/tests/CMakeLists.txt      |    3 
 cpp/tests/Makefile.am         |    9 +
 cpp/tests/poppler-render.cpp  |  113 ++++++++++++++++++++++
 8 files changed, 411 insertions(+), 1 deletion(-)

New commits:
commit 970f075569bf9be5e5ddc3a9ad1fabec5435dfaf
Author: Pino Toscano <pino at kde.org>
Date:   Sun Nov 7 16:31:02 2010 +0100

    [cpp/tests] add a simple poppler-render test
    
    ... to ease testing the render capabilities of poppler-cpp.
    quite minimal at the moment.

diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt
index 85e20fb..6ea24a5 100644
--- a/cpp/tests/CMakeLists.txt
+++ b/cpp/tests/CMakeLists.txt
@@ -20,3 +20,6 @@ endmacro(CPP_ADD_SIMPLETEST)
 
 cpp_add_simpletest(poppler-dump poppler-dump.cpp ${CMAKE_SOURCE_DIR}/utils/parseargs.cc)
 target_link_libraries(poppler-dump poppler)
+
+cpp_add_simpletest(poppler-render poppler-render.cpp ${CMAKE_SOURCE_DIR}/utils/parseargs.cc)
+target_link_libraries(poppler-render poppler)
diff --git a/cpp/tests/Makefile.am b/cpp/tests/Makefile.am
index 87a4f7a..aab55f2 100644
--- a/cpp/tests/Makefile.am
+++ b/cpp/tests/Makefile.am
@@ -11,10 +11,17 @@ LDADDS =					\
 
 
 noinst_PROGRAMS =				\
-	poppler-dump
+	poppler-dump				\
+	poppler-render
 
 poppler_dump_SOURCES = \
 	$(top_srcdir)/utils/parseargs.cc	\
 	poppler-dump.cpp
 poppler_dump_LDADD = $(LDADDS)
 
+
+poppler_render_SOURCES = \
+	$(top_srcdir)/utils/parseargs.cc	\
+	poppler-render.cpp
+poppler_render_LDADD = $(LDADDS)
+
diff --git a/cpp/tests/poppler-render.cpp b/cpp/tests/poppler-render.cpp
new file mode 100644
index 0000000..b440dd4
--- /dev/null
+++ b/cpp/tests/poppler-render.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2010, 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-image.h>
+#include <poppler-page.h>
+#include <poppler-page-renderer.h>
+
+#include <cstdlib>
+#include <iostream>
+#include <memory>
+
+#include "parseargs.h"
+
+bool show_help = false;
+bool show_formats = false;
+char out_filename[4096];
+int doc_page = 0;
+
+static const ArgDesc the_args[] = {
+    { "-f",                    argFlag,  &show_formats,        0,
+      "show supported output image formats" },
+    { "--page",                argInt,   &doc_page,            0,
+      "select page to render" },
+    { "-o",                    argString, &out_filename,       sizeof(out_filename),
+      "output filename for the resulting PNG image" },
+    { "-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);
+}
+
+int main(int argc, char *argv[])
+{
+    if (!parseArgs(the_args, &argc, argv)
+        || (argc < 2 && !show_formats) || show_help) {
+        printUsage(argv[0], "DOCUMENT", the_args);
+        exit(1);
+    }
+
+    if (show_formats) {
+        const std::vector<std::string> formats = poppler::image::supported_image_formats();
+        std::cout << "Supported image formats:" << std::endl;
+        for (size_t i = 0; i < formats.size(); ++i) {
+            std::cout << "  " << formats[i] << std::endl;
+        }
+        exit(0);
+    }
+
+    if (!out_filename[0]) {
+        error("missing output filename (-o)");
+    }
+
+    if (!poppler::page_renderer::can_render()) {
+        error("renderer compiled without Splash support");
+    }
+
+    const 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");
+    }
+
+    if (doc_page < 0 || doc_page >= doc->pages()) {
+        error("specified page number out of page count");
+    }
+    std::auto_ptr<poppler::page> p(doc->create_page(doc_page));
+    if (!p.get()) {
+        error("NULL page");
+    }
+
+    poppler::page_renderer pr;
+    pr.set_render_hint(poppler::page_renderer::antialiasing, true);
+    pr.set_render_hint(poppler::page_renderer::text_antialiasing, true);
+
+    poppler::image img = pr.render_page(p.get());
+    if (!img.is_valid()) {
+        error("rendering failed");
+    }
+
+    if (!img.save(out_filename, "png")) {
+        error("saving to file failed");
+    }
+
+    return 0;
+}
commit bfe4139c742cb0a669f5504df7e22e3e57243d9a
Author: Pino Toscano <pino at kde.org>
Date:   Sun Nov 7 16:23:26 2010 +0100

    [cpp] Add page_renderer, to render pages over images.
    
    This new class introduces a very simple way to render a page, using the Splash backend,
    giving an 'image' as result.
    It can hold a color for the "paper" of the pages, and some hints for the actual rendering.

diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index 6e5724b..e606988 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -14,6 +14,7 @@ set(poppler_cpp_SRCS
   poppler-global.cpp
   poppler-image.cpp
   poppler-page.cpp
+  poppler-page-renderer.cpp
   poppler-page-transition.cpp
   poppler-private.cpp
   poppler-rectangle.cpp
@@ -37,6 +38,7 @@ install(FILES
   poppler-global.h
   poppler-image.h
   poppler-page.h
+  poppler-page-renderer.h
   poppler-page-transition.h
   poppler-rectangle.h
   poppler-toc.h
diff --git a/cpp/Makefile.am b/cpp/Makefile.am
index 6af79af..eddbde3 100644
--- a/cpp/Makefile.am
+++ b/cpp/Makefile.am
@@ -13,6 +13,7 @@ poppler_include_HEADERS =			\
 	poppler-global.h			\
 	poppler-image.h			\
 	poppler-page.h				\
+	poppler-page-renderer.h			\
 	poppler-page-transition.h		\
 	poppler-rectangle.h			\
 	poppler-toc.h				\
@@ -30,6 +31,7 @@ libpoppler_cpp_la_SOURCES =			\
 	poppler-image-private.h			\
 	poppler-page.cpp			\
 	poppler-page-private.h			\
+	poppler-page-renderer.cpp		\
 	poppler-page-transition.cpp		\
 	poppler-private.cpp			\
 	poppler-private.h			\
diff --git a/cpp/poppler-page-renderer.cpp b/cpp/poppler-page-renderer.cpp
new file mode 100644
index 0000000..47678b7
--- /dev/null
+++ b/cpp/poppler-page-renderer.cpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2010, 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-renderer.h"
+
+#include "poppler-document-private.h"
+#include "poppler-page-private.h"
+
+#include <config.h>
+
+#include "PDFDoc.h"
+#if defined(HAVE_SPLASH)
+#include "SplashOutputDev.h"
+#include "splash/SplashBitmap.h"
+#endif
+
+using namespace poppler;
+
+class poppler::page_renderer_private
+{
+public:
+    page_renderer_private()
+        : paper_color(0xffffffff)
+        , hints(0)
+    {
+    }
+
+    argb paper_color;
+    unsigned int hints;
+};
+
+
+/**
+ \class poppler::page_renderer poppler-page-renderer.h "poppler/cpp/poppler-renderer.h"
+
+ Simple way to render a page of a PDF %document.
+
+ \since 0.16
+ */
+
+/**
+ \enum poppler::page_renderer::render_hint
+
+ A flag of an option taken into account when rendering
+*/
+
+
+/**
+ Constructs a new %page renderer.
+ */
+page_renderer::page_renderer()
+    : d(new page_renderer_private())
+{
+}
+
+/**
+ Destructor.
+ */
+page_renderer::~page_renderer()
+{
+    delete d;
+}
+
+/**
+ The color used for the "paper" of the pages.
+
+ The default color is opaque solid white (0xffffffff).
+
+ \returns the paper color
+ */
+argb page_renderer::paper_color() const
+{
+    return d->paper_color;
+}
+
+/**
+ Set a new color for the "paper".
+
+ \param c the new color
+ */
+void page_renderer::set_paper_color(argb c)
+{
+    d->paper_color = c;
+}
+
+/**
+ The hints used when rendering.
+
+ By default no hint is set.
+
+ \returns the render hints set
+ */
+unsigned int page_renderer::render_hints() const
+{
+    return d->hints;
+}
+
+/**
+ Enable or disable a single render %hint.
+
+ \param hint the hint to modify
+ \param on whether enable it or not
+ */
+void page_renderer::set_render_hint(page_renderer::render_hint hint, bool on)
+{
+    if (on) {
+        d->hints |= hint;
+    } else {
+        d->hints &= ~(int)hint;
+    }
+}
+
+/**
+ Set new render %hints at once.
+
+ \param hints the new set of render hints
+ */
+void page_renderer::set_render_hints(unsigned int hints)
+{
+    d->hints = hints;
+}
+
+/**
+ Render the specified page.
+
+ This functions renders the specified page on an image following the specified
+ parameters, returning it.
+
+ \param p the page to render
+ \param xres the X resolution, in dot per inch (DPI)
+ \param yres the Y resolution, in dot per inch (DPI)
+ \param x the X top-right coordinate, in pixels
+ \param y the Y top-right coordinate, in pixels
+ \param w the width in pixels of the area to render
+ \param h the height in pixels of the area to render
+ \param rotate the rotation to apply when rendering the page
+
+ \returns the rendered image, or a null one in case of errors
+
+ \see can_render
+ */
+image page_renderer::render_page(const page *p,
+                                 double xres, double yres,
+                                 int x, int y, int w, int h,
+                                 rotation_enum rotate) const
+{
+    if (!p) {
+        return image();
+    }
+
+#if defined(HAVE_SPLASH)
+    page_private *pp = page_private::get(p);
+    PDFDoc *pdfdoc = pp->doc->doc;
+
+    SplashColor bgColor;
+    bgColor[0] = d->paper_color & 0xff;
+    bgColor[1] = (d->paper_color >> 8) & 0xff;
+    bgColor[2] = (d->paper_color >> 16) & 0xff;
+    const GBool text_AA = d->hints & text_antialiasing ? gTrue : gFalse;
+    SplashOutputDev splashOutputDev(splashModeXBGR8, 4, gFalse, bgColor, gTrue, text_AA);
+    splashOutputDev.setVectorAntialias(d->hints & antialiasing ? gTrue : gFalse);
+    splashOutputDev.setFreeTypeHinting(d->hints & text_hinting ? gTrue : gFalse);
+    splashOutputDev.startDoc(pdfdoc->getXRef());
+    pdfdoc->displayPageSlice(&splashOutputDev, pp->index + 1,
+                             xres, yres, int(rotate) * 90,
+                             gFalse, gTrue, gFalse,
+                             x, y, w, h);
+
+    SplashBitmap *bitmap = splashOutputDev.getBitmap();
+    const int bw = bitmap->getWidth();
+    const int bh = bitmap->getHeight();
+
+    SplashColorPtr data_ptr = bitmap->getDataPtr();
+
+    const image img(reinterpret_cast<char *>(data_ptr), bw, bh, image::format_argb32);
+    return img.copy();
+#else
+    return image();
+#endif
+}
+
+/**
+ Rendering capability test.
+
+ page_renderer can render only if a render backend ('Splash') is compiled in
+ Poppler.
+
+ \returns whether page_renderer can render
+ */
+bool page_renderer::can_render()
+{
+#if defined(HAVE_SPLASH)
+    return true;
+#else
+    return false;
+#endif
+}
diff --git a/cpp/poppler-page-renderer.h b/cpp/poppler-page-renderer.h
new file mode 100644
index 0000000..1383865
--- /dev/null
+++ b/cpp/poppler-page-renderer.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010, 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_RENDERER_H
+#define POPPLER_PAGE_RENDERER_H
+
+#include "poppler-global.h"
+#include "poppler-image.h"
+
+namespace poppler
+{
+
+typedef unsigned int argb;
+
+class page;
+class page_renderer_private;
+
+class POPPLER_CPP_EXPORT page_renderer : public poppler::noncopyable
+{
+public:
+    enum render_hint {
+        antialiasing = 0x00000001,
+        text_antialiasing = 0x00000002,
+        text_hinting = 0x00000004
+    };
+
+    page_renderer();
+    ~page_renderer();
+
+    argb paper_color() const;
+    void set_paper_color(argb c);
+
+    unsigned int render_hints() const;
+    void set_render_hint(render_hint hint, bool on = true);
+    void set_render_hints(unsigned int hints);
+
+    image render_page(const page *p,
+                      double xres = 72.0, double yres = 72.0,
+                      int x = -1, int y = -1, int w = -1, int h = -1,
+                      rotation_enum rotate = rotate_0) const;
+
+    static bool can_render();
+
+private:
+    page_renderer_private *d;
+    friend class page_renderer_private;
+};
+
+}
+
+#endif
commit 91e3f7b4ea42a5821fd78e1edf55e95250c9bc68
Author: Pino Toscano <pino at kde.org>
Date:   Sun Nov 7 16:19:34 2010 +0100

    [cpp] add an internal way to get a 'page_private' of a 'page'
    
    useful for getting a 'page_private' in the implementation of other cpp classes
    without the need to add friends to 'page'

diff --git a/cpp/poppler-page-private.h b/cpp/poppler-page-private.h
index 654478b..b208cb8 100644
--- a/cpp/poppler-page-private.h
+++ b/cpp/poppler-page-private.h
@@ -19,6 +19,8 @@
 #ifndef POPPLER_PAGE_PRIVATE_H
 #define POPPLER_PAGE_PRIVATE_H
 
+#include "poppler-page.h"
+
 class Page;
 
 namespace poppler
@@ -37,6 +39,9 @@ public:
     Page *page;
     int index;
     page_transition *transition;
+
+    static inline page_private* get(const poppler::page *p)
+    { return const_cast<poppler::page *>(p)->d; }
 };
 
 }


More information about the poppler mailing list