Commit | Line | Data |
---|---|---|
f547c930 HG |
1 | --- ./texk/web2c/pdftexdir/pdftoepdf.cc 2016-11-25 18:24:37.000000000 +0000 |
2 | +++ ../pdftoepdf-newpoppler.cc 2018-04-30 18:45:14.463926082 +0000 | |
cac27b87 HG |
3 | @@ -1,5 +1,5 @@ |
4 | /* | |
5 | -Copyright 1996-2016 Han The Thanh, <thanh@pdftex.org> | |
6 | +Copyright 1996-2017 Han The Thanh, <thanh@pdftex.org> | |
7 | ||
8 | This file is part of pdfTeX. | |
9 | ||
10 | @@ -17,6 +17,15 @@ | |
11 | with this program. If not, see <http://www.gnu.org/licenses/>. | |
12 | */ | |
13 | ||
14 | +/* | |
15 | +This is based on the patch texlive-poppler-0.59.patch <2017-09-19> at | |
16 | +https://git.archlinux.org/svntogit/packages.git/plain/texlive-bin/trunk | |
17 | +by Arch Linux. A little modifications are made to avoid a crash for | |
18 | +some kind of pdf images, such as figure_missing.pdf in gnuplot. | |
19 | +The poppler should be 0.59.0 or newer versions. | |
20 | +POPPLER_VERSION should be defined. | |
21 | +*/ | |
22 | + | |
23 | /* Do this early in order to avoid a conflict between | |
24 | MINGW32 <rpcndr.h> defining 'boolean' as 'unsigned char' and | |
25 | <kpathsea/types.h> defining Pascal's boolean as 'int'. | |
26 | @@ -39,10 +48,7 @@ | |
27 | #include <goo/gfile.h> | |
28 | #define GString GooString | |
29 | #else | |
30 | -#include <aconf.h> | |
31 | -#include <GString.h> | |
32 | -#include <gmem.h> | |
33 | -#include <gfile.h> | |
34 | +#error POPPLER_VERSION should be defined. | |
35 | #endif | |
36 | #include <assert.h> | |
37 | ||
38 | @@ -84,31 +90,6 @@ | |
39 | #define MASK_SUPPRESS_PTEX_PAGENUMBER 0x04 | |
40 | #define MASK_SUPPRESS_PTEX_INFODICT 0x08 | |
41 | ||
42 | -// PdfObject encapsulates the xpdf Object type, | |
43 | -// and properly frees its resources on destruction. | |
44 | -// Use obj-> to access members of the Object, | |
45 | -// and &obj to get a pointer to the object. | |
46 | -// It is no longer necessary to call Object::free explicitely. | |
47 | - | |
48 | -class PdfObject { | |
49 | - public: | |
50 | - PdfObject() { // nothing | |
51 | - } ~PdfObject() { | |
52 | - iObject.free(); | |
53 | - } | |
54 | - Object *operator->() { | |
55 | - return &iObject; | |
56 | - } | |
57 | - Object *operator&() { | |
58 | - return &iObject; | |
59 | - } | |
60 | - private: // no copying or assigning | |
61 | - PdfObject(const PdfObject &); | |
62 | - void operator=(const PdfObject &); | |
63 | - public: | |
64 | - Object iObject; | |
65 | -}; | |
66 | - | |
67 | // When copying the Resources of the selected page, all objects are copied | |
68 | // recusively top-down. Indirect objects however are not fetched during | |
69 | // copying, but get a new object number from pdfTeX and then will be | |
70 | @@ -212,18 +193,6 @@ | |
71 | delete pdf_doc; | |
72 | } | |
73 | ||
74 | -// Replacement for | |
75 | -// Object *initDict(Dict *dict1){ initObj(objDict); dict = dict1; return this; } | |
76 | - | |
77 | -static void initDictFromDict(PdfObject & obj, Dict * dict) | |
78 | -{ | |
79 | - obj->initDict(xref); | |
80 | - for (int i = 0, l = dict->getLength(); i < l; i++) { | |
81 | - Object obj1; | |
82 | - obj->dictAdd(copyString(dict->getKey(i)), dict->getValNF(i, &obj1)); | |
83 | - } | |
84 | -} | |
85 | - | |
86 | // -------------------------------------------------------------------- | |
87 | ||
88 | static int addEncoding(GfxFont * gfont) | |
89 | @@ -320,10 +289,10 @@ | |
90 | ||
91 | static void copyDictEntry(Object * obj, int i) | |
92 | { | |
93 | - PdfObject obj1; | |
f547c930 | 94 | - copyName(obj->dictGetKey(i)); |
cac27b87 | 95 | + Object obj1; |
f547c930 | 96 | + copyName((char *)obj->dictGetKey(i)); |
cac27b87 HG |
97 | pdf_puts(" "); |
98 | - obj->dictGetValNF(i, &obj1); | |
99 | + obj1 = obj->dictGetValNF(i); | |
100 | copyObject(&obj1); | |
101 | pdf_puts("\n"); | |
102 | } | |
103 | @@ -376,17 +345,17 @@ | |
104 | static void copyProcSet(Object * obj) | |
105 | { | |
106 | int i, l; | |
107 | - PdfObject procset; | |
108 | + Object procset; | |
109 | if (!obj->isArray()) | |
110 | pdftex_fail("PDF inclusion: invalid ProcSet array type <%s>", | |
111 | obj->getTypeName()); | |
112 | pdf_puts("/ProcSet [ "); | |
113 | for (i = 0, l = obj->arrayGetLength(); i < l; ++i) { | |
114 | - obj->arrayGetNF(i, &procset); | |
115 | - if (!procset->isName()) | |
116 | + procset = obj->arrayGetNF(i); | |
117 | + if (!procset.isName()) | |
118 | pdftex_fail("PDF inclusion: invalid ProcSet entry type <%s>", | |
119 | - procset->getTypeName()); | |
120 | - copyName(procset->getName()); | |
121 | + procset.getTypeName()); | |
f547c930 | 122 | + copyName((char *)procset.getName()); |
cac27b87 HG |
123 | pdf_puts(" "); |
124 | } | |
125 | pdf_puts("]\n"); | |
126 | @@ -394,10 +363,29 @@ | |
127 | ||
128 | #define REPLACE_TYPE1C true | |
129 | ||
130 | +static bool embeddableFont(Object * fontdesc) | |
131 | +{ | |
132 | + Object fontfile, ffsubtype; | |
133 | + | |
134 | + if (!fontdesc->isDict()) | |
135 | + return false; | |
136 | + fontfile = fontdesc->dictLookup("FontFile"); | |
137 | + if (fontfile.isStream()) | |
138 | + return true; | |
139 | + if (REPLACE_TYPE1C) { | |
140 | + fontfile = fontdesc->dictLookup("FontFile3"); | |
141 | + if (!fontfile.isStream()) | |
142 | + return false; | |
143 | + ffsubtype = fontfile.streamGetDict()->lookup("Subtype"); | |
144 | + return ffsubtype.isName() && !strcmp(ffsubtype.getName(), "Type1C"); | |
145 | + } | |
146 | + return false; | |
147 | +} | |
148 | + | |
149 | static void copyFont(char *tag, Object * fontRef) | |
150 | { | |
151 | - PdfObject fontdict, subtype, basefont, fontdescRef, fontdesc, charset, | |
152 | - fontfile, ffsubtype, stemV; | |
153 | + Object fontdict, subtype, basefont, fontdescRef, fontdesc, charset, | |
154 | + stemV; | |
155 | GfxFont *gfont; | |
156 | fd_entry *fd; | |
157 | fm_entry *fontmap; | |
158 | @@ -413,33 +401,39 @@ | |
159 | } | |
160 | // Only handle included Type1 (and Type1C) fonts; anything else will be copied. | |
161 | // Type1C fonts are replaced by Type1 fonts, if REPLACE_TYPE1C is true. | |
162 | - if (!fixedinclusioncopyfont && fontRef->fetch(xref, &fontdict)->isDict() | |
163 | - && fontdict->dictLookup("Subtype", &subtype)->isName() | |
164 | - && !strcmp(subtype->getName(), "Type1") | |
165 | - && fontdict->dictLookup("BaseFont", &basefont)->isName() | |
166 | - && fontdict->dictLookupNF("FontDescriptor", &fontdescRef)->isRef() | |
167 | - && fontdescRef->fetch(xref, &fontdesc)->isDict() | |
168 | - && (fontdesc->dictLookup("FontFile", &fontfile)->isStream() | |
169 | - || (REPLACE_TYPE1C | |
170 | - && fontdesc->dictLookup("FontFile3", &fontfile)->isStream() | |
171 | - && fontfile->streamGetDict()->lookup("Subtype", | |
172 | - &ffsubtype)->isName() | |
173 | - && !strcmp(ffsubtype->getName(), "Type1C"))) | |
174 | - && (fontmap = lookup_fontmap(basefont->getName())) != NULL) { | |
175 | + fontdict = fontRef->fetch(xref); | |
176 | + fontdesc = Object(objNull); | |
177 | + if (fontdict.isDict()) { | |
178 | + subtype = fontdict.dictLookup("Subtype"); | |
179 | + basefont = fontdict.dictLookup("BaseFont"); | |
180 | + fontdescRef = fontdict.dictLookupNF("FontDescriptor"); | |
181 | + if (fontdescRef.isRef()) { | |
182 | + fontdesc = fontdescRef.fetch(xref); | |
183 | + } | |
184 | + } | |
185 | + if (!fixedinclusioncopyfont && fontdict.isDict() | |
186 | + && subtype.isName() | |
187 | + && !strcmp(subtype.getName(), "Type1") | |
188 | + && basefont.isName() | |
189 | + && fontdescRef.isRef() | |
190 | + && fontdesc.isDict() | |
191 | + && embeddableFont(&fontdesc) | |
f547c930 | 192 | + && (fontmap = lookup_fontmap((char *)basefont.getName())) != NULL) { |
cac27b87 HG |
193 | // round /StemV value, since the PDF input is a float |
194 | // (see Font Descriptors in PDF reference), but we only store an | |
195 | // integer, since we don't want to change the struct. | |
196 | - fontdesc->dictLookup("StemV", &stemV); | |
197 | - fd = epdf_create_fontdescriptor(fontmap, zround(stemV->getNum())); | |
198 | - if (fontdesc->dictLookup("CharSet", &charset) && | |
199 | - charset->isString() && is_subsetable(fontmap)) | |
200 | - epdf_mark_glyphs(fd, charset->getString()->getCString()); | |
201 | + stemV = fontdesc.dictLookup("StemV"); | |
202 | + fd = epdf_create_fontdescriptor(fontmap, zround(stemV.getNum())); | |
203 | + charset = fontdesc.dictLookup("CharSet"); | |
204 | + if (!charset.isNull() && | |
205 | + charset.isString() && is_subsetable(fontmap)) | |
f547c930 | 206 | + epdf_mark_glyphs(fd, (char *)charset.getString()->getCString()); |
cac27b87 HG |
207 | else |
208 | embed_whole_font(fd); | |
209 | - addFontDesc(fontdescRef->getRef(), fd); | |
210 | + addFontDesc(fontdescRef.getRef(), fd); | |
211 | copyName(tag); | |
212 | gfont = GfxFont::makeFont(xref, tag, fontRef->getRef(), | |
213 | - fontdict->getDict()); | |
214 | + fontdict.getDict()); | |
215 | pdf_printf(" %d 0 R ", addFont(fontRef->getRef(), fd, | |
216 | addEncoding(gfont))); | |
217 | } else { | |
218 | @@ -451,24 +445,24 @@ | |
219 | ||
220 | static void copyFontResources(Object * obj) | |
221 | { | |
222 | - PdfObject fontRef; | |
223 | + Object fontRef; | |
224 | int i, l; | |
225 | if (!obj->isDict()) | |
226 | pdftex_fail("PDF inclusion: invalid font resources dict type <%s>", | |
227 | obj->getTypeName()); | |
228 | pdf_puts("/Font << "); | |
229 | for (i = 0, l = obj->dictGetLength(); i < l; ++i) { | |
230 | - obj->dictGetValNF(i, &fontRef); | |
231 | - if (fontRef->isRef()) | |
232 | + fontRef = obj->dictGetValNF(i); | |
233 | + if (fontRef.isRef()) | |
234 | copyFont(obj->dictGetKey(i), &fontRef); | |
235 | - else if (fontRef->isDict()) { // some programs generate pdf with embedded font object | |
f547c930 | 236 | - copyName(obj->dictGetKey(i)); |
cac27b87 | 237 | + else if (fontRef.isDict()) { // some programs generate pdf with embedded font object |
f547c930 | 238 | + copyName((char *)obj->dictGetKey(i)); |
cac27b87 HG |
239 | pdf_puts(" "); |
240 | copyObject(&fontRef); | |
241 | } | |
242 | else | |
243 | pdftex_fail("PDF inclusion: invalid font in reference type <%s>", | |
244 | - fontRef->getTypeName()); | |
245 | + fontRef.getTypeName()); | |
246 | } | |
247 | pdf_puts(">>\n"); | |
248 | } | |
249 | @@ -557,7 +551,7 @@ | |
250 | ||
251 | static void copyObject(Object * obj) | |
252 | { | |
253 | - PdfObject obj1; | |
254 | + Object obj1; | |
255 | int i, l, c; | |
256 | Ref ref; | |
257 | char *p; | |
f547c930 HG |
258 | @@ -571,7 +565,7 @@ |
259 | } else if (obj->isNum()) { | |
260 | pdf_printf("%s", convertNumToPDF(obj->getNum())); | |
261 | } else if (obj->isString()) { | |
262 | - s = obj->getString(); | |
263 | + s = (GooString *)obj->getString(); | |
264 | p = s->getCString(); | |
265 | l = s->getLength(); | |
266 | if (strlen(p) == (unsigned int) l) { | |
267 | @@ -595,14 +589,14 @@ | |
268 | pdf_puts(">"); | |
269 | } | |
270 | } else if (obj->isName()) { | |
271 | - copyName(obj->getName()); | |
272 | + copyName((char *)obj->getName()); | |
273 | } else if (obj->isNull()) { | |
274 | pdf_puts("null"); | |
cac27b87 HG |
275 | } else if (obj->isArray()) { |
276 | pdf_puts("["); | |
277 | for (i = 0, l = obj->arrayGetLength(); i < l; ++i) { | |
278 | - obj->arrayGetNF(i, &obj1); | |
279 | - if (!obj1->isName()) | |
280 | + obj1 = obj->arrayGetNF(i); | |
281 | + if (!obj1.isName()) | |
282 | pdf_puts(" "); | |
283 | copyObject(&obj1); | |
284 | } | |
285 | @@ -612,9 +606,8 @@ | |
286 | copyDict(obj); | |
287 | pdf_puts(">>"); | |
288 | } else if (obj->isStream()) { | |
289 | - initDictFromDict(obj1, obj->streamGetDict()); | |
290 | pdf_puts("<<\n"); | |
291 | - copyDict(&obj1); | |
292 | + copyDict(obj->getStream()->getDictObject()); | |
293 | pdf_puts(">>\n"); | |
294 | pdf_puts("stream\n"); | |
295 | copyStream(obj->getStream()->getUndecodedStream()); | |
296 | @@ -638,9 +631,8 @@ | |
297 | InObj *r; | |
298 | for (r = inObjList; r != 0; r = r->next) { | |
299 | if (!r->written) { | |
300 | - Object obj1; | |
301 | r->written = 1; | |
302 | - xref->fetch(r->ref.num, r->ref.gen, &obj1); | |
303 | + Object obj1 = xref->fetch(r->ref.num, r->ref.gen); | |
304 | if (r->type == objFont) { | |
305 | assert(!obj1.isStream()); | |
306 | pdfbeginobj(r->num, 2); // \pdfobjcompresslevel = 2 is for this | |
307 | @@ -656,7 +648,6 @@ | |
308 | pdf_puts("\n"); | |
309 | pdfendobj(); | |
310 | } | |
311 | - obj1.free(); | |
312 | } | |
313 | } | |
314 | } | |
315 | @@ -685,7 +676,7 @@ | |
316 | #ifdef POPPLER_VERSION | |
317 | r->font->decRefCnt(); | |
318 | #else | |
319 | - delete r->font; | |
320 | +#error POPPLER_VERSION should be defined. | |
321 | #endif | |
322 | delete r; | |
323 | } | |
324 | @@ -728,7 +719,7 @@ | |
325 | #ifdef POPPLER_VERSION | |
326 | int pdf_major_version_found, pdf_minor_version_found; | |
327 | #else | |
328 | - float pdf_version_found, pdf_version_wanted; | |
329 | +#error POPPLER_VERSION should be defined. | |
330 | #endif | |
331 | // initialize | |
332 | if (!isInit) { | |
333 | @@ -760,19 +751,7 @@ | |
334 | } | |
335 | } | |
336 | #else | |
337 | - pdf_version_found = pdf_doc->doc->getPDFVersion(); | |
338 | - pdf_version_wanted = 1 + (minor_pdf_version_wanted * 0.1); | |
339 | - if (pdf_version_found > pdf_version_wanted + 0.01) { | |
340 | - char msg[] = | |
341 | - "PDF inclusion: found PDF version <%.1f>, but at most version <%.1f> allowed"; | |
342 | - if (pdf_inclusion_errorlevel > 0) { | |
343 | - pdftex_fail(msg, pdf_version_found, pdf_version_wanted); | |
344 | - } else if (pdf_inclusion_errorlevel < 0) { | |
345 | - ; /* do nothing */ | |
346 | - } else { /* = 0, give warning */ | |
347 | - pdftex_warn(msg, pdf_version_found, pdf_version_wanted); | |
348 | - } | |
349 | - } | |
350 | +#error POPPLER_VERSION should be defined. | |
351 | #endif | |
352 | epdf_num_pages = pdf_doc->doc->getCatalog()->getNumPages(); | |
353 | if (page_name) { | |
354 | @@ -839,8 +818,8 @@ | |
355 | Page *page; | |
356 | Ref *pageRef; | |
357 | Dict *pageDict; | |
358 | - PdfObject contents, obj1, obj2, pageObj, dictObj; | |
359 | - PdfObject groupDict; | |
360 | + Object contents, obj1, obj2, pageObj, dictObj; | |
361 | + Object groupDict; | |
362 | bool writeSepGroup = false; | |
363 | Object info; | |
364 | char *key; | |
365 | @@ -867,8 +846,8 @@ | |
366 | encodingList = 0; | |
367 | page = pdf_doc->doc->getCatalog()->getPage(epdf_selected_page); | |
368 | pageRef = pdf_doc->doc->getCatalog()->getPageRef(epdf_selected_page); | |
369 | - xref->fetch(pageRef->num, pageRef->gen, &pageObj); | |
370 | - pageDict = pageObj->getDict(); | |
371 | + pageObj = xref->fetch(pageRef->num, pageRef->gen); | |
372 | + pageDict = pageObj.getDict(); | |
373 | rotate = page->getRotate(); | |
374 | PDFRectangle *pagebox; | |
375 | // write the Page header | |
376 | @@ -886,7 +865,7 @@ | |
377 | pdf_printf("/%s.PageNumber %i\n", pdfkeyprefix, (int) epdf_selected_page); | |
378 | } | |
379 | if ((suppress_ptex_info & MASK_SUPPRESS_PTEX_INFODICT) == 0) { | |
380 | - pdf_doc->doc->getDocInfoNF(&info); | |
381 | + info = pdf_doc->doc->getDocInfoNF(); | |
382 | if (info.isRef()) { | |
383 | // the info dict must be indirect (PDF Ref p. 61) | |
384 | pdf_printf("/%s.InfoDict ", pdfkeyprefix); | |
385 | @@ -942,14 +921,14 @@ | |
386 | pdf_puts(stripzeros(s)); | |
387 | ||
388 | // Metadata validity check (as a stream it must be indirect) | |
389 | - pageDict->lookupNF("Metadata", &dictObj); | |
390 | - if (!dictObj->isNull() && !dictObj->isRef()) | |
391 | + dictObj = pageDict->lookupNF("Metadata"); | |
392 | + if (!dictObj.isNull() && !dictObj.isRef()) | |
393 | pdftex_warn("PDF inclusion: /Metadata must be indirect object"); | |
394 | ||
395 | // copy selected items in Page dictionary except Resources & Group | |
396 | for (i = 0; pageDictKeys[i] != NULL; i++) { | |
397 | - pageDict->lookupNF(pageDictKeys[i], &dictObj); | |
398 | - if (!dictObj->isNull()) { | |
399 | + dictObj = pageDict->lookupNF(pageDictKeys[i]); | |
400 | + if (!dictObj.isNull()) { | |
401 | pdf_newline(); | |
402 | pdf_printf("/%s ", pageDictKeys[i]); | |
403 | copyObject(&dictObj); // preserves indirection | |
404 | @@ -957,8 +936,8 @@ | |
405 | } | |
406 | ||
407 | // handle page group | |
408 | - pageDict->lookupNF("Group", &dictObj); | |
409 | - if (!dictObj->isNull()) { | |
410 | + dictObj = pageDict->lookupNF("Group"); | |
411 | + if (!dictObj.isNull()) { | |
412 | if (pdfpagegroupval == 0) { | |
413 | // another pdf with page group was included earlier on the | |
414 | // same page; copy the Group entry as is. See manual for | |
415 | @@ -972,11 +951,36 @@ | |
416 | copyObject(&dictObj); | |
417 | } else { | |
418 | // write Group dict as a separate object, since the Page dict also refers to it | |
419 | - pageDict->lookup("Group", &dictObj); | |
420 | - if (!dictObj->isDict()) | |
421 | + dictObj = pageDict->lookup("Group"); | |
422 | + if (!dictObj.isDict()) | |
423 | pdftex_fail("PDF inclusion: /Group dict missing"); | |
424 | writeSepGroup = true; | |
425 | - initDictFromDict(groupDict, page->getGroup()); | |
426 | +/* | |
427 | +This part is only a single line | |
428 | + groupDict = Object(page->getGroup()); | |
429 | +in the original patch. In this case, however, pdftex crashes at | |
430 | +"delete pdf_doc->doc" in "delete_document()" for inclusion of some | |
431 | +kind of pdf images, for example, figure_missing.pdf in gnuplot. | |
432 | +A change | |
433 | + groupDict = Object(page->getGroup()).copy(); | |
434 | +does not improve the situation. | |
435 | +The changes below seem to work fine. | |
436 | +*/ | |
437 | +// begin modification | |
438 | + groupDict = pageDict->lookup("Group"); | |
f547c930 HG |
439 | + const Dict& dic1 = page->getGroup(); |
440 | + const Dict& dic2 = groupDict.getDict(); | |
cac27b87 HG |
441 | + // replace dic2 in groupDict with dic1 |
442 | + l = dic2.getLength(); | |
443 | + for (i = 0; i < l; i++) { | |
444 | + groupDict.dictRemove(dic2.getKey(i)); | |
445 | + } | |
446 | + l = dic1.getLength(); | |
447 | + for (i = 0; i < l; i++) { | |
448 | + groupDict.dictAdd(copyString(dic1.getKey(i)), | |
449 | + dic1.getValNF(i)); | |
450 | + } | |
451 | +// end modification | |
452 | pdf_printf("/Group %ld 0 R\n", (long)pdfpagegroupval); | |
453 | } | |
454 | } | |
455 | @@ -989,14 +993,14 @@ | |
456 | pdftex_warn | |
457 | ("PDF inclusion: /Resources missing. 'This practice is not recommended' (PDF Ref)"); | |
458 | } else { | |
459 | - initDictFromDict(obj1, page->getResourceDict()); | |
460 | + Object *obj1 = page->getResourceDictObject(); | |
461 | if (!obj1->isDict()) | |
462 | pdftex_fail("PDF inclusion: invalid resources dict type <%s>", | |
463 | obj1->getTypeName()); | |
464 | pdf_newline(); | |
465 | pdf_puts("/Resources <<\n"); | |
466 | for (i = 0, l = obj1->dictGetLength(); i < l; ++i) { | |
467 | - obj1->dictGetVal(i, &obj2); | |
468 | + obj2 = obj1->dictGetVal(i); | |
469 | key = obj1->dictGetKey(i); | |
470 | if (strcmp("Font", key) == 0) | |
471 | copyFontResources(&obj2); | |
472 | @@ -1009,8 +1013,8 @@ | |
473 | } | |
474 | ||
475 | // write the page contents | |
476 | - page->getContents(&contents); | |
477 | - if (contents->isStream()) { | |
478 | + contents = page->getContents(); | |
479 | + if (contents.isStream()) { | |
480 | ||
481 | // Variant A: get stream and recompress under control | |
482 | // of \pdfcompresslevel | |
483 | @@ -1021,36 +1025,35 @@ | |
484 | ||
485 | // Variant B: copy stream without recompressing | |
486 | // | |
487 | - contents->streamGetDict()->lookup("F", &obj1); | |
488 | - if (!obj1->isNull()) { | |
489 | + obj1 = contents.streamGetDict()->lookup("F"); | |
490 | + if (!obj1.isNull()) { | |
491 | pdftex_fail("PDF inclusion: Unsupported external stream"); | |
492 | } | |
493 | - contents->streamGetDict()->lookup("Length", &obj1); | |
494 | - assert(!obj1->isNull()); | |
495 | + obj1 = contents.streamGetDict()->lookup("Length"); | |
496 | + assert(!obj1.isNull()); | |
497 | pdf_puts("/Length "); | |
498 | copyObject(&obj1); | |
499 | pdf_puts("\n"); | |
500 | - contents->streamGetDict()->lookup("Filter", &obj1); | |
501 | - if (!obj1->isNull()) { | |
502 | + obj1 = contents.streamGetDict()->lookup("Filter"); | |
503 | + if (!obj1.isNull()) { | |
504 | pdf_puts("/Filter "); | |
505 | copyObject(&obj1); | |
506 | pdf_puts("\n"); | |
507 | - contents->streamGetDict()->lookup("DecodeParms", &obj1); | |
508 | - if (!obj1->isNull()) { | |
509 | + obj1 = contents.streamGetDict()->lookup("DecodeParms"); | |
510 | + if (!obj1.isNull()) { | |
511 | pdf_puts("/DecodeParms "); | |
512 | copyObject(&obj1); | |
513 | pdf_puts("\n"); | |
514 | } | |
515 | } | |
516 | pdf_puts(">>\nstream\n"); | |
517 | - copyStream(contents->getStream()->getUndecodedStream()); | |
518 | + copyStream(contents.getStream()->getUndecodedStream()); | |
519 | pdfendstream(); | |
520 | - } else if (contents->isArray()) { | |
521 | + } else if (contents.isArray()) { | |
522 | pdfbeginstream(); | |
523 | - for (i = 0, l = contents->arrayGetLength(); i < l; ++i) { | |
524 | - Object contentsobj; | |
525 | - copyStream((contents->arrayGet(i, &contentsobj))->getStream()); | |
526 | - contentsobj.free(); | |
527 | + for (i = 0, l = contents.arrayGetLength(); i < l; ++i) { | |
528 | + Object contentsobj = contents.arrayGet(i); | |
529 | + copyStream(contentsobj.getStream()); | |
530 | if (i < l - 1) | |
531 | pdf_newline(); // add a newline after each stream except the last | |
532 | } | |
f547c930 HG |
533 | --- ./texk/web2c/pdftexdir/pdftosrc.cc 2017-10-17 04:24:27.000000000 +0000 |
534 | +++ ../pdftosrc-newpoppler.cc 2018-04-30 18:45:24.223917354 +0000 | |
cac27b87 HG |
535 | @@ -16,6 +16,14 @@ |
536 | You should have received a copy of the GNU General Public License along | |
537 | with this program. If not, see <http://www.gnu.org/licenses/>. | |
538 | */ | |
539 | + | |
540 | +/* | |
541 | +This is based on the patch texlive-poppler-0.59.patch <2017-09-19> at | |
542 | +https://git.archlinux.org/svntogit/packages.git/plain/texlive-bin/trunk | |
543 | +by Arch Linux. The poppler should be 0.59.0 or newer versions. | |
544 | +POPPLER_VERSION should be defined. | |
545 | +*/ | |
546 | + | |
547 | #include <w2c/config.h> | |
548 | ||
549 | #include <stdlib.h> | |
550 | @@ -32,10 +40,7 @@ | |
551 | #include <goo/gmem.h> | |
552 | #include <goo/gfile.h> | |
553 | #else | |
554 | -#include <aconf.h> | |
555 | -#include <GString.h> | |
556 | -#include <gmem.h> | |
557 | -#include <gfile.h> | |
558 | +#error POPPLER_VERSION should be defined. | |
559 | #endif | |
560 | #include <assert.h> | |
561 | ||
f547c930 | 562 | @@ -86,31 +91,29 @@ |
cac27b87 HG |
563 | objgen = atoi(argv[3]); |
564 | } | |
565 | xref = doc->getXRef(); | |
566 | - catalogDict.initNull(); | |
567 | - xref->getCatalog(&catalogDict); | |
568 | + catalogDict = xref->getCatalog(); | |
569 | if (!catalogDict.isDict("Catalog")) { | |
570 | fprintf(stderr, "No Catalog found\n"); | |
571 | exit(1); | |
572 | } | |
573 | - srcStream.initNull(); | |
574 | + srcStream = Object(objNull); | |
575 | if (objnum == 0) { | |
576 | - catalogDict.dictLookup("SourceObject", &srcStream); | |
577 | + srcStream = catalogDict.dictLookup("SourceObject"); | |
578 | static char const_SourceFile[] = "SourceFile"; | |
579 | if (!srcStream.isStream(const_SourceFile)) { | |
580 | fprintf(stderr, "No SourceObject found\n"); | |
581 | exit(1); | |
582 | } | |
583 | - srcName.initNull(); | |
584 | - srcStream.getStream()->getDict()->lookup("SourceName", &srcName); | |
585 | + srcName = srcStream.getStream()->getDict()->lookup("SourceName"); | |
586 | if (!srcName.isString()) { | |
587 | fprintf(stderr, "No SourceName found\n"); | |
588 | exit(1); | |
f547c930 HG |
589 | } |
590 | - outname = srcName.getString()->getCString(); | |
591 | + outname = (char *)srcName.getString()->getCString(); | |
cac27b87 HG |
592 | // We cannot free srcName, as objname shares its string. |
593 | // srcName.free(); | |
594 | } else if (objnum > 0) { | |
595 | - xref->fetch(objnum, objgen, &srcStream); | |
596 | + srcStream = xref->fetch(objnum, objgen); | |
597 | if (!srcStream.isStream()) { | |
598 | fprintf(stderr, "Not a Stream object\n"); | |
599 | exit(1); | |
f547c930 | 600 | @@ -160,34 +163,27 @@ |
cac27b87 HG |
601 | int localOffset = 0; |
602 | Guint firstOffset; | |
603 | ||
604 | - assert(xref->fetch(e->offset, 0, &objStr)->isStream()); | |
605 | - nObjects = objStr.streamGetDict()->lookup("N", &obj1)->getInt(); | |
606 | - obj1.free(); | |
607 | - first = objStr.streamGetDict()->lookup("First", &obj1)->getInt(); | |
608 | - obj1.free(); | |
609 | + objStr = xref->fetch(e->offset, 0); | |
610 | + assert(objStr.isStream()); | |
611 | + obj1 = objStr.streamGetDict()->lookup("N"); | |
612 | + nObjects = obj1.getInt(); | |
613 | + obj1 = objStr.streamGetDict()->lookup("First"); | |
614 | + first = obj1.getInt(); | |
615 | firstOffset = objStr.getStream()->getBaseStream()->getStart() + first; | |
616 | ||
617 | // parse the header: object numbers and offsets | |
618 | objStr.streamReset(); | |
619 | - obj1.initNull(); | |
620 | - str = new EmbedStream(objStr.getStream(), &obj1, gTrue, first); | |
cac27b87 | 621 | + str = new EmbedStream(objStr.getStream(), Object(objNull), gTrue, first); |
f547c930 HG |
622 | lexer = new Lexer(xref, str); |
623 | parser = new Parser(xref, lexer, gFalse); | |
cac27b87 HG |
624 | for (n = 0; n < nObjects; ++n) { |
625 | - parser->getObj(&obj1); | |
626 | - parser->getObj(&obj2); | |
627 | + obj1 = parser->getObj(); | |
628 | + obj2 = parser->getObj(); | |
629 | if (n == e->gen) | |
630 | localOffset = obj2.getInt(); | |
631 | - obj1.free(); | |
632 | - obj2.free(); | |
633 | } | |
f547c930 | 634 | -#if defined(POPPLER_VERSION) || defined(XPDF304) |
cac27b87 | 635 | while (str->getChar() != EOF) ; |
f547c930 HG |
636 | -#else /* xpdf 4.00 */ |
637 | - lexer->skipToEOF(); | |
638 | -#endif | |
cac27b87 HG |
639 | delete parser; |
640 | - objStr.free(); | |
641 | ||
642 | fprintf(outfile, "%.10lu 00000 n\n", | |
643 | (long unsigned)(firstOffset + localOffset)); | |
f547c930 | 644 | @@ -198,7 +194,6 @@ |
cac27b87 HG |
645 | s->reset(); |
646 | while ((c = s->getChar()) != EOF) | |
647 | fputc(c, outfile); | |
648 | - srcStream.free(); | |
649 | } | |
650 | if (objnum == 0) | |
651 | fprintf(stderr, "Source file extracted to %s\n", outname); | |
f547c930 | 652 | @@ -207,7 +202,6 @@ |
cac27b87 HG |
653 | else |
654 | fprintf(stderr, "Cross-reference table extracted to %s\n", outname); | |
655 | fclose(outfile); | |
656 | - catalogDict.free(); | |
657 | delete doc; | |
658 | delete globalParams; | |
659 | } |