Date: Friday, March 22, 2019 @ 19:39:34 Author: felixonmars Revision: 348878
archrelease: copy trunk to staging-x86_64 Added: texlive-bin/repos/staging-x86_64/ texlive-bin/repos/staging-x86_64/PKGBUILD (from rev 348877, texlive-bin/trunk/PKGBUILD) texlive-bin/repos/staging-x86_64/freetype-pkgconfig.patch (from rev 348877, texlive-bin/trunk/freetype-pkgconfig.patch) texlive-bin/repos/staging-x86_64/luatex-poppler-fixes.patch (from rev 348877, texlive-bin/trunk/luatex-poppler-fixes.patch) texlive-bin/repos/staging-x86_64/pdftex-poppler0.75.patch (from rev 348877, texlive-bin/trunk/pdftex-poppler0.75.patch) texlive-bin/repos/staging-x86_64/synctex-missing-header.patch (from rev 348877, texlive-bin/trunk/synctex-missing-header.patch) texlive-bin/repos/staging-x86_64/xetex-poppler-fixes.patch (from rev 348877, texlive-bin/trunk/xetex-poppler-fixes.patch) ------------------------------+ PKGBUILD | 412 ++++++++++++ freetype-pkgconfig.patch | 22 luatex-poppler-fixes.patch | 318 +++++++++ pdftex-poppler0.75.patch | 1341 +++++++++++++++++++++++++++++++++++++++++ synctex-missing-header.patch | 12 xetex-poppler-fixes.patch | 40 + 6 files changed, 2145 insertions(+) Copied: texlive-bin/repos/staging-x86_64/PKGBUILD (from rev 348877, texlive-bin/trunk/PKGBUILD) =================================================================== --- staging-x86_64/PKGBUILD (rev 0) +++ staging-x86_64/PKGBUILD 2019-03-22 19:39:34 UTC (rev 348878) @@ -0,0 +1,412 @@ +# Maintainer: Rémy Oudompheng <r...@archlinux.org> +# Contributor: francois <francois.archlinux.org> + +pkgname=('texlive-bin' 'libsynctex') +pkgver=2018.48691 +pkgrel=7 +license=('GPL') +arch=('x86_64') +makedepends=('git' 'cairo' 'pixman' 'graphite' 't1lib' 'gd' 'poppler' + 'libsigsegv' 'zziplib' 'libpng' 'libjpeg' 'freetype2' + 'icu' 'harfbuzz' 'harfbuzz-icu' 'gmp' 'mpfr' 'potrace' 'libpaper' + 'perl' 'clisp' 'ffcall') +url='http://tug.org/texlive/' +_commit=f68b0992e13a2e155d71beb3e016ea4139023224 # texlive-2018.2 +source=("git+https://github.com/Tex-Live/texlive-source.git#commit=${_commit}" + "pdftex-poppler0.75.patch" + "luatex-poppler-fixes.patch" + "xetex-poppler-fixes.patch" + "freetype-pkgconfig.patch" + "synctex-missing-header.patch") +sha256sums=('SKIP' + 'e3f9efc7303cdd0a90f01b02f32ff749eec745afec2ec9c7f5dde300cf6517b3' + '72f0deec8687feeaad7b4ca5565f0a2ddec0ec7d03b5ae4c1d8ede56a1bc9a5d' + '7deb8bd50640b0f4ff9b4c11985fe6153906384b62cb9b5a3c4b52397fb941ca' + 'bed44f4ccda369410e90eac527cf44b8c1afda7d987ae521b4fd5edb425eef3e' + 'b6c81eb091b5910226e0359768edd178680debee56b63ab0a3753c3429c28ab0') + +prepare() { + cd "$srcdir/texlive-source" + + # Synctex "make install" misses synctex_version.h + patch -Np1 -i "${srcdir}/synctex-missing-header.patch" + + # Freetype2 2.9.1 package no longer has freetype-config + patch -Np1 -i "${srcdir}/freetype-pkgconfig.patch" + + ./reautoconf + + # t4ht expects to be un /usr/share/texmf/bin/t4ht (FS#27251) + sed -i s/SELFAUTOPARENT/TEXMFROOT/ texk/tex4htk/t4ht.c + + # luatex switched from poppler to pplib in newer versions so + # upstream fixes aren't available; hopefully this is correct + patch -Np1 -i "${srcdir}/luatex-poppler-fixes.patch" + find texk/web2c/luatexdir -type f -exec sed -i \ + -e 's|gTrue|true|g' \ + -e 's|gFalse|false|g' \ + -e 's|GBool|bool|g' \ + -e 's|getCString|c_str|g' \ + -e 's|Guint|unsigned int|g' \ + -e 's|Guchar|unsigned char|g' \ + {} + + # xetex poppler compatibility + patch -Np1 -i "${srcdir}/xetex-poppler-fixes.patch" + # pdftex poppler compatibility (upstream patches) + patch -Np1 -i "${srcdir}/pdftex-poppler0.75.patch" + cp -pv texk/web2c/pdftexdir/pdftoepdf{-poppler0.75.0,}.cc + cp -pv texk/web2c/pdftexdir/pdftosrc{-poppler0.75.0,}.cc +} + +build() { + cd "$srcdir/texlive-source" + + ############################################################# + ### configure + mkdir -p Work + cd Work + echo "--> Initial configuration..." + # we use temporary prefix to avoid messing the existing + # $pkgdir/usr/share/texmf tree + ../configure --prefix=/usr -C \ + --sysconfdir=/etc \ + --datarootdir=/usr/share \ + --datadir=/usr/share \ + --mandir=/usr/share/man \ + --disable-native-texlive-build \ + --with-banner-add="/Arch Linux" \ + --disable-multiplatform \ + --disable-dialog \ + --disable-psutils \ + --disable-t1utils \ + --disable-bibtexu \ + --disable-xz \ + --enable-shared \ + --disable-static \ + --with-system-zlib \ + --with-system-zziplib \ + --with-system-pnglib \ + --with-system-ncurses \ + --with-system-t1lib \ + --with-system-gd \ + --with-system-poppler \ + --with-system-xpdf \ + --with-system-freetype2 \ + --with-system-pixman \ + --with-system-cairo \ + --with-system-harfbuzz \ + --with-system-graphite \ + --with-system-icu \ + --with-system-gmp \ + --with-system-mpfr \ + --with-system-potrace \ + --with-system-libpaper \ + --with-freetype2-libdir=/usr/lib \ + --with-freetype2-include=/usr/include/freetype2 \ + --with-xdvi-x-toolkit=xaw \ + --disable-dump-share \ + --disable-aleph \ + --enable-luatex \ + --with-clisp-runtime=default \ + --enable-xindy --disable-xindy-rules --disable-xindy-docs + ############################################################# + ### make + echo "-------------------------------------------------------" + echo "--> Building the whole beast ..." + echo "-------------------------------------------------------" + make +} + +package_libsynctex() { + pkgdesc='Library for synchronization between TeX files and resulting file' + depends=('glibc' 'zlib') + + cd "${srcdir}/texlive-source/Work" + make -C texk/web2c DESTDIR="${pkgdir}" \ + install-data-am install-libLTLIBRARIES +} + +package_texlive-bin() { + pkgdesc="TeX Live binaries" + depends=('cairo' 'pixman' 'graphite' 't1lib' 'gd' 'poppler' + 'libsigsegv' 'zziplib' 'libpng' 'libjpeg' 'freetype2' + 'icu' 'harfbuzz' 'harfbuzz-icu' 'gmp' 'mpfr' 'potrace' 'libpaper' + 'libsynctex') + provides=('lcdf-typetools' 'kpathsea' 'xindy') + optdepends=('ed: for texconfig' + 'biber: for bibliography processing') + options=('!strip') + + cd "$srcdir/texlive-source" + + ############################################################# + ### install + # fixes for xindy + find utils/xindy -name Makefile -exec sed -i -e "s|^prefix =.\+$|prefix = $pkgdir/usr|" -e "s|^mandir =.\+$|mandir = \${prefix}/share/man|" -e "s|^datadir =.\+$|datadir = \${datarootdir}/texmf|" -e "s|^docdir =.\+$|docdir = \${datadir}/doc/xindy|" '{}' \; + + echo "-------------------------------------------------------" + echo "--> Proceeding with make install ..." + echo "-------------------------------------------------------" + cd Work + make DESTDIR="${pkgdir}" texmf="$pkgdir"/usr/share/texmf install + rm -rf "${pkgdir}"/usr/{texmf,share/texmf-dist} + + ## symlink engines by hand. texlinks has moved to texlive-core... + mkdir -p ${pkgdir}/usr/bin + ln -s eptex ${pkgdir}/usr/bin/platex + ln -s euptex ${pkgdir}/usr/bin/uplatex + ln -s luatex ${pkgdir}/usr/bin/dvilualatex + ln -s luatex ${pkgdir}/usr/bin/dviluatex + ln -s luatex ${pkgdir}/usr/bin/lualatex + ln -s pdftex ${pkgdir}/usr/bin/amstex + ln -s pdftex ${pkgdir}/usr/bin/cslatex + ln -s pdftex ${pkgdir}/usr/bin/csplain + ln -s pdftex ${pkgdir}/usr/bin/eplain + ln -s pdftex ${pkgdir}/usr/bin/etex + ln -s pdftex ${pkgdir}/usr/bin/jadetex + ln -s pdftex ${pkgdir}/usr/bin/latex + ln -s tex ${pkgdir}/usr/bin/lollipop + ln -s pdftex ${pkgdir}/usr/bin/mex + ln -s pdftex ${pkgdir}/usr/bin/mllatex + ln -s pdftex ${pkgdir}/usr/bin/mltex + ln -s pdftex ${pkgdir}/usr/bin/pdfetex + ln -s pdftex ${pkgdir}/usr/bin/pdfcslatex + ln -s pdftex ${pkgdir}/usr/bin/pdfcsplain + ln -s pdftex ${pkgdir}/usr/bin/pdfjadetex + ln -s pdftex ${pkgdir}/usr/bin/pdflatex + ln -s pdftex ${pkgdir}/usr/bin/pdfmex + ln -s pdftex ${pkgdir}/usr/bin/pdfxmltex + ln -s pdftex ${pkgdir}/usr/bin/texsis + ln -s pdftex ${pkgdir}/usr/bin/utf8mex + ln -s pdftex ${pkgdir}/usr/bin/xmltex + ln -s xetex ${pkgdir}/usr/bin/xelatex + + ############################################################# + # remove dangling symlinks + _bibtexextra_scripts=" +bbl2bib +bib2gls +bibdoiadd +bibexport +bibmradd +biburl2doi +bibzbladd +convertgls2bib +listbib +ltx2crossrefxml +multibibliography +urlbst +" + _core_scripts=" +a2ping +a5toa4 +adhocfilelist +afm2afm +allcm +allec +allneeded +arara +arlatex +autoinst +bundledoc +checkcites +checklistings +chkweb +cjk-gs-integrate +context +contextjit +ctanify +ctanupload +ctan-o-mat +de-macro +depythontex +deweb +dosepsbin +dtxgen +dvi2fax +dviasm +dviinfox +dvired +e2pall +epstopdf +findhyph +fmtutil +fmtutil-sys +fmtutil-user +fontinst +fragmaster +ht +htcontext +htlatex +htmex +httex +httexi +htxelatex +htxetex +installfont-tl +jfmutil +kpsepath +kpsetool +kpsewhere +kpsexpand +latex-git-log +latex-papersize +latex2man +latex2nemeth +latexdef +latexdiff +latexdiff-vc +latexfileversion +latexindent +latexmk +latexpand +latexrevise +listings-ext.sh +ltxfileinfo +ltximg +lua2dox_filter +luaotfload-tool +luatools +lwarpmk +make4ht +match_parens +mf2pt1 +mk4ht +mkjobtexmf +mkt1font +mktexfmt +mptopdf +mtxrun +mtxrunjit +ot2kpx +pdf180 +pdf270 +pdf90 +pdfatfi +pdfbook +pdfbook2 +pdfcrop +pdfflip +pdfjam +pdfjam-pocketmod +pdfjam-slides3up +pdfjam-slides6up +pdfjoin +pdflatexpicscale +pdfnup +pdfpun +pdfxup +pfarrei +pkfix +pkfix-helper +ps2eps +ps2frag +pslatex +purifyeps +pythontex +repstopdf +rpdfcrop +rungs +simpdftex +srcredact +sty2dtx +tex4ebook +texconfig +texconfig-dialog +texconfig-sys +texcount +texdef +texdiff +texdirflatten +texdoc +texdoctk +texexec +texfot +texindy +texlinks +texliveonfly +texloganalyser +texmfstart +texosquery +texosquery-jre5 +texosquery-jre8 +thumbpdf +tlcockpit +tlshell +typeoutfileinfo +updmap +updmap-sys +updmap-user +vpl2ovp +vpl2vpl +xhlatex +xindy +" + _games_scripts="rubikrotation" + _humanities_scripts="diadia" + _langcyrillic_scripts="rubibtex rumakeindex" + _langextra_scripts="ebong" + _langgreek_scripts="mkgrkindex" + _langjapanese_scripts="convbkmk ptex2pdf +kanji-fontmap-creator +kanji-config-updmap +kanji-config-updmap-sys +kanji-config-updmap-user +" + _langkorean_scripts="jamo-normalize komkindex ttf2kotexfont" + _latexextra_scripts=" +authorindex +exceltex +l3build +makedtx +makeglossaries +makeglossaries-lite +pdfannotextractor +perltex +ps4pdf +splitindex +svn-multi +vpe +wordcount +yplan" + _music_scripts="lily-glyph-commands lily-image-commands lily-rebuild-pdfs +m-tx musixtex musixflx pmxchords" + _pictures_scripts=" +cachepic +epspdf +epspdftk +fig4latex +getmapdl +mathspic +mkpic +pn2pdf" + _pstricks_scripts="pedigree pst2pdf" + _science_scripts="pygmentex ulqda" + for s in \ + ${_bibtexextra_scripts} \ + ${_core_scripts} \ + ${_games_scripts} \ + ${_htmlxml_scripts} \ + ${_humanities_scripts} \ + ${_langcyrillic_scripts} \ + ${_langextra_scripts} \ + ${_langgreek_scripts} \ + ${_langjapanese_scripts} \ + ${_langkorean_scripts} \ + ${_latexextra_scripts} \ + ${_music_scripts} \ + ${_pictures_scripts} \ + ${_pstricks_scripts} \ + ${_science_scripts} \ + tlmgr; do + ! readlink -e "$pkgdir"/usr/bin/$s && rm "$pkgdir"/usr/bin/$s + done + ################################################################### + + # remove libsynctex + rm -f "$pkgdir"/usr/include/synctex/* + rm -f "$pkgdir"/usr/lib/libsynctex.* + rm -f "$pkgdir"/usr/lib/pkgconfig/synctex.pc + rm -f "$pkgdir"/usr/share/man/man*/synctex.* +} + Copied: texlive-bin/repos/staging-x86_64/freetype-pkgconfig.patch (from rev 348877, texlive-bin/trunk/freetype-pkgconfig.patch) =================================================================== --- staging-x86_64/freetype-pkgconfig.patch (rev 0) +++ staging-x86_64/freetype-pkgconfig.patch 2019-03-22 19:39:34 UTC (rev 348878) @@ -0,0 +1,22 @@ +--- source/m4/kpse-freetype2-flags.m4.orig 2015-06-16 01:27:13.292945838 +0200 ++++ source/m4/kpse-freetype2-flags.m4 2018-05-26 23:51:50.567080501 +0200 +@@ -21,17 +21,9 @@ + + # KPSE_FREETYPE2_OPTIONS([WITH-SYSTEM]) + # ------------------------------------- +-AC_DEFUN([KPSE_FREETYPE2_OPTIONS], [_KPSE_LIB_OPTIONS([freetype2], [$1], [freetype-config])]) ++AC_DEFUN([KPSE_FREETYPE2_OPTIONS], [_KPSE_LIB_OPTIONS([freetype2], [$1], [pkg-config])]) + + # KPSE_FREETYPE2_SYSTEM_FLAGS + # --------------------------- + AC_DEFUN([KPSE_FREETYPE2_SYSTEM_FLAGS], [dnl +-AC_REQUIRE([AC_CANONICAL_HOST])[]dnl +-AC_CHECK_TOOL([FT2_CONFIG], [freetype-config], [false])[]dnl +-if $FT2_CONFIG --ftversion >/dev/null 2>&1; then +- FREETYPE2_INCLUDES=`$FT2_CONFIG --cflags` +- FREETYPE2_LIBS=`$FT2_CONFIG --libs` +-elif test "x$need_freetype2:$with_system_freetype2" = xyes:yes; then +- AC_MSG_ERROR([did not find freetype-config required for system freetype2 library]) +-fi +-]) # KPSE_FREETYPE2_SYSTEM_FLAGS ++_KPSE_PKG_CONFIG_FLAGS([freetype2], [freetype2], [])]) Copied: texlive-bin/repos/staging-x86_64/luatex-poppler-fixes.patch (from rev 348877, texlive-bin/trunk/luatex-poppler-fixes.patch) =================================================================== --- staging-x86_64/luatex-poppler-fixes.patch (rev 0) +++ staging-x86_64/luatex-poppler-fixes.patch 2019-03-22 19:39:34 UTC (rev 348878) @@ -0,0 +1,318 @@ +From 69c061f2071d5826fee7940ce7f83ae4a1c8fc2e Mon Sep 17 00:00:00 2001 +From: Akira Kakuto <kak...@fuk.kindai.ac.jp> +Date: Sat, 28 Apr 2018 07:36:22 +0000 +Subject: [PATCH] support poppler-0.64.0 + +git-svn-id: svn://tug.org/texlive/trunk/Build/source@47470 c570f23f-e606-0410-a88d-b1316a301751 +--- + texk/web2c/luatexdir/image/pdftoepdf.w | 4 ++-- + texk/web2c/luatexdir/lua/lepdflib.cc | 4 ++-- + texk/web2c/pdftexdir/ChangeLog | 5 +++++ + texk/web2c/pdftexdir/pdftoepdf-newpoppler.cc | 14 +++++++------- + texk/web2c/pdftexdir/pdftosrc-newpoppler.cc | 2 +- + 5 files changed, 17 insertions(+), 12 deletions(-) + +diff --git a/texk/web2c/luatexdir/image/pdftoepdf.w b/texk/web2c/luatexdir/image/pdftoepdf.w +index 7ba29731c..d69795926 100644 +--- a/texk/web2c/luatexdir/image/pdftoepdf.w ++++ b/texk/web2c/luatexdir/image/pdftoepdf.w +@@ -472,10 +472,10 @@ static void copyObject(PDF pdf, PdfDocument * pdf_doc, Object * obj) + break; + */ + case objString: +- copyString(pdf, obj->getString()); ++ copyString(pdf, (GooString *)obj->getString()); + break; + case objName: +- copyName(pdf, obj->getName()); ++ copyName(pdf, (char *)obj->getName()); + break; + case objNull: + pdf_add_null(pdf); +diff --git a/texk/web2c/luatexdir/lua/lepdflib.cc b/texk/web2c/luatexdir/lua/lepdflib.cc +index a16bf3bd4..32bcdab01 100644 +--- a/texk/web2c/luatexdir/lua/lepdflib.cc ++++ b/texk/web2c/luatexdir/lua/lepdflib.cc +@@ -674,7 +674,7 @@ static int m_##in##_##function(lua_State * L) \ + uin = (udstruct *) luaL_checkudata(L, 1, M_##in); \ + if (uin->pd != NULL && uin->pd->pc != uin->pc) \ + pdfdoc_changed_error(L); \ +- gs = ((in *) uin->d)->function(); \ ++ gs = (GooString *)((in *) uin->d)->function(); \ + if (gs != NULL) \ + lua_pushlstring(L, gs->getCString(), gs->getLength()); \ + else \ +@@ -1813,7 +1813,7 @@ static int m_Object_getString(lua_State * L) + if (uin->pd != NULL && uin->pd->pc != uin->pc) + pdfdoc_changed_error(L); + if (((Object *) uin->d)->isString()) { +- gs = ((Object *) uin->d)->getString(); ++ gs = (GooString *)((Object *) uin->d)->getString(); + lua_pushlstring(L, gs->getCString(), gs->getLength()); + } else + lua_pushnil(L); + +Luatex poppler 0.70 const fixes + +diff -upr source.orig/texk/web2c/luatexdir/image/pdftoepdf.w source/texk/web2c/luatexdir/image/pdftoepdf.w +--- source.orig/texk/web2c/luatexdir/image/pdftoepdf.w 2018-10-28 14:14:32.961111369 +0200 ++++ source/texk/web2c/luatexdir/image/pdftoepdf.w 2018-10-28 14:24:21.735889333 +0200 +@@ -363,7 +363,7 @@ void copyReal(PDF pdf, double d) + + static void copyString(PDF pdf, GooString * string) + { +- char *p; ++ const char *p; + unsigned char c; + size_t i, l; + p = string->getCString(); +@@ -393,7 +393,7 @@ static void copyString(PDF pdf, GooStrin + pdf->cave = true; + } + +-static void copyName(PDF pdf, char *s) ++static void copyName(PDF pdf, const char *s) + { + pdf_out(pdf, '/'); + for (; *s != 0; s++) { +@@ -475,7 +475,7 @@ static void copyObject(PDF pdf, PdfDocum + copyString(pdf, (GooString *)obj->getString()); + break; + case objName: +- copyName(pdf, (char *)obj->getName()); ++ copyName(pdf, obj->getName()); + break; + case objNull: + pdf_add_null(pdf); +@@ -531,22 +531,22 @@ static PDFRectangle *get_pagebox(Page * + { + switch (pagebox_spec) { + case PDF_BOX_SPEC_MEDIA: +- return page->getMediaBox(); ++ return (PDFRectangle *) page->getMediaBox(); + break; + case PDF_BOX_SPEC_CROP: +- return page->getCropBox(); ++ return (PDFRectangle *) page->getCropBox(); + break; + case PDF_BOX_SPEC_BLEED: +- return page->getBleedBox(); ++ return (PDFRectangle *) page->getBleedBox(); + break; + case PDF_BOX_SPEC_TRIM: +- return page->getTrimBox(); ++ return (PDFRectangle *) page->getTrimBox(); + break; + case PDF_BOX_SPEC_ART: +- return page->getArtBox(); ++ return (PDFRectangle *) page->getArtBox(); + break; + default: +- return page->getMediaBox(); ++ return (PDFRectangle *) page->getMediaBox(); + break; + } + } +diff -upr source.orig/texk/web2c/luatexdir/lua/lepdflib.cc source/texk/web2c/luatexdir/lua/lepdflib.cc +--- source.orig/texk/web2c/luatexdir/lua/lepdflib.cc 2018-10-28 14:14:32.961111369 +0200 ++++ source/texk/web2c/luatexdir/lua/lepdflib.cc 2018-10-28 14:19:28.093424519 +0200 +@@ -596,7 +596,7 @@ static int m_##in##_##function(lua_State + uin = (udstruct *) luaL_checkudata(L, 1, M_##in); \ + if (uin->pd != NULL && uin->pd->pc != uin->pc) \ + pdfdoc_changed_error(L); \ +- o = ((in *) uin->d)->function(); \ ++ o = (out *) ((in *) uin->d)->function(); \ + if (o != NULL) { \ + uout = new_##out##_userdata(L); \ + uout->d = o; \ +@@ -1125,12 +1125,12 @@ m_poppler_get_INT(Dict, getLength); + + static int m_Dict_add(lua_State * L) + { +- char *s; ++ const char *s; + udstruct *uin, *uobj; + uin = (udstruct *) luaL_checkudata(L, 1, M_Dict); + if (uin->pd != NULL && uin->pd->pc != uin->pc) + pdfdoc_changed_error(L); +- s = copyString(luaL_checkstring(L, 2)); ++ s = luaL_checkstring(L, 2); + uobj = (udstruct *) luaL_checkudata(L, 3, M_Object); + ((Dict *) uin->d)->add(s, std::move(*((Object *) uobj->d))); + return 0; +@@ -2051,7 +2051,7 @@ static int m_Object_dictAdd(lua_State * + pdfdoc_changed_error(L); + if (!((Object *) uin->d)->isDict()) + luaL_error(L, "Object is not a Dict"); +- ((Object *) uin->d)->dictAdd(copyString(s), std::move(*((Object *) uobj->d))); ++ ((Object *) uin->d)->dictAdd(s, std::move(*((Object *) uobj->d))); + return 0; + } + +@@ -2470,7 +2470,7 @@ static int m_PDFDoc_getFileName(lua_Stat + uin = (udstruct *) luaL_checkudata(L, 1, M_PDFDoc); + if (uin->pd != NULL && uin->pd->pc != uin->pc) + pdfdoc_changed_error(L); +- gs = ((PdfDocument *) uin->d)->doc->getFileName(); ++ gs = (GooString *) ((PdfDocument *) uin->d)->doc->getFileName(); + if (gs != NULL) + lua_pushlstring(L, gs->getCString(), gs->getLength()); + else +@@ -2559,7 +2559,7 @@ static int m_PDFDoc_readMetadata(lua_Sta + if (uin->pd != NULL && uin->pd->pc != uin->pc) + pdfdoc_changed_error(L); + if (((PdfDocument *) uin->d)->doc->getCatalog()->isOk()) { +- gs = ((PdfDocument *) uin->d)->doc->readMetadata(); ++ gs = (GooString *) ((PdfDocument *) uin->d)->doc->readMetadata(); + if (gs != NULL) + lua_pushlstring(L, gs->getCString(), gs->getLength()); + else +@@ -2577,7 +2577,7 @@ static int m_PDFDoc_getStructTreeRoot(lu + if (uin->pd != NULL && uin->pd->pc != uin->pc) + pdfdoc_changed_error(L); + if (((PdfDocument *) uin->d)->doc->getCatalog()->isOk()) { +- obj = ((PdfDocument *) uin->d)->doc->getStructTreeRoot(); ++ obj = (StructTreeRoot *) ((PdfDocument *) uin->d)->doc->getStructTreeRoot(); + uout = new_StructTreeRoot_userdata(L); + uout->d = obj; + uout->pc = uin->pc; + +Luatex fixes for poppler 0.71 + +--- source/texk/web2c/luatexdir/lua/lepdflib.cc.orig 2018-11-01 22:46:43.868534355 +0000 ++++ source/texk/web2c/luatexdir/lua/lepdflib.cc 2018-11-01 22:48:17.358815525 +0000 +@@ -240,7 +240,7 @@ + if (uobj->pd != NULL && uobj->pd->pc != uobj->pc) + pdfdoc_changed_error(L); + uout = new_Attribute_userdata(L); +- uout->d = new Attribute(n, nlen, (Object *)uobj->d); ++ uout->d = new Attribute((GooString)n, (Object *)uobj->d); + uout->atype = ALLOC_LEPDF; + uout->pc = uobj->pc; + uout->pd = uobj->pd; + +--- source/texk/web2c/luatexdir/lua/lepdflib.cc.orig 2019-03-22 11:02:34.966605737 +0000 ++++ source/texk/web2c/luatexdir/lua/lepdflib.cc 2019-03-22 11:09:27.894599672 +0000 +@@ -496,7 +496,7 @@ + double numA = lua_tonumber(L,1); + double genA = lua_tonumber(L,2); + if ( ((numA)==(int)(numA)) && ((genA)==(int)(genA)) ){ +- uout->d = new Object((int)(numA), (int)(genA)); ++ uout->d = new Object({(int)(numA), (int)(genA)}); + uout->atype = ALLOC_LEPDF; + uout->pc = 0; + uout->pd = NULL; +@@ -889,7 +889,7 @@ + if (i > 0 && i <= len) { + uout = new_Object_userdata(L); + uout->d = new Object(); +- *((Object *) uout->d) = ((Array *) uin->d)->getNF(i - 1); ++ *((Object *) uout->d) = ((Array *) uin->d)->getNF(i - 1).copy(); + uout->atype = ALLOC_LEPDF; + uout->pc = uin->pc; + uout->pd = uin->pd; +@@ -1190,7 +1190,7 @@ + s = luaL_checkstring(L, 2); + uout = new_Object_userdata(L); + uout->d = new Object(); +- *((Object *) uout->d) = ((Dict *) uin->d)->lookupNF(s); ++ *((Object *) uout->d) = ((Dict *) uin->d)->lookupNF(s).copy(); + uout->atype = ALLOC_LEPDF; + uout->pc = uin->pc; + uout->pd = uin->pd; +@@ -1263,7 +1263,7 @@ + if (i > 0 && i <= len) { + uout = new_Object_userdata(L); + uout->d = new Object(); +- *((Object *) uout->d) = ((Dict *) uin->d)->getValNF(i - 1); ++ *((Object *) uout->d) = ((Dict *) uin->d)->getValNF(i - 1).copy(); + uout->atype = ALLOC_LEPDF; + uout->pc = uin->pc; + uout->pd = uin->pd; +@@ -1653,7 +1653,7 @@ + pdfdoc_changed_error(L); + num = luaL_checkint(L, 2); + gen = luaL_checkint(L, 3); +- *((Object *) uin->d) = Object(num, gen); ++ *((Object *) uin->d) = Object({num, gen}); + return 0; + } + +@@ -2011,7 +2011,7 @@ + if (i > 0 && i <= len) { + uout = new_Object_userdata(L); + uout->d = new Object(); +- *((Object *) uout->d) = ((Object *) uin->d)->arrayGetNF(i - 1); ++ *((Object *) uout->d) = ((Object *) uin->d)->arrayGetNF(i - 1).copy(); + uout->atype = ALLOC_LEPDF; + uout->pc = uin->pc; + uout->pd = uin->pd; +@@ -2104,7 +2104,7 @@ + if (((Object *) uin->d)->isDict()) { + uout = new_Object_userdata(L); + uout->d = new Object(); +- *((Object *) uout->d) = ((Object *) uin->d)->dictLookupNF(s); ++ *((Object *) uout->d) = ((Object *) uin->d)->dictLookupNF(s).copy(); + uout->atype = ALLOC_LEPDF; + uout->pc = uin->pc; + uout->pd = uin->pd; +@@ -2169,7 +2169,7 @@ + if (i > 0 && i <= len) { + uout = new_Object_userdata(L); + uout->d = new Object(); +- *((Object *) uout->d) = ((Object *) uin->d)->dictGetValNF(i - 1); ++ *((Object *) uout->d) = ((Object *) uin->d)->dictGetValNF(i - 1).copy(); + uout->atype = ALLOC_LEPDF; + uout->pc = uin->pc; + uout->pd = uin->pd; +--- texlive-source/texk/web2c/luatexdir/image/pdftoepdf.w.orig 2019-03-22 19:17:32.861362965 +0000 ++++ texlive-source/texk/web2c/luatexdir/image/pdftoepdf.w 2019-03-22 19:20:22.906973305 +0000 +@@ -412,7 +412,7 @@ + Object obj1; + pdf_begin_array(pdf); + for (i = 0, l = array->getLength(); i < l; ++i) { +- obj1 = array->getNF(i); ++ obj1 = array->getNF(i).copy(); + copyObject(pdf, pdf_doc, &obj1); + } + pdf_end_array(pdf); +@@ -425,7 +425,7 @@ + pdf_begin_dict(pdf); + for (i = 0, l = dict->getLength(); i < l; ++i) { + copyName(pdf, dict->getKey(i)); +- obj1 = dict->getValNF(i); ++ obj1 = dict->getValNF(i).copy(); + copyObject(pdf, pdf_doc, &obj1); + } + pdf_end_dict(pdf); +@@ -788,12 +788,12 @@ + Now all relevant parts of the Page dictionary are copied. Metadata validity + check is needed(as a stream it must be indirect). + */ +- obj1 = pageDict->lookupNF("Metadata"); ++ obj1 = pageDict->lookupNF("Metadata").copy(); + if (!obj1.isNull() && !obj1.isRef()) + formatted_warning("pdf inclusion","/Metadata must be indirect object"); + /* copy selected items in Page dictionary */ + for (i = 0; pagedictkeys[i] != NULL; i++) { +- obj1 = pageDict->lookupNF(pagedictkeys[i]); ++ obj1 = pageDict->lookupNF(pagedictkeys[i]).copy(); + if (!obj1.isNull()) { + pdf_add_name(pdf, pagedictkeys[i]); + /* preserves indirection */ +@@ -806,13 +806,13 @@ + PDF file, climbing up the tree until the Resources are found. + (This fixes a problem with Scribus 1.3.3.14.) + */ +- obj1 = pageDict->lookupNF("Resources"); ++ obj1 = pageDict->lookupNF("Resources").copy(); + if (obj1.isNull()) { + op1 = &pagesobj1; + op2 = &pagesobj2; + *op1 = pageDict->lookup("Parent"); + while (op1->isDict()) { +- obj1 = op1->dictLookupNF("Resources"); ++ obj1 = op1->dictLookupNF("Resources").copy(); + if (!obj1.isNull()) { + pdf_add_name(pdf, "Resources"); + copyObject(pdf, pdf_doc, &obj1); Copied: texlive-bin/repos/staging-x86_64/pdftex-poppler0.75.patch (from rev 348877, texlive-bin/trunk/pdftex-poppler0.75.patch) =================================================================== --- staging-x86_64/pdftex-poppler0.75.patch (rev 0) +++ staging-x86_64/pdftex-poppler0.75.patch 2019-03-22 19:39:34 UTC (rev 348878) @@ -0,0 +1,1341 @@ +commit 67290f70d8143b18f24ffd6a1827def9bdc21108 +Author: Akira Kakuto <kak...@fuk.kindai.ac.jp> +Date: Thu Dec 6 23:31:33 2018 +0000 + + support system poppler 0.72.0 + + git-svn-id: svn://tug.org/texlive/trunk/Build/source@49336 c570f23f-e606-0410-a88d-b1316a301751 + + +diff --git a/texk/web2c/pdftexdir/pdftoepdf-poppler0.75.0.cc b/texk/web2c/pdftexdir/pdftoepdf-poppler0.75.0.cc +new file mode 100644 +index 000000000..630d3366d +--- /dev/null ++++ b/texk/web2c/pdftexdir/pdftoepdf-poppler0.75.0.cc +@@ -0,0 +1,1113 @@ ++/* ++Copyright 1996-2017 Han The Thanh, <th...@pdftex.org> ++ ++This file is part of pdfTeX. ++ ++pdfTeX is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2 of the License, or ++(at your option) any later version. ++ ++pdfTeX is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License along ++with this program. If not, see <http://www.gnu.org/licenses/>. ++*/ ++ ++/* ++This is based on the patch texlive-poppler-0.59.patch <2017-09-19> at ++https://git.archlinux.org/svntogit/packages.git/plain/texlive-bin/trunk ++by Arch Linux. A little modifications are made to avoid a crash for ++some kind of pdf images, such as figure_missing.pdf in gnuplot. ++The poppler should be 0.72.0 or newer versions. ++POPPLER_VERSION should be defined. ++*/ ++ ++/* Do this early in order to avoid a conflict between ++ MINGW32 <rpcndr.h> defining 'boolean' as 'unsigned char' and ++ <kpathsea/types.h> defining Pascal's boolean as 'int'. ++*/ ++#include <w2c/config.h> ++#include <kpathsea/lib.h> ++ ++#include <stdlib.h> ++#include <math.h> ++#include <stddef.h> ++#include <stdio.h> ++#include <string.h> ++#include <ctype.h> ++ ++#ifdef POPPLER_VERSION ++#include <dirent.h> ++#include <poppler-config.h> ++#include <goo/GooString.h> ++#include <goo/gmem.h> ++#include <goo/gfile.h> ++#define GString GooString ++#else ++#error POPPLER_VERSION should be defined. ++#endif ++#include <assert.h> ++ ++#include "Object.h" ++#include "Stream.h" ++#include "Array.h" ++#include "Dict.h" ++#include "XRef.h" ++#include "Catalog.h" ++#include "Link.h" ++#include "Page.h" ++#include "GfxFont.h" ++#include "PDFDoc.h" ++#include "GlobalParams.h" ++#include "Error.h" ++ ++// This file is mostly C and not very much C++; it's just used to interface ++// the functions of xpdf, which are written in C++. ++ ++extern "C" { ++#include <pdftexdir/ptexmac.h> ++#include <pdftexdir/pdftex-common.h> ++ ++// These functions from pdftex.web gets declared in pdftexcoerce.h in the ++// usual web2c way, but we cannot include that file here because C++ ++// does not allow it. ++extern int getpdfsuppresswarningpagegroup(void); ++extern integer getpdfsuppressptexinfo(void); ++extern integer zround(double); ++} ++ ++// The prefix "PTEX" for the PDF keys is special to pdfTeX; ++// this has been registered with Adobe by Hans Hagen. ++ ++#define pdfkeyprefix "PTEX" ++ ++#define MASK_SUPPRESS_PTEX_FULLBANNER 0x01 ++#define MASK_SUPPRESS_PTEX_FILENAME 0x02 ++#define MASK_SUPPRESS_PTEX_PAGENUMBER 0x04 ++#define MASK_SUPPRESS_PTEX_INFODICT 0x08 ++ ++// When copying the Resources of the selected page, all objects are copied ++// recusively top-down. Indirect objects however are not fetched during ++// copying, but get a new object number from pdfTeX and then will be ++// appended into a linked list. Duplicates are checked and removed from the ++// list of indirect objects during appending. ++ ++enum InObjType { ++ objFont, ++ objFontDesc, ++ objOther ++}; ++ ++struct InObj { ++ Ref ref; // ref in original PDF ++ InObjType type; // object type ++ InObj *next; // next entry in list of indirect objects ++ int num; // new object number in output PDF ++ fd_entry *fd; // pointer to /FontDescriptor object structure ++ int enc_objnum; // Encoding for objFont ++ int written; // has it been written to output PDF? ++}; ++ ++struct UsedEncoding { ++ int enc_objnum; ++ GfxFont *font; ++ UsedEncoding *next; ++}; ++ ++static InObj *inObjList; ++static UsedEncoding *encodingList; ++static bool isInit = false; ++ ++// -------------------------------------------------------------------- ++// Maintain list of open embedded PDF files ++// -------------------------------------------------------------------- ++ ++struct PdfDocument { ++ char *file_name; ++ PDFDoc *doc; ++ XRef *xref; ++ InObj *inObjList; ++ int occurences; // number of references to the document; the doc can be ++ // deleted when this is negative ++ PdfDocument *next; ++}; ++ ++static PdfDocument *pdfDocuments = 0; ++ ++static XRef *xref = 0; ++ ++// Returns pointer to PdfDocument record for PDF file. ++// Creates a new record if it doesn't exist yet. ++// xref is made current for the document. ++ ++static PdfDocument *find_add_document(char *file_name) ++{ ++ PdfDocument *p = pdfDocuments; ++ while (p && strcmp(p->file_name, file_name) != 0) ++ p = p->next; ++ if (p) { ++ xref = p->xref; ++ (p->occurences)++; ++ return p; ++ } ++ p = new PdfDocument; ++ p->file_name = xstrdup(file_name); ++ p->xref = xref = 0; ++ p->occurences = 0; ++ GString *docName = new GString(p->file_name); ++ p->doc = new PDFDoc(docName); // takes ownership of docName ++ if (!p->doc->isOk() || !p->doc->okToPrint()) { ++ pdftex_fail("xpdf: reading PDF image failed"); ++ } ++ p->inObjList = 0; ++ p->next = pdfDocuments; ++ pdfDocuments = p; ++ return p; ++} ++ ++// Deallocate a PdfDocument with all its resources ++ ++static void delete_document(PdfDocument * pdf_doc) ++{ ++ PdfDocument **p = &pdfDocuments; ++ while (*p && *p != pdf_doc) ++ p = &((*p)->next); ++ // should not happen: ++ if (!*p) ++ return; ++ // unlink from list ++ *p = pdf_doc->next; ++ // free pdf_doc's resources ++ InObj *r, *n; ++ for (r = pdf_doc->inObjList; r != 0; r = n) { ++ n = r->next; ++ delete r; ++ } ++ xref = pdf_doc->xref; ++ delete pdf_doc->doc; ++ xfree(pdf_doc->file_name); ++ delete pdf_doc; ++} ++ ++// -------------------------------------------------------------------- ++ ++static int addEncoding(GfxFont * gfont) ++{ ++ UsedEncoding *n; ++ n = new UsedEncoding; ++ n->next = encodingList; ++ encodingList = n; ++ n->font = gfont; ++ n->enc_objnum = pdfnewobjnum(); ++ return n->enc_objnum; ++} ++ ++#define addFont(ref, fd, enc_objnum) \ ++ addInObj(objFont, ref, fd, enc_objnum) ++ ++// addFontDesc is only used to avoid writing the original FontDescriptor ++// from the PDF file. ++ ++#define addFontDesc(ref, fd) \ ++ addInObj(objFontDesc, ref, fd, 0) ++ ++#define addOther(ref) \ ++ addInObj(objOther, ref, 0, 0) ++ ++static int addInObj(InObjType type, Ref ref, fd_entry * fd, int e) ++{ ++ InObj *p, *q, *n = new InObj; ++ if (ref.num == 0) ++ pdftex_fail("PDF inclusion: invalid reference"); ++ n->ref = ref; ++ n->type = type; ++ n->next = 0; ++ n->fd = fd; ++ n->enc_objnum = e; ++ n->written = 0; ++ if (inObjList == 0) ++ inObjList = n; ++ else { ++ for (p = inObjList; p != 0; p = p->next) { ++ if (p->ref.num == ref.num && p->ref.gen == ref.gen) { ++ delete n; ++ return p->num; ++ } ++ q = p; ++ } ++ // it is important to add new objects at the end of the list, ++ // because new objects are being added while the list is being ++ // written out. ++ q->next = n; ++ } ++ if (type == objFontDesc) ++ n->num = get_fd_objnum(fd); ++ else ++ n->num = pdfnewobjnum(); ++ return n->num; ++} ++ ++#if 0 /* unusewd */ ++static int getNewObjectNumber(Ref ref) ++{ ++ InObj *p; ++ if (inObjList == 0) { ++ pdftex_fail("No objects copied yet"); ++ } else { ++ for (p = inObjList; p != 0; p = p->next) { ++ if (p->ref.num == ref.num && p->ref.gen == ref.gen) { ++ return p->num; ++ } ++ } ++ pdftex_fail("Object not yet copied: %i %i", ref.num, ref.gen); ++ } ++#ifdef _MSC_VER ++ /* Never reached, but without __attribute__((noreturn)) for pdftex_fail() ++ MSVC 5.0 requires an int return value. */ ++ return -60000; ++#endif ++} ++#endif ++ ++static void copyObject(Object *); ++ ++static void copyName(char *s) ++{ ++ pdf_puts("/"); ++ for (; *s != 0; s++) { ++ if (isdigit(*s) || isupper(*s) || islower(*s) || *s == '_' || ++ *s == '.' || *s == '-' || *s == '+') ++ pdfout(*s); ++ else ++ pdf_printf("#%.2X", *s & 0xFF); ++ } ++} ++ ++static void copyDictEntry(Object * obj, int i) ++{ ++ Object obj1; ++ copyName((char *)obj->dictGetKey(i)); ++ pdf_puts(" "); ++ obj1 = obj->dictGetValNF(i).copy(); ++ copyObject(&obj1); ++ pdf_puts("\n"); ++} ++ ++static void copyDict(Object * obj) ++{ ++ int i, l; ++ if (!obj->isDict()) ++ pdftex_fail("PDF inclusion: invalid dict type <%s>", ++ obj->getTypeName()); ++ for (i = 0, l = obj->dictGetLength(); i < l; ++i) ++ copyDictEntry(obj, i); ++} ++ ++static void copyFontDict(Object * obj, InObj * r) ++{ ++ int i, l; ++ char *key; ++ if (!obj->isDict()) ++ pdftex_fail("PDF inclusion: invalid dict type <%s>", ++ obj->getTypeName()); ++ pdf_puts("<<\n"); ++ assert(r->type == objFont); // FontDescriptor is in fd_tree ++ for (i = 0, l = obj->dictGetLength(); i < l; ++i) { ++ key = (char *)obj->dictGetKey(i); ++ if (strncmp("FontDescriptor", key, strlen("FontDescriptor")) == 0 ++ || strncmp("BaseFont", key, strlen("BaseFont")) == 0 ++ || strncmp("Encoding", key, strlen("Encoding")) == 0) ++ continue; // skip original values ++ copyDictEntry(obj, i); ++ } ++ // write new FontDescriptor, BaseFont, and Encoding ++ pdf_printf("/FontDescriptor %d 0 R\n", get_fd_objnum(r->fd)); ++ pdf_printf("/BaseFont %d 0 R\n", get_fn_objnum(r->fd)); ++ pdf_printf("/Encoding %d 0 R\n", r->enc_objnum); ++ pdf_puts(">>"); ++} ++ ++static void copyStream(Stream * str) ++{ ++ int c, c2 = 0; ++ str->reset(); ++ while ((c = str->getChar()) != EOF) { ++ pdfout(c); ++ c2 = c; ++ } ++ pdflastbyte = c2; ++} ++ ++static void copyProcSet(Object * obj) ++{ ++ int i, l; ++ Object procset; ++ if (!obj->isArray()) ++ pdftex_fail("PDF inclusion: invalid ProcSet array type <%s>", ++ obj->getTypeName()); ++ pdf_puts("/ProcSet [ "); ++ for (i = 0, l = obj->arrayGetLength(); i < l; ++i) { ++ procset = obj->arrayGetNF(i).copy(); ++ if (!procset.isName()) ++ pdftex_fail("PDF inclusion: invalid ProcSet entry type <%s>", ++ procset.getTypeName()); ++ copyName((char *)procset.getName()); ++ pdf_puts(" "); ++ } ++ pdf_puts("]\n"); ++} ++ ++#define REPLACE_TYPE1C true ++ ++static bool embeddableFont(Object * fontdesc) ++{ ++ Object fontfile, ffsubtype; ++ ++ if (!fontdesc->isDict()) ++ return false; ++ fontfile = fontdesc->dictLookup("FontFile"); ++ if (fontfile.isStream()) ++ return true; ++ if (REPLACE_TYPE1C) { ++ fontfile = fontdesc->dictLookup("FontFile3"); ++ if (!fontfile.isStream()) ++ return false; ++ ffsubtype = fontfile.streamGetDict()->lookup("Subtype"); ++ return ffsubtype.isName() && !strcmp(ffsubtype.getName(), "Type1C"); ++ } ++ return false; ++} ++ ++static void copyFont(char *tag, Object * fontRef) ++{ ++ Object fontdict, subtype, basefont, fontdescRef, fontdesc, charset, ++ stemV; ++ GfxFont *gfont; ++ fd_entry *fd; ++ fm_entry *fontmap; ++ // Check whether the font has already been embedded before analysing it. ++ InObj *p; ++ Ref ref = fontRef->getRef(); ++ for (p = inObjList; p; p = p->next) { ++ if (p->ref.num == ref.num && p->ref.gen == ref.gen) { ++ copyName(tag); ++ pdf_printf(" %d 0 R ", p->num); ++ return; ++ } ++ } ++ // Only handle included Type1 (and Type1C) fonts; anything else will be copied. ++ // Type1C fonts are replaced by Type1 fonts, if REPLACE_TYPE1C is true. ++ fontdict = fontRef->fetch(xref); ++ fontdesc = Object(objNull); ++ if (fontdict.isDict()) { ++ subtype = fontdict.dictLookup("Subtype"); ++ basefont = fontdict.dictLookup("BaseFont"); ++ fontdescRef = fontdict.dictLookupNF("FontDescriptor").copy(); ++ if (fontdescRef.isRef()) { ++ fontdesc = fontdescRef.fetch(xref); ++ } ++ } ++ if (!fixedinclusioncopyfont && fontdict.isDict() ++ && subtype.isName() ++ && !strcmp(subtype.getName(), "Type1") ++ && basefont.isName() ++ && fontdescRef.isRef() ++ && fontdesc.isDict() ++ && embeddableFont(&fontdesc) ++ && (fontmap = lookup_fontmap((char *)basefont.getName())) != NULL) { ++ // round /StemV value, since the PDF input is a float ++ // (see Font Descriptors in PDF reference), but we only store an ++ // integer, since we don't want to change the struct. ++ stemV = fontdesc.dictLookup("StemV"); ++ fd = epdf_create_fontdescriptor(fontmap, zround(stemV.getNum())); ++ charset = fontdesc.dictLookup("CharSet"); ++ if (!charset.isNull() && ++ charset.isString() && is_subsetable(fontmap)) ++ epdf_mark_glyphs(fd, (char *)charset.getString()->c_str()); ++ else ++ embed_whole_font(fd); ++ addFontDesc(fontdescRef.getRef(), fd); ++ copyName(tag); ++ gfont = GfxFont::makeFont(xref, tag, fontRef->getRef(), ++ fontdict.getDict()); ++ pdf_printf(" %d 0 R ", addFont(fontRef->getRef(), fd, ++ addEncoding(gfont))); ++ } else { ++ copyName(tag); ++ pdf_puts(" "); ++ copyObject(fontRef); ++ } ++} ++ ++static void copyFontResources(Object * obj) ++{ ++ Object fontRef; ++ int i, l; ++ if (!obj->isDict()) ++ pdftex_fail("PDF inclusion: invalid font resources dict type <%s>", ++ obj->getTypeName()); ++ pdf_puts("/Font << "); ++ for (i = 0, l = obj->dictGetLength(); i < l; ++i) { ++ fontRef = obj->dictGetValNF(i).copy(); ++ if (fontRef.isRef()) ++ copyFont((char *)obj->dictGetKey(i), &fontRef); ++ else if (fontRef.isDict()) { // some programs generate pdf with embedded font object ++ copyName((char *)obj->dictGetKey(i)); ++ pdf_puts(" "); ++ copyObject(&fontRef); ++ } ++ else ++ pdftex_fail("PDF inclusion: invalid font in reference type <%s>", ++ fontRef.getTypeName()); ++ } ++ pdf_puts(">>\n"); ++} ++ ++static void copyOtherResources(Object * obj, char *key) ++{ ++ // copies all other resources (write_epdf handles Fonts and ProcSets), ++ ++ // if Subtype is present, it must be a name ++ if (strcmp("Subtype", key) == 0) { ++ if (!obj->isName()) { ++ pdftex_warn("PDF inclusion: Subtype in Resources dict is not a name" ++ " (key '%s', type <%s>); ignored.", ++ key, obj->getTypeName()); ++ return; ++ } ++ } else if (!obj->isDict()) { ++ //FIXME: Write the message only to the log file ++ pdftex_warn("PDF inclusion: invalid other resource which is no dict" ++ " (key '%s', type <%s>); ignored.", ++ key, obj->getTypeName()); ++ return; ++ } ++ copyName(key); ++ pdf_puts(" "); ++ copyObject(obj); ++} ++ ++// Function onverts double to string; very small and very large numbers ++// are NOT converted to scientific notation. ++// n must be a number or real conforming to the implementation limits ++// of PDF as specified in appendix C.1 of the PDF Ref. ++// These are: ++// maximum value of ints is +2^32 ++// maximum value of reals is +2^15 ++// smalles values of reals is 1/(2^16) ++ ++static char *convertNumToPDF(double n) ++{ ++ static const int precision = 6; ++ static const int fact = (int) 1E6; // must be 10^precision ++ static const double epsilon = 0.5E-6; // 2epsilon must be 10^-precision ++ static char buf[64]; ++ // handle very small values: return 0 ++ if (fabs(n) < epsilon) { ++ buf[0] = '0'; ++ buf[1] = '\0'; ++ } else { ++ char ints[64]; ++ int bindex = 0, sindex = 0; ++ int ival, fval; ++ // handle the sign part if n is negative ++ if (n < 0) { ++ buf[bindex++] = '-'; ++ n = -n; ++ } ++ n += epsilon; // for rounding ++ // handle the integer part, simply with sprintf ++ ival = (int) floor(n); ++ n -= ival; ++ sprintf(ints, "%d", ival); ++ while (ints[sindex] != 0) ++ buf[bindex++] = ints[sindex++]; ++ // handle the fractional part up to 'precision' digits ++ fval = (int) floor(n * fact); ++ if (fval) { ++ // set a dot ++ buf[bindex++] = '.'; ++ sindex = bindex + precision; ++ buf[sindex--] = '\0'; ++ // fill up trailing zeros with the string terminator NULL ++ while (((fval % 10) == 0) && (sindex >= bindex)) { ++ buf[sindex--] = '\0'; ++ fval /= 10; ++ } ++ // fill up the fractional part back to front ++ while (sindex >= bindex) { ++ buf[sindex--] = (fval % 10) + '0'; ++ fval /= 10; ++ } ++ } else ++ buf[bindex++] = 0; ++ } ++ return (char *) buf; ++} ++ ++static void copyObject(Object * obj) ++{ ++ Object obj1; ++ int i, l, c; ++ Ref ref; ++ char *p; ++ GString *s; ++ if (obj->isBool()) { ++ pdf_printf("%s", obj->getBool()? "true" : "false"); ++ } else if (obj->isInt()) { ++ pdf_printf("%i", obj->getInt()); ++ } else if (obj->isReal()) { ++ pdf_printf("%s", convertNumToPDF(obj->getReal())); ++ } else if (obj->isNum()) { ++ pdf_printf("%s", convertNumToPDF(obj->getNum())); ++ } else if (obj->isString()) { ++ s = (GooString *)obj->getString(); ++ p = (char *)s->c_str(); ++ l = s->getLength(); ++ if (strlen(p) == (unsigned int) l) { ++ pdf_puts("("); ++ for (; *p != 0; p++) { ++ c = (unsigned char) *p; ++ if (c == '(' || c == ')' || c == '\\') ++ pdf_printf("\\%c", c); ++ else if (c < 0x20 || c > 0x7F) ++ pdf_printf("\\%03o", c); ++ else ++ pdfout(c); ++ } ++ pdf_puts(")"); ++ } else { ++ pdf_puts("<"); ++ for (i = 0; i < l; i++) { ++ c = s->getChar(i) & 0xFF; ++ pdf_printf("%.2x", c); ++ } ++ pdf_puts(">"); ++ } ++ } else if (obj->isName()) { ++ copyName((char *)obj->getName()); ++ } else if (obj->isNull()) { ++ pdf_puts("null"); ++ } else if (obj->isArray()) { ++ pdf_puts("["); ++ for (i = 0, l = obj->arrayGetLength(); i < l; ++i) { ++ obj1 = obj->arrayGetNF(i).copy(); ++ if (!obj1.isName()) ++ pdf_puts(" "); ++ copyObject(&obj1); ++ } ++ pdf_puts("]"); ++ } else if (obj->isDict()) { ++ pdf_puts("<<\n"); ++ copyDict(obj); ++ pdf_puts(">>"); ++ } else if (obj->isStream()) { ++ pdf_puts("<<\n"); ++ copyDict(obj->getStream()->getDictObject()); ++ pdf_puts(">>\n"); ++ pdf_puts("stream\n"); ++ copyStream(obj->getStream()->getUndecodedStream()); ++ pdf_puts("\nendstream"); ++ } else if (obj->isRef()) { ++ ref = obj->getRef(); ++ if (ref.num == 0) { ++ pdftex_fail ++ ("PDF inclusion: reference to invalid object" ++ " (is the included pdf broken?)"); ++ } else ++ pdf_printf("%d 0 R", addOther(ref)); ++ } else { ++ pdftex_fail("PDF inclusion: type <%s> cannot be copied", ++ obj->getTypeName()); ++ } ++} ++ ++static void writeRefs() ++{ ++ InObj *r; ++ for (r = inObjList; r != 0; r = r->next) { ++ if (!r->written) { ++ r->written = 1; ++ Object obj1 = xref->fetch(r->ref.num, r->ref.gen); ++ if (r->type == objFont) { ++ assert(!obj1.isStream()); ++ pdfbeginobj(r->num, 2); // \pdfobjcompresslevel = 2 is for this ++ copyFontDict(&obj1, r); ++ pdf_puts("\n"); ++ pdfendobj(); ++ } else if (r->type != objFontDesc) { // /FontDescriptor is written via write_fontdescriptor() ++ if (obj1.isStream()) ++ pdfbeginobj(r->num, 0); ++ else ++ pdfbeginobj(r->num, 2); // \pdfobjcompresslevel = 2 is for this ++ copyObject(&obj1); ++ pdf_puts("\n"); ++ pdfendobj(); ++ } ++ } ++ } ++} ++ ++static void writeEncodings() ++{ ++ UsedEncoding *r, *n; ++ char *glyphNames[256], *s; ++ int i; ++ for (r = encodingList; r != 0; r = r->next) { ++ for (i = 0; i < 256; i++) { ++ if (r->font->isCIDFont()) { ++ pdftex_fail ++ ("PDF inclusion: CID fonts are not supported" ++ " (try to disable font replacement to fix this)"); ++ } ++ if ((s = (char *)((Gfx8BitFont *) r->font)->getCharName(i)) != 0) ++ glyphNames[i] = s; ++ else ++ glyphNames[i] = notdef; ++ } ++ epdf_write_enc(glyphNames, r->enc_objnum); ++ } ++ for (r = encodingList; r != 0; r = n) { ++ n = r->next; ++#ifdef POPPLER_VERSION ++ r->font->decRefCnt(); ++#else ++#error POPPLER_VERSION should be defined. ++#endif ++ delete r; ++ } ++} ++ ++// get the pagebox according to the pagebox_spec ++static const PDFRectangle *get_pagebox(Page * page, int pagebox_spec) ++{ ++ if (pagebox_spec == pdfboxspecmedia) ++ return page->getMediaBox(); ++ else if (pagebox_spec == pdfboxspeccrop) ++ return page->getCropBox(); ++ else if (pagebox_spec == pdfboxspecbleed) ++ return page->getBleedBox(); ++ else if (pagebox_spec == pdfboxspectrim) ++ return page->getTrimBox(); ++ else if (pagebox_spec == pdfboxspecart) ++ return page->getArtBox(); ++ else ++ pdftex_fail("PDF inclusion: unknown value of pagebox spec (%i)", ++ (int) pagebox_spec); ++ return page->getMediaBox(); // to make the compiler happy ++} ++ ++ ++// Reads various information about the PDF and sets it up for later inclusion. ++// This will fail if the PDF version of the PDF is higher than ++// minor_pdf_version_wanted or page_name is given and can not be found. ++// It makes no sense to give page_name _and_ page_num. ++// Returns the page number. ++ ++int ++read_pdf_info(char *image_name, char *page_name, int page_num, ++ int pagebox_spec, int minor_pdf_version_wanted, ++ int pdf_inclusion_errorlevel) ++{ ++ PdfDocument *pdf_doc; ++ Page *page; ++ const PDFRectangle *pagebox; ++#ifdef POPPLER_VERSION ++ int pdf_major_version_found, pdf_minor_version_found; ++#else ++#error POPPLER_VERSION should be defined. ++#endif ++ // initialize ++ if (!isInit) { ++ globalParams = new GlobalParams(); ++ globalParams->setErrQuiet(false); ++ isInit = true; ++ } ++ // open PDF file ++ pdf_doc = find_add_document(image_name); ++ epdf_doc = (void *) pdf_doc; ++ ++ // check PDF version ++ // this works only for PDF 1.x -- but since any versions of PDF newer ++ // than 1.x will not be backwards compatible to PDF 1.x, pdfTeX will ++ // then have to changed drastically anyway. ++#ifdef POPPLER_VERSION ++ pdf_major_version_found = pdf_doc->doc->getPDFMajorVersion(); ++ pdf_minor_version_found = pdf_doc->doc->getPDFMinorVersion(); ++ if ((pdf_major_version_found > 1) ++ || (pdf_minor_version_found > minor_pdf_version_wanted)) { ++ const char *msg = ++ "PDF inclusion: found PDF version <%d.%d>, but at most version <1.%d> allowed"; ++ if (pdf_inclusion_errorlevel > 0) { ++ pdftex_fail(msg, pdf_major_version_found, pdf_minor_version_found, minor_pdf_version_wanted); ++ } else if (pdf_inclusion_errorlevel < 0) { ++ ; /* do nothing */ ++ } else { /* = 0, give warning */ ++ pdftex_warn(msg, pdf_major_version_found, pdf_minor_version_found, minor_pdf_version_wanted); ++ } ++ } ++#else ++#error POPPLER_VERSION should be defined. ++#endif ++ epdf_num_pages = pdf_doc->doc->getCatalog()->getNumPages(); ++ if (page_name) { ++ // get page by name ++ GString name(page_name); ++ LinkDest *link = pdf_doc->doc->findDest(&name); ++ if (link == 0 || !link->isOk()) ++ pdftex_fail("PDF inclusion: invalid destination <%s>", page_name); ++ Ref ref = link->getPageRef(); ++ page_num = pdf_doc->doc->getCatalog()->findPage(ref.num, ref.gen); ++ if (page_num == 0) ++ pdftex_fail("PDF inclusion: destination is not a page <%s>", ++ page_name); ++ delete link; ++ } else { ++ // get page by number ++ if (page_num <= 0 || page_num > epdf_num_pages) ++ pdftex_fail("PDF inclusion: required page does not exist <%i>", ++ epdf_num_pages); ++ } ++ // get the required page ++ page = pdf_doc->doc->getCatalog()->getPage(page_num); ++ ++ // get the pagebox (media, crop...) to use. ++ pagebox = get_pagebox(page, pagebox_spec); ++ if (pagebox->x2 > pagebox->x1) { ++ epdf_orig_x = pagebox->x1; ++ epdf_width = pagebox->x2 - pagebox->x1; ++ } else { ++ epdf_orig_x = pagebox->x2; ++ epdf_width = pagebox->x1 - pagebox->x2; ++ } ++ if (pagebox->y2 > pagebox->y1) { ++ epdf_orig_y = pagebox->y1; ++ epdf_height = pagebox->y2 - pagebox->y1; ++ } else { ++ epdf_orig_y = pagebox->y2; ++ epdf_height = pagebox->y1 - pagebox->y2; ++ } ++ ++ // get page rotation ++ epdf_rotate = page->getRotate() % 360; ++ if (epdf_rotate < 0) ++ epdf_rotate += 360; ++ ++ // page group ++ if (page->getGroup() != NULL) ++ epdf_has_page_group = 1; // only flag that page group is present; ++ // the actual object number will be ++ // generated in pdftex.web ++ else ++ epdf_has_page_group = 0; // no page group present ++ ++ pdf_doc->xref = pdf_doc->doc->getXRef(); ++ return page_num; ++} ++ ++// writes the current epf_doc. ++// Here the included PDF is copied, so most errors that can happen during PDF ++// inclusion will arise here. ++ ++void write_epdf(void) ++{ ++ Page *page; ++ Ref *pageRef; ++ Dict *pageDict; ++ Object contents, obj1, obj2, pageObj, dictObj; ++ Object groupDict; ++ bool writeSepGroup = false; ++ Object info; ++ char *key; ++ char s[256]; ++ int i, l; ++ int rotate; ++ double scale[6] = { 0, 0, 0, 0, 0, 0 }; ++ bool writematrix = false; ++ int suppress_ptex_info = getpdfsuppressptexinfo(); ++ static const char *pageDictKeys[] = { ++ "LastModified", ++ "Metadata", ++ "PieceInfo", ++ "SeparationInfo", ++// "Group", ++// "Resources", ++ NULL ++ }; ++ ++ PdfDocument *pdf_doc = (PdfDocument *) epdf_doc; ++ (pdf_doc->occurences)--; ++ xref = pdf_doc->xref; ++ inObjList = pdf_doc->inObjList; ++ encodingList = 0; ++ page = pdf_doc->doc->getCatalog()->getPage(epdf_selected_page); ++ pageRef = pdf_doc->doc->getCatalog()->getPageRef(epdf_selected_page); ++ pageObj = xref->fetch(pageRef->num, pageRef->gen); ++ pageDict = pageObj.getDict(); ++ rotate = page->getRotate(); ++ const PDFRectangle *pagebox; ++ // write the Page header ++ pdf_puts("/Type /XObject\n"); ++ pdf_puts("/Subtype /Form\n"); ++ pdf_puts("/FormType 1\n"); ++ ++ // write additional information ++ if ((suppress_ptex_info & MASK_SUPPRESS_PTEX_FILENAME) == 0) { ++ pdf_printf("/%s.FileName (%s)\n", pdfkeyprefix, ++ convertStringToPDFString(pdf_doc->file_name, ++ strlen(pdf_doc->file_name))); ++ } ++ if ((suppress_ptex_info & MASK_SUPPRESS_PTEX_PAGENUMBER) == 0) { ++ pdf_printf("/%s.PageNumber %i\n", pdfkeyprefix, (int) epdf_selected_page); ++ } ++ if ((suppress_ptex_info & MASK_SUPPRESS_PTEX_INFODICT) == 0) { ++ info = pdf_doc->doc->getDocInfoNF(); ++ if (info.isRef()) { ++ // the info dict must be indirect (PDF Ref p. 61) ++ pdf_printf("/%s.InfoDict ", pdfkeyprefix); ++ pdf_printf("%d 0 R\n", addOther(info.getRef())); ++ } ++ } ++ // get the pagebox (media, crop...) to use. ++ pagebox = get_pagebox(page, epdf_page_box); ++ ++ // handle page rotation ++ if (rotate != 0) { ++ if (rotate % 90 == 0) { ++ // this handles only the simple case: multiple of 90s but these ++ // are the only values allowed according to the reference ++ // (v1.3, p. 78). ++ // the image is rotated around its center. ++ // the /Rotate key is clockwise while the matrix is ++ // counterclockwise :-% ++ tex_printf(", page is rotated %d degrees", rotate); ++ switch (rotate) { ++ case 90: ++ scale[1] = -1; ++ scale[2] = 1; ++ scale[4] = pagebox->x1 - pagebox->y1; ++ scale[5] = pagebox->y1 + pagebox->x2; ++ writematrix = true; ++ break; ++ case 180: ++ scale[0] = scale[3] = -1; ++ scale[4] = pagebox->x1 + pagebox->x2; ++ scale[5] = pagebox->y1 + pagebox->y2; ++ writematrix = true; ++ break; // width and height are exchanged ++ case 270: ++ scale[1] = 1; ++ scale[2] = -1; ++ scale[4] = pagebox->x1 + pagebox->y2; ++ scale[5] = pagebox->y1 - pagebox->x1; ++ writematrix = true; ++ break; ++ } ++ if (writematrix) { // The matrix is only written if the image is rotated. ++ sprintf(s, "/Matrix [%.8f %.8f %.8f %.8f %.8f %.8f]\n", ++ scale[0], ++ scale[1], scale[2], scale[3], scale[4], scale[5]); ++ pdf_puts(stripzeros(s)); ++ } ++ } ++ } ++ ++ sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", ++ pagebox->x1, pagebox->y1, pagebox->x2, pagebox->y2); ++ pdf_puts(stripzeros(s)); ++ ++ // Metadata validity check (as a stream it must be indirect) ++ dictObj = pageDict->lookupNF("Metadata").copy(); ++ if (!dictObj.isNull() && !dictObj.isRef()) ++ pdftex_warn("PDF inclusion: /Metadata must be indirect object"); ++ ++ // copy selected items in Page dictionary except Resources & Group ++ for (i = 0; pageDictKeys[i] != NULL; i++) { ++ dictObj = pageDict->lookupNF(pageDictKeys[i]).copy(); ++ if (!dictObj.isNull()) { ++ pdf_newline(); ++ pdf_printf("/%s ", pageDictKeys[i]); ++ copyObject(&dictObj); // preserves indirection ++ } ++ } ++ ++ // handle page group ++ dictObj = pageDict->lookupNF("Group").copy(); ++ if (!dictObj.isNull()) { ++ if (pdfpagegroupval == 0) { ++ // another pdf with page group was included earlier on the ++ // same page; copy the Group entry as is. See manual for ++ // info on why this is a warning. ++ if (getpdfsuppresswarningpagegroup() == 0) { ++ pdftex_warn ++ ("PDF inclusion: multiple pdfs with page group included in a single page"); ++ } ++ pdf_newline(); ++ pdf_puts("/Group "); ++ copyObject(&dictObj); ++ } else { ++ // write Group dict as a separate object, since the Page dict also refers to it ++ dictObj = pageDict->lookup("Group"); ++ if (!dictObj.isDict()) ++ pdftex_fail("PDF inclusion: /Group dict missing"); ++ writeSepGroup = true; ++/* ++This part is only a single line ++ groupDict = Object(page->getGroup()); ++in the original patch. In this case, however, pdftex crashes at ++"delete pdf_doc->doc" in "delete_document()" for inclusion of some ++kind of pdf images, for example, figure_missing.pdf in gnuplot. ++A change ++ groupDict = Object(page->getGroup()).copy(); ++does not improve the situation. ++The changes below seem to work fine. ++*/ ++// begin modification ++ groupDict = pageDict->lookup("Group"); ++ const Dict& dic1 = page->getGroup(); ++ const Dict& dic2 = groupDict.getDict(); ++ // replace dic2 in groupDict with dic1 ++ l = dic2.getLength(); ++ for (i = 0; i < l; i++) { ++ groupDict.dictRemove(dic2.getKey(i)); ++ } ++ l = dic1.getLength(); ++ for (i = 0; i < l; i++) { ++ groupDict.dictAdd((const char *)copyString(dic1.getKey(i)), ++ dic1.getValNF(i).copy()); ++ } ++// end modification ++ pdf_printf("/Group %ld 0 R\n", (long)pdfpagegroupval); ++ } ++ } ++ ++ // write the Resources dictionary ++ if (page->getResourceDict() == NULL) { ++ // Resources can be missing (files without them have been spotted ++ // in the wild); in which case the /Resouces of the /Page will be used. ++ // "This practice is not recommended". ++ pdftex_warn ++ ("PDF inclusion: /Resources missing. 'This practice is not recommended' (PDF Ref)"); ++ } else { ++ Object *obj1 = page->getResourceDictObject(); ++ if (!obj1->isDict()) ++ pdftex_fail("PDF inclusion: invalid resources dict type <%s>", ++ obj1->getTypeName()); ++ pdf_newline(); ++ pdf_puts("/Resources <<\n"); ++ for (i = 0, l = obj1->dictGetLength(); i < l; ++i) { ++ obj2 = obj1->dictGetVal(i); ++ key = (char *)obj1->dictGetKey(i); ++ if (strcmp("Font", key) == 0) ++ copyFontResources(&obj2); ++ else if (strcmp("ProcSet", key) == 0) ++ copyProcSet(&obj2); ++ else ++ copyOtherResources(&obj2, (char *)key); ++ } ++ pdf_puts(">>\n"); ++ } ++ ++ // write the page contents ++ contents = page->getContents(); ++ if (contents.isStream()) { ++ ++ // Variant A: get stream and recompress under control ++ // of \pdfcompresslevel ++ // ++ // pdfbeginstream(); ++ // copyStream(contents->getStream()); ++ // pdfendstream(); ++ ++ // Variant B: copy stream without recompressing ++ // ++ obj1 = contents.streamGetDict()->lookup("F"); ++ if (!obj1.isNull()) { ++ pdftex_fail("PDF inclusion: Unsupported external stream"); ++ } ++ obj1 = contents.streamGetDict()->lookup("Length"); ++ assert(!obj1.isNull()); ++ pdf_puts("/Length "); ++ copyObject(&obj1); ++ pdf_puts("\n"); ++ obj1 = contents.streamGetDict()->lookup("Filter"); ++ if (!obj1.isNull()) { ++ pdf_puts("/Filter "); ++ copyObject(&obj1); ++ pdf_puts("\n"); ++ obj1 = contents.streamGetDict()->lookup("DecodeParms"); ++ if (!obj1.isNull()) { ++ pdf_puts("/DecodeParms "); ++ copyObject(&obj1); ++ pdf_puts("\n"); ++ } ++ } ++ pdf_puts(">>\nstream\n"); ++ copyStream(contents.getStream()->getUndecodedStream()); ++ pdfendstream(); ++ } else if (contents.isArray()) { ++ pdfbeginstream(); ++ for (i = 0, l = contents.arrayGetLength(); i < l; ++i) { ++ Object contentsobj = contents.arrayGet(i); ++ copyStream(contentsobj.getStream()); ++ if (i < l - 1) ++ pdf_newline(); // add a newline after each stream except the last ++ } ++ pdfendstream(); ++ } else { // the contents are optional, but we need to include an empty stream ++ pdfbeginstream(); ++ pdfendstream(); ++ } ++ ++ // write out all indirect objects ++ writeRefs(); ++ ++ // write out all used encodings (and delete list) ++ writeEncodings(); ++ ++ // write the Group dict if needed ++ if (writeSepGroup) { ++ pdfbeginobj(pdfpagegroupval, 2); ++ copyObject(&groupDict); ++ pdf_puts("\n"); ++ pdfendobj(); ++ pdfpagegroupval = 0; // only the 1st included pdf on a page gets its ++ // Group included in the Page dict ++ } ++ ++ // save object list, xref ++ pdf_doc->inObjList = inObjList; ++ pdf_doc->xref = xref; ++} ++ ++// Called when an image has been written and it's resources in image_tab are ++// freed and it's not referenced anymore. ++ ++void epdf_delete() ++{ ++ PdfDocument *pdf_doc = (PdfDocument *) epdf_doc; ++ xref = pdf_doc->xref; ++ if (pdf_doc->occurences < 0) { ++ delete_document(pdf_doc); ++ } ++} ++ ++// Called when PDF embedding system is finalized. ++// Now deallocate all remaining PdfDocuments. ++ ++void epdf_check_mem() ++{ ++ if (isInit) { ++ PdfDocument *p, *n; ++ for (p = pdfDocuments; p; p = n) { ++ n = p->next; ++ delete_document(p); ++ } ++ // see above for globalParams ++ delete globalParams; ++ } ++} +diff --git a/texk/web2c/pdftexdir/pdftosrc-poppler0.75.0.cc b/texk/web2c/pdftexdir/pdftosrc-poppler0.75.0.cc +new file mode 100644 +index 000000000..6089e68d9 +--- /dev/null ++++ b/texk/web2c/pdftexdir/pdftosrc-poppler0.72.0.cc +@@ -0,0 +1,207 @@ ++/* ++Copyright 1996-2017 Han The Thanh, <th...@pdftex.org> ++ ++This file is part of pdfTeX. ++ ++pdfTeX is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2 of the License, or ++(at your option) any later version. ++ ++pdfTeX is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License along ++with this program. If not, see <http://www.gnu.org/licenses/>. ++*/ ++ ++/* ++This is based on the patch texlive-poppler-0.59.patch <2017-09-19> at ++https://git.archlinux.org/svntogit/packages.git/plain/texlive-bin/trunk ++by Arch Linux. The poppler should be 0.72.0 or newer versions. ++POPPLER_VERSION should be defined. ++*/ ++ ++#include <w2c/config.h> ++ ++#include <stdlib.h> ++#include <stddef.h> ++#include <stdio.h> ++#include <string.h> ++#include <ctype.h> ++ ++#ifdef POPPLER_VERSION ++#define GString GooString ++#define xpdfVersion POPPLER_VERSION ++#include <dirent.h> ++#include <goo/GooString.h> ++#include <goo/gmem.h> ++#include <goo/gfile.h> ++#else ++#error POPPLER_VERSION should be defined. ++#endif ++#include <assert.h> ++ ++#include "Object.h" ++#include "Stream.h" ++#include "Lexer.h" ++#include "Parser.h" ++#include "Array.h" ++#include "Dict.h" ++#include "XRef.h" ++#include "Catalog.h" ++#include "Page.h" ++#include "GfxFont.h" ++#include "PDFDoc.h" ++#include "GlobalParams.h" ++#include "Error.h" ++ ++static XRef *xref = 0; ++ ++int main(int argc, char *argv[]) ++{ ++ char *p, buf[1024]; ++ PDFDoc *doc; ++ GString *fileName; ++ Stream *s; ++ Object srcStream, srcName, catalogDict; ++ FILE *outfile; ++ char *outname; ++ int objnum = 0, objgen = 0; ++ bool extract_xref_table = false; ++ int c; ++ fprintf(stderr, "pdftosrc version %s\n", xpdfVersion); ++ if (argc < 2) { ++ fprintf(stderr, ++ "Usage: pdftosrc <PDF-file> [<stream-object-number>]\n"); ++ exit(1); ++ } ++ fileName = new GString(argv[1]); ++ globalParams = new GlobalParams(); ++ doc = new PDFDoc(fileName); ++ if (!doc->isOk()) { ++ fprintf(stderr, "Invalid PDF file\n"); ++ exit(1); ++ } ++ if (argc >= 3) { ++ objnum = atoi(argv[2]); ++ if (argc >= 4) ++ objgen = atoi(argv[3]); ++ } ++ xref = doc->getXRef(); ++ catalogDict = xref->getCatalog(); ++ if (!catalogDict.isDict("Catalog")) { ++ fprintf(stderr, "No Catalog found\n"); ++ exit(1); ++ } ++ srcStream = Object(objNull); ++ if (objnum == 0) { ++ srcStream = catalogDict.dictLookup("SourceObject"); ++ static char const_SourceFile[] = "SourceFile"; ++ if (!srcStream.isStream(const_SourceFile)) { ++ fprintf(stderr, "No SourceObject found\n"); ++ exit(1); ++ } ++ srcName = srcStream.getStream()->getDict()->lookup("SourceName"); ++ if (!srcName.isString()) { ++ fprintf(stderr, "No SourceName found\n"); ++ exit(1); ++ } ++ outname = (char *)srcName.getString()->c_str(); ++ // We cannot free srcName, as objname shares its string. ++ // srcName.free(); ++ } else if (objnum > 0) { ++ srcStream = xref->fetch(objnum, objgen); ++ if (!srcStream.isStream()) { ++ fprintf(stderr, "Not a Stream object\n"); ++ exit(1); ++ } ++ sprintf(buf, "%s", fileName->c_str()); ++ if ((p = strrchr(buf, '.')) == 0) ++ p = strchr(buf, 0); ++ if (objgen == 0) ++ sprintf(p, ".%i", objnum); ++ else ++ sprintf(p, ".%i+%i", objnum, objgen); ++ outname = buf; ++ } else { // objnum < 0 means we are extracting the XRef table ++ extract_xref_table = true; ++ sprintf(buf, "%s", fileName->c_str()); ++ if ((p = strrchr(buf, '.')) == 0) ++ p = strchr(buf, 0); ++ sprintf(p, ".xref"); ++ outname = buf; ++ } ++ if (!(outfile = fopen(outname, "wb"))) { ++ fprintf(stderr, "Cannot open file \"%s\" for writing\n", outname); ++ exit(1); ++ } ++ if (extract_xref_table) { ++ int size = xref->getNumObjects(); ++ int i; ++ for (i = 0; i < size; i++) { ++ if (xref->getEntry(i)->offset == 0xffffffff) ++ break; ++ } ++ size = i; ++ fprintf(outfile, "xref\n"); ++ fprintf(outfile, "0 %i\n", size); ++ for (i = 0; i < size; i++) { ++ XRefEntry *e = xref->getEntry(i); ++ if (e->type != xrefEntryCompressed) ++ fprintf(outfile, "%.10lu %.5i %s\n", ++ (long unsigned) e->offset, e->gen, ++ (e->type == xrefEntryFree ? "f" : "n")); ++ else { // e->offset is the object number of the object stream ++ Stream *str; ++ Lexer *lexer; ++ Parser *parser; ++ Object objStr, obj1, obj2; ++ int nObjects, first, n; ++ int localOffset = 0; ++ unsigned int firstOffset; ++ ++ objStr = xref->fetch(e->offset, 0); ++ assert(objStr.isStream()); ++ obj1 = objStr.streamGetDict()->lookup("N"); ++ nObjects = obj1.getInt(); ++ obj1 = objStr.streamGetDict()->lookup("First"); ++ first = obj1.getInt(); ++ firstOffset = objStr.getStream()->getBaseStream()->getStart() + first; ++ ++ // parse the header: object numbers and offsets ++ objStr.streamReset(); ++ str = new EmbedStream(objStr.getStream(), Object(objNull), true, first); ++ lexer = new Lexer(xref, str); ++ parser = new Parser(xref, lexer, false); ++ for (n = 0; n < nObjects; ++n) { ++ obj1 = parser->getObj(); ++ obj2 = parser->getObj(); ++ if (n == e->gen) ++ localOffset = obj2.getInt(); ++ } ++ while (str->getChar() != EOF) ; ++ delete parser; ++ ++ fprintf(outfile, "%.10lu 00000 n\n", ++ (long unsigned)(firstOffset + localOffset)); ++ } ++ } ++ } else { ++ s = srcStream.getStream(); ++ s->reset(); ++ while ((c = s->getChar()) != EOF) ++ fputc(c, outfile); ++ } ++ if (objnum == 0) ++ fprintf(stderr, "Source file extracted to %s\n", outname); ++ else if (objnum > 0) ++ fprintf(stderr, "Stream object extracted to %s\n", outname); ++ else ++ fprintf(stderr, "Cross-reference table extracted to %s\n", outname); ++ fclose(outfile); ++ delete doc; ++ delete globalParams; ++} Copied: texlive-bin/repos/staging-x86_64/synctex-missing-header.patch (from rev 348877, texlive-bin/trunk/synctex-missing-header.patch) =================================================================== --- staging-x86_64/synctex-missing-header.patch (rev 0) +++ staging-x86_64/synctex-missing-header.patch 2019-03-22 19:39:34 UTC (rev 348878) @@ -0,0 +1,12 @@ +--- source.orig/texk/web2c/synctexdir/am/synctex.am 2016-05-08 19:08:26.231570952 +0200 ++++ source/texk/web2c/synctexdir/am/synctex.am 2018-05-27 00:14:26.011125669 +0200 +@@ -55,7 +55,8 @@ + if SYNCTEX + syncinclude_HEADERS = \ + synctexdir/synctex_parser.h \ +- synctexdir/synctex_parser_utils.h ++ synctexdir/synctex_parser_utils.h \ ++ synctexdir/synctex_version.h + + pkgconfig_DATA = synctexdir/synctex.pc + endif SYNCTEX Copied: texlive-bin/repos/staging-x86_64/xetex-poppler-fixes.patch (from rev 348877, texlive-bin/trunk/xetex-poppler-fixes.patch) =================================================================== --- staging-x86_64/xetex-poppler-fixes.patch (rev 0) +++ staging-x86_64/xetex-poppler-fixes.patch 2019-03-22 19:39:34 UTC (rev 348878) @@ -0,0 +1,40 @@ +From 729755bcb60695221cb368202822fc3181197ef7 Mon Sep 17 00:00:00 2001 +From: Akira Kakuto <kak...@fuk.kindai.ac.jp> +Date: Mon, 22 Oct 2018 04:01:42 +0000 +Subject: [PATCH] cast types to support new poppler + +git-svn-id: svn://tug.org/texlive/trunk/Build/source@48969 c570f23f-e606-0410-a88d-b1316a301751 +--- + texk/web2c/xetexdir/ChangeLog | 4 ++++ + texk/web2c/xetexdir/pdfimage.cpp | 10 +++++----- + 2 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/texk/web2c/xetexdir/pdfimage.cpp b/texk/web2c/xetexdir/pdfimage.cpp +index fc3e32693..8a38f1ee5 100644 +--- a/texk/web2c/xetexdir/pdfimage.cpp ++++ b/texk/web2c/xetexdir/pdfimage.cpp +@@ -82,19 +82,19 @@ pdf_get_rect(char* filename, int page_num, int pdf_box, realrect* box) + switch (pdf_box) { + default: + case pdfbox_crop: +- r = page->getCropBox(); ++ r = (PDFRectangle *)page->getCropBox(); + break; + case pdfbox_media: +- r = page->getMediaBox(); ++ r = (PDFRectangle *)page->getMediaBox(); + break; + case pdfbox_bleed: +- r = page->getBleedBox(); ++ r = (PDFRectangle *)page->getBleedBox(); + break; + case pdfbox_trim: +- r = page->getTrimBox(); ++ r = (PDFRectangle *)page->getTrimBox(); + break; + case pdfbox_art: +- r = page->getArtBox(); ++ r = (PDFRectangle *)page->getArtBox(); + break; + } +