1 |
commit: fe370d3fcd032cda6c0a0de31d094add85699fff |
2 |
Author: Mikle Kolyada <zlogene <AT> gentoo <DOT> org> |
3 |
AuthorDate: Fri Mar 6 14:05:12 2020 +0000 |
4 |
Commit: Mikle Kolyada <zlogene <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri Mar 6 14:05:12 2020 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/tex.git/commit/?id=fe370d3f |
7 |
|
8 |
Add poppler-0.86 compat patch |
9 |
|
10 |
Signed-off-by: Mikle Kolyada <zlogene <AT> gentoo.org> |
11 |
|
12 |
2019/patches/texlive-core-2019-poppler086.patch | 820 ++++++++++++++++++++++++ |
13 |
1 file changed, 820 insertions(+) |
14 |
|
15 |
diff --git a/2019/patches/texlive-core-2019-poppler086.patch b/2019/patches/texlive-core-2019-poppler086.patch |
16 |
new file mode 100644 |
17 |
index 0000000..4ab4f95 |
18 |
--- /dev/null |
19 |
+++ b/2019/patches/texlive-core-2019-poppler086.patch |
20 |
@@ -0,0 +1,820 @@ |
21 |
+From 1203f6d9d51d6bedf11e36509f3a56638b1c816e Mon Sep 17 00:00:00 2001 |
22 |
+From: Mikle Kolyada <zlogene@g.o> |
23 |
+Date: Fri, 6 Mar 2020 13:31:24 +0000 |
24 |
+Subject: [PATCH] poppler-0.86 compat |
25 |
+ |
26 |
+Signed-off-by: Mikle Kolyada <zlogene@g.o> |
27 |
+--- |
28 |
+ pdftoepdf.cc | 308 ++++++++++++++++++++++++++------------------------- |
29 |
+ pdftosrc.cc | 76 ++++++------- |
30 |
+ utils.c | 1 - |
31 |
+ 3 files changed, 192 insertions(+), 193 deletions(-) |
32 |
+ |
33 |
+diff --git a/pdftoepdf.cc b/pdftoepdf.cc |
34 |
+index 4db0c90..d13293e 100644 |
35 |
+--- a/texk/web2c/pdftexdir/pdftoepdf.cc |
36 |
++++ b/texk/web2c/pdftexdir/pdftoepdf.cc |
37 |
+@@ -1,5 +1,5 @@ |
38 |
+ /* |
39 |
+-Copyright 1996-2016 Han The Thanh, <thanh@××××××.org> |
40 |
++Copyright 1996-2017 Han The Thanh, <thanh@××××××.org> |
41 |
+ |
42 |
+ This file is part of pdfTeX. |
43 |
+ |
44 |
+@@ -17,6 +17,15 @@ You should have received a copy of the GNU General Public License along |
45 |
+ with this program. If not, see <http://www.gnu.org/licenses/>. |
46 |
+ */ |
47 |
+ |
48 |
++/* |
49 |
++This is based on the patch texlive-poppler-0.59.patch <2017-09-19> at |
50 |
++https://git.archlinux.org/svntogit/packages.git/plain/texlive-bin/trunk |
51 |
++by Arch Linux. A little modifications are made to avoid a crash for |
52 |
++some kind of pdf images, such as figure_missing.pdf in gnuplot. |
53 |
++The poppler should be 0.75.0 or newer versions. |
54 |
++POPPLER_VERSION should be defined. |
55 |
++*/ |
56 |
++ |
57 |
+ /* Do this early in order to avoid a conflict between |
58 |
+ MINGW32 <rpcndr.h> defining 'boolean' as 'unsigned char' and |
59 |
+ <kpathsea/types.h> defining Pascal's boolean as 'int'. |
60 |
+@@ -39,10 +48,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. |
61 |
+ #include <goo/gfile.h> |
62 |
+ #define GString GooString |
63 |
+ #else |
64 |
+-#include <aconf.h> |
65 |
+-#include <GString.h> |
66 |
+-#include <gmem.h> |
67 |
+-#include <gfile.h> |
68 |
++#error POPPLER_VERSION should be defined. |
69 |
+ #endif |
70 |
+ #include <assert.h> |
71 |
+ |
72 |
+@@ -84,31 +90,6 @@ extern integer zround(double); |
73 |
+ #define MASK_SUPPRESS_PTEX_PAGENUMBER 0x04 |
74 |
+ #define MASK_SUPPRESS_PTEX_INFODICT 0x08 |
75 |
+ |
76 |
+-// PdfObject encapsulates the xpdf Object type, |
77 |
+-// and properly frees its resources on destruction. |
78 |
+-// Use obj-> to access members of the Object, |
79 |
+-// and &obj to get a pointer to the object. |
80 |
+-// It is no longer necessary to call Object::free explicitely. |
81 |
+- |
82 |
+-class PdfObject { |
83 |
+- public: |
84 |
+- PdfObject() { // nothing |
85 |
+- } ~PdfObject() { |
86 |
+- iObject.free(); |
87 |
+- } |
88 |
+- Object *operator->() { |
89 |
+- return &iObject; |
90 |
+- } |
91 |
+- Object *operator&() { |
92 |
+- return &iObject; |
93 |
+- } |
94 |
+- private: // no copying or assigning |
95 |
+- PdfObject(const PdfObject &); |
96 |
+- void operator=(const PdfObject &); |
97 |
+- public: |
98 |
+- Object iObject; |
99 |
+-}; |
100 |
+- |
101 |
+ // When copying the Resources of the selected page, all objects are copied |
102 |
+ // recusively top-down. Indirect objects however are not fetched during |
103 |
+ // copying, but get a new object number from pdfTeX and then will be |
104 |
+@@ -139,7 +120,7 @@ struct UsedEncoding { |
105 |
+ |
106 |
+ static InObj *inObjList; |
107 |
+ static UsedEncoding *encodingList; |
108 |
+-static GBool isInit = gFalse; |
109 |
++static bool isInit = false; |
110 |
+ |
111 |
+ // -------------------------------------------------------------------- |
112 |
+ // Maintain list of open embedded PDF files |
113 |
+@@ -212,18 +193,6 @@ static void delete_document(PdfDocument * pdf_doc) |
114 |
+ delete pdf_doc; |
115 |
+ } |
116 |
+ |
117 |
+-// Replacement for |
118 |
+-// Object *initDict(Dict *dict1){ initObj(objDict); dict = dict1; return this; } |
119 |
+- |
120 |
+-static void initDictFromDict(PdfObject & obj, Dict * dict) |
121 |
+-{ |
122 |
+- obj->initDict(xref); |
123 |
+- for (int i = 0, l = dict->getLength(); i < l; i++) { |
124 |
+- Object obj1; |
125 |
+- obj->dictAdd(copyString(dict->getKey(i)), dict->getValNF(i, &obj1)); |
126 |
+- } |
127 |
+-} |
128 |
+- |
129 |
+ // -------------------------------------------------------------------- |
130 |
+ |
131 |
+ static int addEncoding(GfxFont * gfont) |
132 |
+@@ -320,10 +289,10 @@ static void copyName(char *s) |
133 |
+ |
134 |
+ static void copyDictEntry(Object * obj, int i) |
135 |
+ { |
136 |
+- PdfObject obj1; |
137 |
+- copyName(obj->dictGetKey(i)); |
138 |
++ Object obj1; |
139 |
++ copyName((char *)obj->dictGetKey(i)); |
140 |
+ pdf_puts(" "); |
141 |
+- obj->dictGetValNF(i, &obj1); |
142 |
++ obj1 = obj->dictGetValNF(i).copy(); |
143 |
+ copyObject(&obj1); |
144 |
+ pdf_puts("\n"); |
145 |
+ } |
146 |
+@@ -348,7 +317,7 @@ static void copyFontDict(Object * obj, InObj * r) |
147 |
+ pdf_puts("<<\n"); |
148 |
+ assert(r->type == objFont); // FontDescriptor is in fd_tree |
149 |
+ for (i = 0, l = obj->dictGetLength(); i < l; ++i) { |
150 |
+- key = obj->dictGetKey(i); |
151 |
++ key = (char *)obj->dictGetKey(i); |
152 |
+ if (strncmp("FontDescriptor", key, strlen("FontDescriptor")) == 0 |
153 |
+ || strncmp("BaseFont", key, strlen("BaseFont")) == 0 |
154 |
+ || strncmp("Encoding", key, strlen("Encoding")) == 0) |
155 |
+@@ -376,17 +345,17 @@ static void copyStream(Stream * str) |
156 |
+ static void copyProcSet(Object * obj) |
157 |
+ { |
158 |
+ int i, l; |
159 |
+- PdfObject procset; |
160 |
++ Object procset; |
161 |
+ if (!obj->isArray()) |
162 |
+ pdftex_fail("PDF inclusion: invalid ProcSet array type <%s>", |
163 |
+ obj->getTypeName()); |
164 |
+ pdf_puts("/ProcSet [ "); |
165 |
+ for (i = 0, l = obj->arrayGetLength(); i < l; ++i) { |
166 |
+- obj->arrayGetNF(i, &procset); |
167 |
+- if (!procset->isName()) |
168 |
++ procset = obj->arrayGetNF(i).copy(); |
169 |
++ if (!procset.isName()) |
170 |
+ pdftex_fail("PDF inclusion: invalid ProcSet entry type <%s>", |
171 |
+- procset->getTypeName()); |
172 |
+- copyName(procset->getName()); |
173 |
++ procset.getTypeName()); |
174 |
++ copyName((char *)procset.getName()); |
175 |
+ pdf_puts(" "); |
176 |
+ } |
177 |
+ pdf_puts("]\n"); |
178 |
+@@ -394,10 +363,29 @@ static void copyProcSet(Object * obj) |
179 |
+ |
180 |
+ #define REPLACE_TYPE1C true |
181 |
+ |
182 |
++static bool embeddableFont(Object * fontdesc) |
183 |
++{ |
184 |
++ Object fontfile, ffsubtype; |
185 |
++ |
186 |
++ if (!fontdesc->isDict()) |
187 |
++ return false; |
188 |
++ fontfile = fontdesc->dictLookup("FontFile"); |
189 |
++ if (fontfile.isStream()) |
190 |
++ return true; |
191 |
++ if (REPLACE_TYPE1C) { |
192 |
++ fontfile = fontdesc->dictLookup("FontFile3"); |
193 |
++ if (!fontfile.isStream()) |
194 |
++ return false; |
195 |
++ ffsubtype = fontfile.streamGetDict()->lookup("Subtype"); |
196 |
++ return ffsubtype.isName() && !strcmp(ffsubtype.getName(), "Type1C"); |
197 |
++ } |
198 |
++ return false; |
199 |
++} |
200 |
++ |
201 |
+ static void copyFont(char *tag, Object * fontRef) |
202 |
+ { |
203 |
+- PdfObject fontdict, subtype, basefont, fontdescRef, fontdesc, charset, |
204 |
+- fontfile, ffsubtype, stemV; |
205 |
++ Object fontdict, subtype, basefont, fontdescRef, fontdesc, charset, |
206 |
++ stemV; |
207 |
+ GfxFont *gfont; |
208 |
+ fd_entry *fd; |
209 |
+ fm_entry *fontmap; |
210 |
+@@ -413,33 +401,39 @@ static void copyFont(char *tag, Object * fontRef) |
211 |
+ } |
212 |
+ // Only handle included Type1 (and Type1C) fonts; anything else will be copied. |
213 |
+ // Type1C fonts are replaced by Type1 fonts, if REPLACE_TYPE1C is true. |
214 |
+- if (!fixedinclusioncopyfont && fontRef->fetch(xref, &fontdict)->isDict() |
215 |
+- && fontdict->dictLookup("Subtype", &subtype)->isName() |
216 |
+- && !strcmp(subtype->getName(), "Type1") |
217 |
+- && fontdict->dictLookup("BaseFont", &basefont)->isName() |
218 |
+- && fontdict->dictLookupNF("FontDescriptor", &fontdescRef)->isRef() |
219 |
+- && fontdescRef->fetch(xref, &fontdesc)->isDict() |
220 |
+- && (fontdesc->dictLookup("FontFile", &fontfile)->isStream() |
221 |
+- || (REPLACE_TYPE1C |
222 |
+- && fontdesc->dictLookup("FontFile3", &fontfile)->isStream() |
223 |
+- && fontfile->streamGetDict()->lookup("Subtype", |
224 |
+- &ffsubtype)->isName() |
225 |
+- && !strcmp(ffsubtype->getName(), "Type1C"))) |
226 |
+- && (fontmap = lookup_fontmap(basefont->getName())) != NULL) { |
227 |
++ fontdict = fontRef->fetch(xref); |
228 |
++ fontdesc = Object(objNull); |
229 |
++ if (fontdict.isDict()) { |
230 |
++ subtype = fontdict.dictLookup("Subtype"); |
231 |
++ basefont = fontdict.dictLookup("BaseFont"); |
232 |
++ fontdescRef = fontdict.dictLookupNF("FontDescriptor").copy(); |
233 |
++ if (fontdescRef.isRef()) { |
234 |
++ fontdesc = fontdescRef.fetch(xref); |
235 |
++ } |
236 |
++ } |
237 |
++ if (!fixedinclusioncopyfont && fontdict.isDict() |
238 |
++ && subtype.isName() |
239 |
++ && !strcmp(subtype.getName(), "Type1") |
240 |
++ && basefont.isName() |
241 |
++ && fontdescRef.isRef() |
242 |
++ && fontdesc.isDict() |
243 |
++ && embeddableFont(&fontdesc) |
244 |
++ && (fontmap = lookup_fontmap((char *)basefont.getName())) != NULL) { |
245 |
+ // round /StemV value, since the PDF input is a float |
246 |
+ // (see Font Descriptors in PDF reference), but we only store an |
247 |
+ // integer, since we don't want to change the struct. |
248 |
+- fontdesc->dictLookup("StemV", &stemV); |
249 |
+- fd = epdf_create_fontdescriptor(fontmap, zround(stemV->getNum())); |
250 |
+- if (fontdesc->dictLookup("CharSet", &charset) && |
251 |
+- charset->isString() && is_subsetable(fontmap)) |
252 |
+- epdf_mark_glyphs(fd, charset->getString()->getCString()); |
253 |
++ stemV = fontdesc.dictLookup("StemV"); |
254 |
++ fd = epdf_create_fontdescriptor(fontmap, zround(stemV.getNum())); |
255 |
++ charset = fontdesc.dictLookup("CharSet"); |
256 |
++ if (!charset.isNull() && |
257 |
++ charset.isString() && is_subsetable(fontmap)) |
258 |
++ epdf_mark_glyphs(fd, (char *)charset.getString()->c_str()); |
259 |
+ else |
260 |
+ embed_whole_font(fd); |
261 |
+- addFontDesc(fontdescRef->getRef(), fd); |
262 |
++ addFontDesc(fontdescRef.getRef(), fd); |
263 |
+ copyName(tag); |
264 |
+ gfont = GfxFont::makeFont(xref, tag, fontRef->getRef(), |
265 |
+- fontdict->getDict()); |
266 |
++ fontdict.getDict()); |
267 |
+ pdf_printf(" %d 0 R ", addFont(fontRef->getRef(), fd, |
268 |
+ addEncoding(gfont))); |
269 |
+ } else { |
270 |
+@@ -451,24 +445,24 @@ static void copyFont(char *tag, Object * fontRef) |
271 |
+ |
272 |
+ static void copyFontResources(Object * obj) |
273 |
+ { |
274 |
+- PdfObject fontRef; |
275 |
++ Object fontRef; |
276 |
+ int i, l; |
277 |
+ if (!obj->isDict()) |
278 |
+ pdftex_fail("PDF inclusion: invalid font resources dict type <%s>", |
279 |
+ obj->getTypeName()); |
280 |
+ pdf_puts("/Font << "); |
281 |
+ for (i = 0, l = obj->dictGetLength(); i < l; ++i) { |
282 |
+- obj->dictGetValNF(i, &fontRef); |
283 |
+- if (fontRef->isRef()) |
284 |
+- copyFont(obj->dictGetKey(i), &fontRef); |
285 |
+- else if (fontRef->isDict()) { // some programs generate pdf with embedded font object |
286 |
+- copyName(obj->dictGetKey(i)); |
287 |
++ fontRef = obj->dictGetValNF(i).copy(); |
288 |
++ if (fontRef.isRef()) |
289 |
++ copyFont((char *)obj->dictGetKey(i), &fontRef); |
290 |
++ else if (fontRef.isDict()) { // some programs generate pdf with embedded font object |
291 |
++ copyName((char *)obj->dictGetKey(i)); |
292 |
+ pdf_puts(" "); |
293 |
+ copyObject(&fontRef); |
294 |
+ } |
295 |
+ else |
296 |
+ pdftex_fail("PDF inclusion: invalid font in reference type <%s>", |
297 |
+- fontRef->getTypeName()); |
298 |
++ fontRef.getTypeName()); |
299 |
+ } |
300 |
+ pdf_puts(">>\n"); |
301 |
+ } |
302 |
+@@ -557,7 +551,7 @@ static char *convertNumToPDF(double n) |
303 |
+ |
304 |
+ static void copyObject(Object * obj) |
305 |
+ { |
306 |
+- PdfObject obj1; |
307 |
++ Object obj1; |
308 |
+ int i, l, c; |
309 |
+ Ref ref; |
310 |
+ char *p; |
311 |
+@@ -571,8 +565,8 @@ static void copyObject(Object * obj) |
312 |
+ } else if (obj->isNum()) { |
313 |
+ pdf_printf("%s", convertNumToPDF(obj->getNum())); |
314 |
+ } else if (obj->isString()) { |
315 |
+- s = obj->getString(); |
316 |
+- p = s->getCString(); |
317 |
++ s = (GooString *)obj->getString(); |
318 |
++ p = (char *)s->c_str(); |
319 |
+ l = s->getLength(); |
320 |
+ if (strlen(p) == (unsigned int) l) { |
321 |
+ pdf_puts("("); |
322 |
+@@ -595,14 +589,14 @@ static void copyObject(Object * obj) |
323 |
+ pdf_puts(">"); |
324 |
+ } |
325 |
+ } else if (obj->isName()) { |
326 |
+- copyName(obj->getName()); |
327 |
++ copyName((char *)obj->getName()); |
328 |
+ } else if (obj->isNull()) { |
329 |
+ pdf_puts("null"); |
330 |
+ } else if (obj->isArray()) { |
331 |
+ pdf_puts("["); |
332 |
+ for (i = 0, l = obj->arrayGetLength(); i < l; ++i) { |
333 |
+- obj->arrayGetNF(i, &obj1); |
334 |
+- if (!obj1->isName()) |
335 |
++ obj1 = obj->arrayGetNF(i).copy(); |
336 |
++ if (!obj1.isName()) |
337 |
+ pdf_puts(" "); |
338 |
+ copyObject(&obj1); |
339 |
+ } |
340 |
+@@ -612,9 +606,8 @@ static void copyObject(Object * obj) |
341 |
+ copyDict(obj); |
342 |
+ pdf_puts(">>"); |
343 |
+ } else if (obj->isStream()) { |
344 |
+- initDictFromDict(obj1, obj->streamGetDict()); |
345 |
+ pdf_puts("<<\n"); |
346 |
+- copyDict(&obj1); |
347 |
++ copyDict(obj->getStream()->getDictObject()); |
348 |
+ pdf_puts(">>\n"); |
349 |
+ pdf_puts("stream\n"); |
350 |
+ copyStream(obj->getStream()->getUndecodedStream()); |
351 |
+@@ -638,9 +631,8 @@ static void writeRefs() |
352 |
+ InObj *r; |
353 |
+ for (r = inObjList; r != 0; r = r->next) { |
354 |
+ if (!r->written) { |
355 |
+- Object obj1; |
356 |
+ r->written = 1; |
357 |
+- xref->fetch(r->ref.num, r->ref.gen, &obj1); |
358 |
++ Object obj1 = xref->fetch(r->ref.num, r->ref.gen); |
359 |
+ if (r->type == objFont) { |
360 |
+ assert(!obj1.isStream()); |
361 |
+ pdfbeginobj(r->num, 2); // \pdfobjcompresslevel = 2 is for this |
362 |
+@@ -656,7 +648,6 @@ static void writeRefs() |
363 |
+ pdf_puts("\n"); |
364 |
+ pdfendobj(); |
365 |
+ } |
366 |
+- obj1.free(); |
367 |
+ } |
368 |
+ } |
369 |
+ } |
370 |
+@@ -673,7 +664,7 @@ static void writeEncodings() |
371 |
+ ("PDF inclusion: CID fonts are not supported" |
372 |
+ " (try to disable font replacement to fix this)"); |
373 |
+ } |
374 |
+- if ((s = ((Gfx8BitFont *) r->font)->getCharName(i)) != 0) |
375 |
++ if ((s = (char *)((Gfx8BitFont *) r->font)->getCharName(i)) != 0) |
376 |
+ glyphNames[i] = s; |
377 |
+ else |
378 |
+ glyphNames[i] = notdef; |
379 |
+@@ -685,14 +676,14 @@ static void writeEncodings() |
380 |
+ #ifdef POPPLER_VERSION |
381 |
+ r->font->decRefCnt(); |
382 |
+ #else |
383 |
+- delete r->font; |
384 |
++#error POPPLER_VERSION should be defined. |
385 |
+ #endif |
386 |
+ delete r; |
387 |
+ } |
388 |
+ } |
389 |
+ |
390 |
+ // get the pagebox according to the pagebox_spec |
391 |
+-static PDFRectangle *get_pagebox(Page * page, int pagebox_spec) |
392 |
++static const PDFRectangle *get_pagebox(Page * page, int pagebox_spec) |
393 |
+ { |
394 |
+ if (pagebox_spec == pdfboxspecmedia) |
395 |
+ return page->getMediaBox(); |
396 |
+@@ -724,17 +715,21 @@ read_pdf_info(char *image_name, char *page_name, int page_num, |
397 |
+ { |
398 |
+ PdfDocument *pdf_doc; |
399 |
+ Page *page; |
400 |
+- PDFRectangle *pagebox; |
401 |
++ const PDFRectangle *pagebox; |
402 |
+ #ifdef POPPLER_VERSION |
403 |
+ int pdf_major_version_found, pdf_minor_version_found; |
404 |
+ #else |
405 |
+- float pdf_version_found, pdf_version_wanted; |
406 |
++#error POPPLER_VERSION should be defined. |
407 |
+ #endif |
408 |
+ // initialize |
409 |
+ if (!isInit) { |
410 |
+- globalParams = new GlobalParams(); |
411 |
+- globalParams->setErrQuiet(gFalse); |
412 |
+- isInit = gTrue; |
413 |
++#if POPPLER_MAJOR_VERSION >= 1 || POPPLER_MINOR_VERSION >= 83 |
414 |
++ globalParams.reset(new GlobalParams()); |
415 |
++#else |
416 |
++ globalParams = std::make_unique<GlobalParams>(); |
417 |
++#endif |
418 |
++ globalParams->setErrQuiet(false); |
419 |
++ isInit = true; |
420 |
+ } |
421 |
+ // open PDF file |
422 |
+ pdf_doc = find_add_document(image_name); |
423 |
+@@ -760,29 +755,17 @@ read_pdf_info(char *image_name, char *page_name, int page_num, |
424 |
+ } |
425 |
+ } |
426 |
+ #else |
427 |
+- pdf_version_found = pdf_doc->doc->getPDFVersion(); |
428 |
+- pdf_version_wanted = 1 + (minor_pdf_version_wanted * 0.1); |
429 |
+- if (pdf_version_found > pdf_version_wanted + 0.01) { |
430 |
+- char msg[] = |
431 |
+- "PDF inclusion: found PDF version <%.1f>, but at most version <%.1f> allowed"; |
432 |
+- if (pdf_inclusion_errorlevel > 0) { |
433 |
+- pdftex_fail(msg, pdf_version_found, pdf_version_wanted); |
434 |
+- } else if (pdf_inclusion_errorlevel < 0) { |
435 |
+- ; /* do nothing */ |
436 |
+- } else { /* = 0, give warning */ |
437 |
+- pdftex_warn(msg, pdf_version_found, pdf_version_wanted); |
438 |
+- } |
439 |
+- } |
440 |
++#error POPPLER_VERSION should be defined. |
441 |
+ #endif |
442 |
+ epdf_num_pages = pdf_doc->doc->getCatalog()->getNumPages(); |
443 |
+ if (page_name) { |
444 |
+ // get page by name |
445 |
+ GString name(page_name); |
446 |
+- LinkDest *link = pdf_doc->doc->findDest(&name); |
447 |
++ LinkDest *link = pdf_doc->doc->findDest(&name).get(); |
448 |
+ if (link == 0 || !link->isOk()) |
449 |
+ pdftex_fail("PDF inclusion: invalid destination <%s>", page_name); |
450 |
+ Ref ref = link->getPageRef(); |
451 |
+- page_num = pdf_doc->doc->getCatalog()->findPage(ref.num, ref.gen); |
452 |
++ page_num = pdf_doc->doc->getCatalog()->findPage(ref); |
453 |
+ if (page_num == 0) |
454 |
+ pdftex_fail("PDF inclusion: destination is not a page <%s>", |
455 |
+ page_name); |
456 |
+@@ -839,8 +822,8 @@ void write_epdf(void) |
457 |
+ Page *page; |
458 |
+ Ref *pageRef; |
459 |
+ Dict *pageDict; |
460 |
+- PdfObject contents, obj1, obj2, pageObj, dictObj; |
461 |
+- PdfObject groupDict; |
462 |
++ Object contents, obj1, obj2, pageObj, dictObj; |
463 |
++ Object groupDict; |
464 |
+ bool writeSepGroup = false; |
465 |
+ Object info; |
466 |
+ char *key; |
467 |
+@@ -867,10 +850,10 @@ void write_epdf(void) |
468 |
+ encodingList = 0; |
469 |
+ page = pdf_doc->doc->getCatalog()->getPage(epdf_selected_page); |
470 |
+ pageRef = pdf_doc->doc->getCatalog()->getPageRef(epdf_selected_page); |
471 |
+- xref->fetch(pageRef->num, pageRef->gen, &pageObj); |
472 |
+- pageDict = pageObj->getDict(); |
473 |
++ pageObj = xref->fetch(pageRef->num, pageRef->gen); |
474 |
++ pageDict = pageObj.getDict(); |
475 |
+ rotate = page->getRotate(); |
476 |
+- PDFRectangle *pagebox; |
477 |
++ const PDFRectangle *pagebox; |
478 |
+ // write the Page header |
479 |
+ pdf_puts("/Type /XObject\n"); |
480 |
+ pdf_puts("/Subtype /Form\n"); |
481 |
+@@ -886,7 +869,7 @@ void write_epdf(void) |
482 |
+ pdf_printf("/%s.PageNumber %i\n", pdfkeyprefix, (int) epdf_selected_page); |
483 |
+ } |
484 |
+ if ((suppress_ptex_info & MASK_SUPPRESS_PTEX_INFODICT) == 0) { |
485 |
+- pdf_doc->doc->getDocInfoNF(&info); |
486 |
++ info = pdf_doc->doc->getDocInfoNF().copy(); |
487 |
+ if (info.isRef()) { |
488 |
+ // the info dict must be indirect (PDF Ref p. 61) |
489 |
+ pdf_printf("/%s.InfoDict ", pdfkeyprefix); |
490 |
+@@ -942,14 +925,14 @@ void write_epdf(void) |
491 |
+ pdf_puts(stripzeros(s)); |
492 |
+ |
493 |
+ // Metadata validity check (as a stream it must be indirect) |
494 |
+- pageDict->lookupNF("Metadata", &dictObj); |
495 |
+- if (!dictObj->isNull() && !dictObj->isRef()) |
496 |
++ dictObj = pageDict->lookupNF("Metadata").copy(); |
497 |
++ if (!dictObj.isNull() && !dictObj.isRef()) |
498 |
+ pdftex_warn("PDF inclusion: /Metadata must be indirect object"); |
499 |
+ |
500 |
+ // copy selected items in Page dictionary except Resources & Group |
501 |
+ for (i = 0; pageDictKeys[i] != NULL; i++) { |
502 |
+- pageDict->lookupNF(pageDictKeys[i], &dictObj); |
503 |
+- if (!dictObj->isNull()) { |
504 |
++ dictObj = pageDict->lookupNF(pageDictKeys[i]).copy(); |
505 |
++ if (!dictObj.isNull()) { |
506 |
+ pdf_newline(); |
507 |
+ pdf_printf("/%s ", pageDictKeys[i]); |
508 |
+ copyObject(&dictObj); // preserves indirection |
509 |
+@@ -957,8 +940,8 @@ void write_epdf(void) |
510 |
+ } |
511 |
+ |
512 |
+ // handle page group |
513 |
+- pageDict->lookupNF("Group", &dictObj); |
514 |
+- if (!dictObj->isNull()) { |
515 |
++ dictObj = pageDict->lookupNF("Group").copy(); |
516 |
++ if (!dictObj.isNull()) { |
517 |
+ if (pdfpagegroupval == 0) { |
518 |
+ // another pdf with page group was included earlier on the |
519 |
+ // same page; copy the Group entry as is. See manual for |
520 |
+@@ -972,11 +955,36 @@ void write_epdf(void) |
521 |
+ copyObject(&dictObj); |
522 |
+ } else { |
523 |
+ // write Group dict as a separate object, since the Page dict also refers to it |
524 |
+- pageDict->lookup("Group", &dictObj); |
525 |
+- if (!dictObj->isDict()) |
526 |
++ dictObj = pageDict->lookup("Group"); |
527 |
++ if (!dictObj.isDict()) |
528 |
+ pdftex_fail("PDF inclusion: /Group dict missing"); |
529 |
+ writeSepGroup = true; |
530 |
+- initDictFromDict(groupDict, page->getGroup()); |
531 |
++/* |
532 |
++This part is only a single line |
533 |
++ groupDict = Object(page->getGroup()); |
534 |
++in the original patch. In this case, however, pdftex crashes at |
535 |
++"delete pdf_doc->doc" in "delete_document()" for inclusion of some |
536 |
++kind of pdf images, for example, figure_missing.pdf in gnuplot. |
537 |
++A change |
538 |
++ groupDict = Object(page->getGroup()).copy(); |
539 |
++does not improve the situation. |
540 |
++The changes below seem to work fine. |
541 |
++*/ |
542 |
++// begin modification |
543 |
++ groupDict = pageDict->lookup("Group"); |
544 |
++ const Dict& dic1 = page->getGroup(); |
545 |
++ const Dict& dic2 = groupDict.getDict(); |
546 |
++ // replace dic2 in groupDict with dic1 |
547 |
++ l = dic2.getLength(); |
548 |
++ for (i = 0; i < l; i++) { |
549 |
++ groupDict.dictRemove(dic2.getKey(i)); |
550 |
++ } |
551 |
++ l = dic1.getLength(); |
552 |
++ for (i = 0; i < l; i++) { |
553 |
++ groupDict.dictAdd((const char *)copyString(dic1.getKey(i)), |
554 |
++ dic1.getValNF(i).copy()); |
555 |
++ } |
556 |
++// end modification |
557 |
+ pdf_printf("/Group %ld 0 R\n", (long)pdfpagegroupval); |
558 |
+ } |
559 |
+ } |
560 |
+@@ -989,28 +997,28 @@ void write_epdf(void) |
561 |
+ pdftex_warn |
562 |
+ ("PDF inclusion: /Resources missing. 'This practice is not recommended' (PDF Ref)"); |
563 |
+ } else { |
564 |
+- initDictFromDict(obj1, page->getResourceDict()); |
565 |
++ Object *obj1 = page->getResourceDictObject(); |
566 |
+ if (!obj1->isDict()) |
567 |
+ pdftex_fail("PDF inclusion: invalid resources dict type <%s>", |
568 |
+ obj1->getTypeName()); |
569 |
+ pdf_newline(); |
570 |
+ pdf_puts("/Resources <<\n"); |
571 |
+ for (i = 0, l = obj1->dictGetLength(); i < l; ++i) { |
572 |
+- obj1->dictGetVal(i, &obj2); |
573 |
+- key = obj1->dictGetKey(i); |
574 |
++ obj2 = obj1->dictGetVal(i); |
575 |
++ key = (char *)obj1->dictGetKey(i); |
576 |
+ if (strcmp("Font", key) == 0) |
577 |
+ copyFontResources(&obj2); |
578 |
+ else if (strcmp("ProcSet", key) == 0) |
579 |
+ copyProcSet(&obj2); |
580 |
+ else |
581 |
+- copyOtherResources(&obj2, key); |
582 |
++ copyOtherResources(&obj2, (char *)key); |
583 |
+ } |
584 |
+ pdf_puts(">>\n"); |
585 |
+ } |
586 |
+ |
587 |
+ // write the page contents |
588 |
+- page->getContents(&contents); |
589 |
+- if (contents->isStream()) { |
590 |
++ contents = page->getContents(); |
591 |
++ if (contents.isStream()) { |
592 |
+ |
593 |
+ // Variant A: get stream and recompress under control |
594 |
+ // of \pdfcompresslevel |
595 |
+@@ -1021,36 +1029,35 @@ void write_epdf(void) |
596 |
+ |
597 |
+ // Variant B: copy stream without recompressing |
598 |
+ // |
599 |
+- contents->streamGetDict()->lookup("F", &obj1); |
600 |
+- if (!obj1->isNull()) { |
601 |
++ obj1 = contents.streamGetDict()->lookup("F"); |
602 |
++ if (!obj1.isNull()) { |
603 |
+ pdftex_fail("PDF inclusion: Unsupported external stream"); |
604 |
+ } |
605 |
+- contents->streamGetDict()->lookup("Length", &obj1); |
606 |
+- assert(!obj1->isNull()); |
607 |
++ obj1 = contents.streamGetDict()->lookup("Length"); |
608 |
++ assert(!obj1.isNull()); |
609 |
+ pdf_puts("/Length "); |
610 |
+ copyObject(&obj1); |
611 |
+ pdf_puts("\n"); |
612 |
+- contents->streamGetDict()->lookup("Filter", &obj1); |
613 |
+- if (!obj1->isNull()) { |
614 |
++ obj1 = contents.streamGetDict()->lookup("Filter"); |
615 |
++ if (!obj1.isNull()) { |
616 |
+ pdf_puts("/Filter "); |
617 |
+ copyObject(&obj1); |
618 |
+ pdf_puts("\n"); |
619 |
+- contents->streamGetDict()->lookup("DecodeParms", &obj1); |
620 |
+- if (!obj1->isNull()) { |
621 |
++ obj1 = contents.streamGetDict()->lookup("DecodeParms"); |
622 |
++ if (!obj1.isNull()) { |
623 |
+ pdf_puts("/DecodeParms "); |
624 |
+ copyObject(&obj1); |
625 |
+ pdf_puts("\n"); |
626 |
+ } |
627 |
+ } |
628 |
+ pdf_puts(">>\nstream\n"); |
629 |
+- copyStream(contents->getStream()->getUndecodedStream()); |
630 |
++ copyStream(contents.getStream()->getUndecodedStream()); |
631 |
+ pdfendstream(); |
632 |
+- } else if (contents->isArray()) { |
633 |
++ } else if (contents.isArray()) { |
634 |
+ pdfbeginstream(); |
635 |
+- for (i = 0, l = contents->arrayGetLength(); i < l; ++i) { |
636 |
+- Object contentsobj; |
637 |
+- copyStream((contents->arrayGet(i, &contentsobj))->getStream()); |
638 |
+- contentsobj.free(); |
639 |
++ for (i = 0, l = contents.arrayGetLength(); i < l; ++i) { |
640 |
++ Object contentsobj = contents.arrayGet(i); |
641 |
++ copyStream(contentsobj.getStream()); |
642 |
+ if (i < l - 1) |
643 |
+ pdf_newline(); // add a newline after each stream except the last |
644 |
+ } |
645 |
+@@ -1105,6 +1112,5 @@ void epdf_check_mem() |
646 |
+ delete_document(p); |
647 |
+ } |
648 |
+ // see above for globalParams |
649 |
+- delete globalParams; |
650 |
+ } |
651 |
+ } |
652 |
+diff --git a/pdftosrc.cc b/pdftosrc.cc |
653 |
+index 67be229..b6700fd 100644 |
654 |
+--- a/texk/web2c/pdftexdir/pdftosrc.cc |
655 |
++++ b/texk/web2c/pdftexdir/pdftosrc.cc |
656 |
+@@ -16,6 +16,14 @@ GNU General Public License for more details. |
657 |
+ You should have received a copy of the GNU General Public License along |
658 |
+ with this program. If not, see <http://www.gnu.org/licenses/>. |
659 |
+ */ |
660 |
++ |
661 |
++/* |
662 |
++This is based on the patch texlive-poppler-0.59.patch <2017-09-19> at |
663 |
++https://git.archlinux.org/svntogit/packages.git/plain/texlive-bin/trunk |
664 |
++by Arch Linux. The poppler should be 0.72.0 or newer versions. |
665 |
++POPPLER_VERSION should be defined. |
666 |
++*/ |
667 |
++ |
668 |
+ #include <w2c/config.h> |
669 |
+ |
670 |
+ #include <stdlib.h> |
671 |
+@@ -32,16 +40,12 @@ with this program. If not, see <http://www.gnu.org/licenses/>. |
672 |
+ #include <goo/gmem.h> |
673 |
+ #include <goo/gfile.h> |
674 |
+ #else |
675 |
+-#include <aconf.h> |
676 |
+-#include <GString.h> |
677 |
+-#include <gmem.h> |
678 |
+-#include <gfile.h> |
679 |
++#error POPPLER_VERSION should be defined. |
680 |
+ #endif |
681 |
+ #include <assert.h> |
682 |
+ |
683 |
+ #include "Object.h" |
684 |
+ #include "Stream.h" |
685 |
+-#include "Lexer.h" |
686 |
+ #include "Parser.h" |
687 |
+ #include "Array.h" |
688 |
+ #include "Dict.h" |
689 |
+@@ -74,7 +78,11 @@ int main(int argc, char *argv[]) |
690 |
+ exit(1); |
691 |
+ } |
692 |
+ fileName = new GString(argv[1]); |
693 |
+- globalParams = new GlobalParams(); |
694 |
++#if POPPLER_MAJOR_VERSION >= 1 || POPPLER_MINOR_VERSION >= 83 |
695 |
++ globalParams.reset(new GlobalParams()); |
696 |
++#else |
697 |
++ globalParams = std::make_unique<GlobalParams>(); |
698 |
++#endif |
699 |
+ doc = new PDFDoc(fileName); |
700 |
+ if (!doc->isOk()) { |
701 |
+ fprintf(stderr, "Invalid PDF file\n"); |
702 |
+@@ -86,36 +94,34 @@ int main(int argc, char *argv[]) |
703 |
+ objgen = atoi(argv[3]); |
704 |
+ } |
705 |
+ xref = doc->getXRef(); |
706 |
+- catalogDict.initNull(); |
707 |
+- xref->getCatalog(&catalogDict); |
708 |
++ catalogDict = xref->getCatalog(); |
709 |
+ if (!catalogDict.isDict("Catalog")) { |
710 |
+ fprintf(stderr, "No Catalog found\n"); |
711 |
+ exit(1); |
712 |
+ } |
713 |
+- srcStream.initNull(); |
714 |
++ srcStream = Object(objNull); |
715 |
+ if (objnum == 0) { |
716 |
+- catalogDict.dictLookup("SourceObject", &srcStream); |
717 |
+- static char const_SourceFile[] = "SourceFile"; |
718 |
+- if (!srcStream.isStream(const_SourceFile)) { |
719 |
++ srcStream = catalogDict.dictLookup("SourceObject"); |
720 |
++ static const char *const_SourceFile = "SourceFile"; |
721 |
++ if (!srcStream.isDict(const_SourceFile)) { |
722 |
+ fprintf(stderr, "No SourceObject found\n"); |
723 |
+ exit(1); |
724 |
+ } |
725 |
+- srcName.initNull(); |
726 |
+- srcStream.getStream()->getDict()->lookup("SourceName", &srcName); |
727 |
++ srcName = srcStream.getStream()->getDict()->lookup("SourceName"); |
728 |
+ if (!srcName.isString()) { |
729 |
+ fprintf(stderr, "No SourceName found\n"); |
730 |
+ exit(1); |
731 |
+ } |
732 |
+- outname = srcName.getString()->getCString(); |
733 |
++ outname = (char *)srcName.getString()->c_str(); |
734 |
+ // We cannot free srcName, as objname shares its string. |
735 |
+ // srcName.free(); |
736 |
+ } else if (objnum > 0) { |
737 |
+- xref->fetch(objnum, objgen, &srcStream); |
738 |
++ srcStream = xref->fetch(objnum, objgen); |
739 |
+ if (!srcStream.isStream()) { |
740 |
+ fprintf(stderr, "Not a Stream object\n"); |
741 |
+ exit(1); |
742 |
+ } |
743 |
+- sprintf(buf, "%s", fileName->getCString()); |
744 |
++ sprintf(buf, "%s", fileName->c_str()); |
745 |
+ if ((p = strrchr(buf, '.')) == 0) |
746 |
+ p = strchr(buf, 0); |
747 |
+ if (objgen == 0) |
748 |
+@@ -125,7 +131,7 @@ int main(int argc, char *argv[]) |
749 |
+ outname = buf; |
750 |
+ } else { // objnum < 0 means we are extracting the XRef table |
751 |
+ extract_xref_table = true; |
752 |
+- sprintf(buf, "%s", fileName->getCString()); |
753 |
++ sprintf(buf, "%s", fileName->c_str()); |
754 |
+ if ((p = strrchr(buf, '.')) == 0) |
755 |
+ p = strchr(buf, 0); |
756 |
+ sprintf(p, ".xref"); |
757 |
+@@ -153,41 +159,32 @@ int main(int argc, char *argv[]) |
758 |
+ (e->type == xrefEntryFree ? "f" : "n")); |
759 |
+ else { // e->offset is the object number of the object stream |
760 |
+ Stream *str; |
761 |
+- Lexer *lexer; |
762 |
+ Parser *parser; |
763 |
+ Object objStr, obj1, obj2; |
764 |
+ int nObjects, first, n; |
765 |
+ int localOffset = 0; |
766 |
+- Guint firstOffset; |
767 |
++ unsigned int firstOffset; |
768 |
+ |
769 |
+- assert(xref->fetch(e->offset, 0, &objStr)->isStream()); |
770 |
+- nObjects = objStr.streamGetDict()->lookup("N", &obj1)->getInt(); |
771 |
+- obj1.free(); |
772 |
+- first = objStr.streamGetDict()->lookup("First", &obj1)->getInt(); |
773 |
+- obj1.free(); |
774 |
++ objStr = xref->fetch(e->offset, 0); |
775 |
++ assert(objStr.isStream()); |
776 |
++ obj1 = objStr.streamGetDict()->lookup("N"); |
777 |
++ nObjects = obj1.getInt(); |
778 |
++ obj1 = objStr.streamGetDict()->lookup("First"); |
779 |
++ first = obj1.getInt(); |
780 |
+ firstOffset = objStr.getStream()->getBaseStream()->getStart() + first; |
781 |
+ |
782 |
+ // parse the header: object numbers and offsets |
783 |
+ objStr.streamReset(); |
784 |
+- obj1.initNull(); |
785 |
+- str = new EmbedStream(objStr.getStream(), &obj1, gTrue, first); |
786 |
+- lexer = new Lexer(xref, str); |
787 |
+- parser = new Parser(xref, lexer, gFalse); |
788 |
++ str = new EmbedStream(objStr.getStream(), Object(objNull), true, first); |
789 |
++ parser = new Parser(xref, str, false); |
790 |
+ for (n = 0; n < nObjects; ++n) { |
791 |
+- parser->getObj(&obj1); |
792 |
+- parser->getObj(&obj2); |
793 |
++ obj1 = parser->getObj(); |
794 |
++ obj2 = parser->getObj(); |
795 |
+ if (n == e->gen) |
796 |
+ localOffset = obj2.getInt(); |
797 |
+- obj1.free(); |
798 |
+- obj2.free(); |
799 |
+ } |
800 |
+-#if defined(POPPLER_VERSION) || defined(XPDF304) |
801 |
+ while (str->getChar() != EOF) ; |
802 |
+-#else /* xpdf 4.00 */ |
803 |
+- lexer->skipToEOF(); |
804 |
+-#endif |
805 |
+ delete parser; |
806 |
+- objStr.free(); |
807 |
+ |
808 |
+ fprintf(outfile, "%.10lu 00000 n\n", |
809 |
+ (long unsigned)(firstOffset + localOffset)); |
810 |
+@@ -198,7 +195,6 @@ int main(int argc, char *argv[]) |
811 |
+ s->reset(); |
812 |
+ while ((c = s->getChar()) != EOF) |
813 |
+ fputc(c, outfile); |
814 |
+- srcStream.free(); |
815 |
+ } |
816 |
+ if (objnum == 0) |
817 |
+ fprintf(stderr, "Source file extracted to %s\n", outname); |
818 |
+@@ -207,7 +203,5 @@ int main(int argc, char *argv[]) |
819 |
+ else |
820 |
+ fprintf(stderr, "Cross-reference table extracted to %s\n", outname); |
821 |
+ fclose(outfile); |
822 |
+- catalogDict.free(); |
823 |
+ delete doc; |
824 |
+- delete globalParams; |
825 |
+ } |
826 |
+diff --git a/utils.c b/utils.c |
827 |
+index c93a878..6f866e7 100644 |
828 |
+--- a/texk/web2c/pdftexdir/utils.c |
829 |
++++ b/texk/web2c/pdftexdir/utils.c |
830 |
+@@ -33,7 +33,6 @@ with this program. If not, see <http://www.gnu.org/licenses/>. |
831 |
+ #include "ptexlib.h" |
832 |
+ #include <png.h> |
833 |
+ #ifdef POPPLER_VERSION |
834 |
+-#include <poppler-config.h> |
835 |
+ #define xpdfVersion POPPLER_VERSION |
836 |
+ #define xpdfString "poppler" |
837 |
+ #else |
838 |
+-- |
839 |
+2.24.1 |
840 |
+ |