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 <[email protected]> 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 <[email protected]> + * + * 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 <[email protected]> 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 <[email protected]> + * + * 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 <[email protected]> + * + * 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 <[email protected]> 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; } }; } _______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
