1 /*
2 * Copyright (C) 2009-2010, Pino Toscano <pino@kde.org>
3 * Copyright (C) 2010, Hib Eris <hib@hiberis.nl>
4 * Copyright (C) 2014, 2015 Hans-Peter Deifel <hpdeifel@gmx.de>
5 * Copyright (C) 2015, Tamas Szekeres <szekerest@gmail.com>
6 * Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com>
7 * Copyright (C) 2018, 2020, 2021, Albert Astals Cid <aacid@kde.org>
8 * Copyright (C) 2018 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
9 * Copyright (C) 2018, 2020, Adam Reichold <adam.reichold@t-online.de>
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-global.h
28 */
29 #include "poppler-global.h"
30
31 #include "poppler-private.h"
32 #include "poppler-document-private.h"
33
34 #include "DateInfo.h"
35
36 #include <algorithm>
37
38 #include <cerrno>
39 #include <cstring>
40 #include <ios>
41 #include <iostream>
42
43 #include <iconv.h>
44
45 #include "config.h"
46
47 namespace {
48
49 struct MiniIconv
50 {
MiniIconv__anonaad816990111::MiniIconv51 MiniIconv(const char *to_code, const char *from_code) : i_(iconv_open(to_code, from_code)) { }
~MiniIconv__anonaad816990111::MiniIconv52 ~MiniIconv()
53 {
54 if (is_valid())
55 iconv_close(i_);
56 }
57 MiniIconv(const MiniIconv &) = delete;
58 MiniIconv &operator=(const MiniIconv &) = delete;
is_valid__anonaad816990111::MiniIconv59 bool is_valid() const { return i_ != (iconv_t)-1; }
operator iconv_t__anonaad816990111::MiniIconv60 explicit operator iconv_t() const { return i_; }
61 iconv_t i_;
62 };
63
64 }
65
66 using namespace poppler;
67
68 /**
69 \namespace poppler
70
71 Single namespace containing all the classes and functions of poppler-cpp.
72 */
73
74 /**
75 \class poppler::noncopyable
76
77 A class that cannot be copied.
78 */
79
80 /**
81 \enum poppler::rotation_enum
82
83 The case sensitivity.
84 */
85 /**
86 \var poppler::rotation_enum poppler::rotate_0
87
88 A rotation of 0 degrees clockwise.
89 */
90 /**
91 \var poppler::rotation_enum poppler::rotate_90
92
93 A rotation of 90 degrees clockwise.
94 */
95 /**
96 \var poppler::rotation_enum poppler::rotate_180
97
98 A rotation of 180 degrees clockwise.
99 */
100 /**
101 \var poppler::rotation_enum poppler::rotate_270
102
103 A rotation of 270 degrees clockwise.
104 */
105
106 /**
107 \enum poppler::page_box_enum
108
109 A possible box of a page in a PDF %document.
110 */
111 /**
112 \var poppler::page_box_enum poppler::media_box
113
114 The "media" box.
115 */
116 /**
117 \var poppler::page_box_enum poppler::crop_box
118
119 The "crop" box.
120 */
121 /**
122 \var poppler::page_box_enum poppler::bleed_box
123
124 The "bleed" box.
125 */
126 /**
127 \var poppler::page_box_enum poppler::trim_box
128
129 The "trim" box.
130 */
131 /**
132 \var poppler::page_box_enum poppler::art_box
133
134 The "art" box.
135 */
136
137 /**
138 \enum poppler::permission_enum
139
140 A possible permission in a PDF %document.
141 */
142 /**
143 \var poppler::permission_enum poppler::perm_print
144
145 The permission to allow the print of a %document.
146 */
147 /**
148 \var poppler::permission_enum poppler::perm_change
149
150 The permission to change a %document.
151
152 This is a generic "change" permission, so other permissions could affect
153 some types of changes.
154 */
155 /**
156 \var poppler::permission_enum poppler::perm_copy
157
158 The permission to allow the copy or extraction of the text in a %document.
159 */
160 /**
161 \var poppler::permission_enum poppler::perm_add_notes
162
163 The permission to allow the addition or editing of annotations,
164 and the filling of interactive form fields (including signature fields).
165 */
166 /**
167 \var poppler::permission_enum poppler::perm_fill_forms
168
169 The permission to allow the filling of interactive form fields
170 (including signature fields).
171
172 \note this permission can be set even when the \ref poppler::perm_add_notes "perm_add_notes"
173 is not: this means that only the filling of forms is allowed.
174 */
175 /**
176 \var poppler::permission_enum poppler::perm_accessibility
177
178 The permission to allow the extracting of content (for example, text) for
179 accessibility usage (e.g. for a screen reader).
180 */
181 /**
182 \var poppler::permission_enum poppler::perm_assemble
183
184 The permission to allow to "assemble" a %document.
185
186 This implies operations such as the insertion, the rotation and the deletion
187 of pages; the creation of bookmarks and thumbnail images.
188
189 \note this permission can be set even when the \ref poppler::perm_change "perm_change"
190 is not
191 */
192 /**
193 \var poppler::permission_enum poppler::perm_print_high_resolution
194
195 The permission to allow the high resolution print of a %document.
196 */
197
198 /**
199 \enum poppler::case_sensitivity_enum
200
201 The case sensitivity.
202 */
203
noncopyable()204 noncopyable::noncopyable() { }
205
~noncopyable()206 noncopyable::~noncopyable() { }
207
ustring()208 ustring::ustring() { }
209
ustring(size_type len,value_type ch)210 ustring::ustring(size_type len, value_type ch) : std::basic_string<value_type>(len, ch) { }
211
~ustring()212 ustring::~ustring() { }
213
to_utf8() const214 byte_array ustring::to_utf8() const
215 {
216 if (!size()) {
217 return byte_array();
218 }
219
220 #ifdef WORDS_BIGENDIAN
221 MiniIconv ic("UTF-8", "UTF-16BE");
222 #else
223 MiniIconv ic("UTF-8", "UTF-16LE");
224 #endif
225 if (!ic.is_valid()) {
226 return byte_array();
227 }
228 const value_type *me_data = data();
229 byte_array str(size() * sizeof(value_type));
230 char *str_data = &str[0];
231 size_t me_len_char = size() * sizeof(value_type);
232 size_t str_len_left = str.size();
233 size_t ir = iconv(static_cast<iconv_t>(ic), (ICONV_CONST char **)&me_data, &me_len_char, &str_data, &str_len_left);
234 if ((ir == (size_t)-1) && (errno == E2BIG)) {
235 const size_t delta = str_data - &str[0];
236 str_len_left += str.size();
237 str.resize(str.size() * 2);
238 str_data = &str[delta];
239 ir = iconv(static_cast<iconv_t>(ic), (ICONV_CONST char **)&me_data, &me_len_char, &str_data, &str_len_left);
240 if (ir == (size_t)-1) {
241 return byte_array();
242 }
243 }
244 str.resize(str.size() - str_len_left);
245 return str;
246 }
247
to_latin1() const248 std::string ustring::to_latin1() const
249 {
250 if (!size()) {
251 return std::string();
252 }
253
254 const size_type mylength = size();
255 std::string ret(mylength, '\0');
256 const value_type *me = data();
257 for (size_type i = 0; i < mylength; ++i) {
258 ret[i] = (char)*me++;
259 }
260 return ret;
261 }
262
from_utf8(const char * str,int len)263 ustring ustring::from_utf8(const char *str, int len)
264 {
265 if (len <= 0) {
266 len = std::strlen(str);
267 if (len <= 0) {
268 return ustring();
269 }
270 }
271
272 #ifdef WORDS_BIGENDIAN
273 MiniIconv ic("UTF-16BE", "UTF-8");
274 #else
275 MiniIconv ic("UTF-16LE", "UTF-8");
276 #endif
277 if (!ic.is_valid()) {
278 return ustring();
279 }
280
281 // +1, because iconv inserts byte order marks
282 ustring ret(len + 1, 0);
283 char *ret_data = reinterpret_cast<char *>(&ret[0]);
284 char *str_data = const_cast<char *>(str);
285 size_t str_len_char = len;
286 size_t ret_len_left = ret.size() * sizeof(ustring::value_type);
287 size_t ir = iconv(static_cast<iconv_t>(ic), (ICONV_CONST char **)&str_data, &str_len_char, &ret_data, &ret_len_left);
288 if ((ir == (size_t)-1) && (errno == E2BIG)) {
289 const size_t delta = ret_data - reinterpret_cast<char *>(&ret[0]);
290 ret_len_left += ret.size() * sizeof(ustring::value_type);
291 ret.resize(ret.size() * 2);
292 ret_data = reinterpret_cast<char *>(&ret[0]) + delta;
293 ir = iconv(static_cast<iconv_t>(ic), (ICONV_CONST char **)&str_data, &str_len_char, &ret_data, &ret_len_left);
294 if (ir == (size_t)-1) {
295 return ustring();
296 }
297 }
298 ret.resize(ret.size() - ret_len_left / sizeof(ustring::value_type));
299
300 return ret;
301 }
302
from_latin1(const std::string & str)303 ustring ustring::from_latin1(const std::string &str)
304 {
305 const size_type l = str.size();
306 if (!l) {
307 return ustring();
308 }
309 const char *c = str.data();
310 ustring ret(l, 0);
311 for (size_type i = 0; i < l; ++i) {
312 ret[i] = static_cast<unsigned char>(*c);
313 c++;
314 }
315 return ret;
316 }
317
318 /**
319 Converts a string representing a PDF date to a value compatible with time_t.
320 */
convert_date(const std::string & date)321 time_type poppler::convert_date(const std::string &date)
322 {
323 GooString gooDateStr(date.c_str());
324 return dateStringToTime(&gooDateStr);
325 }
326
operator <<(std::ostream & stream,const byte_array & array)327 std::ostream &poppler::operator<<(std::ostream &stream, const byte_array &array)
328 {
329 stream << "[";
330 const std::ios_base::fmtflags f = stream.flags();
331 std::hex(stream);
332 const char *data = &array[0];
333 const byte_array::size_type out_len = std::min<byte_array::size_type>(array.size(), 50);
334 for (byte_array::size_type i = 0; i < out_len; ++i) {
335 if (i != 0) {
336 stream << " ";
337 }
338 stream << ((data[i] & 0xf0) >> 4) << (data[i] & 0xf);
339 }
340 stream.flags(f);
341 if (out_len < array.size()) {
342 stream << " ...";
343 }
344 stream << "]";
345 return stream;
346 }
347
348 /**
349 * Sets a custom data directory for initialization of global parameters
350 *
351 * If no instances of \see document currently exist, this will save the
352 * given path as a custom data directory to be used when the first instance
353 * of the \see document is constructed.
354 *
355 * \returns true on success, false on failure
356 *
357 * \since 0.73.0
358 */
set_data_dir(const std::string & new_data_dir)359 bool poppler::set_data_dir(const std::string &new_data_dir)
360 {
361 return GlobalParamsIniter::setCustomDataDir(new_data_dir);
362 }
363
364 /**
365 \typedef poppler::debug_func
366
367 Debug/error function.
368
369 This function type is used for debugging & error output;
370 the first parameter is the actual message, the second is the unaltered
371 closure argument which was passed to the set_debug_error_function() call.
372
373 \since 0.30.0
374 */
375
376 /**
377 Set a new debug/error output function.
378
379 If not set, by default error and debug messages will be sent to stderr.
380
381 \param debug_function the new debug function
382 \param closure user data which will be passed as-is to the debug function
383
384 \since 0.30.0
385 */
set_debug_error_function(debug_func debug_function,void * closure)386 void poppler::set_debug_error_function(debug_func debug_function, void *closure)
387 {
388 poppler::detail::user_debug_function = debug_function;
389 poppler::detail::debug_closure = closure;
390 }
391