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