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