|  | /* | 
|  | * Copyright (C) 2010, Pino Toscano <pino@kde.org> | 
|  | * Copyright (C) 2015 William Bader <williambader@hotmail.com> | 
|  | * Copyright (C) 2018, Zsombor Hollay-Horvath <hollay.horvath@gmail.com> | 
|  | * Copyright (C) 2019, Julián Unrrein <junrrein@gmail.com> | 
|  | * Copyright (C) 2020, Albert Astals Cid <aacid@kde.org> | 
|  | * Copyright (C) 2021, Hubert Figuiere <hub@figuiere.net> | 
|  | * | 
|  | * This program is free software; you can redistribute it and/or modify | 
|  | * it under the terms of the GNU General Public License as published by | 
|  | * the Free Software Foundation; either version 2, or (at your option) | 
|  | * any later version. | 
|  | * | 
|  | * This program is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | * GNU General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU General Public License | 
|  | * along with this program; if not, write to the Free Software | 
|  | * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. | 
|  | */ | 
|  |  | 
|  | /** | 
|  | \file poppler-page-renderer.h | 
|  | */ | 
|  | #include "poppler-page-renderer.h" | 
|  |  | 
|  | #include "poppler-document-private.h" | 
|  | #include "poppler-page-private.h" | 
|  | #include "poppler-image.h" | 
|  |  | 
|  | #include <config.h> | 
|  | #include <poppler-config.h> | 
|  |  | 
|  | #include "PDFDoc.h" | 
|  | #include "SplashOutputDev.h" | 
|  | #include "splash/SplashBitmap.h" | 
|  |  | 
|  | using namespace poppler; | 
|  |  | 
|  | class poppler::page_renderer_private | 
|  | { | 
|  | public: | 
|  | page_renderer_private() : paper_color(0xffffffff), hints(0), image_format(image::format_enum::format_argb32), line_mode(page_renderer::line_mode_enum::line_default) { } | 
|  |  | 
|  | static bool conv_color_mode(image::format_enum mode, SplashColorMode &splash_mode); | 
|  | static bool conv_line_mode(page_renderer::line_mode_enum mode, SplashThinLineMode &splash_mode); | 
|  |  | 
|  | argb paper_color; | 
|  | unsigned int hints; | 
|  | image::format_enum image_format; | 
|  | page_renderer::line_mode_enum line_mode; | 
|  | }; | 
|  |  | 
|  | bool page_renderer_private::conv_color_mode(image::format_enum mode, SplashColorMode &splash_mode) | 
|  | { | 
|  | switch (mode) { | 
|  | case image::format_enum::format_mono: | 
|  | splash_mode = splashModeMono1; | 
|  | break; | 
|  | case image::format_enum::format_gray8: | 
|  | splash_mode = splashModeMono8; | 
|  | break; | 
|  | case image::format_enum::format_rgb24: | 
|  | splash_mode = splashModeRGB8; | 
|  | break; | 
|  | case image::format_enum::format_bgr24: | 
|  | splash_mode = splashModeBGR8; | 
|  | break; | 
|  | case image::format_enum::format_argb32: | 
|  | splash_mode = splashModeXBGR8; | 
|  | break; | 
|  | default: | 
|  | return false; | 
|  | } | 
|  | return true; | 
|  | } | 
|  |  | 
|  | bool page_renderer_private::conv_line_mode(page_renderer::line_mode_enum mode, SplashThinLineMode &splash_mode) | 
|  | { | 
|  | switch (mode) { | 
|  | case page_renderer::line_mode_enum::line_default: | 
|  | splash_mode = splashThinLineDefault; | 
|  | break; | 
|  | case page_renderer::line_mode_enum::line_solid: | 
|  | splash_mode = splashThinLineSolid; | 
|  | break; | 
|  | case page_renderer::line_mode_enum::line_shape: | 
|  | splash_mode = splashThinLineShape; | 
|  | break; | 
|  | default: | 
|  | return false; | 
|  | } | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /** | 
|  | \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; | 
|  | } | 
|  |  | 
|  | /** | 
|  | The image format used when rendering. | 
|  |  | 
|  | By default ARGB32 is set. | 
|  |  | 
|  | \returns the image format | 
|  |  | 
|  | \since 0.65 | 
|  | */ | 
|  | image::format_enum page_renderer::image_format() const | 
|  | { | 
|  | return d->image_format; | 
|  | } | 
|  |  | 
|  | /** | 
|  | Set new image format used when rendering. | 
|  |  | 
|  | \param format the new image format | 
|  |  | 
|  | \since 0.65 | 
|  | */ | 
|  | void page_renderer::set_image_format(image::format_enum format) | 
|  | { | 
|  | d->image_format = format; | 
|  | } | 
|  |  | 
|  | /** | 
|  | The line mode used when rendering. | 
|  |  | 
|  | By default default mode is set. | 
|  |  | 
|  | \returns the line mode | 
|  |  | 
|  | \since 0.65 | 
|  | */ | 
|  | page_renderer::line_mode_enum page_renderer::line_mode() const | 
|  | { | 
|  | return d->line_mode; | 
|  | } | 
|  |  | 
|  | /** | 
|  | Set new line mode used when rendering. | 
|  |  | 
|  | \param mode the new line mode | 
|  |  | 
|  | \since 0.65 | 
|  | */ | 
|  | void page_renderer::set_line_mode(page_renderer::line_mode_enum mode) | 
|  | { | 
|  | d->line_mode = mode; | 
|  | } | 
|  |  | 
|  | /** | 
|  | 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(); | 
|  | } | 
|  |  | 
|  | page_private *pp = page_private::get(p); | 
|  | PDFDoc *pdfdoc = pp->doc->doc; | 
|  |  | 
|  | SplashColorMode colorMode; | 
|  | SplashThinLineMode lineMode; | 
|  |  | 
|  | if (!d->conv_color_mode(d->image_format, colorMode) || !d->conv_line_mode(d->line_mode, lineMode)) { | 
|  | return image(); | 
|  | } | 
|  |  | 
|  | SplashColor bgColor; | 
|  | bgColor[0] = d->paper_color & 0xff; | 
|  | bgColor[1] = (d->paper_color >> 8) & 0xff; | 
|  | bgColor[2] = (d->paper_color >> 16) & 0xff; | 
|  | SplashOutputDev splashOutputDev(colorMode, 4, false, bgColor, true, lineMode); | 
|  | splashOutputDev.setFontAntialias(d->hints & text_antialiasing ? true : false); | 
|  | splashOutputDev.setVectorAntialias(d->hints & antialiasing ? true : false); | 
|  | splashOutputDev.setFreeTypeHinting(d->hints & text_hinting ? true : false, false); | 
|  | splashOutputDev.startDoc(pdfdoc); | 
|  | pdfdoc->displayPageSlice(&splashOutputDev, pp->index + 1, xres, yres, int(rotate) * 90, false, true, false, x, y, w, h, nullptr, nullptr, nullptr, nullptr, true); | 
|  |  | 
|  | 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, d->image_format); | 
|  | return img.copy(); | 
|  | } | 
|  |  | 
|  | /** | 
|  | 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() | 
|  | { | 
|  | return true; | 
|  | } |