Coverage Report

Created: 2026-08-14 08:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poppler/cpp/poppler-page-renderer.cpp
Line
Count
Source
1
/*
2
 * Copyright (C) 2010, Pino Toscano <pino@kde.org>
3
 * Copyright (C) 2015 William Bader <williambader@hotmail.com>
4
 * Copyright (C) 2018, Zsombor Hollay-Horvath <hollay.horvath@gmail.com>
5
 * Copyright (C) 2019, Julián Unrrein <junrrein@gmail.com>
6
 * Copyright (C) 2020, 2026, Albert Astals Cid <aacid@kde.org>
7
 * Copyright (C) 2021, Hubert Figuiere <hub@figuiere.net>
8
 * Copyright (C) 2026, g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
9
 * Copyright (C) 2026, Trevor L Davis <trevor.l.davis@gmail.com>
10
 *
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2, or (at your option)
14
 * any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
24
 */
25
26
/**
27
 \file poppler-page-renderer.h
28
 */
29
#include "poppler-page-renderer.h"
30
31
#include "poppler-document-private.h"
32
#include "poppler-page-private.h"
33
#include "poppler-image.h"
34
35
#include <config.h>
36
#include <poppler-config.h>
37
38
#include "PDFDoc.h"
39
#include "SplashOutputDev.h"
40
#include "splash/SplashBitmap.h"
41
42
using namespace poppler;
43
44
class poppler::page_renderer_private
45
{
46
public:
47
37.2k
    page_renderer_private() = default;
48
49
    static bool conv_color_mode(image::format_enum mode, SplashColorMode &splash_mode);
50
    static bool conv_line_mode(page_renderer::line_mode_enum mode, SplashThinLineMode &splash_mode);
51
52
    argb paper_color = 0xffffffff;
53
    unsigned int hints = 0;
54
    image::format_enum image_format = image::format_enum::format_argb32;
55
    page_renderer::line_mode_enum line_mode = page_renderer::line_mode_enum::line_default;
56
};
57
58
bool page_renderer_private::conv_color_mode(image::format_enum mode, SplashColorMode &splash_mode)
59
77.4k
{
60
77.4k
    switch (mode) {
61
0
    case image::format_enum::format_mono:
62
0
        splash_mode = splashModeMono1;
63
0
        break;
64
0
    case image::format_enum::format_gray8:
65
0
        splash_mode = splashModeMono8;
66
0
        break;
67
0
    case image::format_enum::format_rgb24:
68
0
        splash_mode = splashModeRGB8;
69
0
        break;
70
0
    case image::format_enum::format_bgr24:
71
0
        splash_mode = splashModeBGR8;
72
0
        break;
73
77.4k
    case image::format_enum::format_argb32:
74
77.4k
        splash_mode = splashModeXBGR8;
75
77.4k
        break;
76
0
    default:
77
0
        return false;
78
77.4k
    }
79
77.4k
    return true;
80
77.4k
}
81
82
bool page_renderer_private::conv_line_mode(page_renderer::line_mode_enum mode, SplashThinLineMode &splash_mode)
83
77.4k
{
84
77.4k
    switch (mode) {
85
77.4k
    case page_renderer::line_mode_enum::line_default:
86
77.4k
        splash_mode = splashThinLineDefault;
87
77.4k
        break;
88
0
    case page_renderer::line_mode_enum::line_solid:
89
0
        splash_mode = splashThinLineSolid;
90
0
        break;
91
0
    case page_renderer::line_mode_enum::line_shape:
92
0
        splash_mode = splashThinLineShape;
93
0
        break;
94
0
    default:
95
0
        return false;
96
77.4k
    }
97
77.4k
    return true;
98
77.4k
}
99
100
/**
101
 \class poppler::page_renderer poppler-page-renderer.h "poppler/cpp/poppler-renderer.h"
102
103
 Simple way to render a page of a PDF %document.
104
105
 \since 0.16
106
 */
107
108
/**
109
 \enum poppler::page_renderer::render_hint
110
111
 A flag of an option taken into account when rendering
112
*/
113
114
/**
115
 Constructs a new %page renderer.
116
 */
117
37.2k
page_renderer::page_renderer() : d(new page_renderer_private()) { }
118
119
/**
120
 Destructor.
121
 */
122
page_renderer::~page_renderer()
123
37.2k
{
124
37.2k
    delete d;
125
37.2k
}
126
127
/**
128
 The color used for the "paper" of the pages.
129
130
 The default color is opaque solid white (0xffffffff).
131
132
 \returns the paper color
133
 */
134
argb page_renderer::paper_color() const
135
0
{
136
0
    return d->paper_color;
137
0
}
138
139
/**
140
 Set a new color for the "paper".
141
142
 \param c the new color
143
 */
144
void page_renderer::set_paper_color(argb c)
145
0
{
146
0
    d->paper_color = c;
147
0
}
148
149
/**
150
 The hints used when rendering.
151
152
 By default no hint is set.
153
154
 \returns the render hints set
155
 */
156
unsigned int page_renderer::render_hints() const
157
0
{
158
0
    return d->hints;
159
0
}
160
161
/**
162
 Enable or disable a single render %hint.
163
164
 \param hint the hint to modify
165
 \param on whether enable it or not
166
 */
167
void page_renderer::set_render_hint(page_renderer::render_hint hint, bool on)
168
0
{
169
0
    if (on) {
170
0
        d->hints |= hint;
171
0
    } else {
172
0
        d->hints &= ~static_cast<int>(hint);
173
0
    }
174
0
}
175
176
/**
177
 Set new render %hints at once.
178
179
 \param hints the new set of render hints
180
 */
181
void page_renderer::set_render_hints(unsigned int hints)
182
0
{
183
0
    d->hints = hints;
184
0
}
185
186
/**
187
 The image format used when rendering.
188
189
 By default ARGB32 is set.
190
191
 \returns the image format
192
193
 \since 0.65
194
 */
195
image::format_enum page_renderer::image_format() const
196
0
{
197
0
    return d->image_format;
198
0
}
199
200
/**
201
 Set new image format used when rendering.
202
203
 \param format the new image format
204
205
 \since 0.65
206
 */
207
void page_renderer::set_image_format(image::format_enum format)
208
0
{
209
0
    d->image_format = format;
210
0
}
211
212
/**
213
 The line mode used when rendering.
214
215
 By default default mode is set.
216
217
 \returns the line mode
218
219
 \since 0.65
220
 */
221
page_renderer::line_mode_enum page_renderer::line_mode() const
222
0
{
223
0
    return d->line_mode;
224
0
}
225
226
/**
227
 Set new line mode used when rendering.
228
229
 \param mode the new line mode
230
231
 \since 0.65
232
 */
233
void page_renderer::set_line_mode(page_renderer::line_mode_enum mode)
234
0
{
235
0
    d->line_mode = mode;
236
0
}
237
238
/**
239
 Render the specified page.
240
241
 This functions renders the specified page on an image following the specified
242
 parameters, returning it.
243
244
 \param p the page to render
245
 \param xres the X resolution, in dot per inch (DPI)
246
 \param yres the Y resolution, in dot per inch (DPI)
247
 \param x the X top-right coordinate, in pixels
248
 \param y the Y top-right coordinate, in pixels
249
 \param w the width in pixels of the area to render
250
 \param h the height in pixels of the area to render
251
 \param rotate the rotation to apply when rendering the page
252
253
 \returns the rendered image, or a null one in case of errors
254
255
 \see can_render
256
 */
257
image page_renderer::render_page(const page *p, double xres, double yres, int x, int y, int w, int h, rotation_enum rotate) const
258
77.4k
{
259
77.4k
    if (!p) {
260
0
        return image();
261
0
    }
262
263
77.4k
    page_private *pp = page_private::get(p);
264
77.4k
    PDFDoc *pdfdoc = pp->doc->doc.get();
265
266
77.4k
    SplashColorMode colorMode;
267
77.4k
    SplashThinLineMode lineMode;
268
269
77.4k
    if (!poppler::page_renderer_private::conv_color_mode(d->image_format, colorMode) || !poppler::page_renderer_private::conv_line_mode(d->line_mode, lineMode)) {
270
0
        return image();
271
0
    }
272
273
77.4k
    SplashColor bgColor;
274
77.4k
    bgColor[0] = d->paper_color & 0xff;
275
77.4k
    bgColor[1] = (d->paper_color >> 8) & 0xff;
276
77.4k
    bgColor[2] = (d->paper_color >> 16) & 0xff;
277
77.4k
    const bool ignorePaperColor = (d->hints & ignore_paper_color);
278
77.4k
    SplashOutputDev splashOutputDev(colorMode, 4, ignorePaperColor ? nullptr : bgColor, true, lineMode);
279
77.4k
    splashOutputDev.setFontAntialias((d->hints & text_antialiasing) != 0);
280
77.4k
    splashOutputDev.setVectorAntialias((d->hints & antialiasing) != 0);
281
77.4k
    splashOutputDev.setFreeTypeHinting((d->hints & text_hinting) != 0, false);
282
77.4k
    splashOutputDev.startDoc(pdfdoc);
283
77.4k
    pdfdoc->displayPageSlice(&splashOutputDev, pp->index + 1, xres, yres, static_cast<int>(rotate) * 90, false, true, false, x, y, w, h, nullptr, nullptr, nullptr, nullptr, true);
284
285
77.4k
    SplashBitmap *bitmap = splashOutputDev.getBitmap();
286
77.4k
    const int bw = bitmap->getWidth();
287
77.4k
    const int bh = bitmap->getHeight();
288
289
77.4k
    SplashColorPtr data_ptr = bitmap->getDataPtr();
290
291
77.4k
    if (ignorePaperColor && colorMode == splashModeXBGR8) {
292
0
        bitmap->convertToXBGR(SplashBitmap::conversionAlpha);
293
0
    }
294
295
77.4k
    const image img(reinterpret_cast<char *>(data_ptr), bw, bh, d->image_format);
296
77.4k
    return img.copy();
297
77.4k
}
298
299
/**
300
 Rendering capability test.
301
302
 page_renderer can render only if a render backend ('Splash') is compiled in
303
 Poppler.
304
305
 \returns whether page_renderer can render
306
 */
307
bool page_renderer::can_render()
308
0
{
309
0
    return true;
310
0
}