1 /*
2  * Copyright (C) 2010, Pino Toscano <pino@kde.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2, or (at your option)
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include "poppler-page-renderer.h"
20 
21 #include "poppler-document-private.h"
22 #include "poppler-page-private.h"
23 
24 #include <config.h>
25 
26 #include "PDFDoc.h"
27 #if defined(HAVE_SPLASH)
28 #include "SplashOutputDev.h"
29 #include "splash/SplashBitmap.h"
30 #endif
31 
32 using namespace poppler;
33 
34 class poppler::page_renderer_private
35 {
36 public:
page_renderer_private()37     page_renderer_private()
38         : paper_color(0xffffffff)
39         , hints(0)
40     {
41     }
42 
43     argb paper_color;
44     unsigned int hints;
45 };
46 
47 
48 /**
49  \class poppler::page_renderer poppler-page-renderer.h "poppler/cpp/poppler-renderer.h"
50 
51  Simple way to render a page of a PDF %document.
52 
53  \since 0.16
54  */
55 
56 /**
57  \enum poppler::page_renderer::render_hint
58 
59  A flag of an option taken into account when rendering
60 */
61 
62 
63 /**
64  Constructs a new %page renderer.
65  */
page_renderer()66 page_renderer::page_renderer()
67     : d(new page_renderer_private())
68 {
69 }
70 
71 /**
72  Destructor.
73  */
~page_renderer()74 page_renderer::~page_renderer()
75 {
76     delete d;
77 }
78 
79 /**
80  The color used for the "paper" of the pages.
81 
82  The default color is opaque solid white (0xffffffff).
83 
84  \returns the paper color
85  */
paper_color() const86 argb page_renderer::paper_color() const
87 {
88     return d->paper_color;
89 }
90 
91 /**
92  Set a new color for the "paper".
93 
94  \param c the new color
95  */
set_paper_color(argb c)96 void page_renderer::set_paper_color(argb c)
97 {
98     d->paper_color = c;
99 }
100 
101 /**
102  The hints used when rendering.
103 
104  By default no hint is set.
105 
106  \returns the render hints set
107  */
render_hints() const108 unsigned int page_renderer::render_hints() const
109 {
110     return d->hints;
111 }
112 
113 /**
114  Enable or disable a single render %hint.
115 
116  \param hint the hint to modify
117  \param on whether enable it or not
118  */
set_render_hint(page_renderer::render_hint hint,bool on)119 void page_renderer::set_render_hint(page_renderer::render_hint hint, bool on)
120 {
121     if (on) {
122         d->hints |= hint;
123     } else {
124         d->hints &= ~(int)hint;
125     }
126 }
127 
128 /**
129  Set new render %hints at once.
130 
131  \param hints the new set of render hints
132  */
set_render_hints(unsigned int hints)133 void page_renderer::set_render_hints(unsigned int hints)
134 {
135     d->hints = hints;
136 }
137 
138 /**
139  Render the specified page.
140 
141  This functions renders the specified page on an image following the specified
142  parameters, returning it.
143 
144  \param p the page to render
145  \param xres the X resolution, in dot per inch (DPI)
146  \param yres the Y resolution, in dot per inch (DPI)
147  \param x the X top-right coordinate, in pixels
148  \param y the Y top-right coordinate, in pixels
149  \param w the width in pixels of the area to render
150  \param h the height in pixels of the area to render
151  \param rotate the rotation to apply when rendering the page
152 
153  \returns the rendered image, or a null one in case of errors
154 
155  \see can_render
156  */
render_page(const page * p,double xres,double yres,int x,int y,int w,int h,rotation_enum rotate) const157 image page_renderer::render_page(const page *p,
158                                  double xres, double yres,
159                                  int x, int y, int w, int h,
160                                  rotation_enum rotate) const
161 {
162     if (!p) {
163         return image();
164     }
165 
166 #if defined(HAVE_SPLASH)
167     page_private *pp = page_private::get(p);
168     PDFDoc *pdfdoc = pp->doc->doc;
169 
170     SplashColor bgColor;
171     bgColor[0] = d->paper_color & 0xff;
172     bgColor[1] = (d->paper_color >> 8) & 0xff;
173     bgColor[2] = (d->paper_color >> 16) & 0xff;
174     const GBool text_AA = d->hints & text_antialiasing ? gTrue : gFalse;
175     SplashOutputDev splashOutputDev(splashModeXBGR8, 4, gFalse, bgColor, gTrue, text_AA);
176     splashOutputDev.setVectorAntialias(d->hints & antialiasing ? gTrue : gFalse);
177     splashOutputDev.setFreeTypeHinting(d->hints & text_hinting ? gTrue : gFalse);
178     splashOutputDev.startDoc(pdfdoc->getXRef());
179     pdfdoc->displayPageSlice(&splashOutputDev, pp->index + 1,
180                              xres, yres, int(rotate) * 90,
181                              gFalse, gTrue, gFalse,
182                              x, y, w, h);
183 
184     SplashBitmap *bitmap = splashOutputDev.getBitmap();
185     const int bw = bitmap->getWidth();
186     const int bh = bitmap->getHeight();
187 
188     SplashColorPtr data_ptr = bitmap->getDataPtr();
189 
190     const image img(reinterpret_cast<char *>(data_ptr), bw, bh, image::format_argb32);
191     return img.copy();
192 #else
193     return image();
194 #endif
195 }
196 
197 /**
198  Rendering capability test.
199 
200  page_renderer can render only if a render backend ('Splash') is compiled in
201  Poppler.
202 
203  \returns whether page_renderer can render
204  */
can_render()205 bool page_renderer::can_render()
206 {
207 #if defined(HAVE_SPLASH)
208     return true;
209 #else
210     return false;
211 #endif
212 }
213