From 22bd6a890a64cdf241564cd23404dc33c90653de Mon Sep 17 00:00:00 2001 From: blue-devil Date: Wed, 3 Jun 2020 02:12:19 +0300 Subject: [PATCH] texlive-bin updated --- editor/tex/texlive-bin/actions.py | 158 + .../texlive-bin/files/09-texlive-fonts.conf | 8 + .../files/arch/fix-fontforge-encoding.patch | 12 + .../files/arch/pdftex-poppler0.76.patch | 1411 ++++++ .../texlive-bin/files/arch/poppler-0.26.patch | 104 + ...ive-20190410-source-upstream_fixes-1.patch | 4096 +++++++++++++++++ .../files/arch/texlive-poppler-0.83.patch | 46 + .../files/arch/texlive-poppler-0.84.patch | 44 + .../files/arch/texlive-poppler-0.86.patch | 11 + .../files/fix-fontforge-encoding.patch | 12 + .../luatex-r4449-radical-rule-thickness.patch | 23 + .../tex/texlive-bin/files/poppler-0.20.patch | 22 + editor/tex/texlive-bin/files/texmf.cnf | 724 +++ editor/tex/texlive-bin/pspec.xml | 129 + editor/tex/texlive-bin/translations.xml | 15 + 15 files changed, 6815 insertions(+) create mode 100644 editor/tex/texlive-bin/actions.py create mode 100644 editor/tex/texlive-bin/files/09-texlive-fonts.conf create mode 100644 editor/tex/texlive-bin/files/arch/fix-fontforge-encoding.patch create mode 100644 editor/tex/texlive-bin/files/arch/pdftex-poppler0.76.patch create mode 100644 editor/tex/texlive-bin/files/arch/poppler-0.26.patch create mode 100644 editor/tex/texlive-bin/files/arch/texlive-20190410-source-upstream_fixes-1.patch create mode 100644 editor/tex/texlive-bin/files/arch/texlive-poppler-0.83.patch create mode 100644 editor/tex/texlive-bin/files/arch/texlive-poppler-0.84.patch create mode 100644 editor/tex/texlive-bin/files/arch/texlive-poppler-0.86.patch create mode 100644 editor/tex/texlive-bin/files/fix-fontforge-encoding.patch create mode 100644 editor/tex/texlive-bin/files/luatex-r4449-radical-rule-thickness.patch create mode 100644 editor/tex/texlive-bin/files/poppler-0.20.patch create mode 100644 editor/tex/texlive-bin/files/texmf.cnf create mode 100644 editor/tex/texlive-bin/pspec.xml create mode 100644 editor/tex/texlive-bin/translations.xml diff --git a/editor/tex/texlive-bin/actions.py b/editor/tex/texlive-bin/actions.py new file mode 100644 index 0000000000..a42005c5a9 --- /dev/null +++ b/editor/tex/texlive-bin/actions.py @@ -0,0 +1,158 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Licensed under the GNU General Public License, version 3. +# See the file http://www.gnu.org/licenses/gpl.txt + +from pisi.actionsapi import get +from pisi.actionsapi import libtools +from pisi.actionsapi import autotools +from pisi.actionsapi import pisitools +from pisi.actionsapi import shelltools +from pisi.actionsapi import texlivemodules + +import os + +WorkDir = "." +buildDir = 'texlive-20200406-source/build' + +def setup(): + shelltools.makedirs(buildDir) + shelltools.cd(buildDir) + shelltools.sym("../configure", "configure") + autotools.configure("--with-x \ + --enable-ipc \ + --prefix=/usr \ + --disable-xindy \ + --enable-shared \ + --disable-luatex \ + --disable-static \ + --with-system-gd \ + --sysconfdir=/etc \ + --bindir=/usr/bin \ + --disable-psutils \ + --disable-t1utils \ + --disable-dvisvgm \ + --with-system-zlib \ + --with-system-t1lib \ + --datadir=/usr/share \ + --with-system-pnglib \ + --with-system-ncurses \ + --without-system-xpdf \ + --with-system-harfbuzz \ + --mandir=/usr/share/man \ + --disable-multiplatform \ + --with-system-graphite2 \ + --with-system-freetype2 \ + --datarootdir=/usr/share \ + --with-banner-add=/PisiLinux \ + --disable-native-texlive-build ") + +def build(): + shelltools.cd(buildDir) + autotools.make() + +def install(): + shelltools.cd(buildDir) + autotools.rawInstall("prefix=/usr DESTDIR=%s" % get.installDIR()) + shelltools.system("pwd") + #install biber + pisitools.dobin("../../biber-2.14/bin/biber") + + #pisitools.dodir("/usr/share/tlpkg/TeXLive") + #shelltools.move("%s/source/utils/biber/TeXLive/*.pm" % get.workDIR(), "%s/usr/share/tlpkg/TeXLive" % get.installDIR()) + + # remove aleph from fmtutil.cnf + pisitools.dosed("%s/usr/share/texmf-dist/web2c/fmtutil.cnf" % get.installDIR(), "^.*aleph.*$") + + pisitools.insinto("/etc/texmf/texconfig", "%s/usr/share/texmf-dist/texconfig/tcfmgr.map" % get.installDIR(), sym=True) + + # fix symlinks, some are incorrect + # makefile patching is another way, but there ar/dvipdfmx.cfge lot of scripts + # pathing each makefile makes it much harder, for now this is a "simpler" solution + for binary in shelltools.ls(get.installDIR() + "/usr/bin"): + real_path = shelltools.realPath(get.installDIR() + "/usr/bin/" + binary) + if "texmf" in real_path and not os.path.exists(real_path): # modify only if it is broken + base_path = real_path.replace(get.installDIR() + "/usr", "") + new_path = "/usr/share" + base_path + shelltools.unlink(get.installDIR() + "/usr/bin/" + binary) + pisitools.dosym(new_path, "/usr/bin/" + binary) + + + bibtexextra_scripts=["bibexport", "listbib" ,"multibibliography", "urlbst"] + + core_scripts=["a2ping","a5toa4", "adhocfilelist", "afm2afm", "allcm", "allec", "allneeded", "arara","arlatex" + ,"autoinst", "bundledoc", "checkcites", "chkweb", "context", "ctanify", "ctanupload", "ctxtools", "de-macro", "deweb" + ,"dosepsbin", "dtxgen", "dvi2fax", "dviasm", "dvired", "e2pall", "epstopdf", "findhyph", "fmtutil", "fmtutil-sys" + ,"fontinst", "fragmaster", "installfont-tl", "kpsepath", "kpsetool", "kpsewhere", "kpsexpand", "latex2man", "latexdiff" + ,"latexdiff-vc", "latexfileversion", "latexmk", "latexpand", "latexrevise", "listings-ext.sh", "ltxfileinfo", "lua2dox_filter" + ,"luaotfload-tool", "luatools", "match_parens", "mf2pt1", "mkjobtexmf", "mkluatexfontdb", "mkt1font", "mktexfmt", "mptopdf" + ,"mtxrun", "ot2kpx", "pdf180", "pdf270", "pdf90", "pdfatfi", "pdfbook", "pdfcrop", "pdfflip", "pdfjam", "pdfjam-pocketmod" + ,"pdfjam-slides3up", "pdfjam-slides6up", "pdfjoin", "pdfnup", "pdfpun", "pfarrei", "pkfix", "pkfix-helper", "ps2eps", "ps2frag" + ,"pslatex", "pstopdf", "purifyeps", "repstopdf", "rpdfcrop", "rungs", "simpdftex", "sty2dtx", "texconfig", "texconfig-dialog" + ,"texconfig-sys", "texcount", "texdef", "texdiff", "texdirflatten", "texdoc", "texdoctk", "texexec", "texindy", "texlinks" + ,"texliveonfly", "texloganalyser", "texmfstart", "thumbpdf", "typeoutfileinfo", "updmap", "updmap-sys", "vpl2ovp", "vpl2vpl", "xindy"] + + htmlxml_scripts=["ht", "htcontext", "htlatex", "htmex", "httex", "httexi", "htxelatex", "htxetex", "mk4ht"] + + langcyrillic_scripts=["rubibtex", "rumakeindex"] + + langcjk_scripts=["convbkmk", "ptex2pdf", "kanji-fontmap-creator", "kanji-config-updmap", "kanji-config-updmap-sys"] + + langextra_scripts=["ebong"] + + langgreek_scripts=["mkgrkindex"] + + latexextra_scripts=["authorindex", "exceltex", "makeglossaries", "pdfannotextractor", "perltex", "ps4pdf", "splitindex" ,"svn-multi", "vpe"] + + music_scripts=["m-tx", "musixtex", "musixflx", "pmx2pdf"] + + pictures_scripts=["cachepic", "epspdf", "epspdftk", "fig4latex", "mathspic"] + + pstricks_scripts=["pedigree", "pst2pdf"] + + science_scripts=["ulqda"] + + # remove unneeded files and symlinks + dirs = [] + for g in [bibtexextra_scripts, core_scripts, htmlxml_scripts, \ + langcjk_scripts, langcyrillic_scripts, langextra_scripts, \ + langgreek_scripts, latexextra_scripts, music_scripts, \ + pictures_scripts, pstricks_scripts, science_scripts, \ + ["tlmgr"]]: + for s in g: + if shelltools.isLink("%s/usr/bin/%s" % (get.installDIR(), s)): + realpath = shelltools.realPath("%s/usr/bin/%s" % (get.installDIR(), s)) + dirname = shelltools.dirName(realpath) + if not dirname in dirs: dirs.append(dirname) + if not dirname == "%s/usr/bin" % get.installDIR(): + if shelltools.isFile(realpath): shelltools.unlink(realpath) + pisitools.remove("/usr/bin/%s" % s) + + # remove empty dirs + while dirs: + tmpdirs = dirs[:] + for d in tmpdirs: + if not shelltools.ls(d): + shelltools.unlinkDir(d) + dirname = shelltools.dirName(d) + if not dirname in dirs: dirs.append(dirname) + dirs.remove(d) + + pdftexsymlinks=["amstex", "cslatex", "csplain", "eplain", "etex", "jadetex", "latex", "mex", "mllatex", "mltex" + ,"pdfetex", "pdfcslatex", "pdfcsplain", "pdfjadetex", "pdflatex", "pdfmex", "pdfxmltex", "texsis", "utf8mex", "xmltex"] + + for symlink in pdftexsymlinks: + pisitools.dosym("pdftex", "/usr/bin/%s" % symlink) + + luatexsymlinks=["dvilualatex", "dviluatex", "lualatex"] + + for symlink in luatexsymlinks: + pisitools.dosym("pdftex", "/usr/bin/%s" % symlink) + + + pisitools.dosym("eptex", "/usr/bin/platex") + pisitools.dosym("euptex", "/usr/bin/uplatex") + pisitools.dosym("xetex", "/usr/bin/xelatex") + + pisitools.removeDir("/usr/share/texmf-dist") diff --git a/editor/tex/texlive-bin/files/09-texlive-fonts.conf b/editor/tex/texlive-bin/files/09-texlive-fonts.conf new file mode 100644 index 0000000000..e0b23738a5 --- /dev/null +++ b/editor/tex/texlive-bin/files/09-texlive-fonts.conf @@ -0,0 +1,8 @@ + + + + /usr/share/texmf-dist/fonts/opentype + /usr/share/texmf-dist/fonts/truetype + /usr/local/share/texmf/fonts/opentype + /usr/local/share/texmf/fonts/truetype + \ No newline at end of file diff --git a/editor/tex/texlive-bin/files/arch/fix-fontforge-encoding.patch b/editor/tex/texlive-bin/files/arch/fix-fontforge-encoding.patch new file mode 100644 index 0000000000..7a77886b3f --- /dev/null +++ b/editor/tex/texlive-bin/files/arch/fix-fontforge-encoding.patch @@ -0,0 +1,12 @@ +--- source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/noprefs.c.orig 2009-09-30 19:27:00.935039526 +0200 ++++ source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/noprefs.c 2009-09-30 19:28:04.908364646 +0200 +@@ -495,6 +495,9 @@ + { "Big5HKSCS", e_big5hkscs }, + { "Big5-HKSCS", e_big5hkscs }, + { "UTF-8", e_utf8 }, ++ { "utf-8", e_utf8 }, ++ { "UTF8", e_utf8 }, ++ { "utf8", e_utf8 }, + { "ISO-10646/UTF-8", e_utf8 }, + { "ISO_10646/UTF-8", e_utf8 }, + { "UCS2", e_unicode }, diff --git a/editor/tex/texlive-bin/files/arch/pdftex-poppler0.76.patch b/editor/tex/texlive-bin/files/arch/pdftex-poppler0.76.patch new file mode 100644 index 0000000000..784fe0c93f --- /dev/null +++ b/editor/tex/texlive-bin/files/arch/pdftex-poppler0.76.patch @@ -0,0 +1,1411 @@ +commit 473d82b2e33621d51f5c961baf8b42cdb4c955eb +Author: Akira Kakuto +Date: Fri May 3 04:05:07 2019 +0000 + + support system poppler 0.76.[01] + + git-svn-id: svn://tug.org/texlive/trunk/Build/source@50960 c570f23f-e606-0410-a88d-b1316a301751 + +diff --git a/texk/web2c/pdftexdir/ChangeLog b/texk/web2c/pdftexdir/ChangeLog +index 8af394342..0a43b927c 100644 +--- a/texk/web2c/pdftexdir/ChangeLog ++++ b/texk/web2c/pdftexdir/ChangeLog +@@ -1,3 +1,8 @@ ++2019-05-03 Akira Kakuto ++ ++ * pdftosrc-poppler0.76.0.cc, pdftoepdf-poppler0.76.0.cc: ++ Added to support system poppler 0.76.[01]. ++ + 2019-04-07 Karl Berry + + * TeX Live 2019. +diff --git a/texk/web2c/pdftexdir/NEWS b/texk/web2c/pdftexdir/NEWS +index c21898395..ddc933be4 100644 +--- a/texk/web2c/pdftexdir/NEWS ++++ b/texk/web2c/pdftexdir/NEWS +@@ -28,13 +28,15 @@ pdfTeX 3.14159265-2.6-1.40.19 (TeX Live 2018) (April 14, 2018) + Provide new files: + pdftosrc-newpoppler.cc for poppler-0.59.0 upto poppler-0.70.1. + pdftosrc-poppler0.71.0 for poppler-0.71.0. +- pdftosrc-poppler0.72.0 for poppler-0.72.0 and newer. ++ pdftosrc-poppler0.72.0 for poppler-0.72.0 upto poppler-0.75.0. ++ pdftosrc-poppler0.76.0 for poppler-0.76.0 and newer. + pdftoepdf-poppler0.68.0.cc for poppler-0.59.0 upto poppler-0.68.0. + pdftoepdf-poppler0.69.0.cc for poppler-0.69.0. + pdftoepdf-poppler0.70.0.cc for poppler-0.70.0 and poppler-0.70.1. + pdftoepdf-poppler0.71.0.cc for poppler-0.71.0. + pdftoepdf-poppler0.72.0.cc for poppler-0.72.0 upto poppler-0.74.0. +- pdftoepdf-poppler0.75.0.cc for poppler-0.75.0 and newer. ++ pdftoepdf-poppler0.75.0.cc for poppler-0.75.0. ++ pdftoepdf-poppler0.76.0.cc for poppler-0.76.0 and newer. + Note that pdftosrc-*.cc and pdftoepdf-*.cc should be + renamed as pdftosrc.cc, and pdftoepdf.cc, respectively, before + compilation. +diff --git a/texk/web2c/pdftexdir/pdftoepdf-poppler0.72.0.cc b/texk/web2c/pdftexdir/pdftoepdf-poppler0.72.0.cc +index 630d3366d..6617cfe8b 100644 +--- a/texk/web2c/pdftexdir/pdftoepdf-poppler0.72.0.cc ++++ b/texk/web2c/pdftexdir/pdftoepdf-poppler0.72.0.cc +@@ -23,6 +23,7 @@ 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. ++It is tested upto the poppler 0.74.0. + POPPLER_VERSION should be defined. + */ + +diff --git a/texk/web2c/pdftexdir/pdftoepdf-poppler0.75.0.cc b/texk/web2c/pdftexdir/pdftoepdf-poppler0.75.0.cc +index 13c3bd5ef..30f8fed58 100644 +--- a/texk/web2c/pdftexdir/pdftoepdf-poppler0.75.0.cc ++++ b/texk/web2c/pdftexdir/pdftoepdf-poppler0.75.0.cc +@@ -22,7 +22,7 @@ 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.75.0 or newer versions. ++The poppler should be 0.75.0. + POPPLER_VERSION should be defined. + */ + +diff --git a/texk/web2c/pdftexdir/pdftoepdf-poppler0.76.0.cc b/texk/web2c/pdftexdir/pdftoepdf-poppler0.76.0.cc +new file mode 100644 +index 000000000..e7614aa5c +--- /dev/null ++++ b/texk/web2c/pdftexdir/pdftoepdf-poppler0.76.0.cc +@@ -0,0 +1,1113 @@ ++/* ++Copyright 1996-2017 Han The Thanh, ++ ++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 . ++*/ ++ ++/* ++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.76.0 or newer versions. ++POPPLER_VERSION should be defined. ++*/ ++ ++/* Do this early in order to avoid a conflict between ++ MINGW32 defining 'boolean' as 'unsigned char' and ++ defining Pascal's boolean as 'int'. ++*/ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef POPPLER_VERSION ++#include ++#include ++#include ++#include ++#include ++#define GString GooString ++#else ++#error POPPLER_VERSION should be defined. ++#endif ++#include ++ ++#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 ++#include ++ ++// 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); ++ 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().copy(); ++ 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.72.0.cc b/texk/web2c/pdftexdir/pdftosrc-poppler0.72.0.cc +index d4e247ef6..34bad9ccf 100644 +--- a/texk/web2c/pdftexdir/pdftosrc-poppler0.72.0.cc ++++ b/texk/web2c/pdftexdir/pdftosrc-poppler0.72.0.cc +@@ -21,6 +21,7 @@ with this program. If not, see . + 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. ++It is tested upto the poppler 0.75.0. + POPPLER_VERSION should be defined. + */ + +diff --git a/texk/web2c/pdftexdir/pdftosrc-poppler0.76.0.cc b/texk/web2c/pdftexdir/pdftosrc-poppler0.76.0.cc +new file mode 100644 +index 000000000..3599b5318 +--- /dev/null ++++ b/texk/web2c/pdftexdir/pdftosrc-poppler0.76.0.cc +@@ -0,0 +1,206 @@ ++/* ++Copyright 1996-2017 Han The Thanh, ++ ++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 . ++*/ ++ ++/* ++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.76.0 or newer versions. ++POPPLER_VERSION should be defined. ++*/ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef POPPLER_VERSION ++#define GString GooString ++#define xpdfVersion POPPLER_VERSION ++#include ++#include ++#include ++#include ++#else ++#error POPPLER_VERSION should be defined. ++#endif ++#include ++ ++#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 []\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); ++ parser = new Parser(xref, str, 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; ++} diff --git a/editor/tex/texlive-bin/files/arch/poppler-0.26.patch b/editor/tex/texlive-bin/files/arch/poppler-0.26.patch new file mode 100644 index 0000000000..a97b15529a --- /dev/null +++ b/editor/tex/texlive-bin/files/arch/poppler-0.26.patch @@ -0,0 +1,104 @@ +--- trunk/source/texk/web2c/luatexdir/image/epdf.h 2013/01/20 19:58:26 4559 ++++ trunk/source/texk/web2c/luatexdir/image/epdf.h 2014/01/02 15:35:31 4718 +@@ -40,21 +40,22 @@ + # include + # include + # include +-# include "Object.h" +-# include "Stream.h" +-# include "Gfx.h" +-# include "Annot.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" +-# include "FileSpec.h" ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include + + extern "C" { + +@@ -81,8 +82,8 @@ + # include "utils/avlstuff.h" + # include "pdf/pdftypes.h" + +-# include "lua52/lua.h" +-# include "lua52/lauxlib.h" ++# include "lua.h" ++# include "lauxlib.h" + + /* pdfgen.w */ + extern int ten_pow[10]; +--- trunk/source/texk/web2c/luatexdir/lua/lepdflib.cc 2013/04/05 10:54:08 4629 ++++ trunk/source/texk/web2c/luatexdir/lua/lepdflib.cc 2014/01/02 15:35:31 4718 +@@ -65,6 +65,7 @@ + #define M_PDFRectangle "PDFRectangle" + #define M_Ref "Ref" + #define M_Stream "Stream" ++#define M_StructTreeRoot "StructTreeRoot" + #define M_XRefEntry "XRefEntry" + #define M_XRef "XRef" + +@@ -96,6 +97,7 @@ + new_poppler_userdata(PDFRectangle); + new_poppler_userdata(Ref); + new_poppler_userdata(Stream); ++new_poppler_userdata(StructTreeRoot); + new_poppler_userdata(XRef); + + //********************************************************************** +@@ -573,7 +575,11 @@ + + m_poppler_get_GOOSTRING(Catalog, getBaseURI); + m_poppler_get_GOOSTRING(Catalog, readMetadata); ++#ifdef GETSTRUCTTREEROOT_RETURNS_OBJECT + m_poppler_get_poppler(Catalog, Object, getStructTreeRoot); ++#else ++m_poppler_get_poppler(Catalog, StructTreeRoot, getStructTreeRoot); ++#endif + + static int m_Catalog_findPage(lua_State * L) + { +@@ -2146,14 +2152,22 @@ + + static int m_PDFDoc_getStructTreeRoot(lua_State * L) + { ++#ifdef GETSTRUCTTREEROOT_RETURNS_OBJECT + Object *obj; ++#else ++ StructTreeRoot *obj; ++#endif + udstruct *uin, *uout; + uin = (udstruct *) luaL_checkudata(L, 1, M_PDFDoc); + 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(); ++#ifdef GETSTRUCTTREEROOT_RETURNS_OBJECT + uout = new_Object_userdata(L); ++#else ++ uout = new_StructTreeRoot_userdata(L); ++#endif + uout->d = obj; + uout->pc = uin->pc; + uout->pd = uin->pd; diff --git a/editor/tex/texlive-bin/files/arch/texlive-20190410-source-upstream_fixes-1.patch b/editor/tex/texlive-bin/files/arch/texlive-20190410-source-upstream_fixes-1.patch new file mode 100644 index 0000000000..2245807725 --- /dev/null +++ b/editor/tex/texlive-bin/files/arch/texlive-20190410-source-upstream_fixes-1.patch @@ -0,0 +1,4096 @@ +Submitted By: Ken Moffat +Date: 2019-05-31 +Initial Package Version: 2019 +Upstream Status: Applied +Origin: Upstream +Description: Fixes from branch2019 up to svn r51236, and fixes +from trunk for harfbuzz-2.5.0 changes (svn r51269, 51271). + +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/ChangeLog b/texlive-20190410-source/texk/dvipdfm-x/ChangeLog +--- a/texlive-20190410-source/texk/dvipdfm-x/ChangeLog 2019-04-07 02:42:55.000000000 +0100 ++++ b/texlive-20190410-source/texk/dvipdfm-x/ChangeLog 2019-05-31 22:00:04.006964029 +0100 +@@ -1,3 +1,47 @@ ++2019-05-08 Akira Kakuto ++ ++ * dpxfile.c: Avoid buffer overflow. ++ ++2019-05-08 Shunsaku Hirata ++ ++ * spc_pdfm.c: Transformation also applies to annotations ++ created by pdf:ann. ++ ++2019-05-07 Shunsaku Hirata ++ ++ * tt_cmap.c: Fix a bug that CFF charset data were not read. ++ * unicode.c: Fix a bug that end-of-buffer calculation was ++ wrong. ++ ++2019-05-05 Shunsaku Hirata ++ ++ * pdfdoc.c: g option affects only annotations created by ++ "pdf:bann/eann" and html "a link" specials. ++ Report from Joseph Wright: ++ https://tug.org/pipermail/tex-live/2019-May/043612.html ++ ++2019-05-03 Shunsaku Hirata ++ ++ * specials.c: transformation applied to current point was not ++ done properly. ++ ++2019-05-03 Akira Kakuto ++ ++ * dpxfile.c, mfileio.h, pdfximage.c: Support non-ascii file ++ names in default code page of OS irrespective of values of a ++ variable 'command_line_encoding' (Windows only). ++ ++2019-05-03 Shunsaku Hirata ++ ++ * pdfobj.c, pdfobj.h: Add support for ASCIIHex and ASCII85 ++ decode filter. Support for decoding stream data with multiple ++ filters applied. Remove unused function. ++ * tt_cmap.c, tt_gsub.[ch]: Revise ToUnicode CMap creation for ++ OpenType. Use GSUB for mapping unencoded glyphs to Unicode ++ (XeTeX support), lowering priority of CJK compatibility ++ ideographs. ++ * configure.ac: Version 20190503. ++ + 2019-04-07 Karl Berry + + * TeX Live 2019. +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/configure b/texlive-20190410-source/texk/dvipdfm-x/configure +--- a/texlive-20190410-source/texk/dvipdfm-x/configure 2019-02-24 22:07:11.000000000 +0000 ++++ b/texlive-20190410-source/texk/dvipdfm-x/configure 2019-05-31 22:00:04.007964030 +0100 +@@ -1,8 +1,8 @@ + #! /bin/sh + # Guess values for system-dependent variables and create Makefiles. +-# Generated by GNU Autoconf 2.69 for dvipdfm-x (TeX Live) 20190225. ++# Generated by GNU Autoconf 2.69 for dvipdfm-x (TeX Live) 20190503. + # +-# Report bugs to . ++# Report bugs to . + # + # + # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +@@ -274,7 +274,7 @@ + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else +- $as_echo "$0: Please tell bug-autoconf@gnu.org and tex-k@tug.org ++ $as_echo "$0: Please tell bug-autoconf@gnu.org and dvipdfmx@tug.org + $0: about your system, including any error possibly output + $0: before this message. Then install a modern shell, or + $0: manually run the script under such a shell if you do +@@ -590,9 +590,9 @@ + # Identity of this package. + PACKAGE_NAME='dvipdfm-x (TeX Live)' + PACKAGE_TARNAME='dvipdfm-x--tex-live-' +-PACKAGE_VERSION='20190225' +-PACKAGE_STRING='dvipdfm-x (TeX Live) 20190225' +-PACKAGE_BUGREPORT='tex-k@tug.org' ++PACKAGE_VERSION='20190503' ++PACKAGE_STRING='dvipdfm-x (TeX Live) 20190503' ++PACKAGE_BUGREPORT='dvipdfmx@tug.org' + PACKAGE_URL='' + + ac_unique_file="agl.c" +@@ -1350,7 +1350,7 @@ + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the a/texlive-20190410-source/UX 3.1 sh. + cat <<_ACEOF +-\`configure' configures dvipdfm-x (TeX Live) 20190225 to adapt to many kinds of systems. ++\`configure' configures dvipdfm-x (TeX Live) 20190503 to adapt to many kinds of systems. + + Usage: $0 [OPTION]... [VAR=VALUE]... + +@@ -1421,7 +1421,7 @@ + + if test -n "$ac_init_help"; then + case $ac_init_help in +- short | recursive ) echo "Configuration of dvipdfm-x (TeX Live) 20190225:";; ++ short | recursive ) echo "Configuration of dvipdfm-x (TeX Live) 20190503:";; + esac + cat <<\_ACEOF + +@@ -1488,7 +1488,7 @@ + Use these variables to override the choices made by `configure' or to help + it to find libraries and programs with nonstandard names/locations. + +-Report bugs to . ++Report bugs to . + _ACEOF + ac_status=$? + fi +@@ -1551,7 +1551,7 @@ + test -n "$ac_init_help" && exit $ac_status + if $ac_init_version; then + cat <<\_ACEOF +-dvipdfm-x (TeX Live) configure 20190225 ++dvipdfm-x (TeX Live) configure 20190503 + generated by GNU Autoconf 2.69 + + Copyright (C) 2012 Free Software Foundation, Inc. +@@ -1896,9 +1896,9 @@ + $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 + $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +-( $as_echo "## ---------------------------- ## +-## Report this to tex-k@tug.org ## +-## ---------------------------- ##" ++( $as_echo "## ------------------------------- ## ++## Report this to dvipdfmx@tug.org ## ++## ------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; + esac +@@ -2390,7 +2390,7 @@ + This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. + +-It was created by dvipdfm-x (TeX Live) $as_me 20190225, which was ++It was created by dvipdfm-x (TeX Live) $as_me 20190503, which was + generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ +@@ -8077,7 +8077,7 @@ + + # Define the identity of the package. + PACKAGE='dvipdfm-x--tex-live-' +- VERSION='20190225' ++ VERSION='20190503' + + + cat >>confdefs.h <<_ACEOF +@@ -14746,7 +14746,7 @@ + Report bugs to ." + + lt_cl_version="\ +-dvipdfm-x (TeX Live) config.lt 20190225 ++dvipdfm-x (TeX Live) config.lt 20190503 + configured by $0, generated by GNU Autoconf 2.69. + + Copyright (C) 2011 Free Software Foundation, Inc. +@@ -16636,7 +16636,7 @@ + # report actual input values of CONFIG_FILES etc. instead of their + # values after options handling. + ac_log=" +-This file was extended by dvipdfm-x (TeX Live) $as_me 20190225, which was ++This file was extended by dvipdfm-x (TeX Live) $as_me 20190503, which was + generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES +@@ -16700,13 +16700,13 @@ + Configuration commands: + $config_commands + +-Report bugs to ." ++Report bugs to ." + + _ACEOF + cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" + ac_cs_version="\\ +-dvipdfm-x (TeX Live) config.status 20190225 ++dvipdfm-x (TeX Live) config.status 20190503 + configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/configure.ac b/texlive-20190410-source/texk/dvipdfm-x/configure.ac +--- a/texlive-20190410-source/texk/dvipdfm-x/configure.ac 2019-02-24 22:07:11.000000000 +0000 ++++ b/texlive-20190410-source/texk/dvipdfm-x/configure.ac 2019-05-31 22:00:04.007964030 +0100 +@@ -7,7 +7,7 @@ + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. + dnl +-AC_INIT([dvipdfm-x (TeX Live)], [20190225], [tex-k@tug.org]) ++AC_INIT([dvipdfm-x (TeX Live)], [20190503], [dvipdfmx@tug.org]) + AC_PREREQ([2.65]) + AC_CONFIG_SRCDIR([agl.c]) + AC_CONFIG_AUX_DIR([../../build-aux]) +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/dpxfile.c b/texlive-20190410-source/texk/dvipdfm-x/dpxfile.c +--- a/texlive-20190410-source/texk/dvipdfm-x/dpxfile.c 2018-10-07 22:27:40.000000000 +0100 ++++ b/texlive-20190410-source/texk/dvipdfm-x/dpxfile.c 2019-05-31 22:00:04.007964030 +0100 +@@ -1,5 +1,5 @@ + /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. +- Copyright (C) 2007-2018 by Jin-Hwan Cho and Shunsaku Hirata, ++ Copyright (C) 2007-2019 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks +@@ -159,11 +159,17 @@ + static char _tmpbuf[PATH_MAX+1]; + #endif /* MIKTEX */ + ++#if defined(WIN32) ++extern int utf8name_failed; ++#endif /* WIN32 */ ++ ++#define CMDBUFSIZ 1024 + static int exec_spawn (char *cmd) + { + char **cmdv, **qv; + char *p, *pp; +- char buf[1024]; ++ char buf[CMDBUFSIZ]; ++ int charcnt; + int i, ret = -1; + #ifdef WIN32 + wchar_t **cmdvw, **qvw; +@@ -182,11 +188,12 @@ + i++; + p++; + } +- cmdv = xcalloc (i + 2, sizeof (char *)); ++ cmdv = xcalloc (i + 4, sizeof (char *)); + p = cmd; + qv = cmdv; + while (*p) { + pp = buf; ++ charcnt = 0; + if (*p == '"') { + p++; + while (*p != '"') { +@@ -194,6 +201,10 @@ + goto done; + } + *pp++ = *p++; ++ charcnt++; ++ if (charcnt > CMDBUFSIZ - 1) { ++ ERROR("Too long a command line."); ++ } + } + p++; + } else if (*p == '\'') { +@@ -203,6 +214,10 @@ + goto done; + } + *pp++ = *p++; ++ charcnt++; ++ if (charcnt > CMDBUFSIZ - 1) { ++ ERROR("Too long a command line."); ++ } + } + p++; + } else { +@@ -214,10 +229,18 @@ + goto done; + } + *pp++ = *p++; ++ charcnt++; ++ if (charcnt > CMDBUFSIZ - 1) { ++ ERROR("Too long a command line."); ++ } + } + p++; + } else { + *pp++ = *p++; ++ charcnt++; ++ if (charcnt > CMDBUFSIZ - 1) { ++ ERROR("Too long a command line."); ++ } + } + } + } +@@ -235,20 +258,39 @@ + p++; + qv++; + } ++ *qv = NULL; ++ + #ifdef WIN32 + #if defined(MIKTEX) + ret = _spawnvp(_P_WAIT, *cmdv, (const char* const*)cmdv); + #else +- cmdvw = xcalloc (i + 2, sizeof (wchar_t *)); +- qv = cmdv; +- qvw = cmdvw; +- while (*qv) { +- *qvw = get_wstring_from_fsyscp(*qv, *qvw=NULL); +- qv++; +- qvw++; ++ cmdvw = xcalloc (i + 4, sizeof (wchar_t *)); ++ if (utf8name_failed == 0) { ++ qv = cmdv; ++ qvw = cmdvw; ++ while (*qv) { ++ *qvw = get_wstring_from_fsyscp(*qv, *qvw=NULL); ++ qv++; ++ qvw++; ++ } ++ *qvw = NULL; ++ ret = _wspawnvp (_P_WAIT, *cmdvw, (const wchar_t* const*) cmdvw); ++ } else { ++ int tmpcp; ++ tmpcp = file_system_codepage; ++ file_system_codepage = win32_codepage; ++ qv = cmdv; ++ qvw = cmdvw; ++ while (*qv) { ++ *qvw = get_wstring_from_fsyscp(*qv, *qvw=NULL); ++ qv++; ++ qvw++; ++ } ++ *qvw = NULL; ++ file_system_codepage = tmpcp; ++ utf8name_failed = 0; ++ ret = _wspawnvp (_P_WAIT, *cmdvw, (const wchar_t* const*) cmdvw); + } +- *qvw = NULL; +- ret = _wspawnvp (_P_WAIT, *cmdvw, (const wchar_t* const*) cmdvw); + if (cmdvw) { + qvw = cmdvw; + while (*qvw) { +@@ -1242,3 +1284,21 @@ + + return r; + } ++ ++#if defined(WIN32) ++FILE *generic_fsyscp_fopen (const char *filename, const char *mode) ++{ ++ FILE *f; ++ ++ f = fsyscp_fopen (filename, mode); ++ ++ if (f == NULL && file_system_codepage != win32_codepage) { ++ int tmpcp = file_system_codepage; ++ file_system_codepage = win32_codepage; ++ f = fsyscp_fopen (filename, mode); ++ file_system_codepage = tmpcp; ++ } ++ ++ return f; ++} ++#endif /* WIN32 */ +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/dvipdfmx.c b/texlive-20190410-source/texk/dvipdfm-x/dvipdfmx.c +--- a/texlive-20190410-source/texk/dvipdfm-x/dvipdfmx.c 2019-02-11 18:22:31.000000000 +0000 ++++ b/texlive-20190410-source/texk/dvipdfm-x/dvipdfmx.c 2019-05-31 22:00:04.007964030 +0100 +@@ -232,7 +232,7 @@ + printf ("Papersize is specified by paper format (e.g., \"a4\")\n"); + printf ("\tor by w,h (e.g., \"20cm,30cm\").\n"); + printf ("\n"); +- printf ("Email bug reports to tex-k@tug.org.\n"); ++ printf ("Email bug reports to dvipdfmx@tug.org.\n"); + } + + static void +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/mfileio.h b/texlive-20190410-source/texk/dvipdfm-x/mfileio.h +--- a/texlive-20190410-source/texk/dvipdfm-x/mfileio.h 2016-01-11 03:57:04.000000000 +0000 ++++ b/texlive-20190410-source/texk/dvipdfm-x/mfileio.h 2019-05-31 22:00:04.008964031 +0100 +@@ -1,6 +1,6 @@ + /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + +- Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata, ++ Copyright (C) 2002-2019 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks +@@ -36,7 +36,8 @@ + mfclose((file),__FUNCTION__,__LINE__) + #else + #if defined(WIN32) +-#define MFOPEN(name,mode) fsyscp_fopen((name),(mode)) ++extern FILE *generic_fsyscp_fopen(const char *fname, const char *mode); ++#define MFOPEN(name,mode) generic_fsyscp_fopen((name),(mode)) + #else + #define MFOPEN(name,mode) fopen((name),(mode)) + #endif +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/pdfdoc.c b/texlive-20190410-source/texk/dvipdfm-x/pdfdoc.c +--- a/texlive-20190410-source/texk/dvipdfm-x/pdfdoc.c 2018-12-21 03:39:51.000000000 +0000 ++++ b/texlive-20190410-source/texk/dvipdfm-x/pdfdoc.c 2019-05-31 22:00:04.008964031 +0100 +@@ -1,6 +1,6 @@ + /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + +- Copyright (C) 2008-2018 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, ++ Copyright (C) 2008-2019 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks +@@ -1780,7 +1780,6 @@ + pdf_doc *p = &pdoc; + pdf_page *page; + pdf_obj *rect_array; +- double annot_grow = p->opt.annot_grow; + double xpos, ypos; + pdf_rect annbox; + +@@ -1812,10 +1811,10 @@ + } + + rect_array = pdf_new_array(); +- pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.llx - annot_grow, 0.001))); +- pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.lly - annot_grow, 0.001))); +- pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.urx + annot_grow, 0.001))); +- pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.ury + annot_grow, 0.001))); ++ pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.llx, 0.001))); ++ pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.lly, 0.001))); ++ pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.urx, 0.001))); ++ pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.ury, 0.001))); + pdf_add_dict (annot_dict, pdf_new_name("Rect"), rect_array); + + pdf_add_array(page->annots, pdf_ref_obj(annot_dict)); +@@ -2802,13 +2801,22 @@ + void + pdf_doc_break_annot (void) + { ++ pdf_doc *p = &pdoc; ++ double g = p->opt.annot_grow; ++ + if (breaking_state.dirty) { + pdf_obj *annot_dict; ++ pdf_rect rect; + + /* Copy dict */ + annot_dict = pdf_new_dict(); + pdf_merge_dict(annot_dict, breaking_state.annot_dict); +- pdf_doc_add_annot(pdf_doc_current_page_number(), &(breaking_state.rect), ++ rect = breaking_state.rect; ++ rect.llx -= g; ++ rect.lly -= g; ++ rect.urx += g; ++ rect.ury += g; ++ pdf_doc_add_annot(pdf_doc_current_page_number(), &rect, + annot_dict, !breaking_state.broken); + pdf_release_obj(annot_dict); + +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/pdfobj.c b/texlive-20190410-source/texk/dvipdfm-x/pdfobj.c +--- a/texlive-20190410-source/texk/dvipdfm-x/pdfobj.c 2018-12-26 23:07:57.000000000 +0000 ++++ b/texlive-20190410-source/texk/dvipdfm-x/pdfobj.c 2019-05-31 22:00:04.008964031 +0100 +@@ -1,6 +1,6 @@ + /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + +- Copyright (C) 2007-2018 by Jin-Hwan Cho and Shunsaku Hirata, ++ Copyright (C) 2007-2019 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks +@@ -2223,48 +2223,9 @@ + + #if HAVE_ZLIB + #define WBUF_SIZE 4096 +-int +-pdf_add_stream_flate (pdf_obj *dst, const void *data, int len) +-{ +- z_stream z; +- Bytef wbuf[WBUF_SIZE]; +- +- z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL; +- +- z.next_in = (z_const Bytef *) data; z.avail_in = len; +- z.next_out = (Bytef *) wbuf; z.avail_out = WBUF_SIZE; +- +- if (inflateInit(&z) != Z_OK) { +- WARN("inflateInit() failed."); +- return -1; +- } +- +- for (;;) { +- int status; +- status = inflate(&z, Z_NO_FLUSH); +- if (status == Z_STREAM_END) +- break; +- else if (status != Z_OK) { +- WARN("inflate() failed. Broken PDF file?"); +- inflateEnd(&z); +- return -1; +- } +- +- if (z.avail_out == 0) { +- pdf_add_stream(dst, wbuf, WBUF_SIZE); +- z.next_out = wbuf; +- z.avail_out = WBUF_SIZE; +- } +- } +- +- if (WBUF_SIZE - z.avail_out > 0) +- pdf_add_stream(dst, wbuf, WBUF_SIZE - z.avail_out); +- +- return (inflateEnd(&z) == Z_OK ? 0 : -1); +-} + + static int +-get_decode_parms (struct decode_parms *parms, pdf_obj *dict) ++filter_get_DecodeParms_FlateDecode (struct decode_parms *parms, pdf_obj *dict) + { + pdf_obj *tmp; + +@@ -2278,18 +2239,25 @@ + parms->columns = 1; + + tmp = pdf_deref_obj(pdf_lookup_dict(dict, "Predictor")); +- if (tmp) ++ if (tmp) { + parms->predictor = pdf_number_value(tmp); ++ pdf_release_obj(tmp); ++ } + tmp = pdf_deref_obj(pdf_lookup_dict(dict, "Colors")); +- if (tmp) ++ if (tmp) { + parms->colors = pdf_number_value(tmp); ++ pdf_release_obj(tmp); ++ } + tmp = pdf_deref_obj(pdf_lookup_dict(dict, "BitsPerComponent")); +- if (tmp) ++ if (tmp) { + parms->bits_per_component = pdf_number_value(tmp); ++ pdf_release_obj(tmp); ++ } + tmp = pdf_deref_obj(pdf_lookup_dict(dict, "Columns")); +- if (tmp) ++ if (tmp) { + parms->columns = pdf_number_value(tmp); +- ++ pdf_release_obj(tmp); ++ } + if (parms->bits_per_component != 1 && + parms->bits_per_component != 2 && + parms->bits_per_component != 4 && +@@ -2354,17 +2322,19 @@ + * Especially, calling pdf_add_stream() for each 4 bytes append is highly + * inefficient. + */ +-static int +-filter_decoded (pdf_obj *dst, const void *src, int srclen, +- struct decode_parms *parms) ++static pdf_obj * ++filter_stream_decode_Predictor (const void *src, size_t srclen, struct decode_parms *parms) + { ++ pdf_obj *dst; + const unsigned char *p = (const unsigned char *) src; + const unsigned char *endptr = p + srclen; +- unsigned char *prev, *buf; +- int bits_per_pixel = parms->colors * parms->bits_per_component; +- int bytes_per_pixel = (bits_per_pixel + 7) / 8; +- int length = (parms->columns * bits_per_pixel + 7) / 8; +- int i, error = 0; ++ unsigned char *prev, *buf; ++ int bits_per_pixel = parms->colors * parms->bits_per_component; ++ int bytes_per_pixel = (bits_per_pixel + 7) / 8; ++ int length = (parms->columns * bits_per_pixel + 7) / 8; ++ int i, error = 0; ++ ++ dst = pdf_new_stream(0); + + prev = NEW(length, unsigned char); + buf = NEW(length, unsigned char); +@@ -2491,16 +2461,21 @@ + RELEASE(prev); + RELEASE(buf); + +- return error; ++ if (error) { ++ pdf_release_obj(dst); ++ dst = NULL; ++ } ++ ++ return dst; + } + +-static int +-pdf_add_stream_flate_filtered (pdf_obj *dst, const void *data, int len, struct decode_parms *parms) ++static pdf_obj * ++filter_stream_decode_FlateDecode (const void *data, size_t len, struct decode_parms *parms) + { +- pdf_obj *tmp; +- z_stream z; +- Bytef wbuf[WBUF_SIZE]; +- int error; ++ pdf_obj *dst; ++ pdf_obj *tmp; ++ z_stream z; ++ Bytef wbuf[WBUF_SIZE]; + + z.zalloc = Z_NULL; z.zfree = Z_NULL; z.opaque = Z_NULL; + +@@ -2509,7 +2484,7 @@ + + if (inflateInit(&z) != Z_OK) { + WARN("inflateInit() failed."); +- return -1; ++ return NULL; + } + + tmp = pdf_new_stream(0); +@@ -2521,7 +2496,8 @@ + else if (status != Z_OK) { + WARN("inflate() failed. Broken PDF file?"); + inflateEnd(&z); +- return -1; ++ pdf_release_obj(tmp); ++ return NULL; + } + + if (z.avail_out == 0) { +@@ -2534,79 +2510,310 @@ + if (WBUF_SIZE - z.avail_out > 0) + pdf_add_stream(tmp, wbuf, WBUF_SIZE - z.avail_out); + +- error = filter_decoded(dst, pdf_stream_dataptr(tmp), pdf_stream_length(tmp), parms); ++ if (inflateEnd(&z) == Z_OK) { ++ if (parms) { ++ dst = filter_stream_decode_Predictor(pdf_stream_dataptr(tmp), pdf_stream_length(tmp), parms); ++ } else { ++ dst = pdf_link_obj(tmp); ++ } ++ } else { ++ dst = NULL; ++ } + pdf_release_obj(tmp); + +- return ((!error && inflateEnd(&z) == Z_OK) ? 0 : -1); ++ return dst; + } + #endif + +-int +-pdf_concat_stream (pdf_obj *dst, pdf_obj *src) ++static pdf_obj * ++filter_stream_decode_ASCIIHexDecode (const void *data, size_t len) ++{ ++ pdf_obj *dst; ++ int eod, error; ++ const char *p = (const char *) data; ++ const char *endptr = p + len; ++ unsigned char *buf, ch; ++ size_t pos, n; ++ ++ buf = NEW((len+1)/2, unsigned char); ++ skip_white(&p, endptr); ++ ch = 0; n = 0; pos = 0; eod = 0; error = 0; ++ while (p < endptr && !error && !eod) { ++ char c1, val; ++ c1 = p[0]; ++ if (c1 >= 'A' && c1 <= 'F') { ++ val = c1 - 'A' + 10; ++ } else if (c1 >= 'a' && c1 <= 'f') { ++ val = c1 - 'a' + 10; ++ } else if (c1 >= '0' && c1 <= '9') { ++ val = c1 - '0'; ++ } else if (c1 == '>') { ++ val = 0; ++ eod = 1; ++ if ((pos % 2) == 0) ++ break; ++ } else { ++ error = -1; ++ break; ++ } ++ if (pos % 2) { ++ buf[n] = ch + val; ++ n++; ++ ch = 0; ++ } else { ++ ch = val << 4; ++ } ++ pos++; p++; ++ skip_white(&p, endptr); ++ } ++ if (error || !eod) { ++ WARN("Invalid ASCIIHex data seen: %s", error ? "Invalid character" : "No EOD marker"); ++ dst = NULL; ++ } else { ++ dst = pdf_new_stream(0); ++ pdf_add_stream(dst, buf, n); ++ } ++ RELEASE(buf); ++ ++ return dst; ++} ++ ++/* Percent sign is not start of comment here. ++ * We need this for reading Ascii85 encoded data. ++ */ ++#define is_space(c) ((c) == ' ' || (c) == '\t' || (c) == '\f' || \ ++ (c) == '\r' || (c) == '\n' || (c) == '\0') ++static void ++skip_white_a85 (const char **p, const char *endptr) ++{ ++ while (*p < endptr && (is_space(**p))) { ++ (*p)++; ++ } ++} ++ ++static pdf_obj * ++filter_stream_decode_ASCII85Decode (const void *data, size_t len) + { ++ pdf_obj *dst; ++ int eod, error; ++ const char *p = (const char *) data; ++ const char *endptr = p + len; ++ unsigned char *buf; ++ size_t n; ++ ++ buf = NEW(((len+4)/5)*4, unsigned char); ++ skip_white_a85(&p, endptr); ++ n = 0; eod = 0; error = 0; ++ while (p < endptr && !error && !eod) { ++ char q[5] = {'u', 'u', 'u', 'u', 'u'}; ++ int m; ++ char ch; ++ ++ ch = p[0]; ++ p++; ++ skip_white_a85(&p, endptr); ++ if (ch == 'z') { ++ memset(buf+n, 0, 4); ++ n += 4; ++ continue; ++ } else if (ch == '~') { ++ if (p < endptr && p[0] == '>') { ++ eod = 1; ++ p++; ++ } else { ++ error = -1; ++ } ++ break; ++ } ++ q[0] = ch; ++ for (m = 1; m < 5 && p < endptr; m++) { ++ ch = p[0]; ++ p++; ++ skip_white_a85(&p, endptr); ++ if (ch == '~') { ++ if (p < endptr && p[0] == '>') { ++ eod = 1; ++ p++; ++ } else { ++ error = -1; ++ } ++ break; ++ } else if (ch < '!' || ch > 'u') { ++ error = -1; ++ break; ++ } else { ++ q[m] = ch; ++ } ++ } ++ if (!error) { ++ uint32_t val = 0; ++ int i; ++ if (m <= 1) { ++ error = -1; ++ break; ++ } ++ val = 85*85*85*(q[0] - '!') + 85*85*(q[1] - '!') ++ + 85*(q[2] - '!') + (q[3] - '!'); ++ /* Check overflow */ ++ if (val > UINT32_MAX / 85) { ++ error = -1; ++ break; ++ } else { ++ val = 85 * val; ++ if (val > UINT32_MAX - (q[4] - '!')) { ++ error = -1; ++ break; ++ } ++ val += (q[4] - '!'); ++ } ++ if (!error) { ++ for (i = 3; i >= 0; i--) { ++ buf[n + i] = val & 0xff; ++ val /= 256; ++ } ++ n += m - 1; ++ } ++ } ++ } ++ ++ if (error) { ++ WARN("Error in reading ASCII85 data."); ++ dst = NULL; ++ } else if (!eod) { ++ WARN("Error in reading ASCII85 data: No EOD"); ++ dst = NULL; ++ } else { ++ dst = pdf_new_stream(0); ++ pdf_add_stream(dst, buf, n); ++ } ++ RELEASE(buf); ++ ++ return dst; ++} ++ ++static pdf_obj * ++filter_stream_decode (const char *filter_name, pdf_obj *src, pdf_obj *parm) ++{ ++ pdf_obj *dec; + const char *stream_data; +- int stream_length; +- pdf_obj *stream_dict; +- pdf_obj *filter; +- int error = 0; ++ size_t stream_length; + +- if (!PDF_OBJ_STREAMTYPE(dst) || !PDF_OBJ_STREAMTYPE(src)) +- ERROR("Invalid type."); ++ if (!filter_name) ++ return pdf_link_obj(src); + + stream_data = pdf_stream_dataptr(src); +- stream_length = pdf_stream_length (src); +- stream_dict = pdf_stream_dict (src); ++ stream_length = pdf_stream_length(src); + +- filter = pdf_lookup_dict(stream_dict, "Filter"); +- if (!filter) +- pdf_add_stream(dst, stream_data, stream_length); ++ if (!strcmp(filter_name, "ASCIIHexDecode")) { ++ dec = filter_stream_decode_ASCIIHexDecode(stream_data, stream_length); ++ } else if (!strcmp(filter_name, "ASCII85Decode")) { ++ dec = filter_stream_decode_ASCII85Decode(stream_data, stream_length); + #if HAVE_ZLIB +- else { +- struct decode_parms parms; +- int have_parms = 0; ++ } else if (!strcmp(filter_name, "FlateDecode")) { ++ struct decode_parms decode_parm; ++ if (parm) ++ filter_get_DecodeParms_FlateDecode(&decode_parm, parm); ++ dec = filter_stream_decode_FlateDecode(stream_data, stream_length, parm ? &decode_parm : NULL); ++#endif /* HAVE_ZLIB */ ++ } else { ++ WARN("DecodeFilter \"%s\" not supported.", filter_name); ++ dec = NULL; ++ } + +- if (pdf_lookup_dict(stream_dict, "DecodeParms")) { +- pdf_obj *tmp; ++ return dec; ++} + +- /* Dictionary or array */ +- tmp = pdf_deref_obj(pdf_lookup_dict(stream_dict, "DecodeParms")); +- if (PDF_OBJ_ARRAYTYPE(tmp)) { +- if (pdf_array_length(tmp) > 1) { +- WARN("Unexpected size for DecodeParms array."); +- return -1; +- } +- tmp = pdf_deref_obj(pdf_get_array(tmp, 0)); +- } +- if (!PDF_OBJ_DICTTYPE(tmp)) { +- WARN("PDF dict expected for DecodeParms..."); +- return -1; +- } +- error = get_decode_parms(&parms, tmp); +- if (error) +- ERROR("Invalid value(s) in DecodeParms dictionary."); +- have_parms = 1; +- } +- if (PDF_OBJ_ARRAYTYPE(filter)) { +- if (pdf_array_length(filter) > 1) { +- WARN("Multiple DecodeFilter not supported."); ++int ++pdf_concat_stream (pdf_obj *dst, pdf_obj *src) ++{ ++ pdf_obj *filtered; ++ pdf_obj *stream_dict; ++ pdf_obj *filter, *parms; ++ int error = 0; ++ ++ if (!PDF_OBJ_STREAMTYPE(dst) || !PDF_OBJ_STREAMTYPE(src)) { ++ WARN("Passed invalid type in pdf_concat_stream()."); ++ return -1; ++ } ++ ++ stream_dict = pdf_stream_dict(src); ++ ++ filter = pdf_lookup_dict(stream_dict, "Filter"); ++ if (!filter) { ++ pdf_add_stream(dst, pdf_stream_dataptr(src), pdf_stream_length(src)); ++ return 0; ++ } ++ if (pdf_lookup_dict(stream_dict, "DecodeParms")) { ++ /* Dictionary or array */ ++ parms = pdf_deref_obj(pdf_lookup_dict(stream_dict, "DecodeParms")); ++ if (!parms) { ++ WARN("Failed to deref DeocdeParms..."); ++ return -1; ++ } else if (!PDF_OBJ_ARRAYTYPE(parms) && !PDF_OBJ_DICTTYPE(parms)) { ++ WARN("PDF dict or array expected for DecodeParms..."); ++ pdf_release_obj(parms); ++ return -1; ++ } ++ } else { ++ parms = NULL; ++ } ++ if (PDF_OBJ_ARRAYTYPE(filter)) { ++ int i, num; ++ pdf_obj *prev = NULL; ++ ++ num = pdf_array_length(filter); ++ if (parms) { ++ if (!PDF_OBJ_ARRAYTYPE(parms) || pdf_array_length(parms) != num) { ++ WARN("Invalid DecodeParam object found."); ++ pdf_release_obj(parms); + return -1; + } +- filter = pdf_get_array(filter, 0); + } +- if (PDF_OBJ_NAMETYPE(filter)) { +- char *filter_name = pdf_name_value(filter); +- if (filter_name && !strcmp(filter_name, "FlateDecode")) { +- if (have_parms) +- error = pdf_add_stream_flate_filtered(dst, stream_data, stream_length, &parms); +- else +- error = pdf_add_stream_flate(dst, stream_data, stream_length); +- } else { +- WARN("DecodeFilter \"%s\" not supported.", filter_name); +- error = -1; ++ if (num == 0) { ++ filtered = pdf_link_obj(src); ++ } else { ++ filtered = NULL; ++ prev = pdf_link_obj(src); ++ for (i = 0; i < num && prev != NULL; i++) { ++ pdf_obj *tmp1, *tmp2; ++ ++ tmp1 = pdf_deref_obj(pdf_get_array(filter, i)); ++ if (parms) { ++ tmp2 = pdf_deref_obj(pdf_get_array(parms, i)); ++ } else { ++ tmp2 = NULL; ++ } ++ if (PDF_OBJ_NAMETYPE(tmp1)) { ++ filtered = filter_stream_decode(pdf_name_value(tmp1), prev, tmp2); ++ } else if (PDF_OBJ_NULLTYPE(tmp1)) { ++ filtered = pdf_link_obj(prev); ++ } else { ++ WARN("Unexpected object found for /Filter..."); ++ filtered = NULL; ++ } ++ if (prev) ++ pdf_release_obj(prev); ++ if (tmp1) ++ pdf_release_obj(tmp1); ++ if (tmp2) ++ pdf_release_obj(tmp2); ++ prev = filtered; + } +- } else +- ERROR("Broken PDF file?"); +-#endif /* HAVE_ZLIB */ ++ } ++ } else if (PDF_OBJ_NAMETYPE(filter)) { ++ filtered = filter_stream_decode(pdf_name_value(filter), src, parms); ++ } else { ++ WARN("Invalid value for /Filter found."); ++ filtered = NULL; ++ } ++ if (parms) ++ pdf_release_obj(parms); ++ if (filtered) { ++ pdf_add_stream(dst, pdf_stream_dataptr(filtered), pdf_stream_length(filtered)); ++ pdf_release_obj(filtered); ++ error = 0; ++ } else { ++ error = -1; + } + + return error; +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/pdfobj.h b/texlive-20190410-source/texk/dvipdfm-x/pdfobj.h +--- a/texlive-20190410-source/texk/dvipdfm-x/pdfobj.h 2018-09-15 22:18:43.000000000 +0100 ++++ b/texlive-20190410-source/texk/dvipdfm-x/pdfobj.h 2019-05-31 22:00:04.008964031 +0100 +@@ -1,6 +1,6 @@ + /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + +- Copyright (C) 2007-2018 by Jin-Hwan Cho and Shunsaku Hirata, ++ Copyright (C) 2007-2019 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks +@@ -152,11 +152,6 @@ + extern void pdf_add_stream (pdf_obj *stream, + const void *stream_data_ptr, + int stream_data_len); +-#if HAVE_ZLIB +-extern int pdf_add_stream_flate (pdf_obj *stream, +- const void *stream_data_ptr, +- int stream_data_len); +-#endif + extern int pdf_concat_stream (pdf_obj *dst, pdf_obj *src); + extern pdf_obj *pdf_stream_dict (pdf_obj *stream); + extern int pdf_stream_length (pdf_obj *stream); +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/pdfximage.c b/texlive-20190410-source/texk/dvipdfm-x/pdfximage.c +--- a/texlive-20190410-source/texk/dvipdfm-x/pdfximage.c 2018-09-14 04:34:50.000000000 +0100 ++++ b/texlive-20190410-source/texk/dvipdfm-x/pdfximage.c 2019-05-31 22:00:04.008964031 +0100 +@@ -1,6 +1,6 @@ + /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + +- Copyright (C) 2007-2018 by Jin-Hwan Cho and Shunsaku Hirata, ++ Copyright (C) 2007-2019 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks +@@ -363,6 +363,10 @@ + #define dpx_fopen(n,m) (MFOPEN((n),(m))) + #define dpx_fclose(f) (MFCLOSE((f))) + ++#if defined(WIN32) ++int utf8name_failed = 0; ++#endif /* WIN32 */ ++ + int + pdf_ximage_findresource (const char *ident, load_options options) + { +@@ -394,8 +398,23 @@ + strcpy(fullname, f); + } else { + /* try loading image */ ++#if defined(WIN32) ++ utf8name_failed = 0; ++#endif /* WIN32 */ + fullname = dpx_find_file(ident, "_pic_", ""); ++#if defined(WIN32) ++ if (!fullname && file_system_codepage != win32_codepage) { ++ int tmpcp = file_system_codepage; ++ utf8name_failed = 1; ++ file_system_codepage = win32_codepage; ++ fullname = dpx_find_file(ident, "_pic_", ""); ++ file_system_codepage = tmpcp; ++ } ++#endif /* WIN32 */ + if (!fullname) { ++#if defined(WIN32) ++ utf8name_failed = 0; ++#endif /* WIN32 */ + WARN("Error locating image file \"%s\"", ident); + return -1; + } +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/README b/texlive-20190410-source/texk/dvipdfm-x/README +--- a/texlive-20190410-source/texk/dvipdfm-x/README 2015-07-06 17:13:08.000000000 +0100 ++++ b/texlive-20190410-source/texk/dvipdfm-x/README 2019-05-31 22:00:04.006964029 +0100 +@@ -1,9 +1,17 @@ + dvipdfmx and xdvipdfmx for TeX Live + =================================== + ++This package is released under the GNU GPL, version 2, or (at your ++option) any later version. ++ ++dvipdfmx is now maintained as part of TeX Live. ++ ++Mailing list for bug reports and all discussion: ++https://lists.tug.org/dvipdfmx; anyone can join the list, but it is not ++necessary to join to post. Archives are public. ++ + xdvipdfmx + ========= +- + xdvipdfmx is an extended version of dvipdfmx, and is now incorporated in + the same sources. + +@@ -15,8 +23,6 @@ + redistributed under the terms of the GNU General Public License, + version 2 or (at your option) any later version. + +-There is a hope to merge xdvipdfmx into dvipdfmx. +- + Jonathan Kew mentions that in the past, XeTeX used a Mac-specific + program xdv2pdf as the backend instead of xdvipdfmx. xdv2pdf supported + a couple of special effects that are not yet available through +@@ -26,18 +32,8 @@ + if anyone is looking for some nontrivial but not-impossible job and + happens across this file. + +-The dvipdfmx Project +-==================== +- +-Copyright (C) 2002-2014 by Jin-Hwan Cho, Shunsaku Hirata, +-Matthias Franz, and the dvipdfmx project team. This package is released +-under the GNU GPL, version 2, or (at your option) any later version. +- +-dvipdfmx is now maintained as part of TeX Live. +- + Contents + -------- +- + 1. Introduction + + 2. Installation +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/spc_pdfm.c b/texlive-20190410-source/texk/dvipdfm-x/spc_pdfm.c +--- a/texlive-20190410-source/texk/dvipdfm-x/spc_pdfm.c 2019-03-30 03:42:07.000000000 +0000 ++++ b/texlive-20190410-source/texk/dvipdfm-x/spc_pdfm.c 2019-05-31 22:00:04.008964031 +0100 +@@ -597,6 +597,7 @@ + return dict; + } + ++#define SPC_PDFM_SUPPORT_ANNOT_TRANS 1 + static int + spc_handler_pdfm_annot (struct spc_env *spe, struct spc_arg *args) + { +@@ -604,7 +605,6 @@ + pdf_obj *annot_dict; + pdf_rect rect; + char *ident = NULL; +- pdf_coord cp; + transform_info ti; + + skip_white(&args->curptr, args->endptr); +@@ -642,19 +642,96 @@ + return -1; + } + +- cp.x = spe->x_user; cp.y = spe->y_user; +- pdf_dev_transform(&cp, NULL); +- if (ti.flags & INFO_HAS_USER_BBOX) { +- rect.llx = ti.bbox.llx + cp.x; +- rect.lly = ti.bbox.lly + cp.y; +- rect.urx = ti.bbox.urx + cp.x; +- rect.ury = ti.bbox.ury + cp.y; +- } else { +- rect.llx = cp.x; +- rect.lly = cp.y - spe->mag * ti.depth; +- rect.urx = cp.x + spe->mag * ti.width; +- rect.ury = cp.y + spe->mag * ti.height; ++#ifdef SPC_PDFM_SUPPORT_ANNOT_TRANS ++ { ++ pdf_coord cp1, cp2, cp3, cp4; ++ /* QuadPoints not working? */ ++#ifdef USE_QUADPOINTS ++ pdf_obj *qpoints; ++#endif ++ if (ti.flags & INFO_HAS_USER_BBOX) { ++ cp1.x = spe->x_user + ti.bbox.llx; ++ cp1.y = spe->y_user + ti.bbox.lly; ++ cp2.x = spe->x_user + ti.bbox.urx; ++ cp2.y = spe->y_user + ti.bbox.lly; ++ cp3.x = spe->x_user + ti.bbox.urx; ++ cp3.y = spe->y_user + ti.bbox.ury; ++ cp4.x = spe->x_user + ti.bbox.llx; ++ cp4.y = spe->y_user + ti.bbox.ury; ++ } else { ++ cp1.x = spe->x_user; ++ cp1.y = spe->y_user - spe->mag * ti.depth; ++ cp2.x = spe->x_user + spe->mag * ti.width; ++ cp2.y = spe->y_user - spe->mag * ti.depth; ++ cp3.x = spe->x_user + spe->mag * ti.width; ++ cp3.y = spe->y_user + spe->mag * ti.height; ++ cp4.x = spe->x_user; ++ cp4.y = spe->y_user + spe->mag * ti.height; ++ } ++ pdf_dev_transform(&cp1, NULL); ++ pdf_dev_transform(&cp2, NULL); ++ pdf_dev_transform(&cp3, NULL); ++ pdf_dev_transform(&cp4, NULL); ++ rect.llx = cp1.x; ++ if (cp2.x < rect.llx) ++ rect.llx = cp2.x; ++ if (cp3.x < rect.llx) ++ rect.llx = cp3.x; ++ if (cp4.x < rect.llx) ++ rect.llx = cp4.x; ++ rect.urx = cp1.x; ++ if (cp2.x > rect.urx) ++ rect.urx = cp2.x; ++ if (cp3.x > rect.urx) ++ rect.urx = cp3.x; ++ if (cp4.x > rect.urx) ++ rect.urx = cp4.x; ++ rect.lly = cp1.y; ++ if (cp2.y < rect.lly) ++ rect.lly = cp2.y; ++ if (cp3.y < rect.lly) ++ rect.lly = cp3.y; ++ if (cp4.y < rect.lly) ++ rect.lly = cp4.y; ++ rect.ury = cp1.y; ++ if (cp2.y > rect.ury) ++ rect.ury = cp2.y; ++ if (cp3.y > rect.ury) ++ rect.ury = cp3.y; ++ if (cp4.y > rect.ury) ++ rect.ury = cp4.y; ++#ifdef USE_QUADPOINTS ++ qpoints = pdf_new_array(); ++ pdf_add_array(qpoints, pdf_new_number(ROUND(cp1.x, 0.01))); ++ pdf_add_array(qpoints, pdf_new_number(ROUND(cp1.y, 0.01))); ++ pdf_add_array(qpoints, pdf_new_number(ROUND(cp2.x, 0.01))); ++ pdf_add_array(qpoints, pdf_new_number(ROUND(cp2.y, 0.01))); ++ pdf_add_array(qpoints, pdf_new_number(ROUND(cp3.x, 0.01))); ++ pdf_add_array(qpoints, pdf_new_number(ROUND(cp3.y, 0.01))); ++ pdf_add_array(qpoints, pdf_new_number(ROUND(cp4.x, 0.01))); ++ pdf_add_array(qpoints, pdf_new_number(ROUND(cp4.y, 0.01))); ++ pdf_add_dict(annot_dict, pdf_new_name("QuadPoints"), qpoints); ++#endif + } ++#else ++ { ++ pdf_coord cp; ++ ++ cp.x = spe->x_user; cp.y = spe->y_user; ++ pdf_dev_transform(&cp, NULL); ++ if (ti.flags & INFO_HAS_USER_BBOX) { ++ rect.llx = ti.bbox.llx + cp.x; ++ rect.lly = ti.bbox.lly + cp.y; ++ rect.urx = ti.bbox.urx + cp.x; ++ rect.ury = ti.bbox.ury + cp.y; ++ } else { ++ rect.llx = cp.x; ++ rect.lly = cp.y - spe->mag * ti.depth; ++ rect.urx = cp.x + spe->mag * ti.width; ++ rect.ury = cp.y + spe->mag * ti.height; ++ } ++ } ++#endif + + /* Order is important... */ + if (ident) +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/specials.c b/texlive-20190410-source/texk/dvipdfm-x/specials.c +--- a/texlive-20190410-source/texk/dvipdfm-x/specials.c 2019-03-29 22:13:05.000000000 +0000 ++++ b/texlive-20190410-source/texk/dvipdfm-x/specials.c 2019-05-31 22:00:04.008964031 +0100 +@@ -169,12 +169,12 @@ + switch (k) { + /* xpos and ypos must be position in device space here. */ + case K_OBJ__XPOS: +- cp.x = dvi_dev_xpos(); cp.y = 0.0; ++ cp.x = dvi_dev_xpos(); cp.y = dvi_dev_ypos(); + pdf_dev_transform(&cp, NULL); + value = pdf_new_number(ROUND(cp.x, .01)); + break; + case K_OBJ__YPOS: +- cp.x = 0.0; cp.y = dvi_dev_ypos(); ++ cp.x = dvi_dev_xpos(); cp.y = dvi_dev_ypos(); + pdf_dev_transform(&cp, NULL); + value = pdf_new_number(ROUND(cp.y, .01)); + break; +@@ -233,12 +233,12 @@ + for (k = 0; _rkeys[k] && strcmp(key, _rkeys[k]); k++); + switch (k) { + case K_OBJ__XPOS: +- cp.x = dvi_dev_xpos(); cp.y = 0.0; ++ cp.x = dvi_dev_xpos(); cp.y = dvi_dev_ypos(); + pdf_dev_transform(&cp, NULL); + value = pdf_new_number(ROUND(cp.x, .01)); + break; + case K_OBJ__YPOS: +- cp.x = 0.0; cp.y = dvi_dev_ypos(); ++ cp.x = dvi_dev_xpos(); cp.y = dvi_dev_ypos(); + pdf_dev_transform(&cp, NULL); + value = pdf_new_number(ROUND(cp.y, .01)); + break; +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/tt_cmap.c b/texlive-20190410-source/texk/dvipdfm-x/tt_cmap.c +--- a/texlive-20190410-source/texk/dvipdfm-x/tt_cmap.c 2019-02-25 10:27:33.000000000 +0000 ++++ b/texlive-20190410-source/texk/dvipdfm-x/tt_cmap.c 2019-05-31 22:00:04.009964032 +0100 +@@ -1,6 +1,6 @@ + /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + +- Copyright (C) 2007-2018 by Jin-Hwan Cho and Shunsaku Hirata, ++ Copyright (C) 2002-2019 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + This program is free software; you can redistribute it and/or modify +@@ -68,11 +68,12 @@ + struct cmap0 *map; + int i; + +- if (len < 256) +- ERROR("invalid cmap subtable"); ++ if (len < 256) { ++ WARN("invalid format 0 TT cmap subtable"); ++ return NULL; ++ } + + map = NEW(1, struct cmap0); +- + for (i = 0; i < 256; i++) + map->glyphIndexArray[i] = sfnt_get_byte(sfont); + +@@ -114,14 +115,14 @@ + struct cmap2 *map; + USHORT i, n; + +- if (len < 512) +- ERROR("invalid cmap subtable"); +- +- map = NEW(1, struct cmap2); ++ if (len < 512) { ++ WARN("invalid fromt2 TT cmap subtable"); ++ return NULL; ++ } + ++ map = NEW(1, struct cmap2); + for (i = 0; i < 256; i++) + map->subHeaderKeys[i] = sfnt_get_ushort(sfont); +- + for (n = 0, i = 0; i < 256; i++) { + map->subHeaderKeys[i] /= 8; + if (n < map->subHeaderKeys[i]) +@@ -129,7 +130,13 @@ + } + n += 1; /* the number of subHeaders is one plus the max of subHeaderKeys */ + +- map->subHeaders = NEW(n, struct SubHeader); ++ if (len < 512 + n * 8 ) { ++ WARN("invalid/truncated format2 TT cmap subtable"); ++ RELEASE(map); ++ return NULL; ++ } ++ ++ map->subHeaders = NEW(n, struct SubHeader); + for (i = 0; i < n; i++) { + map->subHeaders[i].firstCode = sfnt_get_ushort(sfont); + map->subHeaders[i].entryCount = sfnt_get_ushort(sfont); +@@ -222,8 +229,10 @@ + struct cmap4 *map; + USHORT i, n, segCount; + +- if (len < 8) +- ERROR("invalid cmap subtable"); ++ if (len < 8) { ++ WARN("invalid format 4 TT cmap subtable"); ++ return NULL; ++ } + + map = NEW(1, struct cmap4); + +@@ -288,19 +297,19 @@ + * Last segment maps 0xffff to gid 0 (?) + */ + i = segCount = map->segCountX2 / 2; +- while (i-- > 0 && cc <= map->endCount[i]) { ++ while (i-- > 0 && cc <= map->endCount[i]) { + if (cc >= map->startCount[i]) { + if (map->idRangeOffset[i] == 0) { +- gid = (cc + map->idDelta[i]) & 0xffff; ++ gid = (cc + map->idDelta[i]) & 0xffff; + } else if (cc == 0xffff && map->idRangeOffset[i] == 0xffff) { +- /* this is for protection against some old broken fonts... */ +- gid = 0; ++ /* this is for protection against some old broken fonts... */ ++ gid = 0; + } else { +- j = map->idRangeOffset[i] - (segCount - i) * 2; +- j = (cc - map->startCount[i]) + (j / 2); +- gid = map->glyphIndexArray[j]; +- if (gid != 0) +- gid = (gid + map->idDelta[i]) & 0xffff; ++ j = map->idRangeOffset[i] - (segCount - i) * 2; ++ j = (cc - map->startCount[i]) + (j / 2); ++ gid = map->glyphIndexArray[j]; ++ if (gid != 0) ++ gid = (gid + map->idDelta[i]) & 0xffff; + } + break; + } +@@ -323,14 +332,15 @@ + struct cmap6 *map; + USHORT i; + +- if (len < 4) +- ERROR("invalid cmap subtable"); ++ if (len < 4) { ++ WARN("invalid format 6 TT cmap subtable"); ++ return NULL; ++ } + + map = NEW(1, struct cmap6); + map->firstCode = sfnt_get_ushort(sfont); + map->entryCount = sfnt_get_ushort(sfont); +- map->glyphIndexArray = NEW(map->entryCount, USHORT); +- ++ map->glyphIndexArray = NEW(map->entryCount, USHORT); + for (i = 0; i < map->entryCount; i++) + map->glyphIndexArray[i] = sfnt_get_ushort(sfont); + +@@ -390,13 +400,14 @@ + struct cmap12 *map; + ULONG i; + +- if (len < 4) +- ERROR("invalid cmap subtable"); ++ if (len < 4) { ++ WARN("invalid format 12 TT cmap subtable"); ++ return NULL; ++ } + + map = NEW(1, struct cmap12); + map->nGroups = sfnt_get_ulong(sfont); + map->groups = NEW(map->nGroups, struct charGroup); +- + for (i = 0; i < map->nGroups; i++) { + map->groups[i].startCharCode = sfnt_get_ulong(sfont); + map->groups[i].endCharCode = sfnt_get_ulong(sfont); +@@ -427,8 +438,8 @@ + cccc <= map->groups[i].endCharCode) { + if (cccc >= map->groups[i].startCharCode) { + gid = (USHORT) ((cccc - +- map->groups[i].startCharCode + +- map->groups[i].startGlyphID) & 0xffff); ++ map->groups[i].startCharCode + ++ map->groups[i].startGlyphID) & 0xffff); + break; + } + } +@@ -510,6 +521,7 @@ + WARN("Unrecognized OpenType/TrueType cmap format."); + tt_cmap_release(cmap); + return NULL; ++ break; + } + + if (!cmap->map) { +@@ -526,24 +538,25 @@ + + if (cmap) { + if (cmap->map) { +- switch(cmap->format) { ++ switch (cmap->format) { + case 0: +- release_cmap0(cmap->map); +- break; ++ release_cmap0(cmap->map); ++ break; + case 2: +- release_cmap2(cmap->map); +- break; ++ release_cmap2(cmap->map); ++ break; + case 4: +- release_cmap4(cmap->map); +- break; ++ release_cmap4(cmap->map); ++ break; + case 6: +- release_cmap6(cmap->map); +- break; ++ release_cmap6(cmap->map); ++ break; + case 12: +- release_cmap12(cmap->map); +- break; ++ release_cmap12(cmap->map); ++ break; + default: +- ERROR("Unrecognized OpenType/TrueType cmap format."); ++ WARN("Unrecognized OpenType/TrueType cmap format: %d", cmap->format); ++ break; + } + } + RELEASE(cmap); +@@ -582,129 +595,20 @@ + gid = lookup_cmap12(cmap->map, (ULONG) cc); + break; + default: +- ERROR("Unrecognized OpenType/TrueType cmap subtable format"); ++ WARN("Unrecognized OpenType/TrueType cmap subtable format: %d", cmap->format); + break; + } + + return gid; + } + +-/* Sorry for placing this here. +- * We need to rewrite TrueType font support code... +- */ + +-#define WBUF_SIZE 1024 +-static unsigned char wbuf[WBUF_SIZE]; + + static unsigned char srange_min[2] = {0x00, 0x00}; + static unsigned char srange_max[2] = {0xff, 0xff}; + static unsigned char lrange_min[4] = {0x00, 0x00, 0x00, 0x00}; + static unsigned char lrange_max[4] = {0x7f, 0xff, 0xff, 0xff}; + +-static void +-load_cmap4 (struct cmap4 *map, +- unsigned char *GIDToCIDMap, +- otl_gsub *gsub_vert, otl_gsub *gsub_list, +- CMap *cmap, CMap *tounicode_add) +-{ +- USHORT c0, c1, gid, cid; +- USHORT j, d, segCount; +- USHORT ch; +- int i; +- +- segCount = map->segCountX2 / 2; +- for (i = segCount - 1; i >= 0 ; i--) { +- c0 = map->startCount[i]; +- c1 = map->endCount[i]; +- d = map->idRangeOffset[i] / 2 - (segCount - i); +- for (j = 0; j <= c1 - c0; j++) { +- ch = c0 + j; +- if (map->idRangeOffset[i] == 0) { +- gid = (ch + map->idDelta[i]) & 0xffff; +- } else if (c0 == 0xffff && c1 == 0xffff && +- map->idRangeOffset[i] == 0xffff) { +- /* this is for protection against some old broken fonts... */ +- gid = 0; +- } else { +- gid = (map->glyphIndexArray[j+d] + map->idDelta[i]) & 0xffff; +- } +- if (gid != 0 && gid != 0xffff) { +- if (gsub_list) +- otl_gsub_apply_chain(gsub_list, &gid); +- if (gsub_vert) +- otl_gsub_apply(gsub_vert, &gid); +- if (GIDToCIDMap) { +- cid = ((GIDToCIDMap[2*gid] << 8)|GIDToCIDMap[2*gid+1]); +- if (cid == 0) +- WARN("GID %u does not have corresponding CID %u.", gid, cid); +- } else { +- cid = gid; +- } +- wbuf[0] = 0; +- wbuf[1] = 0; +- wbuf[2] = (ch >> 8) & 0xff; +- wbuf[3] = ch & 0xff; +- wbuf[4] = (cid >> 8) & 0xff; +- wbuf[5] = cid & 0xff; +- CMap_add_cidchar(cmap, wbuf, 4, cid); +- if (tounicode_add) { +- unsigned char *p = wbuf + 6; +- size_t uc_len; +- uc_len = UC_UTF16BE_encode_char(ch, &p, wbuf + WBUF_SIZE -1 ); +- CMap_add_bfchar(tounicode_add, wbuf+4, 2, wbuf+6, uc_len); +- } +- } +- } +- } +- +- return; +-} +- +-static void +-load_cmap12 (struct cmap12 *map, +- unsigned char *GIDToCIDMap, +- otl_gsub *gsub_vert, otl_gsub *gsub_list, +- CMap *cmap, CMap *tounicode_add) +-{ +- ULONG i, ch; /* LONG ? */ +- USHORT gid, cid; +- +- for (i = 0; i < map->nGroups; i++) { +- for (ch = map->groups[i].startCharCode; +- ch <= map->groups[i].endCharCode; +- ch++) { +- int d = ch - map->groups[i].startCharCode; +- gid = (USHORT) ((map->groups[i].startGlyphID + d) & 0xffff); +- if (gsub_list) +- otl_gsub_apply_chain(gsub_list, &gid); +- if (gsub_vert) +- otl_gsub_apply(gsub_vert, &gid); +- if (GIDToCIDMap) { +- cid = ((GIDToCIDMap[2*gid] << 8)|GIDToCIDMap[2*gid+1]); +- if (cid == 0) +- WARN("GID %u does not have corresponding CID %u.", gid, cid); +- } else { +- cid = gid; +- } +- wbuf[0] = (ch >> 24) & 0xff; +- wbuf[1] = (ch >> 16) & 0xff; +- wbuf[2] = (ch >> 8) & 0xff; +- wbuf[3] = ch & 0xff; +- wbuf[4] = (cid >> 8) & 0xff; +- wbuf[5] = cid & 0xff; +- CMap_add_cidchar(cmap, wbuf, 4, cid); +- if (tounicode_add) { +- unsigned char *p = wbuf + 6; +- size_t uc_len; +- uc_len = UC_UTF16BE_encode_char(ch, &p, wbuf + WBUF_SIZE -1 ); +- CMap_add_bfchar(tounicode_add, wbuf+4, 2, wbuf+6, uc_len); +- } +- } +- } +- +- return; +-} +- + /* OpenType CIDFont: + * + * We don't use GID for them. OpenType cmap table is for +@@ -717,78 +621,37 @@ + #include "cff_dict.h" + #include "cff.h" + +-static int +-handle_CIDFont (sfnt *sfont, +- unsigned char **GIDToCIDMap, CIDSysInfo *csi) +-{ +- cff_font *cffont; +- int offset, i; +- card16 num_glyphs, gid; +- cff_charsets *charset; +- unsigned char *map; +- struct tt_maxp_table *maxp; +- +- ASSERT(csi); +- +- offset = sfnt_find_table_pos(sfont, "CFF "); +- if (offset == 0) { +- csi->registry = NULL; +- csi->ordering = NULL; +- *GIDToCIDMap = NULL; +- return 0; +- } +- +- maxp = tt_read_maxp_table(sfont); +- num_glyphs = (card16) maxp->numGlyphs; +- RELEASE(maxp); +- if (num_glyphs < 1) +- ERROR("No glyph contained in this font..."); +- +- cffont = cff_open(sfont->stream, offset, 0); +- if (!cffont) +- ERROR("Could not open CFF font..."); +- +- +- if (!(cffont->flag & FONTTYPE_CIDFONT)) { +- cff_close(cffont); +- csi->registry = NULL; +- csi->ordering = NULL; +- *GIDToCIDMap = NULL; +- return 0; +- } ++/* This should be moved to cff.c */ ++static void ++create_GIDToCIDMap (uint16_t *GIDToCIDMap, uint16_t num_glyphs, cff_font *cffont) ++{ ++ cff_charsets *charset; ++ uint16_t gid, i; + +- if (!cff_dict_known(cffont->topdict, "ROS")) { +- ERROR("No CIDSystemInfo???"); +- } else { +- card16 reg, ord; ++ ASSERT(GIDToCIDMap); + +- reg = (card16) cff_dict_get(cffont->topdict, "ROS", 0); +- ord = (card16) cff_dict_get(cffont->topdict, "ROS", 1); ++ if (!cffont || !(cffont->flag & FONTTYPE_CIDFONT)) { ++ for (gid = 0; gid < num_glyphs; gid++) { ++ GIDToCIDMap[gid] = gid; ++ } + +- csi->registry = cff_get_string(cffont, reg); +- csi->ordering = cff_get_string(cffont, ord); +- csi->supplement = (int) cff_dict_get(cffont->topdict, "ROS", 2); ++ return; + } + +- cff_read_charsets(cffont); +- charset = cffont->charsets; +- if (!charset) { +- ERROR("No CFF charset data???"); +- } ++ memset(GIDToCIDMap, 0, num_glyphs*sizeof(uint16_t)); + +- map = NEW(65536 * 2, unsigned char); +- memset(map, 0, 65536 * 2); ++ charset = cffont->charsets; ++ if (!charset) ++ return; + switch (charset->format) { + case 0: + { + s_SID *cids; /* CID... */ +- ++ + cids = charset->data.glyphs; +- for (gid = 1, i = 0; +- i < charset->num_entries; i++) { +- map[2*gid ] = (cids[i] >> 8) & 0xff; +- map[2*gid+1] = cids[i] & 0xff; +- gid++; ++ for (gid = 1, i = 0; i < charset->num_entries; i++) { ++ GIDToCIDMap[gid] = cids[i]; ++ gid++; + } + } + break; +@@ -798,16 +661,14 @@ + card16 cid, count; + + ranges = charset->data.range1; +- for (gid = 1, i = 0; +- i < charset->num_entries; i++) { +- cid = ranges[i].first; +- count = ranges[i].n_left + 1; /* card8 */ +- while (count-- > 0 && +- gid <= num_glyphs) { +- map[2*gid ] = (cid >> 8) & 0xff; +- map[2*gid + 1] = cid & 0xff; +- gid++; cid++; +- } ++ for (gid = 1, i = 0; i < charset->num_entries; i++) { ++ cid = ranges[i].first; ++ count = ranges[i].n_left + 1; /* card8 */ ++ while (count-- > 0 && gid <= num_glyphs) { ++ GIDToCIDMap[gid] = cid; ++ gid++; ++ cid++; ++ } + } + } + break; +@@ -817,55 +678,52 @@ + card16 cid, count; + + ranges = charset->data.range2; +- if (charset->num_entries == 1 && +- ranges[0].first == 1) { +- /* "Complete" CIDFont */ +- RELEASE(map); map = NULL; ++ if (charset->num_entries == 1 && ranges[0].first == 1) { ++ /* "Complete" CIDFont */ ++ for (gid = 0; gid < num_glyphs; gid++) { ++ GIDToCIDMap[gid] = gid; ++ } + } else { +- /* Not trivial mapping */ +- for (gid = 1, i = 0; +- i < charset->num_entries; i++) { +- cid = ranges[i].first; +- count = ranges[i].n_left + 1; +- while (count-- > 0 && +- gid <= num_glyphs) { +- map[2*gid] = (cid >> 8) & 0xff; +- map[2*gid+1] = cid & 0xff; +- gid++; cid++; +- } +- } ++ /* Not trivial mapping */ ++ for (gid = 1, i = 0; i < charset->num_entries; i++) { ++ cid = ranges[i].first; ++ count = ranges[i].n_left + 1; ++ while (count-- > 0 && gid <= num_glyphs) { ++ GIDToCIDMap[gid] = cid; ++ gid++; ++ cid++; ++ } ++ } + } + } + break; + default: +- RELEASE(map); map = NULL; +- ERROR("Unknown CFF charset format...: %d", charset->format); ++ WARN("Unknown CFF charset format...: %d", charset->format); + break; + } +- cff_close(cffont); + +- *GIDToCIDMap = map; +- return 1; ++ return; + } + + static int is_PUA_or_presentation (unsigned int uni) + { + /* Some of CJK Radicals Supplement and Kangxi Radicals + * are commonly double encoded, lower the priority. ++ * CJK Compatibility Ideographs & Supplement added. + */ + return ((uni >= 0x2E80 && uni <= 0x2EF3) || (uni >= 0x2F00 && uni <= 0x2FD5) || + (uni >= 0xE000 && uni <= 0xF8FF) || (uni >= 0xFB00 && uni <= 0xFB4F) || ++ (uni >= 0xF900 && uni <= 0xFAFF) || (uni >= 0x2F800 && uni <= 0x2FA1F) || + (uni >= 0xF0000 && uni <= 0xFFFFD) || (uni >= 0x100000 && uni <= 0x10FFFD)); + } + +-static char* +-sfnt_get_glyphname(struct tt_post_table *post, cff_font *cffont, USHORT gid) ++static char * ++lookup_glyph_name (struct tt_post_table *post, cff_font *cffont, USHORT gid) + { +- char* name = NULL; ++ char *name = NULL; + + if (post) + name = tt_get_glyphname(post, gid); +- + if (!name && cffont) + name = cff_get_glyphname(cffont, gid); + +@@ -881,94 +739,82 @@ + #define is_used_char2(b,c) (((b)[(c)/8]) & (1 << (7-((c)%8)))) + #endif + +-static USHORT +-handle_subst_glyphs (CMap *cmap, +- CMap *cmap_add, +- const char *used_glyphs, +- sfnt *sfont, +- cff_font *cffont) ++static int32_t ++handle_subst_glyphs (CMap *cmap, CMap *cmap_add, char *used_chars) + { +- USHORT count; +- USHORT i; +- struct tt_post_table *post = NULL; +- +- if (!cmap_add) +- post = tt_read_post_table(sfont); +- +- for (count = 0, i = 0; i < 8192; i++) { +- int j; +- int32_t len; +- int inbytesleft, outbytesleft; +- const unsigned char *inbuf; +- unsigned char *outbuf; ++ int32_t count = 0; ++ int32_t cid; + +- if (used_glyphs[i] == 0) ++ for (cid = 0; cid < 65536; cid++) { ++ if (!is_used_char2(used_chars, cid)) + continue; ++ else { ++ unsigned char buf[256]; ++ int inbytesleft = 2, outbytesleft = 254; ++ size_t len; ++ unsigned char *outbuf = buf + 2; ++ const unsigned char *inbuf = buf; ++ ++ buf[0] = (cid >> 8) & 0xff; ++ buf[1] = cid & 0xff; ++ CMap_decode(cmap_add, &inbuf, &inbytesleft, &outbuf, &outbytesleft); ++ if (inbytesleft == 0) { ++ len = 254 - outbytesleft; ++ CMap_add_bfchar(cmap, buf, 2, buf + 2, len); ++ used_chars[cid / 8] &= ~(1 << (7 - (cid % 8))); ++ count++; ++ } ++ } ++ } + +- for (j = 0; j < 8; j++) { +- USHORT gid = 8 * i + j; ++ return count; ++} + +- if (!is_used_char2(used_glyphs, gid)) +- continue; ++static int32_t ++add_ToUnicode_via_glyph_name (CMap *cmap, char *used_chars, USHORT num_glyphs, ++ uint16_t *GIDToCIDMap, ++ sfnt *sfont, cff_font *cffont) ++{ ++ int32_t count = 0; ++ USHORT gid; ++ struct tt_post_table *post = NULL; + +- if (!cmap_add) { +-#define MAX_UNICODES 16 +- /* try to look up Unicode values from the glyph name... */ +- char* name; +- int32_t unicodes[MAX_UNICODES]; +- int unicode_count = -1; +- name = sfnt_get_glyphname(post, cffont, gid); +- if (name) { +- unicode_count = agl_get_unicodes(name, unicodes, MAX_UNICODES); +- } ++ post = tt_read_post_table(sfont); ++ if (!post && !cffont) ++ return count; ++ ++ for (gid = 0; gid < num_glyphs; gid++) { ++ uint16_t cid = GIDToCIDMap[gid]; ++ if (is_used_char2(used_chars, cid)) { ++#define MAX_UNICODES 32 ++ char *name; ++ int32_t unicodes[MAX_UNICODES]; ++ int unicode_count = -1; ++ ++ name = lookup_glyph_name(post, cffont, gid); ++ if (name) { ++ unicode_count = agl_get_unicodes(name, unicodes, MAX_UNICODES); + #undef MAX_UNICODES +- if (unicode_count == -1) { +- if(dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) { +- if (name) +- MESG("No Unicode mapping available: GID=%u, name=%s\n", gid, name); +- else +- MESG("No Unicode mapping available: GID=%u\n", gid); +- } +- } else { +- /* the Unicode characters go into wbuf[2] and following, in UTF16BE */ +- /* we rely on WBUF_SIZE being more than adequate for MAX_UNICODES */ +- unsigned char* p = wbuf + 2; +- int k; +- len = 0; ++ RELEASE(name); ++ if (unicode_count > 0) { ++ unsigned char *buf; ++ unsigned char *p, *endptr; ++ int k; ++ size_t len = 0; ++ ++ buf = NEW(unicode_count*4+2, unsigned char); ++ p = buf + 2; ++ endptr = buf + (unicode_count * 4 + 2); + for (k = 0; k < unicode_count; ++k) { +- len += UC_UTF16BE_encode_char(unicodes[k], &p, wbuf+WBUF_SIZE); ++ len += UC_UTF16BE_encode_char(unicodes[k], &p, endptr); + } +- wbuf[0] = (gid >> 8) & 0xff; +- wbuf[1] = gid & 0xff; +- CMap_add_bfchar(cmap, wbuf, 2, wbuf + 2, len); +- } +- RELEASE(name); +- } else { +- wbuf[0] = (gid >> 8) & 0xff; +- wbuf[1] = gid & 0xff; +- +- inbuf = wbuf; +- inbytesleft = 2; +- outbuf = wbuf + 2; +- outbytesleft = WBUF_SIZE - 2; +- CMap_decode(cmap_add, &inbuf, &inbytesleft, &outbuf, &outbytesleft); +- +- if (inbytesleft != 0) { +- WARN("CMap conversion failed..."); +- } else { +- len = WBUF_SIZE - 2 - outbytesleft; +- CMap_add_bfchar(cmap, wbuf, 2, wbuf + 2, len); ++ buf[0] = (cid >> 8) & 0xff; ++ buf[1] = cid & 0xff; ++ CMap_add_bfchar(cmap, buf, 2, buf + 2, len); ++ used_chars[cid / 8] &= ~(1 << (7 - (cid % 8))); + count++; + +- if (dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) { +- int _i; +- +- MESG("otf_cmap>> Additional ToUnicode mapping: <%04X> <", gid); +- for (_i = 0; _i < len; _i++) { +- MESG("%02X", wbuf[2 + _i]); +- } +- MESG(">\n"); +- } ++ RELEASE(buf); + } + } + } +@@ -980,70 +826,11 @@ + return count; + } + +-static cff_font * +-prepare_CIDFont_from_sfnt(sfnt* sfont) +-{ +- cff_font *cffont; +- unsigned offset = 0; +- +- if (sfont->type != SFNT_TYPE_POSTSCRIPT || +- sfnt_read_table_directory(sfont, 0) < 0 || +- (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) { +- return NULL; +- } +- +- cffont = cff_open(sfont->stream, offset, 0); +- if (!cffont) +- return NULL; +- +- cff_read_charsets(cffont); +- return cffont; +-} +- +-static USHORT +-add_to_cmap_if_used (CMap *cmap, +- cff_font *cffont, +- char *used_chars, +- USHORT gid, +- ULONG ch) +-{ +- USHORT count = 0; +- USHORT cid = cffont ? cff_charsets_lookup_inverse(cffont, gid) : gid; +- if (is_used_char2(used_chars, cid)) { +- int len; +- unsigned char *p = wbuf + 2; +- +- count++; +- +- wbuf[0] = (cid >> 8) & 0xff; +- wbuf[1] = (cid & 0xff); +- len = UC_UTF16BE_encode_char((int32_t) ch, &p, wbuf + WBUF_SIZE); +- CMap_add_bfchar(cmap, wbuf, 2, wbuf + 2, len); +- +- /* Skip PUA characters and alphabetic presentation forms, allowing +- * handle_subst_glyphs() as it might find better mapping. Fixes the +- * mapping of ligatures encoded in PUA in fonts like Linux Libertine +- * and old Adobe fonts. +- */ +- if (!is_PUA_or_presentation(ch)) { +- /* Avoid duplicate entry +- * There are problem when two Unicode code is mapped to +- * single glyph... +- */ +- used_chars[cid / 8] &= ~(1 << (7 - (cid % 8))); +- } +- } +- +- return count; +-} +- +-static USHORT +-create_ToUnicode_cmap4 (CMap *cmap, +- struct cmap4 *map, +- char *used_chars, +- cff_font *cffont) ++static void ++create_inverse_cmap4 (int32_t *map_base, int32_t *map_sub, USHORT num_glyphs, ++ struct cmap4 *map) + { +- USHORT count = 0, segCount = map->segCountX2 / 2; ++ USHORT segCount = map->segCountX2 / 2; + USHORT i, j; + + for (i = 0; i < segCount; i++) { +@@ -1062,32 +849,33 @@ + } else { + gid = (map->glyphIndexArray[j + d] + map->idDelta[i]) & 0xffff; + } +- +- count += add_to_cmap_if_used(cmap, cffont, used_chars, gid, ch); ++ if (is_PUA_or_presentation(ch)) { ++ map_sub[gid] = ch; ++ } else { ++ map_base[gid] = ch; ++ } + } + } +- +- return count; + } + +-static USHORT +-create_ToUnicode_cmap12 (CMap *cmap, +- struct cmap12 *map, +- char *used_chars, +- cff_font *cffont) ++static void ++create_inverse_cmap12 (int32_t *map_base, int32_t *map_sub, USHORT num_glyphs, ++ struct cmap12 *map) + { +- ULONG i, ch, count = 0; ++ ULONG i, ch; + + for (i = 0; i < map->nGroups; i++) { + for (ch = map->groups[i].startCharCode; + ch <= map->groups[i].endCharCode; ch++) { + int d = ch - map->groups[i].startCharCode; + USHORT gid = (USHORT) ((map->groups[i].startGlyphID + d) & 0xffff); +- count += add_to_cmap_if_used(cmap, cffont, used_chars, gid, ch); ++ if (is_PUA_or_presentation(ch)) { ++ map_sub[gid] = ch; ++ } else { ++ map_base[gid] = ch; ++ } + } + } +- +- return count; + } + + /* NOTE: Reverse mapping code which had been placed here is removed since: +@@ -1096,60 +884,163 @@ + * Especially, the second one causes problems. + */ + static pdf_obj * +-create_ToUnicode_cmap (tt_cmap *ttcmap, ++create_ToUnicode_cmap (tt_cmap *ttcmap, + const char *cmap_name, +- CMap *cmap_add, ++ CMap *cmap_add, + const char *used_chars, +- sfnt *sfont) ++ sfnt *sfont) + { +- pdf_obj *stream = NULL; +- CMap *cmap; +- USHORT count = 0; +- cff_font *cffont = prepare_CIDFont_from_sfnt(sfont); +- char is_cidfont = cffont && (cffont->flag & FONTTYPE_CIDFONT); +- +- cmap = CMap_new(); +- CMap_set_name (cmap, cmap_name); +- CMap_set_wmode(cmap, 0); +- CMap_set_type (cmap, CMAP_TYPE_TO_UNICODE); +- CMap_set_CIDSysInfo(cmap, &CSI_UNICODE); +- CMap_add_codespacerange(cmap, srange_min, srange_max, 2); ++ pdf_obj *stream = NULL; ++ int32_t *map_base = NULL, *map_sub = NULL; ++ USHORT gid, num_glyphs = 0; + +- /* cmap_add here stores information about all unencoded glyphs which can be +- * accessed only through OT Layout GSUB table. +- */ +- { +- char used_chars_copy[8192]; +- memcpy(used_chars_copy, used_chars, 8192); ++ ASSERT(ttcmap); + +- /* For create_ToUnicode_cmap{4,12}(), cffont is for GID -> CID lookup, +- * so it is only needed for CID fonts. */ +- switch (ttcmap->format) { +- case 4: +- count = create_ToUnicode_cmap4(cmap, ttcmap->map, used_chars_copy, +- is_cidfont ? cffont : NULL); +- break; +- case 12: +- count = create_ToUnicode_cmap12(cmap, ttcmap->map, used_chars_copy, +- is_cidfont ? cffont : NULL); +- break; ++ /* Get num_glyphs from maxp talbe */ ++ { ++ struct tt_maxp_table *maxp; ++ ++ maxp = tt_read_maxp_table(sfont); ++ if (maxp) { ++ num_glyphs = maxp->numGlyphs; ++ RELEASE(maxp); + } ++ } + +- /* For handle_subst_glyphs(), cffont is for GID -> glyph name lookup, so +- * it is only needed for non-CID fonts. */ +- count += handle_subst_glyphs(cmap, cmap_add, used_chars_copy, sfont, +- is_cidfont ? NULL : cffont); ++ /* Initialize GID to Unicode mapping table */ ++ map_base = NEW(num_glyphs, int32_t); ++ map_sub = NEW(num_glyphs, int32_t); ++ for (gid = 0; gid < num_glyphs; gid++) { ++ map_base[gid] = -1; ++ map_sub [gid] = -1; + } + +- if (count < 1) +- stream = NULL; +- else { +- stream = CMap_create_stream(cmap); ++ /* Create "base" mapping from inverse mapping of OpenType cmap */ ++ switch (ttcmap->format) { ++ case 4: ++ create_inverse_cmap4(map_base, map_sub, num_glyphs, ttcmap->map); ++ break; ++ case 12: ++ create_inverse_cmap12(map_base, map_sub, num_glyphs, ttcmap->map); ++ break; + } +- CMap_release(cmap); + +- if (cffont) +- cff_close(cffont); ++ /* Now create ToUnicode CMap stream */ ++ { ++ CMap *cmap; ++ int32_t count; ++ cff_font *cffont = NULL; ++ char is_cidfont = 0; ++ uint16_t *GIDToCIDMap = NULL; ++ char *used_chars_copy = NULL; ++ ++ if (sfont->type == SFNT_TYPE_POSTSCRIPT) { ++ ULONG offset; ++ offset = sfnt_find_table_pos(sfont, "CFF "); ++ cffont = cff_open(sfont->stream, offset, 0); ++ cff_read_charsets(cffont); ++ } ++ is_cidfont = cffont && (cffont->flag & FONTTYPE_CIDFONT); ++ ++ /* GIT to CID mapping info. */ ++ GIDToCIDMap = NEW(num_glyphs, uint16_t); ++ if (is_cidfont) { ++ create_GIDToCIDMap(GIDToCIDMap, num_glyphs, cffont); ++ } else { ++ for (gid = 0; gid < num_glyphs; gid++) { ++ GIDToCIDMap[gid] = gid; ++ } ++ } ++ cmap = CMap_new(); ++ CMap_set_name (cmap, cmap_name); ++ CMap_set_wmode(cmap, 0); ++ CMap_set_type (cmap, CMAP_TYPE_TO_UNICODE); ++ CMap_set_CIDSysInfo(cmap, &CSI_UNICODE); ++ CMap_add_codespacerange(cmap, srange_min, srange_max, 2); ++ ++ count = 0; ++ used_chars_copy = NEW(8192, char); ++ memcpy(used_chars_copy, used_chars, 8192); ++ for (gid = 0; gid < num_glyphs; gid++) { ++ uint16_t cid = GIDToCIDMap[gid]; ++ if (is_used_char2(used_chars_copy, cid)) { ++ int32_t ch; ++ unsigned char src[2], dst[4]; ++ unsigned char *p = dst, *endptr = dst + 4; ++ size_t len; ++ ++ ch = map_base[gid]; ++ if (UC_is_valid(ch)) { ++ src[0] = (cid >> 8) & 0xff; ++ src[1] = cid & 0xff; ++ len = UC_UTF16BE_encode_char(ch, &p, endptr); ++ CMap_add_bfchar(cmap, src, 2, dst, len); ++ used_chars_copy[cid / 8] &= ~(1 << (7 - (cid % 8))); ++ count++; ++ } ++ } ++ } ++ ++ /* cmap_add here stores information about all unencoded glyphs which can be ++ * accessed only through OT Layout GSUB table. ++ * This is only availabel when encoding is "unicode". ++ */ ++ if (cmap_add) { ++ count += handle_subst_glyphs(cmap, cmap_add, used_chars_copy); ++ } else { ++ /* Else, try gathering information from GSUB tables */ ++ count += otl_gsub_add_ToUnicode(cmap, used_chars_copy, ++ map_base, map_sub, num_glyphs, ++ GIDToCIDMap, sfont); ++ } ++ /* Find Unicode mapping via PostScript glyph names... */ ++ count += add_ToUnicode_via_glyph_name(cmap, used_chars_copy, num_glyphs, ++ GIDToCIDMap, sfont, is_cidfont ? NULL : cffont); ++ if (cffont) ++ cff_close(cffont); ++ ++ /* Finaly, PUA and presentation forms... */ ++ for (gid = 0; gid < num_glyphs; gid++) { ++ uint16_t cid = GIDToCIDMap[gid]; ++ if (is_used_char2(used_chars_copy, cid)) { ++ int32_t ch; ++ unsigned char src[2], dst[4]; ++ unsigned char *p = dst, *endptr = dst + 4; ++ size_t len; ++ ++ ch = map_sub[gid]; ++ if (UC_is_valid(ch)) { ++ src[0] = (cid >> 8) & 0xff; ++ src[1] = cid & 0xff; ++ len = UC_UTF16BE_encode_char(ch, &p, endptr); ++ CMap_add_bfchar(cmap, src, 2, dst, len); ++ used_chars_copy[cid / 8] &= ~(1 << (7 - (cid % 8))); ++ count++; ++ } ++ } ++ } ++ ++ /* Check for missing mapping */ ++ if (dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) { ++ for (gid = 0; gid < num_glyphs; gid++) { ++ uint16_t cid = GIDToCIDMap[gid]; ++ if (is_used_char2(used_chars_copy, cid)) { ++ WARN("Unable to find ToUnicode mapping for glyph CID=%u (GID=%u)", cid, gid); ++ } ++ } ++ } ++ RELEASE(GIDToCIDMap); ++ RELEASE(used_chars_copy); ++ ++ if (count < 1) ++ stream = NULL; ++ else { ++ stream = CMap_create_stream(cmap); ++ } ++ CMap_release(cmap); ++ } ++ RELEASE(map_base); ++ RELEASE(map_sub); + + return stream; + } +@@ -1169,29 +1060,27 @@ + + pdf_obj * + otf_create_ToUnicode_stream (const char *font_name, +- int ttc_index, /* 0 for non-TTC */ ++ int ttc_index, /* 0 for non-TTC */ + const char *basefont, + const char *used_chars) + { +- pdf_obj *cmap_ref = NULL; +- int res_id; +- pdf_obj *cmap_obj = NULL; +- CMap *cmap_add; +- int cmap_add_id; +- tt_cmap *ttcmap; +- char *cmap_name, *cmap_add_name; +- FILE *fp = NULL; +- sfnt *sfont; +- ULONG offset = 0; +- int i; ++ pdf_obj *cmap_ref = NULL; /* returned value */ ++ CMap *cmap_add = NULL; ++ char *cmap_name; ++ FILE *fp = NULL; ++ sfnt *sfont; ++ ULONG offset = 0; ++ tt_cmap *ttcmap; ++ int cmap_id, cmap_add_id; ++ int i; + + cmap_name = NEW(strlen(basefont)+strlen("-UTF16")+1, char); + sprintf(cmap_name, "%s-UTF16", basefont); + +- res_id = pdf_findresource("CMap", cmap_name); +- if (res_id >= 0) { ++ cmap_id = pdf_findresource("CMap", cmap_name); ++ if (cmap_id >= 0) { + RELEASE(cmap_name); +- cmap_ref = pdf_get_resource_reference(res_id); ++ cmap_ref = pdf_get_resource_reference(cmap_id); + return cmap_ref; + } + +@@ -1212,7 +1101,10 @@ + } + + if (!sfont) { +- ERROR("Could not open OpenType/TrueType font file \"%s\"", font_name); ++ WARN("Could not open OpenType/TrueType font file \"%s\"", font_name); ++ RELEASE(cmap_name); ++ DPXFCLOSE(fp); ++ return NULL; + } + + switch (sfont->type) { +@@ -1222,7 +1114,11 @@ + case SFNT_TYPE_TTC: + offset = ttc_read_offset(sfont, ttc_index); + if (offset == 0) { +- ERROR("Invalid TTC index"); ++ WARN("Invalid TTC index for font: %s", font_name); ++ sfnt_close(sfont); ++ DPXFCLOSE(fp); ++ RELEASE(cmap_name); ++ return NULL; + } + break; + default: +@@ -1231,111 +1127,180 @@ + } + + if (sfnt_read_table_directory(sfont, offset) < 0) { +- ERROR("Could not read OpenType/TrueType table directory."); ++ WARN("Could not read OpenType/TrueType table directory: %s", font_name); ++ sfnt_close(sfont); ++ DPXFCLOSE(fp); ++ RELEASE(cmap_name); ++ return NULL; + } + +- cmap_add_name = NEW(strlen(font_name)+strlen(",000-UCS32-Add")+1, char); +- sprintf(cmap_add_name, "%s,%03d-UCS32-Add", font_name, ttc_index); +- cmap_add_id = CMap_cache_find(cmap_add_name); +- RELEASE(cmap_add_name); +- if (cmap_add_id < 0) { +- cmap_add = NULL; +- } else { +- cmap_add = CMap_cache_get(cmap_add_id); ++ /* cmap_add is used for storing information on ToUnicode mapping for ++ * unencoded glyphs which can be reached only through GSUB substitution. ++ * This is available only when "unicode" is specified in the encoding ++ * field of fontmap. We remember the inverse mapping via cmap_add in this ++ * case. ++ */ ++ { ++ char *cmap_add_name; ++ ++ cmap_add_name = NEW(strlen(font_name)+strlen(",000-UCS32-Add")+1, char); ++ sprintf(cmap_add_name, "%s,%03d-UCS32-Add", font_name, ttc_index); ++ cmap_add_id = CMap_cache_find(cmap_add_name); ++ RELEASE(cmap_add_name); ++ if (cmap_add_id < 0) { ++ cmap_add = NULL; ++ } else { ++ cmap_add = CMap_cache_get(cmap_add_id); ++ } + } + +- CMap_set_silent(1); /* many warnings without this... */ ++ ttcmap = NULL; + for (i = 0; i < sizeof(cmap_plat_encs) / sizeof(cmap_plat_enc_rec); ++i) { + ttcmap = tt_cmap_read(sfont, cmap_plat_encs[i].platform, cmap_plat_encs[i].encoding); + if (!ttcmap) + continue; + + if (ttcmap->format == 4 || ttcmap->format == 12) { +- cmap_obj = create_ToUnicode_cmap(ttcmap, cmap_name, cmap_add, used_chars, sfont); + break; ++ } else { ++ tt_cmap_release(ttcmap); ++ ttcmap = NULL; + } + } +-#if defined(LIBDPX) +- if (cmap_obj == NULL && dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) +-#else +- if (cmap_obj == NULL) +-#endif /* LIBDPX */ +- WARN("Unable to read OpenType/TrueType Unicode cmap table."); +- tt_cmap_release(ttcmap); +- CMap_set_silent(0); +- +- if (cmap_obj) { +- res_id = pdf_defineresource("CMap", cmap_name, +- cmap_obj, PDF_RES_FLUSH_IMMEDIATE); +- cmap_ref = pdf_get_resource_reference(res_id); +- } else { +- cmap_ref = NULL; ++ if (ttcmap) { ++ pdf_obj *cmap_obj; ++ ++ CMap_set_silent(1); /* many warnings without this... */ ++ cmap_obj = create_ToUnicode_cmap(ttcmap, cmap_name, cmap_add, used_chars, sfont); ++ CMap_set_silent(0); ++ if (cmap_obj) { ++ cmap_id = pdf_defineresource("CMap", cmap_name, ++ cmap_obj, PDF_RES_FLUSH_IMMEDIATE); ++ cmap_ref = pdf_get_resource_reference(cmap_id); ++ } ++ tt_cmap_release(ttcmap); + } +- RELEASE(cmap_name); + ++ /* Cleanup */ ++ RELEASE(cmap_name); + sfnt_close(sfont); +- if (fp) +- DPXFCLOSE(fp); ++ DPXFCLOSE(fp); ++ ++#ifndef LIBDPX ++ if (!cmap_ref) { ++ WARN("Creating ToUnicode CMap failed for \"%s\"", font_name); ++ } ++#endif + + return cmap_ref; + } + +-static int +-load_base_CMap (const char *cmap_name, CMap *tounicode_add, int wmode, +- CIDSysInfo *csi, unsigned char *GIDToCIDMap, +- otl_gsub *gsub_vert, otl_gsub *gsub_list, +- tt_cmap *ttcmap) +-{ +- int cmap_id; + +- cmap_id = CMap_cache_find(cmap_name); +- if (cmap_id < 0) { +- CMap *cmap; ++/* Creating input CMaps from OT cmap table */ + +- cmap = CMap_new(); +- CMap_set_name (cmap, cmap_name); +- CMap_set_type (cmap, CMAP_TYPE_CODE_TO_CID); +- CMap_set_wmode(cmap, wmode); +- CMap_add_codespacerange(cmap, lrange_min, lrange_max, 4); ++static void ++load_cmap4 (struct cmap4 *map, uint16_t *GIDToCIDMap, USHORT num_glyphs, ++ otl_gsub *gsub_vert, otl_gsub *gsub_list, ++ CMap *cmap, int32_t *map_base, int32_t *map_sub) ++{ ++ USHORT c0, c1, gid, cid; ++ USHORT j, d, segCount; ++ USHORT ch; ++ int i; ++ unsigned char buf[4]; + +- if (csi) { /* CID */ +- CMap_set_CIDSysInfo(cmap, csi); +- } else { +- CMap_set_CIDSysInfo(cmap, &CSI_IDENTITY); ++ segCount = map->segCountX2 / 2; ++ for (i = segCount - 1; i >= 0 ; i--) { ++ c0 = map->startCount[i]; ++ c1 = map->endCount[i]; ++ d = map->idRangeOffset[i] / 2 - (segCount - i); ++ for (j = 0; j <= c1 - c0; j++) { ++ ch = c0 + j; ++ if (map->idRangeOffset[i] == 0) { ++ gid = (ch + map->idDelta[i]) & 0xffff; ++ } else if (c0 == 0xffff && c1 == 0xffff && map->idRangeOffset[i] == 0xffff) { ++ /* this is for protection against some old broken fonts... */ ++ gid = 0; ++ } else { ++ gid = (map->glyphIndexArray[j+d] + map->idDelta[i]) & 0xffff; ++ } ++ if (gid != 0 && gid != 0xffff) { ++ /* Apply GSUB features */ ++ if (gsub_list) ++ otl_gsub_apply_chain(gsub_list, &gid); ++ if (gsub_vert) ++ otl_gsub_apply(gsub_vert, &gid); ++ cid = (gid < num_glyphs) ? GIDToCIDMap[gid] : 0; ++ buf[0] = 0; ++ buf[1] = 0; ++ buf[2] = (ch >> 8) & 0xff; ++ buf[3] = ch & 0xff; ++ CMap_add_cidchar(cmap, buf, 4, cid); ++ /* For ToUnicode creation */ ++ if (map_base && map_sub) { ++ if (is_PUA_or_presentation(ch)) { ++ map_sub[gid] = ch; ++ } else { ++ map_base[gid] = ch; ++ } ++ } ++ } + } ++ } + +- if (ttcmap->format == 12) { +- load_cmap12(ttcmap->map, GIDToCIDMap, gsub_vert, gsub_list, +- cmap, tounicode_add); +- } else if (ttcmap->format == 4) { +- load_cmap4(ttcmap->map, GIDToCIDMap, gsub_vert, gsub_list, +- cmap, tounicode_add); +- } ++ return; ++} + +- cmap_id = CMap_cache_add(cmap); ++static void ++load_cmap12 (struct cmap12 *map, uint16_t *GIDToCIDMap, USHORT num_glyphs, ++ otl_gsub *gsub_vert, otl_gsub *gsub_list, ++ CMap *cmap, int32_t *map_base, int32_t *map_sub) ++{ ++ ULONG i, ch; ++ USHORT gid, cid; ++ unsigned char buf[4]; ++ ++ for (i = 0; i < map->nGroups; i++) { ++ for (ch = map->groups[i].startCharCode; ++ ch <= map->groups[i].endCharCode; ch++) { ++ int d = ch - map->groups[i].startCharCode; ++ gid = (USHORT) ((map->groups[i].startGlyphID + d) & 0xffff); ++ if (gsub_list) ++ otl_gsub_apply_chain(gsub_list, &gid); ++ if (gsub_vert) ++ otl_gsub_apply(gsub_vert, &gid); ++ cid = (gid < num_glyphs) ? GIDToCIDMap[gid] : 0; ++ buf[0] = (ch >> 24) & 0xff; ++ buf[1] = (ch >> 16) & 0xff; ++ buf[2] = (ch >> 8) & 0xff; ++ buf[3] = ch & 0xff; ++ CMap_add_cidchar(cmap, buf, 4, cid); ++ if (map_base && map_sub) { ++ if (is_PUA_or_presentation(ch)) { ++ map_sub[gid] = ch; ++ } else { ++ map_base[gid] = ch; ++ } ++ } ++ } + } + +- return cmap_id; ++ return; + } + + int + otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC font */ +- const char *otl_tags, int wmode) ++ const char *otl_tags, int wmode) + { +- int cmap_id = -1; +- /* Additional ToUncidoe mappings required by OTL GSUB substitusion */ +- int tounicode_add_id = -1; +- CMap *tounicode_add = NULL; +- char *tounicode_add_name = NULL; +- int is_cidfont = 0; +- sfnt *sfont; +- ULONG offset = 0; +- char *cmap_name = NULL; +- FILE *fp = NULL; +- otl_gsub *gsub_vert = NULL, *gsub_list = NULL; +- tt_cmap *ttcmap; +- CIDSysInfo csi = {NULL, NULL, 0}; +- unsigned char *GIDToCIDMap = NULL; ++ int cmap_id = -1; ++ char *cmap_name = NULL; ++ sfnt *sfont = NULL; ++ ULONG offset = 0; ++ uint16_t num_glyphs = 0; ++ FILE *fp = NULL; ++ tt_cmap *ttcmap = NULL; ++ CIDSysInfo csi = {NULL, NULL, 0}; ++ uint16_t *GIDToCIDMap = NULL; + + if (!map_name) + return -1; +@@ -1359,11 +1324,6 @@ + sprintf(cmap_name, "%s,%03d-UCS4-H", map_name, ttc_index); + } + } +- if (dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) { +- MESG("\n"); +- MESG("otf_cmap>> Unicode charmap for font=\"%s\" layout=\"%s\"\n", +- map_name, (otl_tags ? otl_tags : "none")); +- } + cmap_id = CMap_cache_find(cmap_name); + if (cmap_id >= 0) { + RELEASE(cmap_name); +@@ -1374,6 +1334,12 @@ + } + + /* CMap not found */ ++ if (dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) { ++ MESG("\n"); ++ MESG("otf_cmap>> Creating Unicode charmap for font=\"%s\" layout=\"%s\"\n", ++ map_name, (otl_tags ? otl_tags : "none")); ++ } ++ + fp = DPXFOPEN(map_name, DPX_RES_TYPE_TTFONT); + if (!fp) { + fp = DPXFOPEN(map_name, DPX_RES_TYPE_OTFONT); +@@ -1390,13 +1356,20 @@ + } + + if (!sfont) { +- ERROR("Could not open OpenType/TrueType/dfont font file \"%s\"", map_name); ++ WARN("Could not open OpenType/TrueType/dfont font file \"%s\"", map_name); ++ RELEASE(cmap_name); ++ DPXFCLOSE(fp); ++ return -1; + } + switch (sfont->type) { + case SFNT_TYPE_TTC: + offset = ttc_read_offset(sfont, ttc_index); + if (offset == 0) { +- ERROR("Invalid TTC index"); ++ WARN("Offset=0 returned for font=%s, TTC_index=%d", map_name, ttc_index); ++ RELEASE(cmap_name); ++ sfnt_close(sfont); ++ DPXFCLOSE(fp); ++ return -1; + } + break; + case SFNT_TYPE_TRUETYPE: +@@ -1407,41 +1380,79 @@ + offset = sfont->offset; + break; + default: +- ERROR("Not a OpenType/TrueType/TTC font?: %s", map_name); ++ WARN("Not a OpenType/TrueType/TTC font?: %s", map_name); ++ RELEASE(cmap_name); ++ sfnt_close(sfont); ++ DPXFCLOSE(fp); ++ return -1; + break; + } + +- if (sfnt_read_table_directory(sfont, offset) < 0) +- ERROR("Could not read OpenType/TrueType table directory."); ++ if (sfnt_read_table_directory(sfont, offset) < 0) { ++ WARN("Could not read OpenType/TrueType table directory: %s", map_name); ++ RELEASE(cmap_name); ++ sfnt_close(sfont); ++ DPXFCLOSE(fp); ++ return -1; ++ } + ++ { ++ struct tt_maxp_table *maxp; + +- if (otl_tags) { +- /* tounicode_add here is later refered by otf_create_ToUnicode_stream() +- * for finding additional CID to Unicode mapping entries required by +- * OTL gsub substitution. +- */ +- tounicode_add_name = NEW(strlen(map_name)+strlen(",000-UCS32-Add")+1, char); +- sprintf(tounicode_add_name, "%s,%03d-UCS32-Add", map_name, ttc_index); +- tounicode_add_id = CMap_cache_find(tounicode_add_name); +- if (tounicode_add_id >= 0) +- tounicode_add = CMap_cache_get(tounicode_add_id); +- else { +- tounicode_add = CMap_new(); +- CMap_set_name (tounicode_add, tounicode_add_name); +- CMap_set_type (tounicode_add, CMAP_TYPE_TO_UNICODE); +- CMap_set_wmode(tounicode_add, 0); +- CMap_add_codespacerange(tounicode_add, srange_min, srange_max, 2); +- CMap_set_CIDSysInfo(tounicode_add, &CSI_UNICODE); +- CMap_add_bfchar(tounicode_add, srange_min, 2, srange_max, 2); +- tounicode_add_id = CMap_cache_add(tounicode_add); +- } +- RELEASE(tounicode_add_name); ++ maxp = tt_read_maxp_table(sfont); ++ num_glyphs = (card16) maxp->numGlyphs; ++ RELEASE(maxp); + } + ++ GIDToCIDMap = NEW(num_glyphs, uint16_t); ++ memset(GIDToCIDMap, 0, num_glyphs*sizeof(uint16_t)); + if (sfont->type == SFNT_TYPE_POSTSCRIPT) { +- is_cidfont = handle_CIDFont(sfont, &GIDToCIDMap, &csi); ++ cff_font *cffont; ++ card16 gid; ++ ++ offset = sfnt_find_table_pos(sfont, "CFF "); ++ cffont = cff_open(sfont->stream, offset, 0); ++ if (!cffont) { ++ RELEASE(cmap_name); ++ RELEASE(GIDToCIDMap); ++ sfnt_close(sfont); ++ DPXFCLOSE(fp); ++ return -1; ++ } ++ if (!(cffont->flag & FONTTYPE_CIDFONT)) { ++ csi.registry = strdup("Adobe"); ++ csi.ordering = strdup("Identity"); ++ csi.supplement = 0; ++ for (gid = 0; gid < num_glyphs; gid++) { ++ GIDToCIDMap[gid] = gid; ++ } ++ } else { ++ if (!cff_dict_known(cffont->topdict, "ROS")) { ++ csi.registry = strdup("Adobe"); ++ csi.ordering = strdup("Identity"); ++ csi.supplement = 0; ++ } else { ++ card16 reg, ord; ++ ++ reg = (card16) cff_dict_get(cffont->topdict, "ROS", 0); ++ ord = (card16) cff_dict_get(cffont->topdict, "ROS", 1); ++ csi.registry = cff_get_string(cffont, reg); ++ csi.ordering = cff_get_string(cffont, ord); ++ csi.supplement = (int) cff_dict_get(cffont->topdict, "ROS", 2); ++ } ++ cff_read_charsets(cffont); ++ create_GIDToCIDMap(GIDToCIDMap, num_glyphs, cffont); ++ } ++ cff_close(cffont); + } else { +- is_cidfont = 0; ++ uint16_t gid; ++ ++ csi.registry = strdup("Adobe"); ++ csi.ordering = strdup("Identity"); ++ csi.supplement = 0; ++ for (gid = 0; gid < num_glyphs; gid++) { ++ GIDToCIDMap[gid] = gid; ++ } + } + + ttcmap = tt_cmap_read(sfont, 3, 10); /* Microsoft UCS4 */ +@@ -1449,63 +1460,122 @@ + ttcmap = tt_cmap_read(sfont, 3, 1); /* Microsoft UCS2 */ + if (!ttcmap) { + ttcmap = tt_cmap_read(sfont, 0, 3); /* Unicode 2.0 or later */ +-#if defined(LIBDPX) +- if (!ttcmap && dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) { +-#else +- if (!ttcmap) { +-#endif /* LIBDPX */ +- ERROR("Unable to read OpenType/TrueType Unicode cmap table."); +- } + } + } +- if (wmode == 1) { +- gsub_vert = otl_gsub_new(); +- if (otl_gsub_add_feat(gsub_vert, "*", "*", "vrt2", sfont) < 0) { +- if (otl_gsub_add_feat(gsub_vert, "*", "*", "vert", sfont) < 0) { +- WARN("GSUB feature vrt2/vert not found."); +- otl_gsub_release(gsub_vert); +- gsub_vert = NULL; ++ ++ if (ttcmap) { ++ CMap *cmap = NULL; ++ int32_t *map_base, *map_sub; ++ otl_gsub *gsub_vert = NULL; ++ otl_gsub *gsub_list = NULL; ++ uint32_t gid; ++ ++ if (wmode == 1) { ++ gsub_vert = otl_gsub_new(); ++ if (otl_gsub_add_feat(gsub_vert, "*", "*", "vrt2", sfont) < 0) { ++ if (otl_gsub_add_feat(gsub_vert, "*", "*", "vert", sfont) < 0) { ++ WARN("GSUB feature vrt2/vert not found."); ++ otl_gsub_release(gsub_vert); ++ gsub_vert = NULL; ++ } else { ++ otl_gsub_select(gsub_vert, "*", "*", "vert"); ++ } + } else { +- otl_gsub_select(gsub_vert, "*", "*", "vert"); ++ otl_gsub_select(gsub_vert, "*", "*", "vrt2"); + } + } else { +- otl_gsub_select(gsub_vert, "*", "*", "vrt2"); ++ gsub_vert = NULL; + } +- } else { +- gsub_vert = NULL; +- } +- if (otl_tags) { +- gsub_list = otl_gsub_new(); +- if (otl_gsub_add_feat_list(gsub_list, otl_tags, sfont) < 0) { +- WARN("Readin GSUB feature table(s) failed for \"%s\"", otl_tags); ++ if (otl_tags) { ++ gsub_list = otl_gsub_new(); ++ if (otl_gsub_add_feat_list(gsub_list, otl_tags, sfont) < 0) { ++ WARN("Reading GSUB feature table(s) failed for \"%s\"", otl_tags); ++ } else { ++ otl_gsub_set_chain(gsub_list, otl_tags); ++ } + } else { +- otl_gsub_set_chain(gsub_list, otl_tags); ++ gsub_list = NULL; + } +- } else { +- gsub_list = NULL; ++ cmap = CMap_new(); ++ CMap_set_name(cmap, cmap_name); ++ CMap_set_type(cmap, CMAP_TYPE_CODE_TO_CID); ++ CMap_set_wmode(cmap, wmode); ++ CMap_add_codespacerange(cmap, lrange_min, lrange_max, 4); ++ CMap_set_CIDSysInfo(cmap, &csi); ++ map_base = NEW(num_glyphs, int32_t); ++ map_sub = NEW(num_glyphs, int32_t); ++ for (gid = 0; gid < num_glyphs; gid++) { ++ map_base[gid] = -1; ++ map_sub[gid] = -1; ++ } ++ switch (ttcmap->format) { ++ case 12: ++ load_cmap12(ttcmap->map, GIDToCIDMap, num_glyphs, ++ gsub_vert, gsub_list, ++ cmap, map_base, map_sub); ++ break; ++ case 4: ++ load_cmap4(ttcmap->map, GIDToCIDMap, num_glyphs, ++ gsub_vert, gsub_list, ++ cmap, map_base, map_sub); ++ break; ++ } ++ if (gsub_vert) ++ otl_gsub_release(gsub_vert); ++ if (gsub_list) ++ otl_gsub_release(gsub_list); ++ tt_cmap_release(ttcmap); ++ ++ if (otl_tags) { ++ CMap *tounicode = NULL; ++ char *tounicode_name; ++ int tounicode_id; ++ ++ tounicode_name = NEW(strlen(map_name)+strlen(",000-UCS32-Add")+1, char); ++ sprintf(tounicode_name, "%s,%03d-UCS32-Add", map_name, ttc_index); ++ tounicode_id = CMap_cache_find(tounicode_name); ++ if (tounicode_id >= 0) ++ tounicode = CMap_cache_get(tounicode_id); ++ else { ++ tounicode = CMap_new(); ++ CMap_set_name (tounicode, tounicode_name); ++ CMap_set_type (tounicode, CMAP_TYPE_TO_UNICODE); ++ CMap_set_wmode(tounicode, 0); ++ CMap_add_codespacerange(tounicode, srange_min, srange_max, 2); ++ CMap_set_CIDSysInfo(tounicode, &CSI_UNICODE); ++ CMap_add_bfchar(tounicode, srange_min, 2, srange_max, 2); ++ tounicode_id = CMap_cache_add(tounicode); ++ } ++ RELEASE(tounicode_name); ++ ++ for (gid = 0; gid < num_glyphs; gid++) { ++ uint16_t cid = GIDToCIDMap[gid]; ++ unsigned char src[2], dst[4]; ++ if (cid > 0) { ++ int32_t ch = UC_is_valid(map_base[gid]) ? map_base[gid] : map_sub[gid]; ++ if (UC_is_valid(ch)) { ++ unsigned char *p = dst; ++ unsigned char *endptr = dst + 4; ++ size_t len; ++ src[0] = (cid >> 8) & 0xff; ++ src[1] = cid & 0xff; ++ len = UC_UTF16BE_encode_char(ch, &p, endptr); ++ if (len > 0) { ++ CMap_add_bfchar(tounicode, src, 2, dst, len); ++ } ++ } ++ } ++ } ++ } ++ cmap_id = CMap_cache_add(cmap); + } +- cmap_id = load_base_CMap(cmap_name, tounicode_add, wmode, +- (is_cidfont ? &csi : NULL), GIDToCIDMap, +- gsub_vert, gsub_list, ttcmap); +- if (cmap_id < 0) +- ERROR("Failed to read OpenType/TrueType cmap table."); +- if (gsub_vert) +- otl_gsub_release(gsub_vert); +- gsub_vert = NULL; +- if (gsub_list) +- otl_gsub_release(gsub_list); +- gsub_list = NULL; + + RELEASE(cmap_name); +- if (GIDToCIDMap) +- RELEASE(GIDToCIDMap); +- if (is_cidfont) { +- if (csi.registry) +- RELEASE(csi.registry); +- if (csi.ordering) +- RELEASE(csi.ordering); +- } +- tt_cmap_release(ttcmap); ++ RELEASE(GIDToCIDMap); ++ if (csi.registry) ++ RELEASE(csi.registry); ++ if (csi.ordering) ++ RELEASE(csi.ordering); + sfnt_close(sfont); + DPXFCLOSE(fp); + +@@ -1515,14 +1585,11 @@ + int + otf_try_load_GID_to_CID_map (const char *map_name, int ttc_index, int wmode) + { +- int cmap_id = -1; +- sfnt *sfont; +- ULONG offset = 0; +- char *cmap_name = NULL; +- FILE *fp = NULL; +- CIDSysInfo csi = {NULL, NULL, 0}; +- int is_cidfont = 0; +- unsigned char *GIDToCIDMap = NULL; ++ int cmap_id = -1; ++ sfnt *sfont = NULL; ++ ULONG offset = 0; ++ char *cmap_name = NULL; ++ FILE *fp = NULL; + + if (!map_name) + return -1; +@@ -1559,13 +1626,20 @@ + } + + if (!sfont) { +- ERROR("Could not open OpenType/TrueType/dfont font file \"%s\"", map_name); ++ WARN("Could not open OpenType/TrueType/dfont font file \"%s\"", map_name); ++ RELEASE(cmap_name); ++ DPXFCLOSE(fp); ++ return -1; + } + switch (sfont->type) { + case SFNT_TYPE_TTC: + offset = ttc_read_offset(sfont, ttc_index); + if (offset == 0) { +- ERROR("Invalid TTC index"); ++ WARN("Invalid TTC index for font \"%s\": %d", map_name, ttc_index); ++ sfnt_close(sfont); ++ DPXFCLOSE(fp); ++ RELEASE(cmap_name); ++ return -1; + } + break; + case SFNT_TYPE_TRUETYPE: +@@ -1576,12 +1650,20 @@ + offset = sfont->offset; + break; + default: +- ERROR("Not a OpenType/TrueType/TTC font?: %s", map_name); +- break; ++ WARN("Not a OpenType/TrueType/TTC font?: %s", map_name); ++ sfnt_close(sfont); ++ DPXFCLOSE(fp); ++ RELEASE(cmap_name); ++ return -1; + } + +- if (sfnt_read_table_directory(sfont, offset) < 0) +- ERROR("Could not read OpenType/TrueType table directory."); ++ if (sfnt_read_table_directory(sfont, offset) < 0) { ++ WARN("Could not read OpenType/TrueType table directory: %s", map_name); ++ sfnt_close(sfont); ++ DPXFCLOSE(fp); ++ RELEASE(cmap_name); ++ return -1; ++ } + if (sfont->type != SFNT_TYPE_POSTSCRIPT) { + RELEASE(cmap_name); + sfnt_close(sfont); +@@ -1590,41 +1672,71 @@ + } + + /* Read GID-to-CID mapping if CFF OpenType is found. */ +- is_cidfont = handle_CIDFont(sfont, &GIDToCIDMap, &csi); +- if (is_cidfont) { +- if (GIDToCIDMap) { +- CMap *cmap; +- int32_t gid; +- const unsigned char csrange[4] = {0x00, 0x00, 0xff, 0xff}; ++ if (sfont->type == SFNT_TYPE_POSTSCRIPT) { ++ cff_font *cffont; ++ struct tt_maxp_table *maxp; ++ const unsigned char csrange[4] = {0x00, 0x00, 0xff, 0xff}; ++ uint16_t num_glyphs = 0; ++ ++ maxp = tt_read_maxp_table(sfont); ++ num_glyphs = (card16) maxp->numGlyphs; ++ RELEASE(maxp); ++ ++ offset = sfnt_find_table_pos(sfont, "CFF "); ++ cffont = cff_open(sfont->stream, offset, 0); ++ if (cffont && cffont->flag & FONTTYPE_CIDFONT) { ++ CMap *cmap; ++ uint16_t gid; ++ uint16_t *GIDToCIDMap = NULL; ++ CIDSysInfo csi = {NULL, NULL, 0}; ++ ++ if (!cff_dict_known(cffont->topdict, "ROS")) { ++ csi.registry = strdup("Adobe"); ++ csi.ordering = strdup("Identity"); ++ csi.supplement = 0; ++ } else { ++ card16 reg, ord; + ++ reg = (card16) cff_dict_get(cffont->topdict, "ROS", 0); ++ ord = (card16) cff_dict_get(cffont->topdict, "ROS", 1); ++ csi.registry = cff_get_string(cffont, reg); ++ csi.ordering = cff_get_string(cffont, ord); ++ csi.supplement = (int) cff_dict_get(cffont->topdict, "ROS", 2); ++ } ++ cff_read_charsets(cffont); ++ GIDToCIDMap = NEW(num_glyphs, uint16_t); ++ memset(GIDToCIDMap, 0, num_glyphs*sizeof(uint16_t)); ++ create_GIDToCIDMap(GIDToCIDMap, num_glyphs, cffont); + cmap = CMap_new(); + CMap_set_name (cmap, cmap_name); + CMap_set_type (cmap, CMAP_TYPE_CODE_TO_CID); + CMap_set_wmode(cmap, wmode); + CMap_add_codespacerange(cmap, &csrange[0], &csrange[2], 2); + CMap_set_CIDSysInfo(cmap, &csi); +- +- for (gid = 0; gid < 65536; gid++) { +- unsigned char src[2]; ++ for (gid = 0; gid < num_glyphs; gid++) { ++ unsigned char src[2], dst[2]; + src[0] = (gid >> 8) & 0xff; + src[1] = gid & 0xff; +- CMap_add_bfchar(cmap, src, 2, &GIDToCIDMap[gid*2], 2); ++ dst[0] = (GIDToCIDMap[gid] >> 8) & 0xff; ++ dst[1] = GIDToCIDMap[gid] & 0xff; ++ CMap_add_bfchar(cmap, src, 2, dst, 2); + } + cmap_id = CMap_cache_add(cmap); + if (dpx_conf.verbose_level > VERBOSE_LEVEL_MIN) { + MESG("\n"); + MESG("otf_cmap>> Creating GID-to-CID mapping for font=\"%s\"\n", map_name); + } ++ RELEASE(GIDToCIDMap); ++ if (csi.registry) ++ RELEASE(csi.registry); ++ if (csi.ordering) ++ RELEASE(csi.ordering); + } +- /* Identity mapping for null GIDToCIDMap */ ++ if (cffont) ++ cff_close(cffont); + } ++ + RELEASE(cmap_name); +- if (GIDToCIDMap) +- RELEASE(GIDToCIDMap); +- if (csi.registry) +- RELEASE(csi.registry); +- if (csi.ordering) +- RELEASE(csi.ordering); + sfnt_close(sfont); + DPXFCLOSE(fp); + +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/tt_gsub.c b/texlive-20190410-source/texk/dvipdfm-x/tt_gsub.c +--- a/texlive-20190410-source/texk/dvipdfm-x/tt_gsub.c 2018-12-21 03:39:51.000000000 +0000 ++++ b/texlive-20190410-source/texk/dvipdfm-x/tt_gsub.c 2019-05-31 22:00:04.009964032 +0100 +@@ -1,6 +1,6 @@ + /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + +- Copyright (C) 2002-2018 by Jin-Hwan Cho and Shunsaku Hirata, ++ Copyright (C) 2002-2019 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + This program is free software; you can redistribute it and/or modify +@@ -977,10 +977,11 @@ + + sfnt_seek_set(sfont, offset); + clt_read_feature_table(&feature_table, sfont); ++#if 0 + if (feature_table.FeatureParams != 0) { + ERROR("unrecognized FeatureParams"); + } +- ++#endif + /* Lookup table */ + for (i = 0; i < feature_table.LookupListIndex.count; i++) { + struct clt_lookup_table lookup_table; +@@ -1680,98 +1681,303 @@ + return retval; + } + +-#if 0 ++#if 1 ++#include "unicode.h" ++ ++#ifndef is_used_char2 ++#define is_used_char2(b,c) (((b)[(c)/8]) & (1 << (7-((c)%8)))) ++#endif ++ ++static int ++add_glyph_if_valid (CMap *cmap, char *used_chars, ++ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs, ++ uint16_t *GIDToCIDMap, USHORT gid, USHORT gid_sub) ++{ ++ int count = 0; ++ unsigned char src[2], dst[4]; ++ unsigned char *p = dst, *endptr = dst + 4; ++ size_t len; ++ uint16_t cid_sub; ++ ++ if (gid_sub >= num_glyphs || gid >= num_glyphs) ++ return 0; ++ ++ cid_sub = GIDToCIDMap[gid_sub]; ++ if (is_used_char2(used_chars, cid_sub)) { ++ int32_t ch = map_base[gid]; ++ if (UC_is_valid(ch)) { ++ src[0] = (cid_sub >> 8) & 0xff; ++ src[1] = cid_sub & 0xff; ++ len = UC_UTF16BE_encode_char(ch, &p, endptr); ++ CMap_add_bfchar(cmap, src, 2, dst, len); ++ used_chars[cid_sub / 8] &= ~(1 << (7 - (cid_sub % 8))); ++ count = 1; ++ } else { ++ ch = map_sub[gid]; ++ if (UC_is_valid(ch)) { ++ src[0] = (cid_sub >> 8) & 0xff; ++ src[1] = cid_sub & 0xff; ++ len = UC_UTF16BE_encode_char(ch, &p, endptr); ++ CMap_add_bfchar(cmap, src, 2, dst, len); ++ used_chars[cid_sub / 8] &= ~(1 << (7 - (cid_sub % 8))); ++ count = 1; ++ } ++ } ++ } ++ return count; ++} ++ + static int +-otl_gsub_dump_single (struct otl_gsub_subtab *subtab) ++add_ToUnicode_single (CMap *cmap, char *used_chars, ++ struct otl_gsub_subtab *subtab, ++ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs, ++ uint16_t *GIDToCIDMap) + { +- int gid, idx; ++ int count = 0; ++ USHORT i, idx, gid; ++ USHORT gid_sub; + + ASSERT(subtab); + + if (subtab->SubstFormat == 1) { + struct otl_gsub_single1 *data; ++ struct clt_coverage *cov; + + data = (subtab->table).single1; +- for (gid = 0; gid < 0x10000; gid++) { +- idx = clt_lookup_coverage(&data->coverage, gid); +- if (idx >= 0) { +- fprintf(stdout, "substitute \\%u by \\%u;\n", +- (USHORT) gid, (USHORT) (gid + data->DeltaGlyphID)); ++ cov = &data->coverage; ++ switch (cov->format) { ++ case 1: /* list */ ++ for (idx = 0; idx < cov->count; idx++) { ++ gid = cov->list[idx]; ++ gid_sub = gid + data->DeltaGlyphID; ++ count += add_glyph_if_valid(cmap, used_chars, ++ map_base, map_sub, num_glyphs, ++ GIDToCIDMap, gid, gid_sub); + } ++ break; ++ case 2: /* range */ ++ for (i = 0; i < cov->count; i++) { ++ for (gid = cov->range[i].Start; ++ gid <= cov->range[i].End && gid < num_glyphs; gid++) { ++ idx = cov->range[i].StartCoverageIndex + gid - cov->range[i].Start; ++ gid_sub = gid + data->DeltaGlyphID; ++ count += add_glyph_if_valid(cmap, used_chars, ++ map_base, map_sub, num_glyphs, ++ GIDToCIDMap, gid, gid_sub); ++ } ++ } ++ break; + } + } else if (subtab->SubstFormat == 2) { + struct otl_gsub_single2 *data; ++ struct clt_coverage *cov; + + data = (subtab->table).single2; +- for (gid = 0; gid < 0x10000; gid++) { +- idx = clt_lookup_coverage(&data->coverage, gid); +- if (idx >= 0 && +- idx < data->GlyphCount) { +- fprintf(stdout, "substitute \\%u by \\%u;\n", +- (USHORT) gid, (data->Substitute)[idx]); ++ cov = &data->coverage; ++ switch (cov->format) { ++ case 1: /* list */ ++ for (idx = 0; idx < cov->count; idx++) { ++ gid = cov->list[idx]; ++ if (idx >= 0 && idx < data->GlyphCount) { ++ gid_sub = (data->Substitute)[idx]; ++ count += add_glyph_if_valid(cmap, used_chars, ++ map_base, map_sub, num_glyphs, ++ GIDToCIDMap, gid, gid_sub); ++ } + } ++ break; ++ case 2: /* range */ ++ for (i = 0; i < cov->count; i++) { ++ for (gid = cov->range[i].Start; ++ gid <= cov->range[i].End && gid < num_glyphs; gid++) { ++ idx = cov->range[i].StartCoverageIndex + gid - cov->range[i].Start; ++ if (idx >= 0 && idx < data->GlyphCount) { ++ gid_sub = (data->Substitute)[idx]; ++ count += add_glyph_if_valid(cmap, used_chars, ++ map_base, map_sub, num_glyphs, ++ GIDToCIDMap, gid, gid_sub); ++ } ++ } ++ } ++ break; + } + } + +- return 0; ++ return count; + } + +-static int +-otl_gsub_dump_alternate (struct otl_gsub_subtab *subtab) ++static int32_t ++add_alternate1_inverse_map (CMap *cmap, char *used_chars, ++ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs, ++ uint16_t *GIDToCIDMap, USHORT gid, int idx, ++ struct otl_gsub_alternate1 *data) + { +- int gid, idx; ++ int32_t count = 0; ++ ++ if (idx >= 0 && idx < data->AlternateSetCount) { ++ struct otl_gsub_altset *altset; ++ USHORT i; ++ ++ altset = &(data->AlternateSet[idx]); ++ if (altset->GlyphCount == 0) ++ return count; ++ for (i = 0; i < altset->GlyphCount; i++) { ++ USHORT gid_alt = altset->Alternate[i]; ++ count += add_glyph_if_valid(cmap, used_chars, ++ map_base, map_sub, num_glyphs, ++ GIDToCIDMap, gid, gid_alt); ++ } ++ } ++ return count; ++} ++ ++static int32_t ++add_ToUnicode_alternate (CMap *cmap, char *used_chars, ++ struct otl_gsub_subtab *subtab, ++ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs, ++ uint16_t *GIDToCIDMap) ++{ ++ int32_t count = 0; ++ USHORT i, gid, idx; + + ASSERT(subtab); + + if (subtab->SubstFormat == 1) { + struct otl_gsub_alternate1 *data; +- ++ struct clt_coverage *cov; + data = subtab->table.alternate1; +- for (gid = 0; gid < 0x10000; gid++) { +- idx = clt_lookup_coverage(&data->coverage, gid); +- if (idx >= 0 && idx < data->AlternateSetCount) { +- struct otl_gsub_altset *altset; +- USHORT i; +- altset = &(data->AlternateSet[idx]); +- if (altset->GlyphCount == 0) +- continue; +- fprintf(stdout, "substitute \\%u from [", (USHORT) gid); +- for (i = 0; i < altset->GlyphCount; i++) { +- fprintf(stdout, " \\%u", altset->Alternate[i]); ++ cov = &data->coverage; ++ switch (cov->format) { ++ case 1: /* list */ ++ for (idx = 0; idx < cov->count; idx++) { ++ gid = cov->list[idx]; ++ if (gid < num_glyphs) { ++ count += add_alternate1_inverse_map(cmap, used_chars, ++ map_base, map_sub, num_glyphs, ++ GIDToCIDMap, gid, idx, data); ++ } ++ } ++ break; ++ case 2: /* range */ ++ for (i = 0; i < cov->count; i++) { ++ for (gid = cov->range[i].Start; ++ gid <= cov->range[i].End && gid < num_glyphs; gid++) { ++ idx = cov->range[i].StartCoverageIndex + gid - cov->range[i].Start; ++ count += add_alternate1_inverse_map(cmap, used_chars, ++ map_base, map_sub, num_glyphs, ++ GIDToCIDMap, gid, idx, data); + } +- fprintf(stdout, " ];\n"); + } ++ break; + } + } ++ return count; ++} + +- return 0; ++static int32_t ++add_ligature1_inverse_map (CMap *cmap, char *used_chars, ++ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs, ++ uint16_t *GIDToCIDMap, USHORT gid_1, int idx, ++ struct otl_gsub_ligature1 *data) ++{ ++ int32_t count = 0; ++ ++ if (idx >= 0 && idx < data->LigSetCount) { ++ struct otl_gsub_ligset *ligset; ++ USHORT i, j; ++ ++ ligset = &(data->LigatureSet[idx]); ++ for (j = 0; j < ligset->LigatureCount; j++) { ++ USHORT gid_sub = ligset->Ligature[j].LigGlyph; ++ if (gid_sub < num_glyphs) { ++ uint16_t cid = GIDToCIDMap[gid_sub]; ++ if (is_used_char2(used_chars, cid)) { ++ int32_t ch, *ucv; ++ USHORT comp_count = ligset->Ligature[j].CompCount; ++ int fail_count = 0; ++ ++ ucv = NEW(comp_count, int32_t); ++ ch = UC_is_valid(map_base[gid_1]) ? map_base[gid_1] : map_sub[gid_1]; ++ ucv[0] = ch; ++ fail_count += UC_is_valid(ch) ? 0 : 1; ++ for (i = 0; i < ligset->Ligature[j].CompCount - 1; i++) { ++ USHORT gid = ligset->Ligature[j].Component[i]; ++ if (gid < num_glyphs) { ++ ch = UC_is_valid(map_base[gid]) ? map_base[gid] : map_sub[gid]; ++ ucv[i+1] = ch; ++ fail_count += UC_is_valid(ch) ? 0 : 1; ++ } else { ++ fail_count += 1; ++ } ++ } ++ if (fail_count == 0) { ++ unsigned char src[2], *dst; ++ unsigned char *p, *endptr; ++ size_t len = 0; ++ ++ src[0] = (cid >> 8) & 0xff; ++ src[1] = cid & 0xff; ++ dst = NEW(comp_count*4, unsigned char); ++ p = dst; ++ endptr = dst + comp_count * 4; ++ for (i = 0; i < comp_count; i++) { ++ len += UC_UTF16BE_encode_char(ucv[i], &p, endptr); ++ } ++ CMap_add_bfchar(cmap, src, 2, dst, len); ++ used_chars[cid / 8] &= ~(1 << (7 - (cid % 8))); ++ count++; ++ RELEASE(dst); ++ } ++ RELEASE(ucv); ++ } ++ } ++ } ++ } ++ ++ return count; + } + +-static int +-otl_gsub_dump_ligature (struct otl_gsub_subtab *subtab) ++static int32_t ++add_ToUnicode_ligature (CMap *cmap, char *used_chars, ++ struct otl_gsub_subtab *subtab, ++ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs, ++ uint16_t *GIDToCIDMap) + { +- int gid, idx; ++ int32_t count = 0; ++ USHORT i, idx, gid; + + ASSERT(subtab); + + if (subtab->SubstFormat == 1) { + struct otl_gsub_ligature1 *data; ++ struct clt_coverage *cov; + + data = subtab->table.ligature1; +- for (gid = 0; gid < 0x10000; gid++) { +- idx = clt_lookup_coverage(&data->coverage, gid); +- if (idx >= 0 && idx < data->LigSetCount) { +- struct otl_gsub_ligset *ligset; +- USHORT i, j; +- ligset = &(data->LigatureSet[idx]); +- for (j = 0; j < ligset->LigatureCount; j++) { +- fprintf(stdout, "substitute \\%u", (USHORT) gid); +- for (i = 0; i < ligset->Ligature[j].CompCount - 1; i++) { +- fprintf(stdout, " \\%u", ligset->Ligature[j].Component[i]); ++ cov = &data->coverage; ++ switch (cov->format) { ++ case 1: /* list */ ++ for (idx = 0; idx < cov->count; idx++) { ++ gid = cov->list[idx]; ++ if (gid < num_glyphs) { ++ count += add_ligature1_inverse_map(cmap, used_chars, ++ map_base, map_sub, num_glyphs, ++ GIDToCIDMap, gid, idx, data); ++ } ++ } ++ break; ++ case 2: /* range */ ++ for (i = 0; i < cov->count; i++) { ++ for (gid = cov->range[i].Start; ++ gid <= cov->range[i].End && gid < num_glyphs; gid++) { ++ idx = cov->range[i].StartCoverageIndex + gid - cov->range[i].Start; ++ if (gid < num_glyphs) { ++ count += add_ligature1_inverse_map(cmap, used_chars, ++ map_base, map_sub, num_glyphs, ++ GIDToCIDMap, gid, idx, data); + } +- fprintf(stdout, " by \\%u;\n", ligset->Ligature[j].LigGlyph); + } + } ++ break; + } + } + +@@ -1779,48 +1985,44 @@ + } + + int +-otl_gsub_dump (otl_gsub *gsub_list, +- const char *script, const char *language, const char *feature) ++otl_gsub_add_ToUnicode (CMap *cmap, char *used_chars, ++ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs, ++ uint16_t *GIDToCIDMap, sfnt *sfont) + { +- int error = -1; ++ int count = 0; ++ otl_gsub *gsub_list; + struct otl_gsub_tab *gsub; + struct otl_gsub_subtab *subtab; +- int sel, i, j; +- +- if (!gsub_list) +- return -1; ++ int i, j; + +- sel = gsub_list->select; +- error = otl_gsub_select(gsub_list, script, language, feature); +- if (error < 0) { +- ERROR("GSUB feature %s.%s.%s not found.", script, language, feature); +- } +- +- i = gsub_list->select; +- if (i < 0 || i >= gsub_list->num_gsubs) { +- ERROR("GSUB not selected..."); +- return -1; +- } +- gsub = &(gsub_list->gsubs[i]); ++ gsub_list = otl_gsub_new(); ++ otl_gsub_add_feat(gsub_list, "*", "*", "*", sfont); + +- for (j = 0; +- !error && +- j < gsub->num_subtables; j++) { +- subtab = &(gsub->subtables[j]); +- switch ((int) subtab->LookupType){ +- case OTL_GSUB_TYPE_SINGLE: +- error = otl_gsub_dump_single(subtab); +- break; +- case OTL_GSUB_TYPE_ALTERNATE: +- error = otl_gsub_dump_alternate(subtab); +- break; +- case OTL_GSUB_TYPE_LIGATURE: +- error = otl_gsub_dump_ligature(subtab); +- break; ++ for (i = 0; i < gsub_list->num_gsubs; i++) { ++ gsub = &(gsub_list->gsubs[i]); ++ for (j = 0; j < gsub->num_subtables; j++) { ++ subtab = &(gsub->subtables[j]); ++ switch ((int) subtab->LookupType){ ++ case OTL_GSUB_TYPE_SINGLE: ++ count += add_ToUnicode_single(cmap, used_chars, subtab, ++ map_base, map_sub, num_glyphs, ++ GIDToCIDMap); ++ break; ++ case OTL_GSUB_TYPE_ALTERNATE: ++ count += add_ToUnicode_alternate(cmap, used_chars, subtab, ++ map_base, map_sub, num_glyphs, ++ GIDToCIDMap); ++ break; ++ case OTL_GSUB_TYPE_LIGATURE: ++ count += add_ToUnicode_ligature(cmap, used_chars, subtab, ++ map_base, map_sub, num_glyphs, ++ GIDToCIDMap); ++ break; ++ } + } + } +- gsub_list->select = sel; ++ otl_gsub_release(gsub_list); + +- return error; ++ return count; + } + #endif +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/tt_gsub.h b/texlive-20190410-source/texk/dvipdfm-x/tt_gsub.h +--- a/texlive-20190410-source/texk/dvipdfm-x/tt_gsub.h 2018-09-14 04:34:50.000000000 +0100 ++++ b/texlive-20190410-source/texk/dvipdfm-x/tt_gsub.h 2019-05-31 22:00:04.009964032 +0100 +@@ -1,6 +1,6 @@ + /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + +- Copyright (C) 2002-2018 by Jin-Hwan Cho and Shunsaku Hirata, ++ Copyright (C) 2002-2019 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + This program is free software; you can redistribute it and/or modify +@@ -23,6 +23,7 @@ + + #include "sfnt.h" + #include "otl_opt.h" ++#include "cmap.h" + + typedef struct otl_gsub otl_gsub; + +@@ -59,11 +60,7 @@ + extern int otl_gsub_set_chain (otl_gsub *gsub_list, const char *otl_tags); + extern int otl_gsub_apply_chain (otl_gsub *gsub_list, USHORT *gid); + +-#if 0 +-extern int otl_gsub_dump (otl_gsub *gsub_list, +- const char *script, +- const char *language, +- const char *feature); +-#endif +- ++extern int otl_gsub_add_ToUnicode (CMap *cmap, char *used_chars, ++ int32_t *map_base, int32_t *map_sub, USHORT num_glyphs, ++ uint16_t *GIDToCIDMap, sfnt *sfont); + #endif /* _TT_GSUB_H_ */ +diff -Naur a/texlive-20190410-source/texk/dvipdfm-x/unicode.c b/texlive-20190410-source/texk/dvipdfm-x/unicode.c +--- a/texlive-20190410-source/texk/dvipdfm-x/unicode.c 2016-01-06 10:13:28.000000000 +0000 ++++ b/texlive-20190410-source/texk/dvipdfm-x/unicode.c 2019-05-31 22:00:04.009964032 +0100 +@@ -1,6 +1,6 @@ + /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + +- Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata, ++ Copyright (C) 2002-2019 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks +@@ -123,7 +123,7 @@ + unsigned char *p = *pp; + + if (ucv >= 0 && ucv <= 0xFFFF) { +- if (p + 2 >= endptr) ++ if (p + 2 > endptr) + return 0; + p[0] = (ucv >> 8) & 0xff; + p[1] = ucv & 0xff; +@@ -131,7 +131,7 @@ + } else if (ucv >= 0x010000 && ucv <= 0x10FFFF) { + unsigned short high, low; + +- if (p + 4 >= endptr) ++ if (p + 4 > endptr) + return 0; + ucv -= 0x00010000; + high = (ucv >> UC_SUR_SHIFT) + UC_SUR_HIGH_START; +@@ -142,7 +142,7 @@ + p[3] = (low & 0xff); + count = 4; + } else { +- if (p + 2 >= endptr) ++ if (p + 2 > endptr) + return 0; + p[0] = (UC_REPLACEMENT_CHAR >> 8) & 0xff; + p[1] = (UC_REPLACEMENT_CHAR & 0xff); +@@ -207,25 +207,25 @@ + return 0; + + if (ucv < 0x7f) { +- if (p >= endptr - 1) ++ if (p + 1 > endptr) + return 0; + p[0] = (unsigned char) ucv; + count = 1; + } else if (ucv <= 0x7ff) { +- if (p >= endptr -2) ++ if (p + 2 > endptr) + return 0; + p[0] = (unsigned char) (0xc0 | (ucv >> 6)); + p[1] = (unsigned char) (0x80 | (ucv & 0x3f)); + count = 2; + } else if (ucv <= 0xffff) { +- if (p >= endptr - 3) ++ if (p + 3 > endptr) + return 0; + p[0] = (unsigned char) (0xe0 | (ucv >> 12)); + p[1] = (unsigned char) (0x80 | ((ucv >> 6) & 0x3f)); + p[2] = (unsigned char) (0x80 | (ucv & 0x3f)); + count = 3; + } else if (ucv <= 0x1fffff) { +- if (p >= endptr - 4) ++ if (p + 4 > endptr) + return 0; + p[0] = (unsigned char) (0xf0 | (ucv >> 18)); + p[1] = (unsigned char) (0x80 | ((ucv >> 12) & 0x3f)); +@@ -233,7 +233,7 @@ + p[3] = (unsigned char) (0x80 | (ucv & 0x3f)); + count = 4; + } else if (ucv <= 0x3ffffff) { +- if (p >= endptr - 5) ++ if (p + 5 > endptr) + return 0; + p[0] = (unsigned char) (0xf8 | (ucv >> 24)); + p[1] = (unsigned char) (0x80 | ((ucv >> 18) & 0x3f)); +@@ -242,7 +242,7 @@ + p[4] = (unsigned char) (0x80 | (ucv & 0x3f)); + count = 5; + } else if (ucv <= 0x7fffffff) { +- if (p >= endptr - 6) ++ if (p + 6 > endptr) + return 0; + p[0] = (unsigned char) (0xfc | (ucv >> 30)); + p[1] = (unsigned char) (0x80 | ((ucv >> 24) & 0x3f)); +diff -Naur a/texlive-20190410-source/texk/dvipsk/ChangeLog b/texlive-20190410-source/texk/dvipsk/ChangeLog +--- a/texlive-20190410-source/texk/dvipsk/ChangeLog 2019-04-07 02:42:55.000000000 +0100 ++++ b/texlive-20190410-source/texk/dvipsk/ChangeLog 2019-05-31 22:00:04.009964032 +0100 +@@ -1,3 +1,9 @@ ++2019-04-30 Karl Berry ++ ++ * dosection.c (dosection): close PostScript string constant ++ for long filenames. tex-k mail from Arnaud Blouin, ++ 24 Apr 2019 13:54:10. ++ + 2019-04-07 Karl Berry + + * TeX Live 2019. +diff -Naur a/texlive-20190410-source/texk/dvipsk/dosection.c b/texlive-20190410-source/texk/dvipsk/dosection.c +--- a/texlive-20190410-source/texk/dvipsk/dosection.c 2019-03-30 01:50:10.000000000 +0000 ++++ b/texlive-20190410-source/texk/dvipsk/dosection.c 2019-05-31 22:00:04.009964032 +0100 +@@ -23,7 +23,7 @@ + int np; + int k; + integer thispage = 0; +- char buf[104]; ++ char buf[300]; /* really 253 */ + + dopsfont(s); + #ifdef HPS +@@ -40,7 +40,9 @@ + doubleout(mag); + numout((integer)DPI); + numout((integer)VDPI); +- snprintf(buf, sizeof(buf), "(%.500s)", fulliname); ++ /* possibly lines in eps files are supposed to be <= 255; ++ not worth testing the limits merely to output a long file name. */ ++ snprintf(buf, sizeof(buf), "(%.250s)", fulliname); + cmdout(buf); + newline(); + cmdout("@start"); +diff -Naur a/texlive-20190410-source/texk/web2c/ptexdir/ChangeLog b/texlive-20190410-source/texk/web2c/ptexdir/ChangeLog +--- a/texlive-20190410-source/texk/web2c/ptexdir/ChangeLog 2019-02-06 11:01:31.000000000 +0000 ++++ b/texlive-20190410-source/texk/web2c/ptexdir/ChangeLog 2019-05-31 22:00:04.010964033 +0100 +@@ -1,3 +1,11 @@ ++2019-05-06 Hironori Kitagawa ++ ++ * ptex-base.ch: ++ Make appropriate comparison of U+0100 by \if in upTeX. ++ https://github.com/texjporg/tex-jp-build/issues/68 ++ Re-eval kcatcode of Japanese character token in \if and \ifcat. ++ https://github.com/texjporg/ptex-manual/issues/4 ++ + 2019-02-03 Hironori Kitagawa + + * ptex-base.ch: Ignore newline char after Japanese control +diff -Naur a/texlive-20190410-source/texk/web2c/ptexdir/ptex-base.ch b/texlive-20190410-source/texk/web2c/ptexdir/ptex-base.ch +--- a/texlive-20190410-source/texk/web2c/ptexdir/ptex-base.ch 2019-02-06 11:00:54.000000000 +0000 ++++ b/texlive-20190410-source/texk/web2c/ptexdir/ptex-base.ch 2019-05-31 22:00:04.010964033 +0100 +@@ -59,6 +59,7 @@ + % (2017-09-07) HK pTeX p3.7.2 More restrictions on direction change commands. + % (2018-01-21) HK Added \ptexversion primitive and co. pTeX p3.8. + % (2018-04-14) HK pTeX p3.8.1 Bug fix for discontinuous KINSOKU table. ++% (2019-02-03) HK pTeX p3.8.2 Change \inhibitglue, add \disinhibitglue. + % + + @x +@@ -324,6 +325,13 @@ + wterm(')'); + @z + ++@x ++@d max_halfword==@"FFFFFFF {largest allowable value in a |halfword|} ++@y ++@d max_halfword==@"FFFFFFF {largest allowable value in a |halfword|} ++@d max_cjk_val=@"10000 ++@z ++ + @x [8.111] l.2436 - pTeX: check hi/ho + (mem_top+sup_main_memory>=max_halfword) then bad:=14; + @y +@@ -2533,19 +2541,19 @@ + end; + @y + if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then +- begin m:=cur_cmd; n:=cur_chr; ++ begin n:=cur_chr; m:=kcat_code(kcatcodekey(n)); + end + else if (cur_cmd>active_char)or(cur_chr>255) then +- begin m:=relax; n:=256; ++ begin m:=relax; n:=max_cjk_val; + end + else begin m:=cur_cmd; n:=cur_chr; + end; + get_x_token_or_active_char; + if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then +- begin cur_cmd:=cur_cmd; +- end {dummy} ++ begin cur_cmd:=kcat_code(kcatcodekey(cur_chr)); ++ end + else if (cur_cmd>active_char)or(cur_chr>255) then +- begin cur_cmd:=relax; cur_chr:=256; ++ begin cur_cmd:=relax; cur_chr:=max_cjk_val; + end; + @z + +diff -Naur a/texlive-20190410-source/texk/web2c/uptexdir/ChangeLog b/texlive-20190410-source/texk/web2c/uptexdir/ChangeLog +--- a/texlive-20190410-source/texk/web2c/uptexdir/ChangeLog 2019-02-23 01:59:36.000000000 +0000 ++++ b/texlive-20190410-source/texk/web2c/uptexdir/ChangeLog 2019-05-31 22:00:04.010964033 +0100 +@@ -1,3 +1,28 @@ ++2019-05-25 TANAKA Takuji ++ ++ * uptex-m.ch: ++ Correct upTeX_revision ".25", upTeX_version_string "-u1.25". ++ ++2019-05-06 TANAKA Takuji ++ ++ * uptex-m.ch, upbibtex.ch, updvitype.ch, uppltotf.ch, uptftopl.ch, ++ uptex_version.h: upTeX version u1.25. ++ * kanji.c, kanji.h: ++ Fix bug of kcatcode at Fullwidth ASCII variants and ++ Halfwidth Katakana variants from Yusuke Terada san: ++ https://github.com/texjporg/tex-jp-build/pull/79 ++ Set default internal encoding EUC/SJIS if a command name is ++ with prefix of "p" or "ep", intending to be compatible with ++ pTeX family (ptex, eptex, pbibtex, pdvitype, ppltotf, ptftopl) ++ (experimental). ++ ++2019-05-06 Hironori Kitagawa ++ ++ * uptex-m.ch: ++ Make appropreate comparison of U+0100 by \if. ++ https://github.com/texjporg/tex-jp-build/issues/68 ++ * tests/test_if.tex: Test case. ++ + 2019-02-23 TANAKA Takuji + + * uptex-m.ch, upbibtex.ch, updvitype.ch, uppltotf.ch, uptftopl.ch, +@@ -24,7 +49,7 @@ + 2018-09-16 TANAKA Takuji + + * upbibtex.ch: Fix bug of substring$ +- from Takashi Sakai: ++ from Takashi Sakai san: + https://github.com/texjporg/tex-jp-build/issues/64 + https://github.com/texjporg/tex-jp-build/pull/66 + +diff -Naur a/texlive-20190410-source/texk/web2c/uptexdir/kanji.c b/texlive-20190410-source/texk/web2c/uptexdir/kanji.c +--- a/texlive-20190410-source/texk/web2c/uptexdir/kanji.c 2019-02-23 01:59:36.000000000 +0000 ++++ b/texlive-20190410-source/texk/web2c/uptexdir/kanji.c 2019-05-31 22:00:04.010964033 +0100 +@@ -444,7 +444,7 @@ + || (LATIN_SMALL_LETTER_O_WITH_STROKE <=c && c<=LATIN_SMALL_LETTER_Y_WITH_DIAERESIS ) ) + return 0x1FD; + } +- if (block==0xa0) { ++ if (block==0xa1) { + /* Fullwidth ASCII variants except for U+FF01..FF0F, U+FF1A..FF20, U+FF3B..FF40, U+FF5B..FF5E */ + if ( (FULLWIDTH_DIGIT_0 <=c && c<=FULLWIDTH_DIGIT_9 ) + || (FULLWIDTH_CAPITAL_A<=c && c<=FULLWIDTH_CAPITAL_Z) +@@ -485,8 +485,6 @@ + { + char *p; + +- enable_UPTEX (true); /* enable */ +- + init_kanji (file_str, internal_str); + + p = getenv ("PTEX_KANJI_ENC"); +@@ -504,3 +502,33 @@ + } + #endif + } ++ ++void init_default_kanji_select(void) ++{ ++ char *base; ++ ++ base = kpse_program_basename (argv[0]); ++ ++ if (FILESTRNCASEEQ(base, "p", 1) || FILESTRNCASEEQ(base, "ep", 2)) { ++ ++ enable_UPTEX (false); /* disable */ ++#if defined(WIN32) ++/* pBibTeX is EUC only */ ++ if (FILESTRNCASEEQ(base, "pbibtex", 7)) { ++ init_default_kanji(NULL, "euc"); ++ } else { ++/* for pTeX, e-pTeX, pDVItype, pPLtoTF, and pTFtoPL */ ++ init_default_kanji(NULL, "sjis"); ++ } ++#else ++ init_default_kanji(NULL, "euc"); ++#endif ++ ++ } else { ++ ++/* for upTeX, e-upTeX, upBibTeX, upDVItype, upPLtoTF, and upTFtoPL */ ++ enable_UPTEX (true); /* enable */ ++ init_default_kanji ("utf8", "uptex"); ++ ++ } ++} +diff -Naur a/texlive-20190410-source/texk/web2c/uptexdir/kanji.h b/texlive-20190410-source/texk/web2c/uptexdir/kanji.h +--- a/texlive-20190410-source/texk/web2c/uptexdir/kanji.h 2019-02-06 11:01:31.000000000 +0000 ++++ b/texlive-20190410-source/texk/web2c/uptexdir/kanji.h 2019-05-31 22:00:04.010964033 +0100 +@@ -38,8 +38,9 @@ + extern integer multilenbuffchar (integer c); + + extern void init_default_kanji (const_string file_str, const_string internal_str); ++extern void init_default_kanji_select (void); + /* for upTeX, e-upTeX, upBibTeX, upDVItype, upPLtoTF, and upTFtoPL */ +-#define initkanji() init_default_kanji("utf8", "uptex") ++#define initkanji() init_default_kanji_select() + /* for upDVItype */ + #define setpriorfileenc() set_prior_file_enc() + +diff -Naur a/texlive-20190410-source/texk/web2c/uptexdir/tests/test_if.tex b/texlive-20190410-source/texk/web2c/uptexdir/tests/test_if.tex +--- a/texlive-20190410-source/texk/web2c/uptexdir/tests/test_if.tex 1970-01-01 01:00:00.000000000 +0100 ++++ b/texlive-20190410-source/texk/web2c/uptexdir/tests/test_if.tex 2019-05-31 22:00:04.010964033 +0100 +@@ -0,0 +1,29 @@ ++\kcatcode`あ=18 ++\def\xA{あ}\let\yA=あ ++\kcatcode`あ=17 ++\def\xB{あ}\let\yB=あ ++\kcatcode`あ=16 ++ ++\message{\ifcat あ\xA Y\else N\fi} ++\message{\ifcat あ\yA Y\else N\fi} ++\message{\ifcat あ\xB Y\else N\fi} ++\message{\ifcat あ\yB Y\else N\fi} ++ ++\message{\if あ\xA Y\else N\fi} ++\message{\if あ\yA Y\else N\fi} ++\message{\if い\xA Y\else N\fi} ++\message{\if い\yA Y\else N\fi} ++ ++\ifx\ucs\undefined\else ++ \kcatcode"100=16 ++ \message{upTeX} ++ \def\xA{Ā}% U+0100 ++ \def\xB{ā}% U+0101 ++ \message{\if \xA\relax Y\else N\fi} ++ \message{\if \xB\relax Y\else N\fi} ++ \message{\ifcat\xA\relax Y\else N\fi} ++ \message{\ifcat\xB\relax Y\else N\fi} ++\fi ++\end ++ ++ +diff -Naur a/texlive-20190410-source/texk/web2c/uptexdir/upbibtex.ch b/texlive-20190410-source/texk/web2c/uptexdir/upbibtex.ch +--- a/texlive-20190410-source/texk/web2c/uptexdir/upbibtex.ch 2019-02-23 01:59:36.000000000 +0000 ++++ b/texlive-20190410-source/texk/web2c/uptexdir/upbibtex.ch 2019-05-31 22:00:04.010964033 +0100 +@@ -3,7 +3,7 @@ + @d banner=='This is pBibTeX, Version 0.99d-j0.33' + @y + @d my_name=='upbibtex' +-@d banner=='This is upBibTeX, Version 0.99d-j0.33-u1.24' ++@d banner=='This is upBibTeX, Version 0.99d-j0.33-u1.25' + @z + + @x +diff -Naur a/texlive-20190410-source/texk/web2c/uptexdir/updvitype.ch b/texlive-20190410-source/texk/web2c/uptexdir/updvitype.ch +--- a/texlive-20190410-source/texk/web2c/uptexdir/updvitype.ch 2019-02-23 01:59:36.000000000 +0000 ++++ b/texlive-20190410-source/texk/web2c/uptexdir/updvitype.ch 2019-05-31 22:00:04.010964033 +0100 +@@ -3,7 +3,7 @@ + @d banner=='This is pDVItype, Version 3.6-p0.4' + @y + @d my_name=='updvitype' +-@d banner=='This is upDVItype, Version 3.6-p0.4-u1.24' ++@d banner=='This is upDVItype, Version 3.6-p0.4-u1.25' + @z + + @x procedure initialize +diff -Naur a/texlive-20190410-source/texk/web2c/uptexdir/uppltotf.ch b/texlive-20190410-source/texk/web2c/uptexdir/uppltotf.ch +--- a/texlive-20190410-source/texk/web2c/uptexdir/uppltotf.ch 2019-02-23 01:59:36.000000000 +0000 ++++ b/texlive-20190410-source/texk/web2c/uptexdir/uppltotf.ch 2019-05-31 22:00:04.010964033 +0100 +@@ -3,7 +3,7 @@ + @d banner=='This is pPLtoTF, Version 3.6-p2.0' + @y + @d my_name=='uppltotf' +-@d banner=='This is upPLtoTF, Version 3.6-p2.0-u1.24' ++@d banner=='This is upPLtoTF, Version 3.6-p2.0-u1.25' + @z + + @x +diff -Naur a/texlive-20190410-source/texk/web2c/uptexdir/uptex-m.ch b/texlive-20190410-source/texk/web2c/uptexdir/uptex-m.ch +--- a/texlive-20190410-source/texk/web2c/uptexdir/uptex-m.ch 2019-02-23 01:59:36.000000000 +0000 ++++ b/texlive-20190410-source/texk/web2c/uptexdir/uptex-m.ch 2019-05-31 22:00:04.010964033 +0100 +@@ -1,4 +1,4 @@ +-% This is a change file for upTeX u1.24 ++% This is a change file for upTeX u1.25 + % By Takuji Tanaka. + % + % (02/26/2007) TTK upTeX u0.01 +@@ -39,6 +39,8 @@ + % (2018-01-21) HK Added \uptexversion primitive and co. + % (2018-02-24) TTK upTeX u1.23 + % (2019-02-23) TTK upTeX u1.24 ++% (2019-05-06) HK Hironori Kitagawa fixed a bug in \if. ++% (2019-05-06) TTK upTeX u1.25 + + @x upTeX: banner + {printed when \pTeX\ starts} +@@ -46,8 +48,8 @@ + {printed when \pTeX\ starts} + @# + @d upTeX_version=1 +-@d upTeX_revision==".24" +-@d upTeX_version_string=='-u1.24' {current u\pTeX\ version} ++@d upTeX_revision==".25" ++@d upTeX_version_string=='-u1.25' {current u\pTeX\ version} + @# + @d upTeX_banner=='This is upTeX, Version 3.14159265',pTeX_version_string,upTeX_version_string + @d upTeX_banner_k==upTeX_banner +@@ -142,6 +144,7 @@ + @d max_quarterword=255 {largest allowable value in a |quarterword|} + @d min_halfword==-@"FFFFFFF {smallest allowable value in a |halfword|} + @d max_halfword==@"FFFFFFF {largest allowable value in a |halfword|} ++@d max_cjk_val=@"10000 + @y + @d min_quarterword=0 {smallest allowable value in a |quarterword|} + @d max_quarterword=@"FFFF {largest allowable value in a |quarterword|} +@@ -699,16 +702,24 @@ + + @x + if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then ++ begin n:=cur_chr; m:=kcat_code(kcatcodekey(n)); ++ end + @y + if (cur_cmd>=kanji)and(cur_cmd<=hangul) then ++ begin m:=cur_cmd; n:=cur_chr; ++ end + @z + + @x + get_x_token_or_active_char; + if (cur_cmd=kanji)or(cur_cmd=kana)or(cur_cmd=other_kchar) then ++ begin cur_cmd:=kcat_code(kcatcodekey(cur_chr)); ++ end + @y + get_x_token_or_active_char; + if (cur_cmd>=kanji)and(cur_cmd<=hangul) then ++ begin cur_cmd:=cur_cmd; ++ end {dummy} + @z + + @x +diff -Naur a/texlive-20190410-source/texk/web2c/uptexdir/uptex_version.h b/texlive-20190410-source/texk/web2c/uptexdir/uptex_version.h +--- a/texlive-20190410-source/texk/web2c/uptexdir/uptex_version.h 2019-02-23 01:59:36.000000000 +0000 ++++ b/texlive-20190410-source/texk/web2c/uptexdir/uptex_version.h 2019-05-31 22:00:04.010964033 +0100 +@@ -1 +1 @@ +-#define UPTEX_VERSION "u1.24" ++#define UPTEX_VERSION "u1.25" +diff -Naur a/texlive-20190410-source/texk/web2c/uptexdir/uptftopl.ch b/texlive-20190410-source/texk/web2c/uptexdir/uptftopl.ch +--- a/texlive-20190410-source/texk/web2c/uptexdir/uptftopl.ch 2019-02-23 01:59:36.000000000 +0000 ++++ b/texlive-20190410-source/texk/web2c/uptexdir/uptftopl.ch 2019-05-31 22:00:04.010964033 +0100 +@@ -3,7 +3,7 @@ + @d banner=='This is pTFtoPL, Version 3.3-p2.0' + @y + @d my_name=='uptftopl' +-@d banner=='This is upTFtoPL, Version 3.3-p2.0-u1.24' ++@d banner=='This is upTFtoPL, Version 3.3-p2.0-u1.25' + @z + + @x +diff -Naur a/texlive-20190410-source/texk/web2c/xetexdir/ChangeLog b/texlive-20190410-source/texk/web2c/xetexdir/ChangeLog +--- a/texlive-20190410-source/texk/web2c/xetexdir/ChangeLog 2019-01-02 22:41:45.000000000 +0000 ++++ b/texlive-20190410-source/texk/web2c/xetexdir/ChangeLog 2019-05-31 22:02:30.345042172 +0100 +@@ -1,3 +1,8 @@ ++2019-05-30 Khaled Hosny ++ ++ * XeTeXLayoutInterface.cpp: Do not use hb-icu if HarfBuzz ++ version is 2.5.0 or newer. ++ + 2019-01-03 Akira Kakuto + + * NEWS, xetex_version.h, xetex.web: Sync with the upstream. +diff -Naur a/texlive-20190410-source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp b/texlive-20190410-source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp +--- a/texlive-20190410-source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp 2017-03-12 08:47:36.000000000 +0000 ++++ b/texlive-20190410-source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp 2019-05-31 22:05:06.636170781 +0100 +@@ -2,7 +2,7 @@ + Part of the XeTeX typesetting system + Copyright (c) 1994-2008 by SIL International + Copyright (c) 2009-2012 by Jonathan Kew +- Copyright (c) 2012-2015 by Khaled Hosny ++ Copyright (c) 2012-2019 by Khaled Hosny + + SIL Author(s): Jonathan Kew + +@@ -39,8 +39,11 @@ + + #include + #include ++#include + #include ++#if !HB_VERSION_ATLEAST(2,5,0) + #include ++#endif + #include + + #include "XeTeX_web.h" +@@ -661,6 +664,7 @@ + free(engine->shaper); + } + ++#if !HB_VERSION_ATLEAST(2,5,0) + static unsigned int + _decompose_compat(hb_unicode_funcs_t* ufuncs, + hb_codepoint_t u, +@@ -677,8 +681,7 @@ + hb_unicode_funcs_set_decompose_compatibility_func(ufuncs, _decompose_compat, NULL, NULL); + return ufuncs; + } +- +-static hb_unicode_funcs_t* hbUnicodeFuncs = NULL; ++#endif + + int + layoutChars(XeTeXLayoutEngine engine, uint16_t chars[], int32_t offset, int32_t count, int32_t max, +@@ -699,11 +702,15 @@ + + script = hb_ot_tag_to_script (engine->script); + ++ hb_buffer_reset(engine->hbBuffer); ++ ++#if !HB_VERSION_ATLEAST(2,5,0) ++ static hb_unicode_funcs_t* hbUnicodeFuncs = NULL; + if (hbUnicodeFuncs == NULL) + hbUnicodeFuncs = _get_unicode_funcs(); +- +- hb_buffer_reset(engine->hbBuffer); + hb_buffer_set_unicode_funcs(engine->hbBuffer, hbUnicodeFuncs); ++#endif ++ + hb_buffer_add_utf16(engine->hbBuffer, chars, max, offset, count); + hb_buffer_set_direction(engine->hbBuffer, direction); + hb_buffer_set_script(engine->hbBuffer, script); diff --git a/editor/tex/texlive-bin/files/arch/texlive-poppler-0.83.patch b/editor/tex/texlive-bin/files/arch/texlive-poppler-0.83.patch new file mode 100644 index 0000000000..afc5e4a729 --- /dev/null +++ b/editor/tex/texlive-bin/files/arch/texlive-poppler-0.83.patch @@ -0,0 +1,46 @@ +diff -ru texlive-source-orig/texk/web2c/pdftexdir/pdftoepdf.cc texlive-source/texk/web2c/pdftexdir/pdftoepdf.cc +--- texlive-source-orig/texk/web2c/pdftexdir/pdftoepdf.cc 2020-01-07 22:42:03.717667766 +0000 ++++ texlive-source/texk/web2c/pdftexdir/pdftoepdf.cc 2020-01-07 22:47:42.818888622 +0000 +@@ -723,7 +723,7 @@ + #endif + // initialize + if (!isInit) { +- globalParams = new GlobalParams(); ++ globalParams.reset(new GlobalParams()); + globalParams->setErrQuiet(false); + isInit = true; + } +@@ -1108,6 +1108,5 @@ + delete_document(p); + } + // see above for globalParams +- delete globalParams; + } + } +diff -ru texlive-source-orig/texk/web2c/pdftexdir/pdftosrc.cc texlive-source/texk/web2c/pdftexdir/pdftosrc.cc +--- texlive-source-orig/texk/web2c/pdftexdir/pdftosrc.cc 2020-01-07 22:42:03.714334387 +0000 ++++ texlive-source/texk/web2c/pdftexdir/pdftosrc.cc 2020-01-07 22:50:08.070708640 +0000 +@@ -79,7 +79,7 @@ + exit(1); + } + fileName = new GString(argv[1]); +- globalParams = new GlobalParams(); ++ globalParams.reset(new GlobalParams()); + doc = new PDFDoc(fileName); + if (!doc->isOk()) { + fprintf(stderr, "Invalid PDF file\n"); +@@ -100,7 +100,7 @@ + if (objnum == 0) { + srcStream = catalogDict.dictLookup("SourceObject"); + static char const_SourceFile[] = "SourceFile"; +- if (!srcStream.isStream(const_SourceFile)) { ++ if (!srcStream.isDict(const_SourceFile)) { + fprintf(stderr, "No SourceObject found\n"); + exit(1); + } +@@ -202,5 +202,4 @@ + fprintf(stderr, "Cross-reference table extracted to %s\n", outname); + fclose(outfile); + delete doc; +- delete globalParams; + } diff --git a/editor/tex/texlive-bin/files/arch/texlive-poppler-0.84.patch b/editor/tex/texlive-bin/files/arch/texlive-poppler-0.84.patch new file mode 100644 index 0000000000..c8d8bef860 --- /dev/null +++ b/editor/tex/texlive-bin/files/arch/texlive-poppler-0.84.patch @@ -0,0 +1,44 @@ +From cf05aae9685e5c6a46b4313e7bfce49edc6f51f9 Mon Sep 17 00:00:00 2001 +From: Mikle Kolyada +Date: Tue, 31 Dec 2019 11:29:30 +0300 +Subject: [PATCH] poppler-0.84 compat + +Upstream report: https://tug.org/pipermail/tex-k/2019-December/003096.html + +Signed-off-by: Mikle Kolyada +--- + texk/web2c/pdftexdir/utils.c | 1 - + texk/web2c/xetexdir/XeTeX_ext.c | 3 +++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/texk/web2c/pdftexdir/utils.c b/texk/web2c/pdftexdir/utils.c +index c93a8781..6f866e76 100644 +--- a/texk/web2c/pdftexdir/utils.c ++++ b/texk/web2c/pdftexdir/utils.c +@@ -33,7 +33,6 @@ with this program. If not, see . + #include "ptexlib.h" + #include + #ifdef POPPLER_VERSION +-#include + #define xpdfVersion POPPLER_VERSION + #define xpdfString "poppler" + #else +diff --git a/texk/web2c/xetexdir/XeTeX_ext.c b/texk/web2c/xetexdir/XeTeX_ext.c +index 4968ee41..0aee4ee3 100644 +--- a/texk/web2c/xetexdir/XeTeX_ext.c ++++ b/texk/web2c/xetexdir/XeTeX_ext.c +@@ -38,7 +38,10 @@ authorization from the copyright holders. + + #include + ++#ifndef POPPLER_VERSION + #include ++#endif ++ + #include + #include + #include +-- +2.24.1 + + diff --git a/editor/tex/texlive-bin/files/arch/texlive-poppler-0.86.patch b/editor/tex/texlive-bin/files/arch/texlive-poppler-0.86.patch new file mode 100644 index 0000000000..56a781e07c --- /dev/null +++ b/editor/tex/texlive-bin/files/arch/texlive-poppler-0.86.patch @@ -0,0 +1,11 @@ +--- a/texk/web2c/pdftexdir/pdftoepdf.cc 2020-03-03 21:11:35.102711802 +0000 ++++ b/texk/web2c/pdftexdir/pdftoepdf.cc 2020-03-03 21:13:13.057420111 +0000 +@@ -757,7 +757,7 @@ + if (page_name) { + // get page by name + GString name(page_name); +- LinkDest *link = pdf_doc->doc->findDest(&name); ++ LinkDest *link = pdf_doc->doc->findDest(&name).get(); + if (link == 0 || !link->isOk()) + pdftex_fail("PDF inclusion: invalid destination <%s>", page_name); + Ref ref = link->getPageRef(); diff --git a/editor/tex/texlive-bin/files/fix-fontforge-encoding.patch b/editor/tex/texlive-bin/files/fix-fontforge-encoding.patch new file mode 100644 index 0000000000..8104b32899 --- /dev/null +++ b/editor/tex/texlive-bin/files/fix-fontforge-encoding.patch @@ -0,0 +1,12 @@ +--- source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/noprefs.c.orig 2009-09-30 19:27:00.935039526 +0200 ++++ source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/noprefs.c 2009-09-30 19:28:04.908364646 +0200 +@@ -495,6 +495,9 @@ + { "Big5HKSCS", e_big5hkscs }, + { "Big5-HKSCS", e_big5hkscs }, + { "UTF-8", e_utf8 }, ++ { "utf-8", e_utf8 }, ++ { "UTF8", e_utf8 }, ++ { "utf8", e_utf8 }, + { "ISO-10646/UTF-8", e_utf8 }, + { "ISO_10646/UTF-8", e_utf8 }, + { "UCS2", e_unicode }, diff --git a/editor/tex/texlive-bin/files/luatex-r4449-radical-rule-thickness.patch b/editor/tex/texlive-bin/files/luatex-r4449-radical-rule-thickness.patch new file mode 100644 index 0000000000..26cc9877a2 --- /dev/null +++ b/editor/tex/texlive-bin/files/luatex-r4449-radical-rule-thickness.patch @@ -0,0 +1,23 @@ +Index: source/texk/web2c/luatexdir/tex/mlist.w +=================================================================== +--- source/texk/web2c/luatexdir/tex/mlist.w (revision 4448) ++++ source/texk/web2c/luatexdir/tex/mlist.w (revision 4449) +@@ -1798,7 +1798,17 @@ + theta = fraction_rule(cur_style); + y = var_delimiter(left_delimiter(q), cur_size, + height(x) + depth(x) + clr + theta, NULL, cur_style); +- theta = height(y); ++ /* If |y| is a composite then set |theta| to the height of its top ++ character, else set it to the height of |y|. */ ++ if (list_ptr(y) != null ++ && type(list_ptr(y)) == hlist_node ++ && list_ptr(list_ptr(y)) != null ++ && type(list_ptr(list_ptr(y))) == glyph_node) { /* and it should be */ ++ theta = char_height(font(list_ptr(list_ptr(y))), ++ character(list_ptr(list_ptr(y)))); ++ } else { ++ theta = height(y); ++ } + } else { + y = var_delimiter(left_delimiter(q), cur_size, + height(x) + depth(x) + clr + theta, NULL, cur_style); \ No newline at end of file diff --git a/editor/tex/texlive-bin/files/poppler-0.20.patch b/editor/tex/texlive-bin/files/poppler-0.20.patch new file mode 100644 index 0000000000..eb6db07f44 --- /dev/null +++ b/editor/tex/texlive-bin/files/poppler-0.20.patch @@ -0,0 +1,22 @@ +--- source/texk/web2c/luatexdir/lua/lepdflib.cc.orig 2011-10-06 06:14:20.000000000 +0000 ++++ source/texk/web2c/luatexdir/lua/lepdflib.cc 2012-05-17 11:30:26.327236883 +0000 +@@ -1433,7 +1433,7 @@ + + static int m_Object_getTypeName(lua_State * L) + { +- char *s; ++ const char *s; + udstruct *uin; + uin = (udstruct *) luaL_checkudata(L, 1, M_Object); + if (uin->pd != NULL && uin->pd->pc != uin->pc) +--- source/texk/web2c/pdftexdir/pdftosrc.cc.orig 2012-06-24 17:12:34.376329435 +0200 ++++ source/texk/web2c/pdftexdir/pdftosrc.cc 2012-06-24 17:12:25.490003152 +0200 +@@ -134,7 +134,7 @@ + exit(1); + } + if (extract_xref_table) { +- int size = xref->getSize(); ++ int size = xref->getNumObjects(); + int i; + for (i = 0; i < size; i++) { + if (xref->getEntry(i)->offset == 0xffffffff) \ No newline at end of file diff --git a/editor/tex/texlive-bin/files/texmf.cnf b/editor/tex/texlive-bin/files/texmf.cnf new file mode 100644 index 0000000000..d23ebdbc79 --- /dev/null +++ b/editor/tex/texlive-bin/files/texmf.cnf @@ -0,0 +1,724 @@ +% texmf.cnf for TeXLive/Arch Linux -- runtime path configuration file for kpathsea. +% Public domain. +% +% If you modify this original file, YOUR CHANGES WILL BE LOST when it is +% updated. Instead, put your changes -- and only your changes, not an +% entire copy of the full texmf.cnf! -- in ../../texmf.cnf. That is, if +% this file is installed in /some/path/to/texlive/2011/texmf/web2c/texmf.cnf, +% add your custom settings to /some/path/to/texlive/2011/texmf.cnf. +% +% What follows is a super-summary of what this .cnf file can +% contain. Please read the Kpathsea manual for more information. +% +% Any identifier (sticking to A-Za-z_ for names is safest) can be assigned. +% The `=' (and surrounding spaces) is optional. +% $foo (or ${foo}) in a value expands to the envvar or cnf value of foo. +% Long lines can be continued with a \. +% +% Earlier entries (in the same or another file) override later ones, and +% an environment variable foo overrides any texmf.cnf definition of foo. +% +% All definitions are read before anything is expanded, so you can use +% variables before they are defined. +% +% If a variable assignment is qualified with `.PROGRAM', it is ignored +% unless the current executable (last filename component of argv[0]) is +% named PROGRAM. This foo.PROGRAM construct is not recognized on the +% right-hand side. For environment variables, use FOO_PROGRAM. +% +% Which file formats use which paths for searches is described in the +% various programs' and the Kpathsea documentation (http://tug.org/kpathsea). +% +% // means to search subdirectories (recursively). +% A leading !! means to look only in the ls-R db, never on the disk. +% In this file, either ; or : can be used to separate path components. +% A leading/trailing/doubled path separator in the paths will be +% expanded into the compile-time default. Probably not what you want. +% +% Brace notation is supported, for example: /usr/local/{mytex,othertex} +% expands to /usr/local/mytex:/usr/local/othertex. We make extensive +% use of this. + + +% Part 1: Search paths and directories. + +% This is the parent directory of our several trees, i.e., +% /usr/local/texlive/YYYY in the original TeX Live distribution. +% +% All trees must be organized according to the TeX Directory Structure +% (http://tug.org/tds), or files may not be found. +% +% Redistributors will probably want $SELFAUTODIR/share, i.e., /usr/share. +TEXMFROOT = $SELFAUTODIR/share + +% The tree containing runtime files related to the specific +% distribution and version. +TEXMFMAIN = $TEXMFROOT/texmf + +% The main tree of packages, distribution-agnostic: +TEXMFDIST = $TEXMFROOT/texmf-dist + +% Local additions to the distribution trees. +TEXMFLOCAL = /usr/local/share/texmf + +% TEXMFSYSVAR, where *-sys store cached runtime data. +TEXMFSYSVAR = /var/lib/texmf + +% TEXMFSYSCONFIG, where *-sys store configuration data. +TEXMFSYSCONFIG = /etc/texmf + +% Per-user texmf tree(s) -- organized per the TDS, as usual. To define +% more than one per-user tree, set this to a list of directories in +% braces, as described above. (This used to be HOMETEXMF.) ~ expands +% to %USERPROFILE% on Windows, $HOME otherwise. +TEXMFHOME = ~/texmf + +% TEXMFVAR, where texconfig/updmap/fmtutil store cached runtime data. +TEXMFVAR = ~/.texlive/texmf-var + +% TEXMFCONFIG, where texconfig/updmap/fmtutil store configuration data. +TEXMFCONFIG = ~/.texlive/texmf-config + +% List all the texmf trees. +% +% For texconfig to work properly, TEXMFCONFIG and TEXMFVAR should be named +% explicitly and before all other trees. +% +% TEXMFLOCAL follows TEXMFMAIN (and precedes TEXMFDIST) because the +% files in TEXMFMAIN are tightly coupled with the particular version of +% the distribution, such as configuration files. Overriding them would +% be more likely to cause trouble than help. On the other hand, the +% bulk of packages and fonts are in TEXMFDIST, and locally-installed +% versions should take precedence over those -- although it is generally +% a source of confusion to have different versions of a package +% installed, whatever the trees, so try to avoid it. +TEXMF = {$TEXMFCONFIG,$TEXMFVAR,$TEXMFHOME,!!$TEXMFSYSCONFIG,!!$TEXMFSYSVAR,!!$TEXMFMAIN,!!$TEXMFLOCAL,!!$TEXMFDIST} + +% Where to look for ls-R files. There need not be an ls-R in the +% directories in this path, but if there is one, Kpathsea will use it. +% By default, this is only the !! elements of TEXMF, so that mktexlsr +% does not create ls-R files in the non-!! elements -- because if an +% ls-R is present, it will be used, and the disk will not be searched. +% This is arguably a bug in kpathsea. +TEXMFDBS = {!!$TEXMFSYSCONFIG,!!$TEXMFSYSVAR,!!$TEXMFMAIN,!!$TEXMFLOCAL,!!$TEXMFDIST} + +% The system trees. These are the trees that are shared by all users. +% If a tree appears in this list, the mktex* scripts will use +% VARTEXFONTS for generated files, if the original tree isn't writable; +% otherwise the current working directory is used. +SYSTEXMF = $TEXMFSYSVAR;$TEXMFMAIN;$TEXMFLOCAL;$TEXMFDIST + +% Where generated fonts may be written. This tree is used when the sources +% were found in a system tree and either that tree wasn't writable, or the +% varfonts feature was enabled in MT_FEATURES in mktex.cnf. +VARTEXFONTS = $TEXMFVAR/fonts + +% On some systems, there will be a system tree which contains all the font +% files that may be created as well as the formats. For example +% TEXMFVAR = /var/lib/texmf +% is used in many distros. In this case, set VARTEXFONTS like this +%VARTEXFONTS = $TEXMFVAR/fonts +% and do not mention it in TEXMFDBS (but _do_ mention TEXMFVAR). +% +% Remove $VARTEXFONTS from TEXMFDBS if the VARTEXFONTS directory is below +% one of the TEXMF directories (avoids overlapping ls-R files). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Usually you will not need to edit any of the following variables. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% WEB2C is for Web2C specific files. The current directory may not be +% a good place to look for them. +WEB2C = $TEXMF/web2c + +% TEXINPUTS is for TeX input files -- i.e., anything to be found by \input +% or \openin, including .sty, .eps, etc. We specify paths for all known +% formats, past or present. Not all of them are built these days. + +% Plain TeX. Have the command tex check all directories as a last +% resort, we may have plain-compatible stuff anywhere. +TEXINPUTS.tex = .;$TEXMF/tex/{plain,generic,}// + +% Fontinst needs to read afm files. +TEXINPUTS.fontinst = .;$TEXMF/{tex,fonts/afm}// + +% Other plain-based formats. +TEXINPUTS.amstex = .;$TEXMF/tex/{amstex,plain,generic,}// +TEXINPUTS.csplain = .;$TEXMF/tex/{csplain,plain,generic,}// +TEXINPUTS.eplain = .;$TEXMF/tex/{eplain,plain,generic,}// +TEXINPUTS.ftex = .;$TEXMF/tex/{formate,plain,generic,}// +TEXINPUTS.mex = .;$TEXMF/tex/{mex,plain,generic,}// +TEXINPUTS.texinfo = .;$TEXMF/tex/{texinfo,plain,generic,}// + +% LaTeX 2e specific macros are stored in latex/, macros that can only be +% used with 2.09 in latex209/. In addition, we look in the directory +% latex209, useful for macros that were written for 2.09 and do not +% mention 2e at all, but can be used with 2e. +TEXINPUTS.cslatex = .;$TEXMF/tex/{cslatex,csplain,latex,generic,}// +TEXINPUTS.latex = .;$TEXMF/tex/{latex,generic,}// +TEXINPUTS.latex209 = .;$TEXMF/tex/{latex209,generic,latex,}// +TEXINPUTS.olatex = .;$TEXMF/tex/{latex,generic,}// + +% MLTeX. +TEXINPUTS.frlatex = .;$TEXMF/tex/{french,latex,generic,}// +TEXINPUTS.frtex = .;$TEXMF/tex/{french,plain,generic,}// +TEXINPUTS.mllatex = .;$TEXMF/tex/{latex,generic,}// +TEXINPUTS.mltex = .;$TEXMF/tex/{plain,generic,}// + +% e-TeX. +TEXINPUTS.elatex = .;$TEXMF/tex/{latex,generic,}// +TEXINPUTS.etex = .;$TEXMF/tex/{plain,generic,}// + +% pdfTeX. +TEXINPUTS.pdfcslatex = .;$TEXMF/tex/{cslatex,csplain,latex,generic,}// +TEXINPUTS.pdfcsplain = .;$TEXMF/tex/{csplain,plain,generic,}// +TEXINPUTS.pdflatex = .;$TEXMF/tex/{latex,generic,}// +TEXINPUTS.pdfmex = .;$TEXMF/tex/{mex,plain,generic,}// +TEXINPUTS.utf8mex = .;$TEXMF/tex/{mex,plain,generic,}// +TEXINPUTS.pdftex = .;$TEXMF/tex/{plain,generic,}// +TEXINPUTS.pdftexinfo = .;$TEXMF/tex/{texinfo,plain,generic,}// +TEXINPUTS.pdfamstex = .;$TEXMF/tex/{amstex,plain,generic,}// + +% pdfeTeX. +TEXINPUTS.pdfelatex = .;$TEXMF/tex/{latex,generic,}// +TEXINPUTS.pdfetex = .;$TEXMF/tex/{plain,generic,}// + +% pdfxTeX. +TEXINPUTS.pdfxlatex = .;$TEXMF/tex/{latex,generic,}// +TEXINPUTS.pdfxmex = .;$TEXMF/tex/{mex,plain,generic,}// +TEXINPUTS.pdfxtex = .;$TEXMF/tex/{plain,generic,}// + +% LuaTeX. +TEXINPUTS.lualatex = .;$TEXMF/tex/{lualatex,latex,luatex,generic,}// +TEXINPUTS.luatex = .;$TEXMF/tex/{luatex,plain,generic,}// +TEXINPUTS.dvilualatex = .;$TEXMF/tex/{lualatex,latex,luatex,generic,}// +TEXINPUTS.dviluatex = .;$TEXMF/tex/{luatex,plain,generic,}// + +% XeTeX. +TEXINPUTS.xelatex = .;$TEXMF/tex/{xelatex,latex,xetex,generic,}// +TEXINPUTS.xeplain = .;$TEXMF/tex/{xeplain,eplain,plain,xetex,generic,}// +TEXINPUTS.xetex = .;$TEXMF/tex/{xetex,plain,generic,}// + +% Omega / Aleph. +TEXINPUTS.aleph = .;$TEXMF/tex/{plain,generic,}// +TEXINPUTS.elambda = .;$TEXMF/tex/{lambda,latex,generic,}// +TEXINPUTS.eomega = .;$TEXMF/tex/{plain,generic,}// +TEXINPUTS.lambda = .;$TEXMF/tex/{lambda,latex,generic,}// +TEXINPUTS.lamed = .;$TEXMF/tex/{lamed,lambda,latex,generic,}// +TEXINPUTS.omega = .;$TEXMF/tex/{plain,generic,}// + +% p(La)TeX. +TEXINPUTS.ptex = .;$TEXMF/tex/{ptex,ptexgeneric,plain,generic,}// +TEXINPUTS.platex = .;$TEXMF/tex/{platex,ptexgeneric,latex,generic,}// + +% epTeX. +TEXINPUTS.eptex = .;$TEXMF/tex/{ptex,ptexgeneric,plain,generic,}// + +% pBibTeX bibliographies and style files. +BIBINPUTS.pbibtex = .;$TEXMF/{pbibtex,bibtex}/bib// +BSTINPUTS.pbibtex = .;$TEXMF/{pbibtex,bibtex}/bst// + +% ConTeXt. +TEXINPUTS.context = .;$TEXMF/tex/{context,plain,generic,}// + +% jadetex. +TEXINPUTS.jadetex = .;$TEXMF/tex/{jadetex,latex,generic,}// +TEXINPUTS.pdfjadetex = .;$TEXMF/tex/{jadetex,latex,generic,}// + +% XMLTeX. +TEXINPUTS.xmltex = .;$TEXMF/tex/{xmltex,latex,generic,}// +TEXINPUTS.pdfxmltex = .;$TEXMF/tex/{xmltex,latex,generic,}// + +% Miscellany, no longer built. +TEXINPUTS.lamstex = .;$TEXMF/tex/{lamstex,plain,generic,}// +TEXINPUTS.lollipop = .;$TEXMF/tex/{lollipop,plain,generic,}// +TEXINPUTS.frpdflatex = .;$TEXMF/tex/{french,latex,generic,}// +TEXINPUTS.frpdftex = .;$TEXMF/tex/{french,plain,generic,}// + +% Earlier entries override later ones, so put this generic one last. +TEXINPUTS = .;$TEXMF/tex/{$progname,generic,}// + +% ttf2tfm. +TTF2TFMINPUTS = .;$TEXMF/ttf2pk// + +% Metafont, MetaPost inputs. +MFINPUTS = .;$TEXMF/metafont//;{$TEXMF/fonts,$VARTEXFONTS}/source// +MPINPUTS = .;$TEXMF/metapost// + +% Dump files (fmt/base/mem) for vir{tex,mf,mp} to read. +% We want to find the engine-specific file, e.g., cont-en.fmt can +% exist under both pdftex/ and xetex/. But just in case some formats +% end up without an engine directory, look directly in web2c/ too. +% We repeat the same definition three times because of the way fmtutil +% is implemented; if we use ${TEXFORMATS}, the mpost/mf/etc. formats +% will not be found. +TEXFORMATS = .;$TEXMF/web2c{/$engine,} +MFBASES = .;$TEXMF/web2c{/$engine,} +MPMEMS = .;$TEXMF/web2c{/$engine,} +% +% As of 2008, pool files don't exist any more (the strings are compiled +% into the binaries), but just in case something expects to find these: +TEXPOOL = .;$TEXMF/web2c +MFPOOL = ${TEXPOOL} +MPPOOL = ${TEXPOOL} + +% support the original xdvi. Must come before the generic settings. +PKFONTS.XDvi = .;$TEXMF/%s;$VARTEXFONTS/pk/{%m,modeless}// +VFFONTS.XDvi = .;$TEXMF/%s +PSHEADERS.XDvi = .;$TEXMF/%q{dvips,fonts/type1}// +TEXPICTS.XDvi = .;$TEXMF/%q{dvips,tex}// + +% Device-independent font metric files. +VFFONTS = .;$TEXMF/fonts/vf// +TFMFONTS = .;{$TEXMF/fonts,$VARTEXFONTS}/tfm// + +% The $MAKETEX_MODE below means the drivers will not use a cx font when +% the mode is ricoh. If no mode is explicitly specified, kpse_prog_init +% sets MAKETEX_MODE to /, so all subdirectories are searched. See the manual. +% The modeless part guarantees that bitmaps for PostScript fonts are found. +PKFONTS = .;{$TEXMF/fonts,$VARTEXFONTS}/pk/{$MAKETEX_MODE,modeless}// + +% Similarly for the GF format, which only remains in existence because +% Metafont outputs it (and MF isn't going to change). +GFFONTS = .;$TEXMF/fonts/gf/$MAKETEX_MODE// + +% A backup for PKFONTS and GFFONTS. Not used for anything. +GLYPHFONTS = .;$TEXMF/fonts + +% A place to puth everything that doesn't fit the other font categories. +MISCFONTS = .;$TEXMF/fonts/misc// + +% font name map files. This isn't just fonts/map// because ConTeXt +% wants support for having files with the same name in the different +% subdirs. Maybe if the programs ever get unified to accepting the same +% map file syntax the definition can be simplified again. +TEXFONTMAPS = .;$TEXMF/fonts/map/{$progname,pdftex,dvips,}// + +% BibTeX bibliographies and style files. bibtex8 also uses these. +BIBINPUTS = .;$TEXMF/bibtex/bib// +BSTINPUTS = .;$TEXMF/bibtex/{bst,csf}// + +% MlBibTeX. +MLBIBINPUTS = .;$TEXMF/bibtex/bib/{mlbib,}// +MLBSTINPUTS = .;$TEXMF/bibtex/{mlbst,bst}// + +% .ris and .bltxml bibliography formats. +RISINPUTS = .;$TEXMF/bibtex/ris// +BLTXMLINPUTS = .;$TEXMF/bibtex/bltxml// + +% MFT style files. +MFTINPUTS = .;$TEXMF/mft// + +% PostScript headers and prologues (.pro); unfortunately, some programs +% also use this for acessing font files (enc, type1, truetype) +TEXPSHEADERS = .;$TEXMF/{dvips,fonts/{enc,type1,type42,type3}}// +TEXPSHEADERS.gsftopk = .;$TEXMF/{dvips,fonts/{enc,type1,type42,type3,truetype}}// + +% OSFONTDIR is to provide a convenient hook for allowing TeX to find +% fonts installed on the system (outside of TeX). An empty default +% value would add "//" to the search paths, so we give it a dummy value. +% OSFONTDIR = /usr/share/fonts + +% PostScript Type 1 outline fonts. +T1FONTS = .;$TEXMF/fonts/type1//;$OSFONTDIR// + +% PostScript AFM metric files. +AFMFONTS = .;$TEXMF/fonts/afm//;$OSFONTDIR// + +% TrueType outline fonts. +TTFONTS = .;$TEXMF/fonts/{truetype,opentype}//;$OSFONTDIR// + +% OpenType outline fonts. +OPENTYPEFONTS = .;$TEXMF/fonts/{opentype,truetype}//;$OSFONTDIR// + +% Type 42 outline fonts. +T42FONTS = .;$TEXMF/fonts/type42// + +% Ligature definition files. +LIGFONTS = .;$TEXMF/fonts/lig// + +% Dvips' config.* files (this name should not start with `TEX'!). +TEXCONFIG = $TEXMF/dvips// + +% Makeindex style (.ist) files. +INDEXSTYLE = .;$TEXMF/makeindex// + +% Font encoding files (.enc). +ENCFONTS = .;$TEXMF/fonts/enc// + +% CMap files. +CMAPFONTS = .;$TEXMF/fonts/cmap// + +% Subfont definition files. +SFDFONTS = .;$TEXMF/fonts/sfd// + +% OpenType feature files (.fea). +FONTFEATURES=.;$TEXMF/fonts/fea// + +% .cid and .cidmap +FONTCIDMAPS=.;$TEXMF/fonts/cid// + +% pdftex config files: +PDFTEXCONFIG = .;$TEXMF/pdftex/{$progname,}// + +% Used by DMP (ditroff-to-mpx), called by makempx -troff. +TRFONTS = /usr{/local,}/share/groff/{current/font,site-font}/devps +MPSUPPORT = .;$TEXMF/metapost/support + +% For xdvi to find mime.types and .mailcap, if they do not exist in +% ~. These are single directories, not paths. +% (But the default mime.types, at least, may well suffice.) +MIMELIBDIR = /etc +MAILCAPLIBDIR = /etc + +% Default settings for the fontconfig library as used by the Windows +% versions of xetex/xdvipdfmx. On Unixish systems, fontconfig ignores +% this. ConTeXT MkIV (all platforms) also use these values. +% +FONTCONFIG_FILE = fonts.conf +FONTCONFIG_PATH = $TEXMFSYSVAR/fonts/conf +FC_CACHEDIR = $TEXMFSYSVAR/fonts/cache + +% TeX documentation and source files, for use with texdoc and kpsewhich. +TEXDOCS = $TEXMF/doc// +TEXSOURCES = .;$TEXMF/source// + +% Web and CWeb input paths. +WEBINPUTS = .;$TEXMF/web// +CWEBINPUTS = .;$TEXMF/cweb// + +% Omega-related fonts and other files. +OFMFONTS = .;{$TEXMF/fonts,$VARTEXFONTS}/{ofm,tfm}// +OPLFONTS = .;{$TEXMF/fonts,$VARTEXFONTS}/opl// +OVFFONTS = .;{$TEXMF/fonts,$VARTEXFONTS}/{ovf,vf}// +OVPFONTS = .;{$TEXMF/fonts,$VARTEXFONTS}/ovp// +OTPINPUTS = .;$TEXMF/omega/otp// +OCPINPUTS = .;$TEXMF/omega/ocp// + +% Some additional input variables for several programs. If you add +% a program that uses the `other text files' or `other binary files' +% search formats, you'll want to add their variables here as well. +T4HTINPUTS = .;$TEXMF/tex4ht// + +%% t4ht utility, sharing files with TeX4ht +TEX4HTFONTSET=alias,iso8859,unicode +TEX4HTINPUTS = .;$TEXMF/tex4ht/base//;$TEXMF/tex4ht/ht-fonts/{$TEX4HTFONTSET}// + +% TeXworks editor configuration and settings +TW_LIBPATH = $TEXMFCONFIG/texworks +TW_INIPATH = $TW_LIBPATH + +% For security, do not look in . for dvipdfmx.cfg, since the D option +% would allow command execution. +DVIPDFMXINPUTS = $TEXMF/dvipdfmx + +% Lua needs to look in TEXINPUTS for lua scripts distributed with packages. +% +% But we can't simply use $TEXINPUTS, since then if TEXINPUTS is set in +% the environment with a colon, say, TEXINPUTS=/some/dir:, the intended +% default expansion of TEXINPUTS will not happen and .lua files under +% the /tex/ will not be found. +% +% So, duplicate the TEXINPUTS.*lualatex values as LUAINPUTS.*lualatex. +% The default LUAINPUTS sufficess for luatex and dviluatex. +% +LUAINPUTS.lualatex = .;$TEXMF/scripts/{$progname,$engine,}/{lua,}//;$TEXMF/tex/{lualatex,latex,luatex,generic,}// +LUAINPUTS.dvilualatex = .;$TEXMF/scripts/{$progname,$engine,}/{lua,}//;$TEXMF/tex/{lualatex,latex,luatex,generic,}// +LUAINPUTS = .;$TEXMF/scripts/{$progname,$engine,}/{lua,}//;$TEXMF/tex/{luatex,plain,generic,}// + +% Lua needs to look for binary lua libraries distributed with packages. +CLUAINPUTS = .;$SELFAUTOLOC/lib/{$progname,$engine,}/lua// + +% Architecture independent executables. +TEXMFSCRIPTS = $TEXMF/scripts/{$progname,$engine,}// + +% Other languages. +JAVAINPUTS = .;$TEXMF/scripts/{$progname,$engine,}/java// +PERLINPUTS = .;$TEXMF/scripts/{$progname,$engine,}/perl// +PYTHONINPUTS = .;$TEXMF/scripts/{$progname,$engine,}/python// +RUBYINPUTS = .;$TEXMF/scripts/{$progname,$engine,}/ruby// + + +%% The mktex* scripts rely on KPSE_DOT. Do not set it in the environment. +% KPSE_DOT = . + +% This definition isn't used from this .cnf file itself (that would be +% paradoxical), but the compile-time default in paths.h is built from it. +% The SELFAUTO* variables are set automatically from the location of +% argv[0], in kpse_set_program_name. +% +% This main texmf.cnf file is installed, for a release YYYY, in a +% directory such as /usr/local/texlive/YYYY/texmf/web2c/texmf.cnf. +% Since this file is subject to future updates, the TeX Live installer +% or human administrator may also create a file +% /usr/local/texlive/YYYY/texmf.cnf; any settings in this latter file +% will take precedence over the distributed one under texmf/web2c. +% +% For security reasons, it is better not to include . in this path. +% +TEXMFCNF = {$SELFAUTOLOC,$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c} + +% kpathsea 3.5.3 and later sets these at runtime. To avoid empty +% expansions from binaries linked against an earlier version of the +% library, we set $progname and $engine to something non-empty: +progname = unsetprogname +engine = unsetengine + + +% Part 2: Options. + +% If this option is set to true, `tex a.b' will look first for a.b.tex +% (within each path element), and then for a.b, i.e., we try standard +% extensions first. If this is false, we first look for a.b and then +% a.b.tex, i.e., we try the name as-is first. +% +% Both names are always tried; the difference is the order in which they +% are tried. The setting applies to all searches, not just .tex. +% +% This setting only affects names being looked up which *already* have +% an extension. A name without an extension (e.g., `tex story') will +% always have an extension added first. +% +% The default is true, because we already avoid adding the standard +% extension(s) in the usual cases. E.g., babel.sty will only look for +% babel.sty, not babel.sty.tex, regardless of this setting. +try_std_extension_first = t + +% Enable system commands via \write18{...}. When enabled fully (set to +% t), obviously insecure. When enabled partially (set to p), only the +% commands listed in shell_escape_commands are allowed. Although this +% is not fully secure either, it is much better, and so useful that we +% enable it for everything but bare tex. +shell_escape = p + +% No spaces in this command list. +% +% The programs listed here are as safe as any we know: they either do +% not write any output files, respect openout_any, or have hard-coded +% restrictions similar or higher to openout_any=p. They also have no +% features to invoke arbitrary other programs, and no known exploitable +% bugs. All to the best of our knowledge. They also have practical use +% for being called from TeX. +% +shell_escape_commands = \ +bibtex,bibtex8,\ +kpsewhich,\ +makeindex,\ +repstopdf,\ + +% we'd like to allow: +% dvips - but external commands can be executed, need at least -R1. +% epspdf, ps2pdf, pstopdf - need to respect openout_any, +% and gs -dSAFER must be used and check for shell injection with filenames. +% (img)convert (ImageMagick) - delegates.mgk possible misconfig, besides, +% without Unix convert it hardly seems worth it, and Windows convert +% is something completely different that destroys filesystems, so skip. +% pygmentize - but is the filter feature insecure? +% ps4pdf - but it calls an unrestricted latex. +% rpdfcrop - maybe ok, but let's get experience with repstopdf first. +% texindy,xindy - but is the module feature insecure? +% ulqda - but requires optional SHA1.pm, so why bother. +% tex, latex, etc. - need to forbid --shell-escape, and inherit openout_any. + +% plain TeX should remain unenhanced. +shell_escape.tex = f +shell_escape.initex = f + +% This is used by the Windows script wrapper for restricting searching +% for the purportedly safe shell_escape_commands above to system +% directories. +TEXMF_RESTRICTED_SCRIPTS = \ + {!!$TEXMFMAIN,!!$TEXMFLOCAL,!!$TEXMFDIST}/scripts/{$progname,$engine,}// + +% Allow TeX \openin, \openout, or \input on filenames starting with `.' +% (e.g., .rhosts) or outside the current tree (e.g., /etc/passwd)? +% a (any) : any file can be opened. +% r (restricted) : disallow opening "dotfiles". +% p (paranoid) : as `r' and disallow going to parent directories, and +% restrict absolute paths to be under $TEXMFOUTPUT. +openout_any = p +openin_any = a + +% Write .log/.dvi/etc. files here, if the current directory is unwritable. +%TEXMFOUTPUT = /tmp + +% If a dynamic file creation fails, log the command to this file, in +% either the current directory or TEXMFOUTPUT. Set to the +% empty string or 0 to avoid logging. +MISSFONT_LOG = missfont.log + +% Set to a colon-separated list of words specifying warnings to suppress. +% To suppress everything, use TEX_HUSH = all; this is currently equivalent to +% TEX_HUSH = checksum:lostchar:readable:special +% To suppress nothing, use TEX_HUSH = none or do not set the variable at all. +TEX_HUSH = none + +% Allow TeX, and MF to parse the first line of an input file for +% the %&format construct. +parse_first_line = t + +% But don't parse the first line if invoked as "tex", since we want that +% to remain Knuth-compatible. The src_specials and +% file_line_error_style settings, as well as the options -enctex, +% -mltex, -8bit, etc., also affect this, but they are all off by default. +parse_first_line.tex = f +parse_first_line.initex = f + +% Control file:line:error style messages. +file_line_error_style = f + +% Enable the mktex... scripts by default? These must be set to 0 or 1. +% Particular programs can and do override these settings, for example +% dvips's -M option. Your first chance to specify whether the scripts +% are invoked by default is at configure time. +% +% These values are ignored if the script names are changed; e.g., if you +% set DVIPSMAKEPK to `foo', what counts is the value of the environment +% variable/config value `FOO', not the `MKTEXPK' value. +% +%MKTEXTEX = 0 +%MKTEXPK = 0 +%MKTEXMF = 0 +%MKTEXTFM = 0 +%MKTEXFMT = 0 +%MKOCP = 0 +%MKOFM = 0 + +% Used by makempx to run TeX. We use "etex" because MetaPost is +% expecting DVI, and not "tex" because we want first line parsing. +TEX = etex + +% These variables specify the external program called for the +% interactive `e' option. %d is replaced by the line number and %s by +% the current filename. The default is specified at compile-time, and +% we let that stay in place since different platforms like different values. +%TEXEDIT = vi +%d '%s' % default for Unix +%TEXEDIT = texworks --position=+%d "%s" % default for Windows +%MFEDIT = ${TEXEDIT} +%MPEDIT = ${TEXEDIT} + +% The default `codepage and sort order' file for BibTeX8, when none is +% given as command line option or environment variable. +BIBTEX_CSFILE = 88591lat.csf + +% This variable is specific to Windows. It must be set to 0 or 1. The +% default is 0. Setting it to 1 tells the Windows script wrappers to +% use an already installed Perl interpreter if one is found on the +% search path, in preference to the Perl shipped with TeX Live. Thus, +% it may be useful if you both (a) installed a full Perl distribution +% for general use, and (b) need to run Perl programs from TL that use +% additional modules we don't provide. The TL Perl does provide all the +% standard Perl modules. +% +%TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL = 0 + + +% Part 3: Array and other sizes for TeX (and Metafont). +% +% If you want to change some of these sizes only for a certain TeX +% variant, the usual dot notation works, e.g., +% main_memory.hugetex = 20000000 +% +% If a change here appears to be ignored, try redumping the format file. + +% Memory. Must be less than 8,000,000 total. +% +% main_memory is relevant only to initex, extra_mem_* only to non-ini. +% Thus, have to redump the .fmt file after changing main_memory; to add +% to existing fmt files, increase extra_mem_*. (To get an idea of how +% much, try \tracingstats=2 in your TeX source file; +% web2c/tests/memtest.tex might also be interesting.) +% +% To increase space for boxes (as might be needed by, e.g., PiCTeX), +% increase extra_mem_bot. +% +% For some xy-pic samples, you may need as much as 700000 words of memory. +% For the vast majority of documents, 60000 or less will do. +% +main_memory = 3000000 % words of inimemory available; also applies to inimf&mp +extra_mem_top = 0 % extra high memory for chars, tokens, etc. +extra_mem_bot = 0 % extra low memory for boxes, glue, breakpoints, etc. + +% ConTeXt needs lots of memory. +extra_mem_top.context = 2000000 +extra_mem_bot.context = 4000000 + +% Words of font info for TeX (total size of all TFM files, approximately). +% Must be >= 20000 and <= 147483647 (without tex.ch changes). +font_mem_size = 3000000 + +% Total number of fonts. Must be >= 50 and <= 9000 (without tex.ch changes). +font_max = 9000 + +% Extra space for the hash table of control sequences. +hash_extra = 200000 + +% Max number of characters in all strings, including all error messages, +% help texts, font names, control sequences. These values apply to TeX. +pool_size = 3250000 +% Minimum pool space after TeX's own strings; must be at least +% 25000 less than pool_size, but doesn't need to be nearly that large. +string_vacancies = 90000 +% Maximum number of strings. +max_strings = 500000 +% min pool space left after loading .fmt +pool_free = 47500 + +% Buffer size. TeX uses the buffer to contain input lines, but macro +% expansion works by writing material into the buffer and reparsing the +% line. As a consequence, certain constructs require the buffer to be +% very large, even though most documents can be handled with a small value. +buf_size = 200000 + +% Hyphenation trie. The maximum possible is 4194303 (ssup_trie_size in +% the sources), but we don't need that much. The value here suffices +% for all known free hyphenation patterns to be loaded simultaneously +% (as TeX Live does). +% +trie_size = 1000000 + +hyph_size = 8191 % prime number of hyphenation exceptions, >610, <32767. + % http://primes.utm.edu/curios/page.php/8191.html +nest_size = 500 % simultaneous semantic levels (e.g., groups) +max_in_open = 15 % simultaneous input files and error insertions, + % also applies to MetaPost +param_size = 10000 % simultaneous macro parameters, also applies to MP +save_size = 50000 % for saving values outside current group +stack_size = 5000 % simultaneous input sources + +% These are Omega-specific. +ocp_buf_size = 500000 % character buffers for ocp filters. +ocp_stack_size = 10000 % stacks for ocp computations. +ocp_list_size = 1000 % control for multiple ocps. + +% These work best if they are the same as the I/O buffer size, but it +% doesn't matter much. Must be a multiple of 8. +dvi_buf_size = 16384 % TeX +gf_buf_size = 16384 % MF + +% It's probably inadvisable to change these. At any rate, we must have: +% 45 < error_line < 255; +% 30 < half_error_line < error_line - 15; +% 60 <= max_print_line; +% These apply to TeX, Metafont, and MetaPost. +error_line = 79 +half_error_line = 50 +max_print_line = 79 + +% Metafont only. +screen_width.mf = 1664 +screen_depth.mf = 1200 + +% BibTeX only (max_strings also determines hash_size and hash_prime). +ent_str_size = 250 +glob_str_size = 5000 +max_strings.bibtex = 35307 +max_strings.bibtex8 = 35307 +max_strings.bibtexu = 35307 +max_strings.pbibtex = 35307 + +% GFtype only. +line_length.gftype = 500 +max_rows.gftype = 8191 +max_cols.gftype = 8191 \ No newline at end of file diff --git a/editor/tex/texlive-bin/pspec.xml b/editor/tex/texlive-bin/pspec.xml new file mode 100644 index 0000000000..79cdda92d6 --- /dev/null +++ b/editor/tex/texlive-bin/pspec.xml @@ -0,0 +1,129 @@ + + + + + texlive-bin + http://www.tug.org/texlive + + PisiLinux Community + admins@pisilinux.org + + editor.tex + GPLv2 + data:doc + app:console + Tex Live binaries + Texlive binaries that are an essential part of TeXLive component. + + + ftp://tug.org/texlive/historic/2020/texlive-20200406-source.tar.xz + https://github.com/plk/biber/archive/v2.14.tar.gz + + gd-devel + clisp-devel + icu4c-devel + t1lib-devel + libXi-devel + libXt-devel + ffcall-devel + libpng-devel + libXaw-devel + libXmu-devel + libXpm-devel + poppler-devel + libpaper-devel + harfbuzz-devel + freetype-devel + graphite2-devel + fontconfig-devel + libsigsegv-devel + ghostscript-devel + + + + + + + + + texlive-bin + Tex Live binaries + + gd + zlib + icu4c + libXt + libXi + t1lib + ffcall + libX11 + libgcc + libpng + libXaw + libXmu + libXpm + harfbuzz + freetype + graphite2 + fontconfig + libsigsegv + ghostscript + + + + /etc + /usr/share + /usr/lib + /usr/share/man + /usr/share/info + /usr/bin + /usr/share/tlpkg + /usr/share/texmf-dist + + + + + + + + + texlive-bin-devel + Development files for texlive-bin + + texlive-bin + + + /usr/include + /usr/lib/pkgconfig + + + + + + 2020-06-01 + 20200406 + Version bump. + Blue Devil + bluedevil@sctzine.com + + + 2020-03-21 + 20190410 + Version bump + Mustafa Cinasal + muscnsl@pisilinux.org + + + 2020-03-21 + 2018.47465 + First release + Osman Erkan + osman.erkan@pisilinux.org + + + \ No newline at end of file diff --git a/editor/tex/texlive-bin/translations.xml b/editor/tex/texlive-bin/translations.xml new file mode 100644 index 0000000000..12aa89793c --- /dev/null +++ b/editor/tex/texlive-bin/translations.xml @@ -0,0 +1,15 @@ + + + + texlive-bin + TeX Live Dağıtımının Ana Parçası + texlive-bin Tex Live dağıtımının ana parçasıdır. + texlive-bin est la part essentiel de TeXLive. + + + + texlive-bin-devel + texlive-bin için geliştirme dosyaları + texlive-bin-devel, texlive-bin için geliştirme dosyalarını içerir. + + \ No newline at end of file