texlive[52203] Build/source/libs: xpdf 4.02

commits+kakuto at tug.org commits+kakuto at tug.org
Sun Sep 29 12:00:12 CEST 2019


Revision: 52203
          http://tug.org/svn/texlive?view=revision&revision=52203
Author:   kakuto
Date:     2019-09-29 12:00:12 +0200 (Sun, 29 Sep 2019)
Log Message:
-----------
xpdf 4.02

Modified Paths:
--------------
    trunk/Build/source/libs/README
    trunk/Build/source/libs/xpdf/ChangeLog
    trunk/Build/source/libs/xpdf/TLpatches/ChangeLog
    trunk/Build/source/libs/xpdf/TLpatches/TL-Changes
    trunk/Build/source/libs/xpdf/TLpatches/patch-bunched
    trunk/Build/source/libs/xpdf/configure
    trunk/Build/source/libs/xpdf/version.ac
    trunk/Build/source/libs/xpdf/xpdf-src/ANNOUNCE
    trunk/Build/source/libs/xpdf/xpdf-src/CHANGES
    trunk/Build/source/libs/xpdf/xpdf-src/INSTALL
    trunk/Build/source/libs/xpdf/xpdf-src/README
    trunk/Build/source/libs/xpdf/xpdf-src/aconf2.h
    trunk/Build/source/libs/xpdf/xpdf-src/cmake-config.txt
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.1
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.1
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.1
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.1
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.1
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.1
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.1
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.1
    trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat
    trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1
    trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat
    trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5
    trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat
    trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc
    trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc
    trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h
    trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc
    trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc
    trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h
    trunk/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h
    trunk/Build/source/libs/xpdf/xpdf-src/goo/GMutex.h
    trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc
    trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.h
    trunk/Build/source/libs/xpdf/xpdf-src/goo/gmem.cc
    trunk/Build/source/libs/xpdf/xpdf-src/goo/gmem.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDocEncoding.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc

Added Paths:
-----------
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/README	2019-09-29 10:00:12 UTC (rev 52203)
@@ -59,7 +59,7 @@
 teckit 2.5.9 - checked 03may19
   https://github.com/silnrsi/teckit/archive/2.5.9.tar.gz
 
-xpdf 4.01.01 - checked 03may19
+xpdf 4.02 - checked 29sep19
   http://www.xpdfreader.com/download.html
   with modifications for pdftex
 

Modified: trunk/Build/source/libs/xpdf/ChangeLog
===================================================================
--- trunk/Build/source/libs/xpdf/ChangeLog	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/ChangeLog	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,3 +1,8 @@
+2019-09-29  Akira Kakuto  <kakuto at w32tex.org>
+
+	* Import xpdf-4.02.
+	* version.ac: Adjust.
+
 2019-05-03  Akira Kakuto  <kakuto at w32tex.org>
 
 	* Import xpdf-4.01.01.

Modified: trunk/Build/source/libs/xpdf/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/xpdf/TLpatches/ChangeLog	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/TLpatches/ChangeLog	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,3 +1,7 @@
+2019-09-29  Akira Kakuto  <kakuto at w32tex.org>
+
+	* patch-bunched: Adjust.
+
 2019-05-03  Akira Kakuto  <kakuto at w32tex.org>
 
 	* patch-bunched: Adjust.

Modified: trunk/Build/source/libs/xpdf/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/xpdf/TLpatches/TL-Changes	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/TLpatches/TL-Changes	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,4 +1,4 @@
-Changes applied to the xpdf-4.01.01/ tree as obtained from:
+Changes applied to the xpdf-4.02/ tree as obtained from:
 	http://www.xpdfreader.com/download.html
 
 Removed:

Modified: trunk/Build/source/libs/xpdf/TLpatches/patch-bunched
===================================================================
--- trunk/Build/source/libs/xpdf/TLpatches/patch-bunched	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/TLpatches/patch-bunched	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,6 +1,6 @@
-diff -ur xpdf-4.01.01/goo/gfile.cc xpdf-src/goo/gfile.cc
---- xpdf-4.01.01/goo/gfile.cc	Fri Mar 15 06:01:02 2019
-+++ xpdf-src/goo/gfile.cc	Mon Feb 25 11:09:32 2019
+diff -ur xpdf-4.02/goo/gfile.cc xpdf-src/goo/gfile.cc
+--- xpdf-4.02/goo/gfile.cc	Thu Sep 26 04:54:33 2019
++++ xpdf-src/goo/gfile.cc	Sun Sep 29 11:23:53 2019
 @@ -7,6 +7,9 @@
  // Copyright 1996-2003 Glyph & Cog, LLC
  //
@@ -11,7 +11,7 @@
  
  #include <aconf.h>
  
-@@ -52,7 +55,11 @@
+@@ -54,7 +57,11 @@
    char *s;
    GString *ret;
  
@@ -23,7 +23,7 @@
      ret = new GString(s);
    else
      ret = new GString(".");
-@@ -401,6 +408,7 @@
+@@ -403,6 +410,7 @@
  #endif
  }
  
@@ -31,7 +31,7 @@
  GBool openTempFile(GString **name, FILE **f,
  		   const char *mode, const char *ext) {
  #if defined(_WIN32)
-@@ -515,10 +523,11 @@
+@@ -517,10 +525,11 @@
    return gTrue;
  #endif
  }
@@ -44,7 +44,7 @@
  #else
    return !mkdir(path, mode);
  #endif
-@@ -572,6 +581,8 @@
+@@ -574,6 +583,8 @@
  
  FILE *openFile(const char *path, const char *mode) {
  #if defined(_WIN32)
@@ -53,7 +53,7 @@
    OSVERSIONINFO version;
    wchar_t wPath[_MAX_PATH + 1];
    char nPath[_MAX_PATH + 1];
-@@ -628,6 +639,7 @@
+@@ -630,6 +641,7 @@
      nPath[i] = '\0';
      return fopen(nPath, mode);
    }
@@ -61,7 +61,7 @@
  #elif defined(VMS)
    return fopen(path, mode, "ctx=stm");
  #else
-@@ -688,6 +700,7 @@
+@@ -690,6 +702,7 @@
  #endif
  }
  
@@ -69,15 +69,15 @@
  void fixCommandLine(int *argc, char **argv[]) {
  #ifdef _WIN32
    int argcw;
-@@ -713,3 +726,4 @@
+@@ -715,3 +728,4 @@
    LocalFree(argvw);
  #endif
  }
 +#endif /* !PDF_PARSER_ONLY */
-diff -ur xpdf-4.01.01/goo/gfile.h xpdf-src/goo/gfile.h
---- xpdf-4.01.01/goo/gfile.h	Fri Mar 15 06:01:02 2019
-+++ xpdf-src/goo/gfile.h	Mon Feb 25 11:07:26 2019
-@@ -114,6 +114,8 @@
+diff -ur xpdf-4.02/goo/gfile.h xpdf-src/goo/gfile.h
+--- xpdf-4.02/goo/gfile.h	Thu Sep 26 04:54:33 2019
++++ xpdf-src/goo/gfile.h	Sun Sep 29 11:25:19 2019
+@@ -115,6 +115,8 @@
  
  // On Windows, this gets the Unicode command line and converts it to
  // UTF-8.  On other systems, this is a nop.
@@ -86,9 +86,9 @@
 +#endif /* !PDF_PARSER_ONLY */
  
  #endif
-diff -ur xpdf-4.01.01/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
---- xpdf-4.01.01/xpdf/GlobalParams.cc	Fri Mar 15 06:01:02 2019
-+++ xpdf-src/xpdf/GlobalParams.cc	Mon Feb 25 08:01:11 2019
+diff -ur xpdf-4.02/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
+--- xpdf-4.02/xpdf/GlobalParams.cc	Thu Sep 26 04:54:33 2019
++++ xpdf-src/xpdf/GlobalParams.cc	Sun Sep 29 11:32:58 2019
 @@ -5,6 +5,9 @@
  // Copyright 2001-2003 Glyph & Cog, LLC
  //
@@ -99,7 +99,7 @@
  
  #include <aconf.h>
  
-@@ -39,8 +42,12 @@
+@@ -44,8 +47,12 @@
  #include "GlobalParams.h"
  
  #ifdef _WIN32
@@ -114,7 +114,7 @@
  #endif
  
  #if MULTITHREADED
-@@ -684,6 +691,7 @@
+@@ -803,6 +810,7 @@
    f = NULL;
    fileName = NULL;
    if (cfgFileName && cfgFileName[0]) {
@@ -122,7 +122,7 @@
      fileName = new GString(cfgFileName);
      if (!(f = fopen(fileName->getCString(), "r"))) {
        delete fileName;
-@@ -716,6 +724,7 @@
+@@ -835,6 +843,7 @@
      parseFile(fileName, f);
      delete fileName;
      fclose(f);
@@ -130,7 +130,7 @@
    }
  }
  
-@@ -2092,8 +2101,11 @@
+@@ -2265,8 +2274,11 @@
  				   base14->fontNum,
  				   displayFontTab[i].obliqueFactor));
        } else {
@@ -142,9 +142,9 @@
        }
      }
    }
-diff -ur xpdf-4.01.01/xpdf/GlobalParams.h xpdf-src/xpdf/GlobalParams.h
---- xpdf-4.01.01/xpdf/GlobalParams.h	Fri Mar 15 06:01:02 2019
-+++ xpdf-src/xpdf/GlobalParams.h	Mon Feb 25 08:02:36 2019
+diff -ur xpdf-4.02/xpdf/GlobalParams.h xpdf-src/xpdf/GlobalParams.h
+--- xpdf-4.02/xpdf/GlobalParams.h	Thu Sep 26 04:54:33 2019
++++ xpdf-src/xpdf/GlobalParams.h	Sun Sep 29 11:34:12 2019
 @@ -5,6 +5,9 @@
  // Copyright 2001-2003 Glyph & Cog, LLC
  //
@@ -155,7 +155,7 @@
  
  #ifndef GLOBALPARAMS_H
  #define GLOBALPARAMS_H
-@@ -218,7 +221,7 @@
+@@ -219,7 +222,7 @@
  
    // Initialize the global parameters by attempting to read a config
    // file.
@@ -164,10 +164,10 @@
  
    ~GlobalParams();
  
-diff -ur xpdf-4.01.01/xpdf/PDFDoc.cc xpdf-src/xpdf/PDFDoc.cc
---- xpdf-4.01.01/xpdf/PDFDoc.cc	Fri Mar 15 06:01:02 2019
-+++ xpdf-src/xpdf/PDFDoc.cc	Sun Mar 17 08:59:43 2019
-@@ -147,20 +147,25 @@
+diff -ur xpdf-4.02/xpdf/PDFDoc.cc xpdf-src/xpdf/PDFDoc.cc
+--- xpdf-4.02/xpdf/PDFDoc.cc	Thu Sep 26 04:54:33 2019
++++ xpdf-src/xpdf/PDFDoc.cc	Sun Sep 29 11:41:09 2019
+@@ -156,20 +156,25 @@
  
  PDFDoc::PDFDoc(char *fileNameA, GString *ownerPassword,
  	       GString *userPassword, PDFCore *coreA) {
@@ -193,20 +193,19 @@
    n = 0;
    i = 0;
    while (getUTF8(fileName, &i, &u)) {
-@@ -178,8 +183,12 @@
+@@ -187,8 +192,11 @@
    if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-     file = _wfopen(fileNameU, L"rb");
+     file = _wfopen(fileNameU, wfopenReadMode);
    } else {
 +#endif /* 0 */
-     file = fopen(fileName->getCString(), "rb");
+     file = fopen(fileName->getCString(), fopenReadMode);
 +#if 0
    }
 +#endif /* 0 */
-+
  #elif defined(VMS)
-   file = fopen(fileName->getCString(), "rb", "ctx=stm");
+   file = fopen(fileName->getCString(), fopenReadMode, "ctx=stm");
  #else
-@@ -572,6 +581,7 @@
+@@ -581,6 +589,7 @@
    GBool ret;
  
    // NB: _wfopen is only available in NT
@@ -214,7 +213,7 @@
    version.dwOSVersionInfoSize = sizeof(version);
    GetVersionEx(&version);
    if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-@@ -581,12 +591,15 @@
+@@ -590,12 +599,15 @@
      path2w[i] = 0;
      f = _wfopen(path2w, L"wb");
    } else {
@@ -230,9 +229,9 @@
    if (!f) {
      return gFalse;
    }
-diff -ur xpdf-4.01.01/xpdf/Page.cc xpdf-src/xpdf/Page.cc
---- xpdf-4.01.01/xpdf/Page.cc	Fri Mar 15 06:01:02 2019
-+++ xpdf-src/xpdf/Page.cc	Mon Feb 25 08:19:00 2019
+diff -ur xpdf-4.02/xpdf/Page.cc xpdf-src/xpdf/Page.cc
+--- xpdf-4.02/xpdf/Page.cc	Thu Sep 26 04:54:33 2019
++++ xpdf-src/xpdf/Page.cc	Sun Sep 29 11:43:12 2019
 @@ -480,9 +480,9 @@
    delete links;
  }
@@ -251,10 +250,10 @@
 -}
  #endif
 +}
-diff -ur xpdf-4.01.01/xpdf/XFAForm.cc xpdf-src/xpdf/XFAForm.cc
---- xpdf-4.01.01/xpdf/XFAForm.cc	Fri Mar 15 06:01:02 2019
-+++ xpdf-src/xpdf/XFAForm.cc	Mon Feb 25 08:20:00 2019
-@@ -28,8 +28,10 @@
+diff -ur xpdf-4.02/xpdf/XFAForm.cc xpdf-src/xpdf/XFAForm.cc
+--- xpdf-4.02/xpdf/XFAForm.cc	Thu Sep 26 04:54:33 2019
++++ xpdf-src/xpdf/XFAForm.cc	Sun Sep 29 11:44:10 2019
+@@ -29,8 +29,10 @@
  #include "XFAForm.h"
  
  #ifdef _WIN32
@@ -267,9 +266,9 @@
  #endif
  
  //------------------------------------------------------------------------
-diff -ur xpdf-4.01.01/xpdf/config.h xpdf-src/xpdf/config.h
---- xpdf-4.01.01/xpdf/config.h	Fri Mar 15 06:01:02 2019
-+++ xpdf-src/xpdf/config.h	Sun Mar 17 16:09:03 2019
+diff -ur xpdf-4.02/xpdf/config.h xpdf-src/xpdf/config.h
+--- xpdf-4.02/xpdf/config.h	Thu Sep 26 04:54:33 2019
++++ xpdf-src/xpdf/config.h	Sun Sep 29 11:45:39 2019
 @@ -78,11 +78,6 @@
  // popen
  //------------------------------------------------------------------------

Modified: trunk/Build/source/libs/xpdf/configure
===================================================================
--- trunk/Build/source/libs/xpdf/configure	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/configure	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for xpdf (TeX Live) 4.01.01.
+# Generated by GNU Autoconf 2.69 for xpdf (TeX Live) 4.02.
 #
 # Report bugs to <tex-k at tug.org>.
 #
@@ -580,8 +580,8 @@
 # Identity of this package.
 PACKAGE_NAME='xpdf (TeX Live)'
 PACKAGE_TARNAME='xpdf--tex-live-'
-PACKAGE_VERSION='4.01.01'
-PACKAGE_STRING='xpdf (TeX Live) 4.01.01'
+PACKAGE_VERSION='4.02'
+PACKAGE_STRING='xpdf (TeX Live) 4.02'
 PACKAGE_BUGREPORT='tex-k at tug.org'
 PACKAGE_URL=''
 
@@ -1290,7 +1290,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/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures xpdf (TeX Live) 4.01.01 to adapt to many kinds of systems.
+\`configure' configures xpdf (TeX Live) 4.02 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1356,7 +1356,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of xpdf (TeX Live) 4.01.01:";;
+     short | recursive ) echo "Configuration of xpdf (TeX Live) 4.02:";;
    esac
   cat <<\_ACEOF
 
@@ -1460,7 +1460,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-xpdf (TeX Live) configure 4.01.01
+xpdf (TeX Live) configure 4.02
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1867,7 +1867,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by xpdf (TeX Live) $as_me 4.01.01, which was
+It was created by xpdf (TeX Live) $as_me 4.02, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3791,7 +3791,7 @@
 
 # Define the identity of the package.
  PACKAGE='xpdf--tex-live-'
- VERSION='4.01.01'
+ VERSION='4.02'
 
 
 # Some tools Automake needs.
@@ -6704,7 +6704,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by xpdf (TeX Live) $as_me 4.01.01, which was
+This file was extended by xpdf (TeX Live) $as_me 4.02, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -6774,7 +6774,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-xpdf (TeX Live) config.status 4.01.01
+xpdf (TeX Live) config.status 4.02
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/xpdf/version.ac
===================================================================
--- trunk/Build/source/libs/xpdf/version.ac	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/version.ac	2019-09-29 10:00:12 UTC (rev 52203)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current xpdf version
-m4_define([xpdf_version], [4.01.01])
+m4_define([xpdf_version], [4.02])

Modified: trunk/Build/source/libs/xpdf/xpdf-src/ANNOUNCE
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/ANNOUNCE	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/ANNOUNCE	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,4 +1,4 @@
-Subject: ANNOUNCE: Xpdf 4.01 - a PDF viewer and related tools
+Subject: ANNOUNCE: Xpdf 4.02 - a PDF viewer and related tools
 
 Glyph & Cog, LLC is pleased to announce a new version of Xpdf, the
 open source Portable Document Format (PDF) viewer.  The Xpdf project
@@ -5,22 +5,24 @@
 also includes a PDF text extractor, PDF-to-PostScript converter, and
 various other utilities.
 
-*** The Xpdf web site has moved to www.xpdfreader.com ***
-
 Xpdf uses the Qt toolkit and runs on Linux and Windows.  The
 non-graphical components (pdftops, pdftotext, etc.) run on Linux,
 Unix, Windows, MacOSX, and pretty much any other system with a decent
 C++ compiler.
 
-4.01 is primarily a bug fix release.  There are some new features:
-* Added remote server mode back into xpdf.
-* Added support for Unicode file names for the command line tools on
-  Windows.
-* Added the tabStateFile setting, the saveTabState/loadTabState
-  commands, and the "-tabstate" switch to xpdf.  [Thanks to Christian
-  Barthel for the suggestion.]
-* Added the defaultPrinter xpdfrc setting.
+4.02 is primarily a bug fix release.  There are some new features:
 
+* Pdftohtml now extracts embedded fonts.
+
+* Various user interface tweaks in XpdfReader: added a button to
+  toggle sidebar visibilty, added menu items to toggle the sidebar and
+  toolbar, added the 'initialDisplayMode', 'initialToolbarState', and
+  'initialSelectMode' xpdfrc settings.
+
+* If XpdfReader is already running, double-clicking on a PDF file (or
+  dragging-and-dropping it on the XpdfReader icon) opens the file in a
+  new tab (via the new '-open' command line switch).
+
 See the `CHANGES' file for a complete list of changes.
 
 Source (C++ and C) is available, and it should be fairly easy to

Modified: trunk/Build/source/libs/xpdf/xpdf-src/CHANGES
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/CHANGES	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/CHANGES	2019-09-29 10:00:12 UTC (rev 52203)
@@ -2550,3 +2550,99 @@
 Pdffonts now checks more carefully for loops between objects.
 Fixed a problem parsing large real numbers.  [Thanks to Loginsoft for
   the bug report.]
+
+4.02 (2019-sep-25)
+------------------
+Pdftohtml now extracts embedded fonts (TrueType and CFF only).
+Added the margin settings (-marginl -marginr -margint -marginb) to
+  pdftotext.
+Various user interface tweaks:
+  - added a toolbar button to toggle (show/hide) the sidebar
+  - added view menu items to toggle (show/hide) the sidebar and
+    toolbar
+  - added the 'showToolbar', 'hideToolbar', 'toggleToolbar',
+    'expandSidebar', and 'shrinkSidebar' commands
+  - added the 'initialDisplayMode', 'initialToolbarState', and
+    'initialSelectMode' xpdfrc settings
+  - rearranged the xpdf toolbar
+Implemented drag-and-drop, so that PDF files can be drag-and-dropped
+  onto an already-open xpdf window.
+Added the option to display page labels, rather than page numbers.
+Implemented the missing 'openInNewWin' command.
+Added the 'openFileIn', 'openFileAtDestIn', 'openFileAtPageIn', and
+  'openIn' commands; removed the 'openInNewWin' command.
+Added the '-open' switch to xpdf.
+Added the reverseVideoInvertImages setting.
+Page-up and page-down now "snap" to the nearest page, if it's within a
+  few pixels.  This avoids annoying behavior when the window is a tiny
+  bit too short or too tall for a page.
+Properly handle overprint in non-isolated transparency groups.
+Missing null check in Gfx::opSetExtGState().  [Thanks to
+  pwd at 360TeamSeri0us for the bug report.]
+The DCT decoder doesn't handle a sampling factor of 3 -- check for
+  this and report an error.  [Thanks for Agostino Sarubbo of Gentoo
+  for the bug report.]
+Check for images with a Pattern color space, and report an error.
+  [Thanks to TeamSeri0us for the bug report.]
+Check that the Width, Height, and BitsPerComponent are valid in image
+  soft masks.  [Thanks to TeamSeri0us for the bug report.]
+Check for zero page width/height in PSOutputDev.  [Thanks to
+  TeamSeri0us for the bug report.]
+Check for divide-by-zero in PostScript functions.  [Thanks to
+  TeamSeri0us for the bug report.]
+Properly handle overprint in shading pattern strokes.
+The "save image" feature in Xpdf wasn't getting the user-specified
+  page number correctly.
+PostScript doesn't support progressive or non-interleaved DCT (JPEG)
+  streams, so check for those and re-encode them in PS output.
+Splash now caches the most recent scaled image, in case it is
+  immediately reused -- this results in a significant speedup in
+  certain cases.
+Fixed a problem with parsing the TrueType loca table.  [Thanks to
+  Pangu Lab for the bug report.]
+Fixed a problem with int overflow on image bounds.  [Thanks to
+  Pangu Lab for the bug report.]
+Fixed a problem with TrueType font parsing where there is gibberish in
+  the TrueType table directory.  [Thanks to Pangu Lab for the bug
+  report.]
+Fixed a problem with JPX image resolution reduction.  [Thanks to Pangu
+  Lab for the bug report.]
+Fixed a problem with non-isolated transparency groups in 1-bit
+  monochrome mode.  [Thanks to Pangu Lab for the bug report.]
+Fixed various bugs in FoFi.  [Thanks to Pangu Lab for the bug
+  reports.]
+Added a missing bounds check to Annot::setFillColor().  [Thanks to
+  Pangu Lab for the bug report.]
+Added a check on the DCT quant table selector.  [Thanks to Pangu Lab
+  for the bug report.]
+Fixed a problem with the Type 3 font cache running out of entries.
+  [Thanks to Pangu Lab for the bug report.]
+Fixed an integer overflow bug in SampledFunction.  [Thanks to Pangu
+  Lab for the bug report.]
+Fixed an integer overflow bug in the tiling pattern size.  [Thanks to
+  Martin Muskens at Ergosoft for the bug report.]
+Fixed a read-past-end-of-buffer in the Type 1 font parser.  [Thanks to
+  Pangu Lab for the bug report.]
+Fixed an int overflow bug in the JBIG2 decoder.  [Thanks to
+  TeamSeri0us for the bug report.]
+Added a missing bounds check to GfxPatchMeshShading::parse().  [Thanks
+  to TeamSeri0us for the bug report.]
+JPEG 2000 tile indexes were being computed incorrectly.  [Thanks to
+  TeamSeri0us for the bug report.]
+Large sample separation values in a JPX stream were resulting in
+  zero-width/height tiles, which caused problems.  [Thanks to Pangu
+  Lab for the bug report.]
+The XFA parser now looks for "ancestor matches" when searching for
+  data to fill a form field.
+Fixed an uninitialized variable in BuiltinFontWidths::getWidth().
+  [Thanks to Martin Muskens at Ergosoft for the bug report.]
+If there are no popupMenuCmd instances, construct a popup menu with
+  basic instructions pointing to 'popupMenuCmd'.
+Ignore color operators in uncolored tiling patterns.  [Thanks to
+  Martin Muskens at Ergosoft for the bug report.]
+Pdftotext raw mode output looks for space characters.
+Increased the width of the font name column in the pdffonts output.
+Function objects weren't checking their input/output counts properly.
+  [Thanks to Pangu Lab for the bug report.]
+TextPage::findGaps() wasn't checking the x/y min/max values for int
+  overflow.  [Thanks to Taolaw for the bugf report.]

Modified: trunk/Build/source/libs/xpdf/xpdf-src/INSTALL
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/INSTALL	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/INSTALL	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,8 +1,8 @@
 Xpdf
 ====
 
-version 4.01.01
-2019-mar-14
+version 4.02
+2019-sep-25
 
 The Xpdf software and documentation are
 copyright 1996-2019 Glyph & Cog, LLC.
@@ -97,6 +97,11 @@
         Enables support for generation of OPI (Open Prepress
         Interface) comments with pdftops.
 
+    -DNO_FONTCONFIG=ON
+        Disables use of libfontconfig, which is used to locate system
+        fonts on Linux/Unix systems.  The default is to search for the
+        library, and to use it if found.
+
     -DMULTITHREADED=0
         Disables multithreading, which also disables building the GUI
         viewer (xpdf).  This does not affect the command line tools.
@@ -104,6 +109,9 @@
         building with a compiler other than gcc, clang, or Microsoft
         Visual Studio.
 
+    -DXPDFWIDGET_PRINTING=OFF
+        Disable printing support.
+
     -DSYSTEM_XPDFRC="/etc/xpdfrc"
         Look for a system-wide xpdfrc config file in this directory.
 
@@ -110,7 +118,9 @@
      -DCMAKE_DISABLE_FIND_PACKAGE_Qt4=1
      -DCMAKE_DISABLE_FIND_PACKAGE_Qt5Widgets=1
         Do not search for the Qt4/Qt5 libraries.  This will disable
-        building the GUI viewer (xpdf).
+        building the GUI viewer (xpdf).  Cmake will look for a "qmake"
+        binary -- make sure the first qmake binary on your executable
+        search path matches the desired version of Qt.
 
      -DCMAKE_C_FLAGS="..."
      -DCMAKE_CXX_FLAGS="..."

Modified: trunk/Build/source/libs/xpdf/xpdf-src/README
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/README	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/README	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,8 +1,8 @@
 Xpdf
 ====
 
-version 4.01.01
-2019-mar-14
+version 4.02
+2019-sep-25
 
 The Xpdf software and documentation are
 copyright 1996-2019 Glyph & Cog, LLC.

Modified: trunk/Build/source/libs/xpdf/xpdf-src/aconf2.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/aconf2.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/aconf2.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -28,4 +28,14 @@
 #  endif
 #endif
 
+/*
+ * Speed up Windows compilation.  This will only work for the command
+ * line tools.
+ */
+/*
+ *#ifdef _WIN32
+ *#  define WIN32_LEAN_AND_MEAN
+ *#endif
+ */
+
 #endif

Modified: trunk/Build/source/libs/xpdf/xpdf-src/cmake-config.txt
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/cmake-config.txt	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/cmake-config.txt	2019-09-29 10:00:12 UTC (rev 52203)
@@ -81,6 +81,7 @@
 option(USE_EXCEPTIONS "use C++ exceptions" ON)
 option(USE_FIXEDPOINT "use fixed point (instead of floating point) arithmetic" OFF)
 option(SPLASH_CMYK "include support for CMYK rasterization" OFF)
+option(NO_FONTCONFIG "disable support for libfontconfig" OFF)
 option(SYSTEM_XPDFRC "full path for system-wide xpdfrc file" "")
 if (SYSTEM_XPDFRC)
   set(SYSTEM_XPDFRC_DEFINE "#define SYSTEM_XPDFRC \"${SYSTEM_XPDFRC}\"")
@@ -193,7 +194,7 @@
   find_package(Qt5Network)
   find_package(Qt5PrintSupport)
 else ()
-  find_package(Qt4)
+  find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED)
 endif ()
 if(Qt5Widgets_FOUND)
   message(STATUS "Qt5 found")
@@ -200,13 +201,7 @@
   if (XPDFWIDGET_PRINTING)
     set(QT_INCLUDES "${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5PrintSupport_INCLUDE_DIRS}")
     set(QT_DEFINITIONS "${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS} ${Qt5PrintSupport_DEFINITIONS}")
-    if (APPLE)
-      set(QT_LIBRARIES Qt5::Widgets Qt5::Network Qt5::PrintSupport "-framework ApplicationServices")
-    elseif (UNIX)
-      set(QT_LIBRARIES Qt5::Widgets Qt5::Network Qt5::PrintSupport cups)
-    else ()
-      set(QT_LIBRARIES Qt5::Widgets Qt5::Network Qt5::PrintSupport)
-    endif ()
+    set(QT_LIBRARIES Qt5::Widgets Qt5::Network Qt5::PrintSupport)
   else ()
     set(QT_INCLUDES "${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS}")
     set(QT_DEFINITIONS "${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS}")
@@ -216,7 +211,12 @@
     if (APPLE)
       set(EXTRA_QT_LIBRARIES "-framework ApplicationServices")
     elseif (UNIX)
-      set(EXTRA_QT_LIBRARIES cups)
+      find_package(Cups)
+      if (CUPS_FOUND)
+        set(EXTRA_QT_LIBRARIES ${CUPS_LIBRARIES})
+      else ()
+        set (XPDFWIDGET_PRINTING OFF)
+      endif ()
     else ()
       set(EXTRA_QT_LIBRARIES "")
     endif ()
@@ -229,7 +229,12 @@
     if (APPLE)
       set(EXTRA_QT_LIBRARIES "-framework ApplicationServices")
     elseif (UNIX)
-      set(EXTRA_QT_LIBRARIES cups)
+      find_package(Cups)
+      if (CUPS_FOUND)
+        set(EXTRA_QT_LIBRARIES ${CUPS_LIBRARIES})
+      else ()
+        set (XPDFWIDGET_PRINTING OFF)
+      endif ()
     else ()
       set(EXTRA_QT_LIBRARIES "")
     endif ()
@@ -250,8 +255,30 @@
   set(PAPER_LIBRARY "")
 endif ()
 
+#--- look for fontconfig
+if (NOT NO_FONTCONFIG)
+  find_library(FONTCONFIG_LIBRARY
+               NAMES fontconfig libfontconfig
+               PATH_SUFFIXES lib64 lib
+  )
+  if (FONTCONFIG_LIBRARY)
+    set(HAVE_FONTCONFIG TRUE)
+    message(STATUS "Found fontconfig")
+  else ()
+    set(HAVE_FONTCONFIG FALSE)
+    set(FONTCONFIG_LIBRARY "")
+  endif ()
+else ()
+  set(HAVE_FONTCONFIG FALSE)
+  set(FONTCONFIG_LIBRARY "")
+endif ()
+
 #--- look for pthreads
-find_package(Threads)
+if (MULTITHREADED)
+  find_package(Threads)
+else ()
+  set(CMAKE_THREAD_LIBS_INIT "")
+endif ()
 
 #--- create aconf.h
 configure_file("aconf.h.in" "aconf.h")

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,8 +1,8 @@
 .\" Copyright 2013-2019 Glyph & Cog, LLC
-.TH pdfdetach 1 "18 Feb 2019"
+.TH pdfdetach 1 "25 Sep 2019"
 .SH NAME
 pdfdetach \- Portable Document Format (PDF) document embedded file
-extractor (version 4.01)
+extractor (version 4.02)
 .SH SYNOPSIS
 .B pdfdetach
 [options]

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat	2019-09-29 10:00:12 UTC (rev 52203)
@@ -4,7 +4,7 @@
 
 NAME
        pdfdetach  -  Portable  Document  Format  (PDF)  document embedded file
-       extractor (version 4.01)
+       extractor (version 4.02)
 
 SYNOPSIS
        pdfdetach [options] [PDF-file]
@@ -89,4 +89,4 @@
 
 
 
-                                  18 Feb 2019                     pdfdetach(1)
+                                  25 Sep 2019                     pdfdetach(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.1	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.1	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,8 +1,8 @@
 .\" Copyright 1999-2019 Glyph & Cog, LLC
-.TH pdffonts 1 "18 Feb 2019"
+.TH pdffonts 1 "25 Sep 2019"
 .SH NAME
 pdffonts \- Portable Document Format (PDF) font analyzer (version
-4.01)
+4.02)
 .SH SYNOPSIS
 .B pdffonts
 [options]

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat	2019-09-29 10:00:12 UTC (rev 52203)
@@ -3,7 +3,7 @@
 
 
 NAME
-       pdffonts - Portable Document Format (PDF) font analyzer (version 4.01)
+       pdffonts - Portable Document Format (PDF) font analyzer (version 4.02)
 
 SYNOPSIS
        pdffonts [options] [PDF-file]
@@ -115,4 +115,4 @@
 
 
 
-                                  18 Feb 2019                      pdffonts(1)
+                                  25 Sep 2019                      pdffonts(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.1	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.1	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,8 +1,8 @@
 .\" Copyright 1998-2019 Glyph & Cog, LLC
-.TH pdfimages 1 "18 Feb 2019"
+.TH pdfimages 1 "25 Sep 2019"
 .SH NAME
 pdfimages \- Portable Document Format (PDF) image extractor
-(version 4.01)
+(version 4.02)
 .SH SYNOPSIS
 .B pdfimages
 [options]

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat	2019-09-29 10:00:12 UTC (rev 52203)
@@ -4,7 +4,7 @@
 
 NAME
        pdfimages  -  Portable  Document  Format (PDF) image extractor (version
-       4.01)
+       4.02)
 
 SYNOPSIS
        pdfimages [options] PDF-file image-root
@@ -95,4 +95,4 @@
 
 
 
-                                  18 Feb 2019                     pdfimages(1)
+                                  25 Sep 2019                     pdfimages(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.1	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.1	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,8 +1,8 @@
 .\" Copyright 1999-2019 Glyph & Cog, LLC
-.TH pdfinfo 1 "18 Feb 2019"
+.TH pdfinfo 1 "25 Sep 2019"
 .SH NAME
 pdfinfo \- Portable Document Format (PDF) document information
-extractor (version 4.01)
+extractor (version 4.02)
 .SH SYNOPSIS
 .B pdfinfo
 [options]

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat	2019-09-29 10:00:12 UTC (rev 52203)
@@ -4,7 +4,7 @@
 
 NAME
        pdfinfo - Portable Document Format (PDF) document information extractor
-       (version 4.01)
+       (version 4.02)
 
 SYNOPSIS
        pdfinfo [options] [PDF-file]
@@ -114,4 +114,4 @@
 
 
 
-                                  18 Feb 2019                       pdfinfo(1)
+                                  25 Sep 2019                       pdfinfo(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.1	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.1	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,8 +1,8 @@
 .\" Copyright 1997-2019 Glyph & Cog, LLC
-.TH pdftohtml 1 "18 Feb 2019"
+.TH pdftohtml 1 "25 Sep 2019"
 .SH NAME
 pdftohtml \- Portable Document Format (PDF) to HTML converter
-(version 4.01)
+(version 4.02)
 .SH SYNOPSIS
 .B pdftohtml
 [options]

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat	2019-09-29 10:00:12 UTC (rev 52203)
@@ -4,7 +4,7 @@
 
 NAME
        pdftohtml  -  Portable Document Format (PDF) to HTML converter (version
-       4.01)
+       4.02)
 
 SYNOPSIS
        pdftohtml [options] PDF-file HTML-dir
@@ -107,4 +107,4 @@
 
 
 
-                                  18 Feb 2019                     pdftohtml(1)
+                                  25 Sep 2019                     pdftohtml(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.1	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.1	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,8 +1,8 @@
 .\" Copyright 2017-2019 Glyph & Cog, LLC
-.TH pdftopng 1 "18 Feb 2019"
+.TH pdftopng 1 "25 Sep 2019"
 .SH NAME
 pdftopng \- Portable Document Format (PDF) to Portable Network Graphics
-(PNG) converter (version 4.01)
+(PNG) converter (version 4.02)
 .SH SYNOPSIS
 .B pdftopng
 [options]

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat	2019-09-29 10:00:12 UTC (rev 52203)
@@ -4,7 +4,7 @@
 
 NAME
        pdftopng  - Portable Document Format (PDF) to Portable Network Graphics
-       (PNG) converter (version 4.01)
+       (PNG) converter (version 4.02)
 
 SYNOPSIS
        pdftopng [options] PDF-file PNG-root
@@ -97,4 +97,4 @@
 
 
 
-                                  18 Feb 2019                      pdftopng(1)
+                                  25 Sep 2019                      pdftopng(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.1	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.1	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,8 +1,8 @@
 .\" Copyright 2005-2019 Glyph & Cog, LLC
-.TH pdftoppm 1 "18 Feb 2019"
+.TH pdftoppm 1 "25 Sep 2019"
 .SH NAME
 pdftoppm \- Portable Document Format (PDF) to Portable Pixmap (PPM)
-converter (version 4.01)
+converter (version 4.02)
 .SH SYNOPSIS
 .B pdftoppm
 [options]

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat	2019-09-29 10:00:12 UTC (rev 52203)
@@ -4,7 +4,7 @@
 
 NAME
        pdftoppm - Portable Document Format (PDF) to Portable Pixmap (PPM) con-
-       verter (version 4.01)
+       verter (version 4.02)
 
 SYNOPSIS
        pdftoppm [options] PDF-file PPM-root
@@ -96,4 +96,4 @@
 
 
 
-                                  18 Feb 2019                      pdftoppm(1)
+                                  25 Sep 2019                      pdftoppm(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.1	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.1	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,8 +1,8 @@
 .\" Copyright 1996-2019 Glyph & Cog, LLC
-.TH pdftops 1 "18 Feb 2019"
+.TH pdftops 1 "25 Sep 2019"
 .SH NAME
 pdftops \- Portable Document Format (PDF) to PostScript converter
-(version 4.01)
+(version 4.02)
 .SH SYNOPSIS
 .B pdftops
 [options]

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat	2019-09-29 10:00:12 UTC (rev 52203)
@@ -4,7 +4,7 @@
 
 NAME
        pdftops  - Portable Document Format (PDF) to PostScript converter (ver-
-       sion 4.01)
+       sion 4.02)
 
 SYNOPSIS
        pdftops [options] [PDF-file [PS-file]]
@@ -211,4 +211,4 @@
 
 
 
-                                  18 Feb 2019                       pdftops(1)
+                                  25 Sep 2019                       pdftops(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.1	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.1	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,8 +1,8 @@
 .\" Copyright 1997-2019 Glyph & Cog, LLC
-.TH pdftotext 1 "18 Feb 2019"
+.TH pdftotext 1 "25 Sep 2019"
 .SH NAME
 pdftotext \- Portable Document Format (PDF) to text converter
-(version 4.01)
+(version 4.02)
 .SH SYNOPSIS
 .B pdftotext
 [options]
@@ -125,6 +125,26 @@
 Insert a Unicode byte order marker (BOM) at the start of the text
 output.
 .TP
+.BI \-marginl " number"
+Specifies the left margin, in points.  Text in the left margin (i.e.,
+within that many points of the left edge of the page) is discarded.
+The default value is zero.
+.TP
+.BI \-marginr " number"
+Specifies the right margin, in points.  Text in the right margin
+(i.e., within that many points of the right edge of the page) is
+discarded.  The default value is zero.
+.TP
+.BI \-margint " number"
+Specifies the top margin, in points.  Text in the top margin (i.e.,
+within that many points of the top edge of the page) is discarded.
+The default value is zero.
+.TP
+.BI \-marginb " number"
+Specifies the bottom margin, in points.  Text in the bottom margin
+(i.e., within that many points of the bottom edge of the page) is
+discarded.  The default value is zero.
+.TP
 .BI \-opw " password"
 Specify the owner password for the PDF file.  Providing this will
 bypass all security restrictions.

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat	2019-09-29 10:00:12 UTC (rev 52203)
@@ -4,7 +4,7 @@
 
 NAME
        pdftotext  -  Portable Document Format (PDF) to text converter (version
-       4.01)
+       4.02)
 
 SYNOPSIS
        pdftotext [options] [PDF-file [text-file]]
@@ -102,6 +102,26 @@
        -bom   Insert a Unicode byte order marker (BOM) at  the  start  of  the
               text output.
 
+       -marginl number
+              Specifies  the  left margin, in points.  Text in the left margin
+              (i.e., within that many points of the left edge of the page)  is
+              discarded.  The default value is zero.
+
+       -marginr number
+              Specifies the right margin, in points.  Text in the right margin
+              (i.e., within that many points of the right edge of the page) is
+              discarded.  The default value is zero.
+
+       -margint number
+              Specifies  the  top  margin,  in points.  Text in the top margin
+              (i.e., within that many points of the top edge of the  page)  is
+              discarded.  The default value is zero.
+
+       -marginb number
+              Specifies the bottom margin, in points.  Text in the bottom mar-
+              gin (i.e., within that many points of the  bottom  edge  of  the
+              page) is discarded.  The default value is zero.
+
        -opw password
               Specify  the  owner  password  for the PDF file.  Providing this
               will bypass all security restrictions.
@@ -148,4 +168,4 @@
 
 
 
-                                  18 Feb 2019                     pdftotext(1)
+                                  25 Sep 2019                     pdftotext(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,7 +1,7 @@
 .\" Copyright 1996-2019 Glyph & Cog, LLC
-.TH xpdf 1 "18 Feb 2019"
+.TH xpdf 1 "25 Sep 2019"
 .SH NAME
-xpdf \- Portable Document Format (PDF) file viewer (version 4.01)
+xpdf \- Portable Document Format (PDF) file viewer (version 4.02)
 .SH SYNOPSIS
 .B xpdf
 [options]
@@ -12,6 +12,11 @@
 [options]
 .B -remote
 .IR remote-name " [" command " ...]"
+.PP
+.B xpdf
+[options]
+.B -open
+.RI "[" PDF-file "]"
 .SH DESCRIPTION
 .B Xpdf
 is a viewer for Portable Document Format (PDF) files.  (These are also
@@ -74,6 +79,14 @@
 .BI \-title " title"
 Set the window title.  By default, the title will be "xpdf: foo.pdf".
 .TP
+.BI \-open " \fR[\fPPDF-file\fR]\fP"
+This option sets up a default remote server.  If Xpdf is already
+running (with the "-open" switch), the PDF file (if any) is opened in
+a new tab.  If Xpdf (with the "-open" switch) is not already running,
+starts Xpdf and opens the PDF file (if any).  This is useful for GUI
+desktop environments, e.g., the typical double-click on a PDF file
+case.
+.TP
 .B \-rv
 Set reverse video mode.  This reverses the colors of everything except
 images.  It may not always produce great results for PDF files which
@@ -155,11 +168,25 @@
 are equivalent.)
 .PP
 .SH CONTROLS
-.SS Tool bar
+.SS Toolbar
 .TP
-.B "\'page' entry box"
+.B "toggle sidebar button"
+Toggles (i.e., shows or hides) the sidebar.
+.TP
+.B "status indicator"
+This icon is animated while Xpdf is rendering a page.  It turns red
+when an error or warning has been issued.  Clicking on it opens the
+error dialog.
+.TP
+.B "selection mode"
+This icon is an "I-beam" in linear selection mode, and an arrow in
+block selection mode.  Clicking on it toggles between the two
+selection modes.
+.TP
+.B "page number entry box"
 Move to a specific page number.  Click in the box to activate it, type
-the page number, then hit return.
+the page number, then hit return.  This will instead display and
+accept page labels, if the "view - page labels" menu item is checked.
 .TP
 .B "left/right arrow buttons"
 Go backward or forward along the history path.
@@ -176,12 +203,7 @@
 .B "fit page button"
 Change the zoom factor to fit the page to the window size.
 .TP
-.B "working/error indicator"
-This icon is animated while Xpdf is rendering a page.  It turns red
-when an error or warning has been issued.  Clicking on it opens the
-error dialog.
-.TP
-.B "\'find' box"
+.B "find entry box"
 Find a text string.  Click in the box to activate it, type a search
 string, then hit return.
 .TP
@@ -196,11 +218,11 @@
 words (on/off).
 .PP
 .SS Menu bar
-The menu bar is above the tool bar.  The menu items should be
+The menu bar is above the toolbar.  The menu items should be
 self-explanatory.
 .PP
 .SS Tab list
-The tab list is on the left, just below the tool bar.  It lists all
+The tab list is on the left, just below the toolbar.  It lists all
 open tabs.
 .PP
 .SS Outline/layers/attachments pane
@@ -291,6 +313,9 @@
 Close the current tab.  Closes the window if this was the last open
 tab.  Quits the application if this was the last open window.
 .TP
+.B control-l
+Toggle between full-screen and window modes.
+.TP
 .B control-q
 Quit.
 .TP
@@ -433,6 +458,11 @@
 .B endSelection
 End a selection.
 .TP
+.BI expandSidebar( n )
+Expand the sidebar by
+.I n
+pixels.  Opens the sidebar if it is currently closed.
+.TP
 .B find
 Set keyboard focus to the \'find' box.
 .TP
@@ -497,6 +527,9 @@
 .BI help
 Open the help URL.
 .TP
+.B hideToolbar
+Hide the toolbar.
+.TP
 .B horizontalContinuousMode
 Switch to horizontal continuous view mode.
 .TP
@@ -526,7 +559,7 @@
 Switch to the next tab.
 .TP
 .B open
-Open a PDF file in this tab, using the open dialog.
+Open a PDF file in the current tab, using the open dialog.
 .TP
 .B openErrorWindow
 Open the error window.
@@ -538,9 +571,25 @@
 Open the specified file in the current tab at the specified named
 destination.
 .TP
+.BI openFileAtDestIn( file, dest, location )
+Open the specified file at the specified named destination.  Location
+must be "win" for a new window or "tab" for a new tab.
+.TP
 .BI openFileAtPage( file, page )
 Open the specified file in the current tab at the specified page.
 .TP
+.BI openFileAtPageIn( file, page, location )
+Open the specified file at the specified page.  Location must be "win"
+for a new window or "tab" for a new tab.
+.TP
+.BI openFileIn( file, location )
+Open the specified file.  Location must be "win" for a new window or
+"tab" for a new tab.
+.TP
+.BI openIn( location )
+Open a PDF file, using the open dialog.  Location must be "win" for a
+new window or "tab" for a new tab.
+.TP
 .B openSidebar
 Open the sidebar.
 .TP
@@ -705,6 +754,15 @@
 .BI setSelection( pg , ulx , uly , lrx , lry )
 Set the selection to the specified coordinates on the specified page.
 .TP
+.B showToolbar
+Show the toolbar.
+.TP
+.BI shrinkSidebar( n )
+Shrink the sidebar by
+.I n
+pixels.  Closes the sidebar if shrinking it would go below the minimum
+allowed side.
+.TP
 .B sideBySideContinuousMode
 Switch to side-by-side continuous view mode.
 .TP
@@ -743,6 +801,15 @@
 Toggle the sidebar between open and closed, resizing the window so
 that the document size doesn't change.
 .TP
+.B toggleToolbar
+Toggle the toolbar between shown and hidden.
+.TP
+.B viewPageLabels
+Show page labels (if the PDF file has them), rather than page numbers.
+.TP
+.B viewPageNumbers
+Show page numbers, rather than page labels.
+.TP
 .B windowMode
 Go to window (non-full-screen) mode.
 .TP

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat	2019-09-29 10:00:12 UTC (rev 52203)
@@ -3,7 +3,7 @@
 
 
 NAME
-       xpdf - Portable Document Format (PDF) file viewer (version 4.01)
+       xpdf - Portable Document Format (PDF) file viewer (version 4.02)
 
 SYNOPSIS
        xpdf [options] [PDF-file [:page | +dest]] ...
@@ -10,6 +10,8 @@
 
        xpdf [options] -remote remote-name [command ...]
 
+       xpdf [options] -open [PDF-file]
+
 DESCRIPTION
        Xpdf  is a viewer for Portable Document Format (PDF) files.  (These are
        also sometimes also called 'Acrobat' files, from the  name  of  Adobe's
@@ -61,15 +63,23 @@
               Set the window title.  By default,  the  title  will  be  "xpdf:
               foo.pdf".
 
-       -rv    Set  reverse video mode.  This reverses the colors of everything
-              except images.  It may not always produce great results for  PDF
-              files  which  do  weird things with color.  This also causes the
+       -open [PDF-file]
+              This option sets up a default remote server.  If Xpdf is already
+              running (with the "-open" switch), the  PDF  file  (if  any)  is
+              opened  in  a new tab.  If Xpdf (with the "-open" switch) is not
+              already running, starts Xpdf and opens the PDF  file  (if  any).
+              This  is  useful for GUI desktop environments, e.g., the typical
+              double-click on a PDF file case.
+
+       -rv    Set reverse video mode.  This reverses the colors of  everything
+              except  images.  It may not always produce great results for PDF
+              files which do weird things with color.  This  also  causes  the
               paper color to default to black.
 
        -papercolor color
               Set the "paper color", i.e., the background of the page display.
-              The  color  can be #RRGGBB (hexadecimal) or a named color.  This
-              option will not work well with PDF files  that  do  things  like
+              The color can be #RRGGBB (hexadecimal) or a named  color.   This
+              option  will  not  work  well with PDF files that do things like
               filling in white behind the text.  [config file: paperColor]
 
        -mattecolor color
@@ -78,18 +88,18 @@
               a named color.  [config file: matteColor]
 
        -fsmattecolor color
-              Set  the  matte  color  for  full-screen mode.  The color can be
-              #RRGGBB  (hexadecimal)  or  a  named   color.    [config   file:
+              Set the matte color for full-screen  mode.   The  color  can  be
+              #RRGGBB   (hexadecimal)   or   a  named  color.   [config  file:
               fullScreenMatteColor]
 
        -z zoom
               Set the initial zoom factor.  A number specifies a zoom percent-
-              age, where 100 means 72 dpi.  You may also  specify  'page',  to
-              fit  the  page  to  the window size, or 'width', to fit the page
+              age,  where  100  means 72 dpi.  You may also specify 'page', to
+              fit the page to the window size, or 'width',  to  fit  the  page
               width to the window width.  [config file: initialZoom]
 
        -aa yes | no
-              Enable or disable font anti-aliasing.  This defaults  to  "yes".
+              Enable  or  disable font anti-aliasing.  This defaults to "yes".
               [config file: antialias]
 
        -aaVector yes | no
@@ -97,14 +107,14 @@
               [config file: vectorAntialias]
 
        -enc encoding-name
-              Sets the encoding to use for  text  output.   The  encoding-name
-              must  be  defined  with  the unicodeMap command (see xpdfrc(5)).
+              Sets  the  encoding  to  use for text output.  The encoding-name
+              must be defined with the  unicodeMap  command  (see  xpdfrc(5)).
               This defaults to "Latin1" (which is a built-in encoding).  [con-
               fig file: textEncoding]
 
        -pw password
-              Specify  the  password for the PDF file.  This can be either the
-              owner password (which will bypass all security restrictions)  or
+              Specify the password for the PDF file.  This can be  either  the
+              owner  password (which will bypass all security restrictions) or
               the user password.
 
        -fullscreen
@@ -111,13 +121,13 @@
               Open xpdf in full-screen mode, useful for presentations.
 
        -remote remote-name
-              Start  Xpdf  in  remote server mode.  See the REMOVE SERVER MODE
+              Start Xpdf in remote server mode.  See the  REMOVE  SERVER  MODE
               section.
 
        -display display
               Set the X display (only available with X11).
 
-       -cmd   Print commands  as  they're  executed  (useful  for  debugging).
+       -cmd   Print  commands  as  they're  executed  (useful  for debugging).
               [config file: printCommands]
 
        -cfg config-file
@@ -129,11 +139,26 @@
        -h     Print usage information.  (-help and --help are equivalent.)
 
 CONTROLS
-   Tool bar
-       'page' entry box
-              Move to a specific page number.  Click in the  box  to  activate
-              it, type the page number, then hit return.
+   Toolbar
+       toggle sidebar button
+              Toggles (i.e., shows or hides) the sidebar.
 
+       status indicator
+              This  icon is animated while Xpdf is rendering a page.  It turns
+              red when an error or warning has been issued.   Clicking  on  it
+              opens the error dialog.
+
+       selection mode
+              This  icon is an "I-beam" in linear selection mode, and an arrow
+              in block selection mode.  Clicking on it toggles between the two
+              selection modes.
+
+       page number entry box
+              Move  to  a  specific page number.  Click in the box to activate
+              it, type the page number, then hit return.   This  will  instead
+              display and accept page labels, if the "view - page labels" menu
+              item is checked.
+
        left/right arrow buttons
               Go backward or forward along the history path.
 
@@ -141,23 +166,18 @@
               Zoom out or in (i.e., change magnification) incrementally.
 
        zoom popup menu
-              Change  the  zoom  factor  (see the description of the -z option
+              Change the zoom factor (see the description  of  the  -z  option
               above).
 
        fit width button
-              Change the zoom factor to fit  the  page  width  to  the  window
+              Change  the  zoom  factor  to  fit  the page width to the window
               width.
 
        fit page button
               Change the zoom factor to fit the page to the window size.
 
-       working/error indicator
-              This  icon is animated while Xpdf is rendering a page.  It turns
-              red when an error or warning has been issued.   Clicking  on  it
-              opens the error dialog.
-
-       'find' box
-              Find  a  text  string.   Click in the box to activate it, type a
+       find entry box
+              Find a text string.  Click in the box to  activate  it,  type  a
               search string, then hit return.
 
        find next button
@@ -171,41 +191,41 @@
               whole words (on/off).
 
    Menu bar
-       The  menu  bar  is  above the tool bar.  The menu items should be self-
+       The menu bar is above the toolbar.  The  menu  items  should  be  self-
        explanatory.
 
    Tab list
-       The tab list is on the left, just below the tool  bar.   It  lists  all
-       open tabs.
+       The tab list is on the left, just below the toolbar.  It lists all open
+       tabs.
 
    Outline/layers/attachments pane
-       This  pane is on the left, below the tab list.  The popup allows you to
+       This pane is on the left, below the tab list.  The popup allows you  to
        select from outline, layers, or attachments.
 
-       The outline is a tree-like structure of bookmarks  that  allows  moving
+       The  outline  is  a tree-like structure of bookmarks that allows moving
        within the PDF file.  Not all PDF files have outlines.
 
-       Layers  (a.k.a.  optional content) allow parts of the PDF content to be
+       Layers (a.k.a. optional content) allow parts of the PDF content  to  be
        shown or hidden.  Not all PDF files have layers.
 
-       Attachments are other files embedded within the PDF file.  There  is  a
-       'save'  button  for each attached file.  Not all PDF files have attach-
+       Attachments  are  other files embedded within the PDF file.  There is a
+       'save' button for each attached file.  Not all PDF files  have  attach-
        ments.
 
    Text selection
-       Dragging the mouse with the left button held  down  will  highlight  an
-       arbitrary  rectangle.   Selected  text  can  be copied to the clipboard
-       (with the edit/copy menu item).  On X11, selected text will  be  avail-
+       Dragging  the  mouse  with  the left button held down will highlight an
+       arbitrary rectangle.  Selected text can  be  copied  to  the  clipboard
+       (with  the  edit/copy menu item).  On X11, selected text will be avail-
        able in the X selection buffer.
 
    Links
-       When  the mouse is over a hyperlink, the link target will be shown in a
+       When the mouse is over a hyperlink, the link target will be shown in  a
        popup near the bottom of the window.
 
        Clicking on a hyperlink will jump to the link's destination.  A link to
-       another  PDF  document  will  make xpdf load that document.  A 'launch'
-       link to an executable program will display a dialog, and if  you  click
-       'ok',  execute the program.  URL links are opened in a system-dependent
+       another PDF document will make xpdf load  that  document.   A  'launch'
+       link  to  an executable program will display a dialog, and if you click
+       'ok', execute the program.  URL links are opened in a  system-dependent
        way.  (On UNIX, Qt uses the $BROWSER environment variable.)
 
    Mouse bindings
@@ -215,11 +235,11 @@
 
        Dragging the mouse with the middle button held down pans the window.
 
-       The right  mouse  button  opens  a  popup  menu  (see  popupMenuCmd  in
+       The  right  mouse  button  opens  a  popup  menu  (see  popupMenuCmd in
        xpdfrc(5)).
 
    Key bindings
-       This  section  lists the default key bindings.  Bindings can be changed
+       This section lists the default key bindings.  Bindings can  be  changed
        using the config file (see xpdfrc(5)).
 
        control-o
@@ -226,8 +246,8 @@
               Open a new PDF file via a file requester.
 
        control-r
-              Reload the current PDF file.  Note that  Xpdf  will  reload  the
-              file  automatically  (on  a  page  change  or  redraw) if it has
+              Reload  the  current  PDF  file.  Note that Xpdf will reload the
+              file automatically (on a  page  change  or  redraw)  if  it  has
               changed since it was last loaded.
 
        control-f
@@ -261,10 +281,13 @@
               Open a new window.
 
        control-w
-              Close the current tab.  Closes the window if this was  the  last
-              open  tab.  Quits the application if this was the last open win-
+              Close  the  current tab.  Closes the window if this was the last
+              open tab.  Quits the application if this was the last open  win-
               dow.
 
+       control-l
+              Toggle between full-screen and window modes.
+
        control-q
               Quit.
 
@@ -294,11 +317,11 @@
               Go to the last page.
 
        <space> or <PageDown>
-              Scroll down on the current page; if already at bottom,  move  to
+              Scroll  down  on the current page; if already at bottom, move to
               next page.
 
        control-<PageDown> or control-<down-arrow>
-              Go  to the next page.  If <ScrollLock> is active, this maintains
+              Go to the next page.  If <ScrollLock> is active, this  maintains
               the relative position on the page.
 
        <PageUp>
@@ -306,7 +329,7 @@
               ous page.
 
        control-<PageUp> or control-<up-arrow>
-              Go  to the previous page.  If <ScrollLock> is active, this main-
+              Go to the previous page.  If <ScrollLock> is active, this  main-
               tains the relative position on the page.
 
        <esc>  Exit full-screen mode.
@@ -320,20 +343,20 @@
        w      Set the zoom factor to 'width' (fit page width to window).
 
 Full-screen mode
-       Xpdf can be placed into full-screen mode via  the  -fullscreen  command
-       line  option,  the  'full  screen'  menu  item,  or  a  binding  to the
+       Xpdf  can  be  placed into full-screen mode via the -fullscreen command
+       line option,  the  'full  screen'  menu  item,  or  a  binding  to  the
        fullScreenMode or toggleFullScreenMode command.
 
-       Entering full-screen mode automatically switches  to  single-page  view
+       Entering  full-screen  mode  automatically switches to single-page view
        mode and to the fit-page zoom factor.
 
-       Full-screen  mode  can  be exited via the default <esc> key binding, or
+       Full-screen mode can be exited via the default <esc>  key  binding,  or
        via a binding to the windowMode or toggleFullScreenModecommand.
 
 COMMANDS
        Xpdf's key and mouse bindings are user-configurable, using the bind and
-       unbind  commands  in the config file (see xpdfrc(5)).  The bind command
-       allows you to bind a key or mouse button to a sequence of one  or  more
+       unbind commands in the config file (see xpdfrc(5)).  The  bind  command
+       allows  you  to bind a key or mouse button to a sequence of one or more
        commands.
 
        The following commands are supported:
@@ -349,11 +372,11 @@
               Check that file is open in the current tab, and open it if not.
 
        checkOpenFileAtDest(file,dest)
-              Check  that file is open in the current tab, and open it if not.
+              Check that file is open in the current tab, and open it if  not.
               In either case go to the specified named destination.
 
        checkOpenFileAtPage(file,page)
-              Check that file is open in the current tab, and open it if  not.
+              Check  that file is open in the current tab, and open it if not.
               In either case go to the specified page.
 
        closeSidebar
@@ -385,6 +408,10 @@
        endSelection
               End a selection.
 
+       expandSidebar(n)
+              Expand the sidebar by n pixels.  Opens the sidebar if it is cur-
+              rently closed.
+
        find   Set keyboard focus to the 'find' box.
 
        findFirst
@@ -448,6 +475,9 @@
 
        help   Open the help URL.
 
+       hideToolbar
+              Hide the toolbar.
+
        horizontalContinuousMode
               Switch to horizontal continuous view mode.
 
@@ -475,7 +505,7 @@
        nextTab
               Switch to the next tab.
 
-       open   Open a PDF file in this tab, using the open dialog.
+       open   Open a PDF file in the current tab, using the open dialog.
 
        openErrorWindow
               Open the error window.
@@ -487,10 +517,26 @@
               Open  the  specified  file  in  the current tab at the specified
               named destination.
 
+       openFileAtDestIn(file,dest,location)
+              Open the specified file  at  the  specified  named  destination.
+              Location must be "win" for a new window or "tab" for a new tab.
+
        openFileAtPage(file,page)
-              Open the specified file in the  current  tab  at  the  specified
+              Open  the  specified  file  in  the current tab at the specified
               page.
 
+       openFileAtPageIn(file,page,location)
+              Open the specified file at the specified page.  Location must be
+              "win" for a new window or "tab" for a new tab.
+
+       openFileIn(file,location)
+              Open  the specified file.  Location must be "win" for a new win-
+              dow or "tab" for a new tab.
+
+       openIn(location)
+              Open a PDF file, using the open dialog.  Location must be  "win"
+              for a new window or "tab" for a new tab.
+
        openSidebar
               Open the sidebar.
 
@@ -632,6 +678,13 @@
               Set  the selection to the specified coordinates on the specified
               page.
 
+       showToolbar
+              Show the toolbar.
+
+       shrinkSidebar(n)
+              Shrink the sidebar by n pixels.  Closes the sidebar if shrinking
+              it would go below the minimum allowed side.
+
        sideBySideContinuousMode
               Switch to side-by-side continuous view mode.
 
@@ -642,11 +695,11 @@
               Switch to single-page view mode.
 
        startPan
-              Start a pan operation at the current mouse position, which  will
+              Start  a pan operation at the current mouse position, which will
               scroll the document as the mouse moves.
 
        startSelection
-              Start  a  selection at the current mouse position, which will be
+              Start a selection at the current mouse position, which  will  be
               extended as the mouse moves.
 
        toggleContinuousMode
@@ -662,14 +715,24 @@
               Toggle the sidebar between open and closed.
 
        toggleSidebarMoveResizeWin
-              Toggle the sidebar between open and closed, resizing the  window
-              so  that the document size doesn't change, and moving the window
+              Toggle  the sidebar between open and closed, resizing the window
+              so that the document size doesn't change, and moving the  window
               so that the document stays in the same place on the screen.
 
        toggleSidebarResizeWin
-              Toggle the sidebar between open and closed, resizing the  window
+              Toggle  the sidebar between open and closed, resizing the window
               so that the document size doesn't change.
 
+       toggleToolbar
+              Toggle the toolbar between shown and hidden.
+
+       viewPageLabels
+              Show page labels (if the PDF file has them),  rather  than  page
+              numbers.
+
+       viewPageNumbers
+              Show page numbers, rather than page labels.
+
        windowMode
               Go to window (non-full-screen) mode.
 
@@ -732,4 +795,4 @@
 
 
 
-                                  18 Feb 2019                          xpdf(1)
+                                  25 Sep 2019                          xpdf(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1,7 +1,7 @@
 .\" Copyright 2002-2019 Glyph & Cog, LLC
-.TH xpdfrc 5 "18 Feb 2019"
+.TH xpdfrc 5 "25 Sep 2019"
 .SH NAME
-xpdfrc \- configuration file for Xpdf tools (version 4.01)
+xpdfrc \- configuration file for Xpdf tools (version 4.02)
 .SH DESCRIPTION
 All of the Xpdf tools read a single configuration file.  If you have a
 .I .xpdfrc
@@ -537,11 +537,21 @@
 zoom factor (which must be a percentage).  The default value is
 based on the screen resolution.
 .TP
+.BR initialDisplayMode " single | continuous | sideBySideSingle | sideBySideContinuous | horizontalContinuous"
+Sets the initial display mode.  The default setting is "continuous".
+.TP
+.BI initialToolbarState " yes | no"
+If set to "yes", xpdf opens with the toolbar visible.  If set to "no",
+xpdf opens with the toolbar hidden.  The default is "yes".
+.TP
 .BI initialSidebarState " yes | no"
 If set to "yes", xpdf opens with the sidebar (tabs, outline, etc.)
 visible.  If set to "no", xpdf opens with the sidebar collapsed.  The
 default is "yes".
 .TP
+.BR initialSelectMode " block | linear"
+Sets the initial selection mode.  The default setting is "linear".
+.TP
 .BI paperColor " color"
 Set the "paper color", i.e., the background of the page display.  The
 color can be #RRGGBB (hexadecimal) or a named color.  This option will
@@ -557,6 +567,11 @@
 Set the matte color for full-screen mode.  The color can be #RRGGBB
 (hexadecimal) or a named color.
 .TP
+.BI reverseVideoInvertImages " yes | no"
+If set to "no", xpdf's reverse-video mode inverts text and vector
+graphic content, but not images.  If set to "yes", xpdf inverts images
+as well.  The default is "no".
+.TP
 .BI popupMenuCmd " title command ..."
 Add a command to the popup menu.
 .I Title

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat	2019-09-29 10:00:12 UTC (rev 52203)
@@ -3,7 +3,7 @@
 
 
 NAME
-       xpdfrc - configuration file for Xpdf tools (version 4.01)
+       xpdfrc - configuration file for Xpdf tools (version 4.02)
 
 DESCRIPTION
        All  of the Xpdf tools read a single configuration file.  If you have a
@@ -493,11 +493,24 @@
               window  at  this  zoom factor (which must be a percentage).  The
               default value is based on the screen resolution.
 
+       initialDisplayMode single | continuous | sideBySideSingle | sideBySide-
+       Continuous | horizontalContinuous
+              Sets the initial display mode.  The default setting is "continu-
+              ous".
+
+       initialToolbarState yes | no
+              If set to "yes", xpdf opens with the toolbar visible.  If set to
+              "no", xpdf opens with the toolbar hidden.  The default is "yes".
+
        initialSidebarState yes | no
-              If set to "yes", xpdf opens with  the  sidebar  (tabs,  outline,
-              etc.)   visible.   If  set  to "no", xpdf opens with the sidebar
+              If  set  to  "yes",  xpdf opens with the sidebar (tabs, outline,
+              etc.)  visible.  If set to "no", xpdf  opens  with  the  sidebar
               collapsed.  The default is "yes".
 
+       initialSelectMode block | linear
+              Sets  the  initial selection mode.  The default setting is "lin-
+              ear".
+
        paperColor color
               Set the "paper color", i.e., the background of the page display.
               The  color  can be #RRGGBB (hexadecimal) or a named color.  This
@@ -513,6 +526,11 @@
               Set  the  matte  color  for  full-screen mode.  The color can be
               #RRGGBB (hexadecimal) or a named color.
 
+       reverseVideoInvertImages yes | no
+              If set to "no", xpdf's reverse-video mode inverts text and  vec-
+              tor  graphic  content,  but  not  images.  If set to "yes", xpdf
+              inverts images as well.  The default is "no".
+
        popupMenuCmd title command ...
               Add a command to the popup menu.  Title is the text to  be  dis-
               played  in  the  menu.  Command is an Xpdf command (see the COM-
@@ -716,4 +734,4 @@
 
 
 
-                                  18 Feb 2019                        xpdfrc(5)
+                                  25 Sep 2019                        xpdfrc(5)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -171,6 +171,7 @@
 
 GBool FoFiBase::checkRegion(int pos, int size) {
   return pos >= 0 &&
-         pos + size >= pos &&
+         size >= 0 &&
+         size <= INT_MAX - pos &&
          pos + size <= len;
 }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -320,6 +320,7 @@
   nCmaps = 0;
   nameToGID = NULL;
   isDfont = isDfontA;
+  isTTC = gFalse;
   parsedOk = gFalse;
 
   parse(fontNum, allowHeadlessCFF);
@@ -985,7 +986,8 @@
 
 GBool FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
 			     void *outputStream, char *name,
-			     int *codeToGID) {
+			     int *codeToGID, Guchar *replacementCmapTable,
+			     int replacementCmapTableLen) {
   // this substitute cmap table maps char code ffff to glyph 0,
   // with tables for MacRoman and MS Unicode
   static char cmapTab[44] = {
@@ -1188,7 +1190,7 @@
   if (!missingCmap && !missingName && !missingPost && !missingOS2 &&
       !unsortedLoca && !emptyCmap && !badCmapLen && !abbrevHMTX &&
       nZeroLengthTables == 0 && nBogusTables == 0 &&
-      !name && !codeToGID && !isDfont) {
+      !name && !codeToGID && !replacementCmapTable && !isDfont && !isTTC) {
     (*outputFunc)(outputStream, (char *)file, len);
     gfree(locaTable);
     return gFalse;
@@ -1306,7 +1308,7 @@
   }
 
   // construct the new cmap table
-  if (codeToGID) {
+  if (codeToGID && !replacementCmapTable) {
     newCmapLen = 44 + 256 * 2;
     newCmapTab = (char *)gmalloc(newCmapLen);
     newCmapTab[0] = 0;		// table version number = 0
@@ -1435,8 +1437,15 @@
 	  // don't include the file checksum
 	  newTables[j].checksum -= getU32BE(tables[i].offset + 8, &ok);
 	}
+      } else {
+	// we'll write four zero bytes for this table
+	newTables[j].len = 4;
       }
-      if (newTables[j].tag == cmapTag && codeToGID) {
+      if (newTables[j].tag == cmapTag && replacementCmapTable) {
+	newTables[j].len = replacementCmapTableLen;
+	newTables[j].checksum = computeTableChecksum(replacementCmapTable,
+						     replacementCmapTableLen);
+      } else if (newTables[j].tag == cmapTag && codeToGID) {
 	newTables[j].len = newCmapLen;
 	newTables[j].checksum = computeTableChecksum((Guchar *)newCmapTab,
 						     newCmapLen);
@@ -1470,7 +1479,11 @@
   }
   if (missingCmap) {
     newTables[j].tag = cmapTag;
-    if (codeToGID) {
+    if (replacementCmapTable) {
+      newTables[j].checksum = computeTableChecksum(replacementCmapTable,
+						   replacementCmapTableLen);
+      newTables[j].len = replacementCmapTableLen;
+    } else if (codeToGID) {
       newTables[j].checksum = computeTableChecksum((Guchar *)newCmapTab,
 						   newCmapLen);
       newTables[j].len = newCmapLen;
@@ -1588,6 +1601,9 @@
 	  (*outputFunc)(outputStream, "\0", 1);
 	}
       }
+    } else if (newTables[i].tag == cmapTag && replacementCmapTable) {
+      (*outputFunc)(outputStream, (char *)replacementCmapTable,
+		    newTables[i].len);
     } else if (newTables[i].tag == cmapTag && codeToGID) {
       (*outputFunc)(outputStream, newCmapTab, newTables[i].len);
     } else if (newTables[i].tag == cmapTag && missingCmap) {
@@ -1816,7 +1832,8 @@
     } else {
       locaTable[i].origOffset = 2 * getU16BE(pos + i*2, &ok);
     }
-    if (locaTable[i].origOffset > glyfTableLen) {
+    if (locaTable[i].origOffset < 0 ||
+	locaTable[i].origOffset > glyfTableLen) {
       locaTable[i].origOffset = glyfTableLen;
     }
   }
@@ -2172,7 +2189,9 @@
     tables[j].checksum = getU32BE(offset + pos + 4, &parsedOk);
     tables[j].offset = offset + (int)getU32BE(offset + pos + 8, &parsedOk);
     tables[j].len = (int)getU32BE(offset + pos + 12, &parsedOk);
-    if (tables[j].offset + tables[j].len >= tables[j].offset &&
+    if (tables[j].offset >= 0 &&
+	tables[j].len >= 0 &&
+	tables[j].offset + tables[j].len >= tables[j].offset &&
 	tables[j].offset + tables[j].len <= len) {
       // ignore any bogus entries in the table directory
       ++j;
@@ -2274,6 +2293,7 @@
 void FoFiTrueType::parseTTC(int fontNum, int *pos) {
   int nFonts;
 
+  isTTC = gTrue;
   nFonts = getU32BE(8, &parsedOk);
   if (!parsedOk) {
     return;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -95,6 +95,9 @@
   // for OpenType CFF fonts.)
   void getFontMatrix(double *mat);
 
+  // Return the number of glyphs in the font.
+  int getNumGlyphs() { return nGlyphs; }
+
   // Returns true if this looks like a CJK font that uses bytecode
   // instructions to assemble glyphs.
   GBool checkForTrickyCJK();
@@ -154,10 +157,15 @@
   // various other errors.  If <name> is non-NULL, the font is renamed
   // to <name>.  If <codeToGID> is non-NULL, the font is re-encoded,
   // using a Windows Unicode cmap.  If <name> is NULL and the font is
-  // complete and correct, it will be written unmodified.  (Not useful
-  // for OpenType CFF fonts.)  Returns true if the font was modified.
+  // complete and correct, it will be written unmodified.  If
+  // <replacementCmapTable> is non-NULL it will be used as the cmap
+  // table in the written font (overriding any existing cmap table
+  // and/or the codeToGID arg).  (Not useful for OpenType CFF fonts.)
+  // Returns true if the font was modified.
   GBool writeTTF(FoFiOutputFunc outputFunc, void *outputStream,
-		 char *name = NULL, int *codeToGID = NULL);
+		 char *name = NULL, int *codeToGID = NULL,
+		 Guchar *replacementCmapTable = NULL,
+		 int replacementCmapTableLen = 0);
 
   // Returns a pointer to the CFF font embedded in this OpenType font.
   // If successful, sets *<start> and *<length>, and returns true.
@@ -200,6 +208,7 @@
   GBool openTypeCFF;
   GBool headlessCFF;
   GBool isDfont;
+  GBool isTTC;
 
   GBool parsedOk;
 };

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -99,7 +99,7 @@
 
   // copy everything up to the encoding
   for (line = (char *)file;
-       line && strncmp(line, "/Encoding", 9);
+       line && line + 9 <= (char *)file + len && strncmp(line, "/Encoding", 9);
        line = getNextLine(line)) ;
   if (!line) {
     // no encoding - just copy the whole font file
@@ -122,7 +122,8 @@
   
   // find the end of the encoding data
   //~ this ought to parse PostScript tokens
-  if (!strncmp(line, "/Encoding StandardEncoding def", 30)) {
+  if (line + 30 <= (char *)file + len && 
+      !strncmp(line, "/Encoding StandardEncoding def", 30)) {
     line = getNextLine(line);
   } else {
     // skip "/Encoding" + one whitespace char,
@@ -144,16 +145,18 @@
   // check for a second one here
   if (line) {
     for (line2 = line, i = 0;
-	 i < 20 && line2 && strncmp(line2, "/Encoding", 9);
+	 i < 20 && line2 && line2 + 9 <= (char *)file + len &&
+	   strncmp(line2, "/Encoding", 9);
 	 line2 = getNextLine(line2), ++i) ;
     if (i < 20 && line2) {
       (*outputFunc)(outputStream, line, (int)(line2 - line));
-      if (!strncmp(line2, "/Encoding StandardEncoding def", 30)) {
+      if (line2 + 30 <= (char *)file + len && 
+	  !strncmp(line2, "/Encoding StandardEncoding def", 30)) {
 	line = getNextLine(line2);
       } else {
-	// skip "/Encoding" + one whitespace char,
+	// skip "/Encoding",
 	// then look for 'def' preceded by PostScript whitespace
-	p = line2 + 10;
+	p = line2 + 9;
 	line = NULL;
 	for (; p < (char *)file + len; ++p) {
 	  if ((*p == ' ' || *p == '\t' || *p == '\x0a' ||
@@ -203,9 +206,14 @@
        ++i) {
 
     // get font name
-    if (!name && !strncmp(line, "/FontName", 9)) {
-      strncpy(buf, line, 255);
-      buf[255] = '\0';
+    if (!name && line + 9 <= (char *)file + len &&
+	!strncmp(line, "/FontName", 9)) {
+      n = 255;
+      if (line + n > (char *)file + len) {
+	n = (int)(((char *)file + len) - line);
+      }
+      strncpy(buf, line, n);
+      buf[n] = '\0';
       if ((p = strchr(buf+9, '/')) &&
 	  (p = strtok(p+1, " \t\n\r"))) {
 	name = copyString(p);
@@ -213,10 +221,10 @@
       line = getNextLine(line);
 
     // get encoding
-    } else if (!encoding &&
+    } else if (!encoding && line + 30 <= (char *)file + len &&
 	       !strncmp(line, "/Encoding StandardEncoding def", 30)) {
       encoding = (char **)fofiType1StandardEncoding;
-    } else if (!encoding &&
+    } else if (!encoding && line + 19 <= (char *)file + len &&
 	       !strncmp(line, "/Encoding 256 array", 19)) {
       encoding = (char **)gmallocn(256, sizeof(char *));
       for (j = 0; j < 256; ++j) {
@@ -284,9 +292,14 @@
       }
       //~ check for getinterval/putinterval junk
 
-    } else if (!gotMatrix && !strncmp(line, "/FontMatrix", 11)) {
-      strncpy(buf, line + 11, 255);
-      buf[255] = '\0';
+    } else if (!gotMatrix && line + 11 <= (char *)file + len &&
+	       !strncmp(line, "/FontMatrix", 11)) {
+      n = 255;
+      if (line + 11 + n > (char *)file + len) {
+	n = (int)(((char *)file + len) - (line + 11));
+      }
+      strncpy(buf, line + 11, n);
+      buf[n] = '\0';
       if ((p = strchr(buf, '['))) {
 	++p;
 	if ((p2 = strchr(p, ']'))) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -18,6 +18,7 @@
 #include "gmem.h"
 #include "gmempp.h"
 #include "GString.h"
+#include "GHash.h"
 #include "FoFiEncodings.h"
 #include "FoFiType1C.h"
 
@@ -152,6 +153,23 @@
   return new GString(buf);
 }
 
+GHash *FoFiType1C::getNameToGIDMap() {
+  GHash *map;
+  char name[256];
+  GBool ok;
+  int gid;
+
+  map = new GHash(gTrue);
+  for (gid = 0; gid < nGlyphs; ++gid) {
+    ok = gTrue;
+    getString(charset[gid], name, &ok);
+    if (ok) {
+      map->add(new GString(name), gid);
+    }
+  }
+  return map;
+}
+
 int *FoFiType1C::getCIDToGIDMap(int *nCIDs) {
   int *map;
   int n, i;
@@ -2183,6 +2201,371 @@
   (*outputFunc)(outputStream, buf, i);
 }
 
+void FoFiType1C::convertToOpenType(FoFiOutputFunc outputFunc,
+				   void *outputStream,
+				   int nWidths, Gushort *widths,
+				   Guchar *cmapTable, int cmapTableLen) {
+  // dummy OS/2 table (taken from FoFiTrueType::writeTTF)
+  static Guchar os2Tab[86] = {
+    0, 1,			// version
+    0, 1,			// xAvgCharWidth
+    0x01, 0x90,			// usWeightClass
+    0, 5,			// usWidthClass
+    0, 0,			// fsType
+    0, 0,			// ySubscriptXSize
+    0, 0,			// ySubscriptYSize
+    0, 0,			// ySubscriptXOffset
+    0, 0,			// ySubscriptYOffset
+    0, 0,			// ySuperscriptXSize
+    0, 0,			// ySuperscriptYSize
+    0, 0,			// ySuperscriptXOffset
+    0, 0,			// ySuperscriptYOffset
+    0, 0,			// yStrikeoutSize
+    0, 0,			// yStrikeoutPosition
+    0, 0,			// sFamilyClass
+    0, 0, 0, 0, 0,		// panose
+    0, 0, 0, 0, 0,
+    0, 0, 0, 0,			// ulUnicodeRange1
+    0, 0, 0, 0,			// ulUnicodeRange2
+    0, 0, 0, 0,			// ulUnicodeRange3
+    0, 0, 0, 0,			// ulUnicodeRange4
+    0, 0, 0, 0,			// achVendID
+    0, 0,			// fsSelection
+    0, 0,			// usFirstCharIndex
+    0, 0,			// usLastCharIndex
+    0, 0,			// sTypoAscender
+    0, 0,			// sTypoDescender
+    0, 0,			// sTypoLineGap
+    0x20, 0x00,			// usWinAscent
+    0x20, 0x00,			// usWinDescent
+    0, 0, 0, 1,			// ulCodePageRange1
+    0, 0, 0, 0			// ulCodePageRange2
+  };
+  Guchar headTable[54], hheaTable[36], maxpTable[6];
+  Guchar nameTable[26], postTable[32];
+  Guchar *hmtxTable;
+  static const char *tableTag[9] = {
+    "CFF ",
+    "OS/2",
+    "cmap",
+    "head",
+    "hhea",
+    "hmtx",
+    "maxp",
+    "name",
+    "post"
+  };
+  Guchar *tableData[9];
+  int tableLength[9];
+  Guchar header[12 + 9*16];
+  double mat[6];
+  Gushort maxWidth;
+  Guint checksum, fileChecksum;
+  int unitsPerEm, xMin, yMin, xMax, yMax, offset, i;
+
+  //--- CFF_ table
+  tableData[0] = file;
+  tableLength[0] = len;
+
+  //--- OS/2 table
+  tableData[1] = os2Tab;
+  tableLength[1] = 86;
+
+  //--- cmap table
+  tableData[2] = cmapTable;
+  tableLength[2] = cmapTableLen;
+
+  //--- head table
+  getFontMatrix(mat);
+  if (mat[0] == 0) {
+    unitsPerEm = 1000;
+  } else {
+    unitsPerEm = (int)(1 / mat[0] + 0.5);
+  }
+  xMin = (int)(topDict.fontBBox[0] + 0.5);
+  yMin = (int)(topDict.fontBBox[1] + 0.5);
+  xMax = (int)(topDict.fontBBox[2] + 0.5);
+  yMax = (int)(topDict.fontBBox[3] + 0.5);
+  headTable[ 0] = 0x00;				// version
+  headTable[ 1] = 0x01;
+  headTable[ 2] = 0x00;
+  headTable[ 3] = 0x00;
+  headTable[ 4] = 0x00;				// revision
+  headTable[ 5] = 0x00;
+  headTable[ 6] = 0x00;
+  headTable[ 7] = 0x00;
+  headTable[ 8] = 0x00;				// checksumAdjustment
+  headTable[ 9] = 0x00;				//   (set later)
+  headTable[10] = 0x00;
+  headTable[11] = 0x00;
+  headTable[12] = 0x5f;				// magicNumber
+  headTable[13] = 0x0f;
+  headTable[14] = 0x3c;
+  headTable[15] = 0xf5;
+  headTable[16] = 0x00;				// flags
+  headTable[17] = 0x03;
+  headTable[18] = (Guchar)(unitsPerEm >> 8);	// unitsPerEm
+  headTable[19] = (Guchar)unitsPerEm;
+  headTable[20] = 0x00;				// created
+  headTable[21] = 0x00;
+  headTable[22] = 0x00;
+  headTable[23] = 0x00;
+  headTable[24] = 0x00;
+  headTable[25] = 0x00;
+  headTable[26] = 0x00;
+  headTable[27] = 0x00;
+  headTable[28] = 0x00;				// modified
+  headTable[29] = 0x00;
+  headTable[30] = 0x00;
+  headTable[31] = 0x00;
+  headTable[32] = 0x00;
+  headTable[33] = 0x00;
+  headTable[34] = 0x00;
+  headTable[35] = 0x00;
+  headTable[36] = (Guchar)(xMin >> 8);		// xMin
+  headTable[37] = (Guchar)xMin;
+  headTable[38] = (Guchar)(yMin >> 8);		// yMin
+  headTable[39] = (Guchar)yMin;
+  headTable[40] = (Guchar)(xMax >> 8);		// xMax
+  headTable[41] = (Guchar)xMax;
+  headTable[42] = (Guchar)(yMax >> 8);		// yMax
+  headTable[43] = (Guchar)yMax;
+  headTable[44] = 0;				// macStyle
+  headTable[45] = 0;
+  headTable[46] = 0;				// lowestRecPPEM
+  headTable[47] = 3;
+  headTable[48] = 0;				// fontDirectionHint
+  headTable[49] = 2;				//   (deprecated)
+  headTable[50] = 0;				// indexToLocFormat
+  headTable[51] = 0;				//   (n/a to CFF fonts)
+  headTable[52] = 0;				// glyphDataFormat
+  headTable[53] = 0;				//   (n/a to CFF fonts)
+  tableData[3] = headTable;
+  tableLength[3] = 54;
+
+  //--- hhea table
+  maxWidth = widths[0];
+  for (i = 1; i < nWidths; ++i) {
+    if (widths[i] > maxWidth) {
+      maxWidth = widths[i];
+    }
+  }
+  hheaTable[ 0] = 0x00;				// version
+  hheaTable[ 1] = 0x01;
+  hheaTable[ 2] = 0x00;
+  hheaTable[ 3] = 0x00;
+  hheaTable[ 4] = (Guchar)(yMax >> 8);		// ascender
+  hheaTable[ 5] = (Guchar)yMax;
+  hheaTable[ 6] = (Guchar)(yMin >> 8);		// descender
+  hheaTable[ 7] = (Guchar)yMin;
+  hheaTable[ 8] = 0;				// lineGap
+  hheaTable[ 9] = 0;
+  hheaTable[10] = (Guchar)(maxWidth >> 8);	// advanceWidthMax
+  hheaTable[11] = (Guchar)maxWidth;
+  hheaTable[12] = 0;				// minLeftSideBearing
+  hheaTable[13] = 0;
+  hheaTable[14] = 0;				// minRightSideBearing
+  hheaTable[15] = 0;
+  hheaTable[16] = (Guchar)(maxWidth >> 8);	// xMaxExtent
+  hheaTable[17] = (Guchar)maxWidth;
+  hheaTable[18] = 0;				// caretSlopeRise
+  hheaTable[19] = 1;
+  hheaTable[20] = 0;				// caretSlopeRun
+  hheaTable[21] = 0;
+  hheaTable[22] = 0;				// caretOffset
+  hheaTable[23] = 0;
+  hheaTable[24] = 0;				// reserved
+  hheaTable[25] = 0;
+  hheaTable[26] = 0;				// reserved
+  hheaTable[27] = 0;
+  hheaTable[28] = 0;				// reserved
+  hheaTable[29] = 0;
+  hheaTable[30] = 0;				// reserved
+  hheaTable[31] = 0;
+  hheaTable[32] = 0;				// metricDataFormat
+  hheaTable[33] = 0;
+  hheaTable[34] = (Guchar)(nWidths >> 8);	// numberOfHMetrics
+  hheaTable[35] = (Guchar)nWidths;
+  tableData[4] = hheaTable;
+  tableLength[4] = 36;
+
+  //--- hmtx table
+  //~ this currently sets LSB to 0 for all glyphs
+  hmtxTable = (Guchar *)gmallocn(nWidths, 4);
+  for (i = 0; i < nWidths; ++i) {
+    hmtxTable[4*i  ] = (Guchar)(widths[i] >> 8);
+    hmtxTable[4*i+1] = (Guchar)widths[i];
+    hmtxTable[4*i+2] = 0;
+    hmtxTable[4*i+3] = 0;
+  }
+  tableData[5] = hmtxTable;
+  tableLength[5] = 4 * nWidths;
+
+  //--- maxp table
+  maxpTable[0] = 0x00;				// version = 0.5
+  maxpTable[1] = 0x00;
+  maxpTable[2] = 0x50;
+  maxpTable[3] = 0x00;
+  maxpTable[4] = (Guchar)(nGlyphs >> 8);	// numGlyphs
+  maxpTable[5] = (Guchar)nGlyphs;
+  tableData[6] = maxpTable;
+  tableLength[6] = 6;
+
+  //--- name table
+  nameTable[ 0] = 0x00;				// format
+  nameTable[ 1] = 0x00;
+  nameTable[ 2] = 0x00;				// count
+  nameTable[ 3] = 0x01;
+  nameTable[ 4] = 0x00;				// stringOffset
+  nameTable[ 5] = 0x12;
+  nameTable[ 6] = 0x00;				// platformID
+  nameTable[ 7] = 0x00;
+  nameTable[ 8] = 0x00;				// encodingID
+  nameTable[ 9] = 0x03;
+  nameTable[10] = 0x00;				// languageID
+  nameTable[11] = 0x00;
+  nameTable[12] = 0x00;				// nameID
+  nameTable[13] = 0x00;
+  nameTable[14] = 0x00;				// length
+  nameTable[15] = 0x08;
+  nameTable[16] = 0x00;				// offset
+  nameTable[17] = 0x00;
+  nameTable[18] = 0x00;				// string data
+  nameTable[19] = (Guchar)'n';
+  nameTable[20] = 0x00;
+  nameTable[21] = (Guchar)'o';
+  nameTable[22] = 0x00;
+  nameTable[23] = (Guchar)'n';
+  nameTable[24] = 0x00;
+  nameTable[25] = (Guchar)'e';
+  tableData[7] = nameTable;
+  tableLength[7] = 26;
+
+  //--- post table
+  postTable[ 0] = 0x00;				// version = 3.0
+  postTable[ 1] = 0x03;
+  postTable[ 2] = 0x00;
+  postTable[ 3] = 0x00;
+  postTable[ 4] = 0x00;				// italicAngle
+  postTable[ 5] = 0x00;
+  postTable[ 6] = 0x00;
+  postTable[ 7] = 0x00;
+  postTable[ 8] = 0x00;				// underlinePosition
+  postTable[ 9] = 0x00;
+  postTable[10] = 0x00;				// underlineThickness
+  postTable[11] = 0x00;
+  postTable[12] = 0x00;				// isFixedPitch
+  postTable[13] = 0x00;
+  postTable[14] = 0x00;
+  postTable[15] = 0x00;
+  postTable[16] = 0x00;				// minMemType42
+  postTable[17] = 0x00;
+  postTable[18] = 0x00;
+  postTable[19] = 0x00;
+  postTable[20] = 0x00;				// maxMemType42
+  postTable[21] = 0x00;
+  postTable[22] = 0x00;
+  postTable[23] = 0x00;
+  postTable[24] = 0x00;				// minMemType1
+  postTable[25] = 0x00;
+  postTable[26] = 0x00;
+  postTable[27] = 0x00;
+  postTable[28] = 0x00;				// maxMemType1
+  postTable[29] = 0x00;
+  postTable[30] = 0x00;
+  postTable[31] = 0x00;
+  tableData[8] = postTable;
+  tableLength[8] = 32;
+
+  //--- header and table directory
+  header[ 0] = 'O';				// sfnt version
+  header[ 1] = 'T';
+  header[ 2] = 'T';
+  header[ 3] = 'O';
+  header[ 4] = 0x00;				// numTables
+  header[ 5] = 0x09;
+  header[ 6] = 0x00;				// searchRange
+  header[ 7] = 0x80;
+  header[ 8] = 0x00;				// entrySelector
+  header[ 9] = 0x03;
+  header[10] = 0x00;				// rangeShift
+  header[11] = 0x10;
+  offset = 12 + 9*16;
+  fileChecksum = 0;
+  for (i = 0; i < 9; ++i) {
+    header[12 + i*16 +  0] = tableTag[i][0];
+    header[12 + i*16 +  1] = tableTag[i][1];
+    header[12 + i*16 +  2] = tableTag[i][2];
+    header[12 + i*16 +  3] = tableTag[i][3];
+    checksum = computeOpenTypeTableChecksum(tableData[i], tableLength[i]);
+    fileChecksum += checksum;
+    header[12 + i*16 +  4] = (Guchar)(checksum >> 24);
+    header[12 + i*16 +  5] = (Guchar)(checksum >> 16);
+    header[12 + i*16 +  6] = (Guchar)(checksum >> 8);
+    header[12 + i*16 +  7] = (Guchar)checksum;
+    header[12 + i*16 +  8] = (Guchar)(offset >> 24);
+    header[12 + i*16 +  9] = (Guchar)(offset >> 16);
+    header[12 + i*16 + 10] = (Guchar)(offset >> 8);
+    header[12 + i*16 + 11] = (Guchar)offset;
+    header[12 + i*16 + 12] = (Guchar)(tableLength[i] >> 24);
+    header[12 + i*16 + 13] = (Guchar)(tableLength[i] >> 16);
+    header[12 + i*16 + 14] = (Guchar)(tableLength[i] >> 8);
+    header[12 + i*16 + 15] = (Guchar)tableLength[i];
+    offset += tableLength[i];
+    if (tableLength[i] & 3) {
+      offset += 4 - (tableLength[i] & 3);
+    }
+  }
+
+  //--- file checksum
+  fileChecksum += computeOpenTypeTableChecksum(header, 12 + 9*16);
+  fileChecksum = 0xb1b0afba - fileChecksum;
+  headTable[ 8] = (Guchar)(fileChecksum >> 24);
+  headTable[ 9] = (Guchar)(fileChecksum >> 16);
+  headTable[10] = (Guchar)(fileChecksum >>  8);
+  headTable[11] = (Guchar)fileChecksum;
+
+  //--- write the OpenType font
+  (*outputFunc)(outputStream, (char *)header, 12 + 9*16);
+  for (i = 0; i < 9; ++i) {
+    (*outputFunc)(outputStream, (char *)tableData[i], tableLength[i]);
+    if (tableLength[i] & 3) {
+      (*outputFunc)(outputStream, "\0\0\0", 4 - (tableLength[i] & 3));
+    }
+  }
+
+  gfree(hmtxTable);
+}
+
+Guint FoFiType1C::computeOpenTypeTableChecksum(Guchar *data, int length) {
+  Guint checksum, word;
+  int i;
+
+  checksum = 0;
+  for (i = 0; i+3 < length; i += 4) {
+    word = ((data[i  ] & 0xff) << 24) +
+           ((data[i+1] & 0xff) << 16) +
+           ((data[i+2] & 0xff) <<  8) +
+            (data[i+3] & 0xff);
+    checksum += word;
+  }
+  if (length & 3) {
+    word = 0;
+    i = length & ~3;
+    switch (length & 3) {
+    case 3:
+      word |= (data[i+2] & 0xff) <<  8;
+    case 2:
+      word |= (data[i+1] & 0xff) << 16;
+    case 1:
+      word |= (data[i  ] & 0xff) << 24;
+      break;
+    }
+    checksum += word;
+  }
+  return checksum;
+}
+
 GBool FoFiType1C::parse() {
   Type1CIndex fdIdx;
   Type1CIndexVal val;
@@ -2577,7 +2960,14 @@
 	parsedOk = gFalse;
 	return;
       }
-      memcpy(fdSelect, file + pos, nGlyphs);
+      for (gid0 = 0; gid0 < nGlyphs; ++gid0) {
+	if (file[pos + gid0] >= nFDs) {
+	  //~ error(-1, "Bad FDSelect table in CID font");
+	  parsedOk = gFalse;
+	  return;
+	}
+	fdSelect[gid0] = file[pos + gid0];
+      }
     } else if (fdSelectFmt == 3) {
       nRanges = getU16BE(pos, &parsedOk);
       pos += 2;
@@ -2590,7 +2980,7 @@
 	  return;
 	}
 	pos += 2;
-	if (gid0 > gid1 || gid1 > nGlyphs) {
+	if (gid0 > gid1 || gid1 > nGlyphs || fd >= nFDs) {
 	  //~ error(-1, "Bad FDSelect table in CID font");
 	  parsedOk = gFalse;
 	  return;
@@ -2703,10 +3093,19 @@
 
   if (topDict.charsetOffset == 0) {
     charset = fofiType1CISOAdobeCharset;
+    if (nGlyphs > 229) {
+      nGlyphs = 229;
+    }
   } else if (topDict.charsetOffset == 1) {
     charset = fofiType1CExpertCharset;
+    if (nGlyphs > 166) {
+      nGlyphs = 166;
+    }
   } else if (topDict.charsetOffset == 2) {
     charset = fofiType1CExpertSubsetCharset;
+    if (nGlyphs > 87) {
+      nGlyphs = 87;
+    }
   } else {
     charset = (Gushort *)gmallocn(nGlyphs, sizeof(Gushort));
     for (i = 0; i < nGlyphs; ++i) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -18,6 +18,7 @@
 #include "gtypes.h"
 #include "FoFiBase.h"
 
+class GHash;
 class GString;
 
 //------------------------------------------------------------------------
@@ -169,6 +170,10 @@
   int getNumGlyphs() { return nGlyphs; }
   GString *getGlyphName(int gid);
 
+  // Returns a hash mapping glyph names to GIDs.  This is only useful
+  // with 8-bit fonts.
+  GHash *getNameToGIDMap();
+
   // Return the mapping from CIDs to GIDs, and return the number of
   // CIDs in *<nCIDs>.  This is only useful for CID fonts.
   int *getCIDToGIDMap(int *nCIDs);
@@ -208,6 +213,13 @@
   void convertToType0(char *psName, int *codeMap, int nCodes,
 		      FoFiOutputFunc outputFunc, void *outputStream);
 
+  // Write an OpenType file, encapsulating the CFF font.  <widths>
+  // provides the glyph widths (in design units) for <nWidths> glyphs.
+  // The cmap table must be supplied by the caller.
+  void convertToOpenType(FoFiOutputFunc outputFunc, void *outputStream,
+			 int nWidths, Gushort *widths,
+			 Guchar *cmapTable, int cmapTableLen);
+
 private:
 
   FoFiType1C(char *fileA, int lenA, GBool freeFileDataA);
@@ -224,6 +236,7 @@
   void eexecWrite(Type1CEexecBuf *eb, const char *s);
   void eexecWriteCharstring(Type1CEexecBuf *eb, Guchar *s, int n);
   void writePSString(char *s, FoFiOutputFunc outputFunc, void *outputStream);
+  Guint computeOpenTypeTableChecksum(Guchar *data, int length);
   GBool parse();
   void readTopDict();
   void readFD(int offset, int length, Type1CPrivateDict *pDict);

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -36,7 +36,7 @@
   FixedPoint(const FixedPoint &x) { val = x.val; }
   FixedPoint(double x) { val = (int)(x * (1 << fixptShift) + 0.5); }
   FixedPoint(int x) { val = x << fixptShift; }
-  FixedPoint(long x) { val = x << fixptShift; }
+  FixedPoint(long x) { val = (int)x << fixptShift; }
 
   operator float()
     { return (float) val * ((float)1 / (float)(1 << fixptShift)); }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/GMutex.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/GMutex.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/GMutex.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -12,6 +12,7 @@
 #ifndef GMUTEX_H
 #define GMUTEX_H
 
+#include <aconf.h>
 #ifdef _WIN32
 #  include <windows.h>
 #  include <intrin.h>

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -14,6 +14,8 @@
 #include <aconf.h>
 
 #ifdef _WIN32
+#  undef WIN32_LEAN_AND_MEAN
+#  include <windows.h>
 #  include <time.h>
 #  include <direct.h>
 #else
@@ -613,7 +615,7 @@
       }
     }
     wPath[i] = (wchar_t)0;
-    for (i = 0; mode[i] && i < sizeof(wMode) - 1; ++i) {
+    for (i = 0; mode[i] && i < sizeof(wMode)/sizeof(wchar_t) - 1; ++i) {
       wMode[i] = (wchar_t)(mode[i] & 0xff);
     }
     wMode[i] = (wchar_t)0;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -11,6 +11,7 @@
 #ifndef GFILE_H
 #define GFILE_H
 
+#include <aconf.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/gmem.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/gmem.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/gmem.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -11,7 +11,9 @@
 #include <stdlib.h>
 #include <stddef.h>
 // older compilers won't define SIZE_MAX in stdint.h without this
-#define __STDC_LIMIT_MACROS 1
+#ifndef __STDC_LIMIT_MACROS
+#  define __STDC_LIMIT_MACROS 1
+#endif
 #include <stdint.h>
 #include <string.h>
 #include <limits.h>
@@ -107,12 +109,12 @@
   trl = (unsigned long *)(mem + gMemHdrSize + size1);
   hdr->magic = gMemMagic;
   hdr->size = size;
+  gMemLock;
   if (ignore) {
     hdr->index = -1;
   } else {
     hdr->index = gMemIndex++;
   }
-  gMemLock;
   if (gMemTail) {
     gMemTail->next = hdr;
     hdr->prev = gMemTail;
@@ -233,12 +235,12 @@
   trl = (unsigned long *)(mem + gMemHdrSize + size1);
   hdr->magic = gMemMagic;
   hdr->size = size;
+  gMemLock;
   if (ignore) {
     hdr->index = -1;
   } else {
     hdr->index = gMemIndex++;
   }
-  gMemLock;
   if (gMemTail) {
     gMemTail->next = hdr;
     hdr->prev = gMemTail;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/gmem.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/gmem.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/gmem.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -20,7 +20,11 @@
   ~GMemException() {}
 };
 
-#define GMEM_EXCEP throw(GMemException)
+// This used to be:
+//   #define GMEM_EXCEP throw(GMemException)
+// but the throw decl was never really very useful, and is deprecated
+// as of C++11 and illegal as of C++17.
+#define GMEM_EXCEP
 
 #else // USE_EXCEPTIONS
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -18,6 +18,7 @@
 #include <math.h>
 #include "gmem.h"
 #include "gmempp.h"
+#include "GString.h"
 #include "SplashErrorCodes.h"
 #include "SplashMath.h"
 #include "SplashBitmap.h"
@@ -257,6 +258,22 @@
       pipe->run = &Splash::pipeRunAACMYK8;
 #endif
     }
+  } else if (!pipe->pattern && !pipe->noTransparency && !state->softMask &&
+	     usesShape &&
+	     state->inNonIsolatedGroup && groupBackBitmap->alpha &&
+	     !state->inKnockoutGroup &&
+	     !state->blendFunc && !pipe->nonIsolatedGroup) {
+    if (mode == splashModeMono8 && bitmap->alpha) {
+      pipe->run = &Splash::pipeRunNonIsoMono8;
+    } else if (mode == splashModeRGB8 && bitmap->alpha) {
+      pipe->run = &Splash::pipeRunNonIsoRGB8;
+    } else if (mode == splashModeBGR8 && bitmap->alpha) {
+      pipe->run = &Splash::pipeRunNonIsoBGR8;
+#if SPLASH_CMYK
+    } else if (mode == splashModeCMYK8 && bitmap->alpha) {
+      pipe->run = &Splash::pipeRunNonIsoCMYK8;
+#endif
+    }
   }
 }
 
@@ -276,6 +293,7 @@
   Guchar *alpha0Ptr;
   SplashColorPtr softMaskPtr;
 #if SPLASH_CMYK
+  Guchar aPrev;
   SplashColor cSrc2, cDest2;
 #endif
 
@@ -514,25 +532,38 @@
 	break;
 #if SPLASH_CMYK
       case splashModeCMYK8:
+	if (alpha0Ptr) {   // non-isolated group
+	  if (color0Ptr) { //   non-isolated, knockout group
+	    aPrev = *alpha0Ptr;
+	  } else {         //   non-isolated, non-knockout group
+	    aPrev = (Guchar)(*alpha0Ptr + aDest - div255(*alpha0Ptr * aDest));
+	  }
+	} else {           // isolated group
+	  if (color0Ptr) { //   isolated, knockout group
+	    aPrev = 0;
+	  } else {         //   isolated, non-knockout group
+	    aPrev = aDest;
+	  }
+	}
 	if (state->overprintMask & 0x01) {
 	  cSrc[0] = state->cmykTransferC[cSrcPtr[0]];
 	} else {
-	  cSrc[0] = div255(aDest * cDest[0]);
+	  cSrc[0] = div255(aPrev * cDest[0]);
 	}
 	if (state->overprintMask & 0x02) {
 	  cSrc[1] = state->cmykTransferM[cSrcPtr[1]];
 	} else {
-	  cSrc[1] = div255(aDest * cDest[1]);
+	  cSrc[1] = div255(aPrev * cDest[1]);
 	}
 	if (state->overprintMask & 0x04) {
 	  cSrc[2] = state->cmykTransferY[cSrcPtr[2]];
 	} else {
-	  cSrc[2] = div255(aDest * cDest[2]);
+	  cSrc[2] = div255(aPrev * cDest[2]);
 	}
 	if (state->overprintMask & 0x08) {
 	  cSrc[3] = state->cmykTransferK[cSrcPtr[3]];
 	} else {
-	  cSrc[3] = div255(aDest * cDest[3]);
+	  cSrc[3] = div255(aPrev * cDest[3]);
 	}
 	break;
 #endif
@@ -1986,6 +2017,398 @@
 #endif
 
 
+void Splash::pipeRunNonIsoMono8(SplashPipe *pipe, int x0, int x1, int y,
+				Guchar *shapePtr, SplashColorPtr cSrcPtr) {
+  Guchar shape, aSrc, aDest, alphaI, alpha0, aResult;
+  Guchar cSrc0, cDest0, cResult0;
+  SplashColorPtr destColorPtr;
+  Guchar *destAlphaPtr;
+  Guchar *alpha0Ptr;
+  int cSrcStride, x, lastX;
+
+  if (cSrcPtr) {
+    cSrcStride = 1;
+  } else {
+    cSrcPtr = pipe->cSrcVal;
+    cSrcStride = 0;
+  }
+  for (; x0 <= x1; ++x0) {
+    if (*shapePtr) {
+      break;
+    }
+    cSrcPtr += cSrcStride;
+    ++shapePtr;
+  }
+  if (x0 > x1) {
+    return;
+  }
+  updateModX(x0);
+  updateModY(y);
+  lastX = x0;
+
+  destColorPtr = &bitmap->data[y * bitmap->rowSize + x0];
+  destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0];
+  alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + y)
+				        * groupBackBitmap->alphaRowSize +
+				      (groupBackX + x0)];
+
+  for (x = x0; x <= x1; ++x) {
+
+    //----- shape
+    shape = *shapePtr;
+    if (!shape) {
+      destColorPtr += 1;
+      ++destAlphaPtr;
+      ++alpha0Ptr;
+      cSrcPtr += cSrcStride;
+      ++shapePtr;
+      continue;
+    }
+    lastX = x;
+
+    //----- read destination pixel
+    cDest0 = destColorPtr[0];
+    aDest = *destAlphaPtr;
+
+    //----- source color
+    cSrc0 = state->grayTransfer[cSrcPtr[0]];
+
+    //----- source alpha
+    aSrc = div255(pipe->aInput * shape);
+
+    //----- result alpha and non-isolated group element correction
+    aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest));
+    alpha0 = *alpha0Ptr++;
+    alphaI = (Guchar)(aResult + alpha0 - div255(aResult * alpha0));
+
+    //----- result color
+    if (alphaI == 0) {
+      cResult0 = 0;
+    } else {
+      cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI);
+    }
+
+    //----- write destination pixel
+    *destColorPtr++ = cResult0;
+    *destAlphaPtr++ = aResult;
+
+    cSrcPtr += cSrcStride;
+    ++shapePtr;
+  } // for (x ...)
+
+  updateModX(lastX);
+}
+
+void Splash::pipeRunNonIsoRGB8(SplashPipe *pipe, int x0, int x1, int y,
+			       Guchar *shapePtr, SplashColorPtr cSrcPtr) {
+  Guchar shape, aSrc, aDest, alphaI, alpha0, aResult;
+  Guchar cSrc0, cSrc1, cSrc2;
+  Guchar cDest0, cDest1, cDest2;
+  Guchar cResult0, cResult1, cResult2;
+  SplashColorPtr destColorPtr;
+  Guchar *destAlphaPtr;
+  Guchar *alpha0Ptr;
+  int cSrcStride, x, lastX;
+
+  if (cSrcPtr) {
+    cSrcStride = 3;
+  } else {
+    cSrcPtr = pipe->cSrcVal;
+    cSrcStride = 0;
+  }
+  for (; x0 <= x1; ++x0) {
+    if (*shapePtr) {
+      break;
+    }
+    cSrcPtr += cSrcStride;
+    ++shapePtr;
+  }
+  if (x0 > x1) {
+    return;
+  }
+  updateModX(x0);
+  updateModY(y);
+  lastX = x0;
+
+  destColorPtr = &bitmap->data[y * bitmap->rowSize + x0 * 3];
+  destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0];
+  alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + y)
+				        * groupBackBitmap->alphaRowSize +
+				      (groupBackX + x0)];
+
+  for (x = x0; x <= x1; ++x) {
+
+    //----- shape
+    shape = *shapePtr;
+    if (!shape) {
+      destColorPtr += 3;
+      ++destAlphaPtr;
+      ++alpha0Ptr;
+      cSrcPtr += cSrcStride;
+      ++shapePtr;
+      continue;
+    }
+    lastX = x;
+
+    //----- read destination pixel
+    cDest0 = destColorPtr[0];
+    cDest1 = destColorPtr[1];
+    cDest2 = destColorPtr[2];
+    aDest = *destAlphaPtr;
+
+    //----- source color
+    cSrc0 = state->rgbTransferR[cSrcPtr[0]];
+    cSrc1 = state->rgbTransferG[cSrcPtr[1]];
+    cSrc2 = state->rgbTransferB[cSrcPtr[2]];
+
+    //----- source alpha
+    aSrc = div255(pipe->aInput * shape);
+
+    //----- result alpha and non-isolated group element correction
+    aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest));
+    alpha0 = *alpha0Ptr++;
+    alphaI = (Guchar)(aResult + alpha0 - div255(aResult * alpha0));
+
+    //----- result color
+    if (alphaI == 0) {
+      cResult0 = 0;
+      cResult1 = 0;
+      cResult2 = 0;
+    } else {
+      cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI);
+      cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI);
+      cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI);
+    }
+
+    //----- write destination pixel
+    destColorPtr[0] = cResult0;
+    destColorPtr[1] = cResult1;
+    destColorPtr[2] = cResult2;
+    destColorPtr += 3;
+    *destAlphaPtr++ = aResult;
+
+    cSrcPtr += cSrcStride;
+    ++shapePtr;
+  } // for (x ...)
+
+  updateModX(lastX);
+}
+
+void Splash::pipeRunNonIsoBGR8(SplashPipe *pipe, int x0, int x1, int y,
+			       Guchar *shapePtr, SplashColorPtr cSrcPtr) {
+  Guchar shape, aSrc, aDest, alphaI, alpha0, aResult;
+  Guchar cSrc0, cSrc1, cSrc2;
+  Guchar cDest0, cDest1, cDest2;
+  Guchar cResult0, cResult1, cResult2;
+  SplashColorPtr destColorPtr;
+  Guchar *destAlphaPtr;
+  Guchar *alpha0Ptr;
+  int cSrcStride, x, lastX;
+
+  if (cSrcPtr) {
+    cSrcStride = 3;
+  } else {
+    cSrcPtr = pipe->cSrcVal;
+    cSrcStride = 0;
+  }
+  for (; x0 <= x1; ++x0) {
+    if (*shapePtr) {
+      break;
+    }
+    cSrcPtr += cSrcStride;
+    ++shapePtr;
+  }
+  if (x0 > x1) {
+    return;
+  }
+  updateModX(x0);
+  updateModY(y);
+  lastX = x0;
+
+  destColorPtr = &bitmap->data[y * bitmap->rowSize + x0 * 3];
+  destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0];
+  alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + y)
+				        * groupBackBitmap->alphaRowSize +
+				      (groupBackX + x0)];
+
+  for (x = x0; x <= x1; ++x) {
+
+    //----- shape
+    shape = *shapePtr;
+    if (!shape) {
+      destColorPtr += 3;
+      ++destAlphaPtr;
+      ++alpha0Ptr;
+      cSrcPtr += cSrcStride;
+      ++shapePtr;
+      continue;
+    }
+    lastX = x;
+
+    //----- read destination pixel
+    cDest0 = destColorPtr[2];
+    cDest1 = destColorPtr[1];
+    cDest2 = destColorPtr[0];
+    aDest = *destAlphaPtr;
+
+    //----- source color
+    cSrc0 = state->rgbTransferR[cSrcPtr[0]];
+    cSrc1 = state->rgbTransferG[cSrcPtr[1]];
+    cSrc2 = state->rgbTransferB[cSrcPtr[2]];
+
+    //----- source alpha
+    aSrc = div255(pipe->aInput * shape);
+
+    //----- result alpha and non-isolated group element correction
+    aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest));
+    alpha0 = *alpha0Ptr++;
+    alphaI = (Guchar)(aResult + alpha0 - div255(aResult * alpha0));
+
+    //----- result color
+    if (alphaI == 0) {
+      cResult0 = 0;
+      cResult1 = 0;
+      cResult2 = 0;
+    } else {
+      cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI);
+      cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI);
+      cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI);
+    }
+
+    //----- write destination pixel
+    destColorPtr[0] = cResult2;
+    destColorPtr[1] = cResult1;
+    destColorPtr[2] = cResult0;
+    destColorPtr += 3;
+    *destAlphaPtr++ = aResult;
+
+    cSrcPtr += cSrcStride;
+    ++shapePtr;
+  } // for (x ...)
+
+  updateModX(lastX);
+}
+
+#if SPLASH_CMYK
+void Splash::pipeRunNonIsoCMYK8(SplashPipe *pipe, int x0, int x1, int y,
+				Guchar *shapePtr, SplashColorPtr cSrcPtr) {
+  Guchar shape, aSrc, aDest, alphaI, alpha0, aResult, aPrev;
+  Guchar cSrc0, cSrc1, cSrc2, cSrc3;
+  Guchar cDest0, cDest1, cDest2, cDest3;
+  Guchar cResult0, cResult1, cResult2, cResult3;
+  SplashColorPtr destColorPtr;
+  Guchar *destAlphaPtr;
+  Guchar *alpha0Ptr;
+  int cSrcStride, x, lastX;
+
+  if (cSrcPtr) {
+    cSrcStride = 4;
+  } else {
+    cSrcPtr = pipe->cSrcVal;
+    cSrcStride = 0;
+  }
+  for (; x0 <= x1; ++x0) {
+    if (*shapePtr) {
+      break;
+    }
+    cSrcPtr += cSrcStride;
+    ++shapePtr;
+  }
+  if (x0 > x1) {
+    return;
+  }
+  updateModX(x0);
+  updateModY(y);
+  lastX = x0;
+
+  destColorPtr = &bitmap->data[y * bitmap->rowSize + x0 * 4];
+  destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0];
+  alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + y)
+				        * groupBackBitmap->alphaRowSize +
+				      (groupBackX + x0)];
+
+  for (x = x0; x <= x1; ++x) {
+
+    //----- shape
+    shape = *shapePtr;
+    if (!shape) {
+      destColorPtr += 4;
+      ++destAlphaPtr;
+      ++alpha0Ptr;
+      cSrcPtr += cSrcStride;
+      ++shapePtr;
+      continue;
+    }
+    lastX = x;
+
+    //----- read destination pixel
+    cDest0 = destColorPtr[0];
+    cDest1 = destColorPtr[1];
+    cDest2 = destColorPtr[2];
+    cDest3 = destColorPtr[3];
+    aDest = *destAlphaPtr;
+
+    //----- overprint
+    aPrev = (Guchar)(*alpha0Ptr + aDest - div255(*alpha0Ptr * aDest));
+    if (state->overprintMask & 0x01) {
+      cSrc0 = state->cmykTransferC[cSrcPtr[0]];
+    } else {
+      cSrc0 = div255(aPrev * cDest0);
+    }
+    if (state->overprintMask & 0x02) {
+      cSrc1 = state->cmykTransferM[cSrcPtr[1]];
+    } else {
+      cSrc1 = div255(aPrev * cDest1);
+    }
+    if (state->overprintMask & 0x04) {
+      cSrc2 = state->cmykTransferY[cSrcPtr[2]];
+    } else {
+      cSrc2 = div255(aPrev * cDest2);
+    }
+    if (state->overprintMask & 0x08) {
+      cSrc3 = state->cmykTransferK[cSrcPtr[3]];
+    } else {
+      cSrc3 = div255(aPrev * cDest3);
+    }
+
+    //----- source alpha
+    aSrc = div255(pipe->aInput * shape);
+
+    //----- result alpha and non-isolated group element correction
+    aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest));
+    alpha0 = *alpha0Ptr++;
+    alphaI = (Guchar)(aResult + alpha0 - div255(aResult * alpha0));
+
+    //----- result color
+    if (alphaI == 0) {
+      cResult0 = 0;
+      cResult1 = 0;
+      cResult2 = 0;
+      cResult3 = 0;
+    } else {
+      cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI);
+      cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI);
+      cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI);
+      cResult3 = (Guchar)(((alphaI - aSrc) * cDest3 + aSrc * cSrc3) / alphaI);
+    }
+
+    //----- write destination pixel
+    destColorPtr[0] = cResult0;
+    destColorPtr[1] = cResult1;
+    destColorPtr[2] = cResult2;
+    destColorPtr[3] = cResult3;
+    destColorPtr += 4;
+    *destAlphaPtr++ = aResult;
+
+    cSrcPtr += cSrcStride;
+    ++shapePtr;
+  } // for (x ...)
+
+  updateModX(lastX);
+}
+#endif
+
+
 //------------------------------------------------------------------------
 
 // Transform a point from user space to device space.
@@ -2000,10 +2423,41 @@
 }
 
 //------------------------------------------------------------------------
+// SplashImageCache
+//------------------------------------------------------------------------
+
+SplashImageCache::SplashImageCache() {
+  tag = NULL;
+  image = NULL;
+  refCount = 1;
+}
+
+SplashImageCache::~SplashImageCache() {
+  if (tag) {
+    delete tag;
+  }
+  if (image) {
+    delete image;
+  }
+}
+
+void SplashImageCache::incRefCount() {
+  ++refCount;
+}
+
+void SplashImageCache::decRefCount() {
+  --refCount;
+  if (refCount == 0) {
+    delete this;
+  }
+}
+
+//------------------------------------------------------------------------
 // Splash
 //------------------------------------------------------------------------
 
 Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
+	       SplashImageCache *imageCacheA,
 	       SplashScreenParams *screenParams) {
   bitmap = bitmapA;
   bitmapComps = splashColorModeNComps[bitmap->mode];
@@ -2021,10 +2475,17 @@
   minLineWidth = 0;
   clearModRegion();
   debugMode = gFalse;
+
+  if (imageCacheA) {
+    imageCache = imageCacheA;
+    imageCache->incRefCount();
+  } else {
+    imageCache = new SplashImageCache();
+  }
 }
 
 Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
-	       SplashScreen *screenA) {
+	       SplashImageCache *imageCacheA, SplashScreen *screenA) {
   bitmap = bitmapA;
   bitmapComps = splashColorModeNComps[bitmap->mode];
   vectorAntialias = vectorAntialiasA;
@@ -2041,9 +2502,18 @@
   minLineWidth = 0;
   clearModRegion();
   debugMode = gFalse;
+
+  if (imageCacheA) {
+    imageCache = imageCacheA;
+    imageCache->incRefCount();
+  } else {
+    imageCache = new SplashImageCache();
+  }
 }
 
 Splash::~Splash() {
+  imageCache->decRefCount();
+
   while (state->next) {
     restoreState();
   }
@@ -3335,6 +3805,30 @@
 void Splash::getImageBounds(SplashCoord xyMin, SplashCoord xyMax,
 			    int *xyMinI, int *xyMaxI) {
   if (state->strokeAdjust == splashStrokeAdjustOff) {
+    // make sure the coords fit in 32-bit ints
+#if USE_FIXEDPOINT
+    if (xyMin < -32767) {
+      xyMin = -32767;
+    } else if (xyMin > 32767) {
+      xyMin = 32767;
+    }
+    if (xyMax < -32767) {
+      xyMax = -32767;
+    } else if (xyMax > 32767) {
+      xyMax = 32767;
+    }
+#else
+    if (xyMin < -1e9) {
+      xyMin = -1e9;
+    } else if (xyMin > 1e9) {
+      xyMin = 1e9;
+    }
+    if (xyMax < -1e9) {
+      xyMax = -1e9;
+    } else if (xyMax > 1e9) {
+      xyMax = 1e9;
+    }
+#endif
     *xyMinI = splashFloor(xyMin);
     *xyMaxI = splashFloor(xyMax);
     if (*xyMaxI <= *xyMinI) {
@@ -3347,7 +3841,8 @@
 
 // The glyphMode flag is not currently used, but may be useful if the
 // stroke adjustment behavior is changed.
-SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
+SplashError Splash::fillImageMask(GString *imageTag,
+				  SplashImageMaskSource src, void *srcData,
 				  int w, int h, SplashCoord *mat,
 				  GBool glyphMode, GBool interpolate) {
   SplashBitmap *scaledMask;
@@ -3401,10 +3896,17 @@
     if (clipRes != splashClipAllOutside) {
       scaledWidth = x1 - x0;
       scaledHeight = y1 - y0;
-      scaledMask = scaleMask(src, srcData, w, h, scaledWidth, scaledHeight,
-			     interpolate);
+      scaledMask = scaleMask(imageTag, src, srcData, w, h,
+			     scaledWidth, scaledHeight, interpolate);
+      if (imageCache->vertFlip) {
+	vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+	imageCache->vertFlip = gFalse;
+      }
+      if (imageCache->horizFlip) {
+	horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+	imageCache->horizFlip = gFalse;
+      }
       blitMask(scaledMask, x0, y0, clipRes);
-      delete scaledMask;
     }
     
   // scaling plus vertical flip
@@ -3417,11 +3919,17 @@
     if (clipRes != splashClipAllOutside) {
       scaledWidth = x1 - x0;
       scaledHeight = y1 - y0;
-      scaledMask = scaleMask(src, srcData, w, h, scaledWidth, scaledHeight,
-			     interpolate);
-      vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+      scaledMask = scaleMask(imageTag, src, srcData, w, h,
+			     scaledWidth, scaledHeight, interpolate);
+      if (!imageCache->vertFlip) {
+	vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+	imageCache->vertFlip = gTrue;
+      }
+      if (imageCache->horizFlip) {
+	horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+	imageCache->horizFlip = gFalse;
+      }
       blitMask(scaledMask, x0, y0, clipRes);
-      delete scaledMask;
     }
 
   // scaling plus horizontal flip
@@ -3434,11 +3942,17 @@
     if (clipRes != splashClipAllOutside) {
       scaledWidth = x1 - x0;
       scaledHeight = y1 - y0;
-      scaledMask = scaleMask(src, srcData, w, h, scaledWidth, scaledHeight,
-			     interpolate);
-      horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+      scaledMask = scaleMask(imageTag, src, srcData, w, h,
+			     scaledWidth, scaledHeight, interpolate);
+      if (imageCache->vertFlip) {
+	vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+	imageCache->vertFlip = gFalse;
+      }
+      if (!imageCache->horizFlip) {
+	horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+	imageCache->horizFlip = gTrue;
+      }
       blitMask(scaledMask, x0, y0, clipRes);
-      delete scaledMask;
     }
 
   // scaling plus horizontal and vertical flips
@@ -3451,17 +3965,23 @@
     if (clipRes != splashClipAllOutside) {
       scaledWidth = x1 - x0;
       scaledHeight = y1 - y0;
-      scaledMask = scaleMask(src, srcData, w, h, scaledWidth, scaledHeight,
-			     interpolate);
-      vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
-      horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+      scaledMask = scaleMask(imageTag, src, srcData, w, h,
+			     scaledWidth, scaledHeight, interpolate);
+      if (!imageCache->vertFlip) {
+	vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+	imageCache->vertFlip = gTrue;
+      }
+      if (!imageCache->horizFlip) {
+	horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+	imageCache->horizFlip = gTrue;
+      }
       blitMask(scaledMask, x0, y0, clipRes);
-      delete scaledMask;
     }
 
   // all other cases
   } else {
-    arbitraryTransformMask(src, srcData, w, h, mat, glyphMode, interpolate);
+    arbitraryTransformMask(imageTag, src, srcData, w, h,
+			   mat, glyphMode, interpolate);
   }
 
   return splashOk;
@@ -3634,7 +4154,8 @@
 
 // The glyphMode flag is not currently used, but may be useful if the
 // stroke adjustment behavior is changed.
-void Splash::arbitraryTransformMask(SplashImageMaskSource src, void *srcData,
+void Splash::arbitraryTransformMask(GString *imageTag,
+				    SplashImageMaskSource src, void *srcData,
 				    int srcWidth, int srcHeight,
 				    SplashCoord *mat, GBool glyphMode,
 				    GBool interpolate) {
@@ -3727,8 +4248,16 @@
   ir11 = r00 / det;
 
   // scale the input image
-  scaledMask = scaleMask(src, srcData, srcWidth, srcHeight,
+  scaledMask = scaleMask(imageTag, src, srcData, srcWidth, srcHeight,
 			 scaledWidth, scaledHeight, interpolate);
+  if (imageCache->vertFlip) {
+    vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+    imageCache->vertFlip = gFalse;
+  }
+  if (imageCache->horizFlip) {
+    horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+    imageCache->horizFlip = gFalse;
+  }
 
   // construct the three sections
   i = 0;
@@ -3901,42 +4430,61 @@
       (this->*pipe.run)(&pipe, xa, xb - 1, y, scanBuf + xa, NULL);
     }
   }
-
-  delete scaledMask;
 }
 
 // Scale an image mask into a SplashBitmap.
-SplashBitmap *Splash::scaleMask(SplashImageMaskSource src, void *srcData,
+SplashBitmap *Splash::scaleMask(GString *imageTag,
+				SplashImageMaskSource src, void *srcData,
 				int srcWidth, int srcHeight,
 				int scaledWidth, int scaledHeight,
 				GBool interpolate) {
-  SplashBitmap *dest;
-
-  dest = new SplashBitmap(scaledWidth, scaledHeight, 1, splashModeMono8,
-			  gFalse);
+  if (imageCache->tag && imageTag &&
+      !imageCache->tag->cmp(imageTag) &&
+      imageCache->isMask &&
+      imageCache->width == scaledWidth &&
+      imageCache->height == scaledHeight &&
+      imageCache->interpolate == interpolate) {
+    return imageCache->image;
+  }
+  if (imageCache->tag) {
+    delete imageCache->tag;
+  }
+  if (imageCache->image) {
+    delete imageCache->image;
+  }
+  imageCache->tag = imageTag ? imageTag->copy() : (GString *)NULL;
+  imageCache->isMask = gTrue;
+  imageCache->width = scaledWidth;
+  imageCache->height = scaledHeight;
+  imageCache->interpolate = interpolate;
+  imageCache->vertFlip = gFalse;
+  imageCache->horizFlip = gFalse;
+  imageCache->image = new SplashBitmap(scaledWidth, scaledHeight,
+				       1, splashModeMono8, gFalse,
+				       gTrue, NULL);
   if (scaledHeight < srcHeight) {
     if (scaledWidth < srcWidth) {
       scaleMaskYdXd(src, srcData, srcWidth, srcHeight,
-		    scaledWidth, scaledHeight, dest);
+		    scaledWidth, scaledHeight, imageCache->image);
     } else {
       scaleMaskYdXu(src, srcData, srcWidth, srcHeight,
-		    scaledWidth, scaledHeight, dest);
+		    scaledWidth, scaledHeight, imageCache->image);
     }
   } else {
     if (scaledWidth < srcWidth) {
       scaleMaskYuXd(src, srcData, srcWidth, srcHeight,
-		    scaledWidth, scaledHeight, dest);
+		    scaledWidth, scaledHeight, imageCache->image);
     } else {
       if (interpolate) {
 	scaleMaskYuXuI(src, srcData, srcWidth, srcHeight,
-		       scaledWidth, scaledHeight, dest);
+		       scaledWidth, scaledHeight, imageCache->image);
       } else {
 	scaleMaskYuXu(src, srcData, srcWidth, srcHeight,
-		      scaledWidth, scaledHeight, dest);
+		      scaledWidth, scaledHeight, imageCache->image);
       }
     }
   }
-  return dest;
+  return imageCache->image;
 }
 
 void Splash::scaleMaskYdXd(SplashImageMaskSource src, void *srcData,
@@ -4009,7 +4557,7 @@
 	pix += pixBuf[xx++];
       }
       // (255 * pix) / xStep * yStep
-      pix = (pix * d) >> 23;
+      pix = (pix * d + (1 << 22)) >> 23;
 
       // store the pixel
       *destPtr++ = (Guchar)pix;
@@ -4083,7 +4631,7 @@
       // compute the final pixel
       pix = pixBuf[x];
       // (255 * pix) / yStep
-      pix = (pix * d) >> 23;
+      pix = (pix * d + (1 << 22)) >> 23;
 
       // store the pixel
       for (i = 0; i < xStep; ++i) {
@@ -4158,7 +4706,7 @@
 	pix += lineBuf[xx++];
       }
       // (255 * pix) / xStep
-      pix = (pix * d) >> 23;
+      pix = (pix * d + (1 << 22)) >> 23;
 
       // store the pixel
       for (i = 0; i < yStep; ++i) {
@@ -4403,7 +4951,8 @@
   }
 }
 
-SplashError Splash::drawImage(SplashImageSource src, void *srcData,
+SplashError Splash::drawImage(GString *imageTag,
+			      SplashImageSource src, void *srcData,
 			      SplashColorMode srcMode, GBool srcAlpha,
 			      int w, int h, SplashCoord *mat,
 			      GBool interpolate) {
@@ -4489,10 +5038,18 @@
     if (clipRes != splashClipAllOutside) {
       scaledWidth = x1 - x0;
       scaledHeight = y1 - y0;
-      scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha, w, h,
+      scaledImg = scaleImage(imageTag,
+			     src, srcData, srcMode, nComps, srcAlpha, w, h,
 			     scaledWidth, scaledHeight, interpolate);
+      if (imageCache->vertFlip) {
+	vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+	imageCache->vertFlip = gFalse;
+      }
+      if (imageCache->horizFlip) {
+	horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+	imageCache->horizFlip = gFalse;
+      }
       blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
-      delete scaledImg;
     }
     
   // scaling plus vertical flip
@@ -4505,11 +5062,18 @@
     if (clipRes != splashClipAllOutside) {
       scaledWidth = x1 - x0;
       scaledHeight = y1 - y0;
-      scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha, w, h,
+      scaledImg = scaleImage(imageTag,
+			     src, srcData, srcMode, nComps, srcAlpha, w, h,
 			     scaledWidth, scaledHeight, interpolate);
-      vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+      if (!imageCache->vertFlip) {
+	vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+	imageCache->vertFlip = gTrue;
+      }
+      if (imageCache->horizFlip) {
+	horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+	imageCache->horizFlip = gFalse;
+      }
       blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
-      delete scaledImg;
     }
 
   // scaling plus horizontal flip
@@ -4522,11 +5086,18 @@
     if (clipRes != splashClipAllOutside) {
       scaledWidth = x1 - x0;
       scaledHeight = y1 - y0;
-      scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha, w, h,
+      scaledImg = scaleImage(imageTag,
+			     src, srcData, srcMode, nComps, srcAlpha, w, h,
 			     scaledWidth, scaledHeight, interpolate);
-      horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+      if (imageCache->vertFlip) {
+	vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+	imageCache->vertFlip = gFalse;
+      }
+      if (!imageCache->horizFlip) {
+	horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+	imageCache->horizFlip = gTrue;
+      }
       blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
-      delete scaledImg;
     }
     
   // scaling plus horizontal and vertical flips
@@ -4539,17 +5110,23 @@
     if (clipRes != splashClipAllOutside) {
       scaledWidth = x1 - x0;
       scaledHeight = y1 - y0;
-      scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha, w, h,
+      scaledImg = scaleImage(imageTag,
+			     src, srcData, srcMode, nComps, srcAlpha, w, h,
 			     scaledWidth, scaledHeight, interpolate);
-      vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
-      horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+      if (!imageCache->vertFlip) {
+	vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+	imageCache->vertFlip = gTrue;
+      }
+      if (!imageCache->horizFlip) {
+	horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+	imageCache->horizFlip = gTrue;
+      }
       blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
-      delete scaledImg;
     }
 
   // all other cases
   } else {
-    arbitraryTransformImage(src, srcData, srcMode, nComps, srcAlpha,
+    arbitraryTransformImage(imageTag, src, srcData, srcMode, nComps, srcAlpha,
 			    w, h, mat, interpolate);
   }
 
@@ -4765,7 +5342,8 @@
   gfree(unscaledAlpha);
 }
 
-void Splash::arbitraryTransformImage(SplashImageSource src, void *srcData,
+void Splash::arbitraryTransformImage(GString *imageTag,
+				     SplashImageSource src, void *srcData,
 				     SplashColorMode srcMode, int nComps,
 				     GBool srcAlpha,
 				     int srcWidth, int srcHeight,
@@ -4860,9 +5438,17 @@
   ir11 = r00 / det;
 
   // scale the input image
-  scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha,
+  scaledImg = scaleImage(imageTag, src, srcData, srcMode, nComps, srcAlpha,
 			 srcWidth, srcHeight, scaledWidth, scaledHeight,
 			 interpolate);
+  if (imageCache->vertFlip) {
+    vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+    imageCache->vertFlip = gFalse;
+  }
+  if (imageCache->horizFlip) {
+    horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+    imageCache->horizFlip = gFalse;
+  }
 
   // construct the three sections
   i = 0;
@@ -5045,41 +5631,70 @@
   }
 
   gfree(pixelBuf);
-  delete scaledImg;
 }
 
 // Scale an image into a SplashBitmap.
-SplashBitmap *Splash::scaleImage(SplashImageSource src, void *srcData,
+SplashBitmap *Splash::scaleImage(GString *imageTag,
+				 SplashImageSource src, void *srcData,
 				 SplashColorMode srcMode, int nComps,
 				 GBool srcAlpha, int srcWidth, int srcHeight,
 				 int scaledWidth, int scaledHeight,
 				 GBool interpolate) {
-  SplashBitmap *dest;
-
-  dest = new SplashBitmap(scaledWidth, scaledHeight, 1, srcMode, srcAlpha);
+  if (imageCache->tag && imageTag &&
+      !imageCache->tag->cmp(imageTag) &&
+      !imageCache->isMask &&
+      imageCache->width == scaledWidth &&
+      imageCache->height == scaledHeight &&
+      imageCache->mode == srcMode &&
+      imageCache->alpha == srcAlpha &&
+      imageCache->interpolate == interpolate) {
+    return imageCache->image;
+  }
+  if (imageCache->tag) {
+    delete imageCache->tag;
+  }
+  if (imageCache->image) {
+    delete imageCache->image;
+  }
+  imageCache->tag = imageTag ? imageTag->copy() : (GString *)NULL;
+  imageCache->isMask = gFalse;
+  imageCache->width = scaledWidth;
+  imageCache->height = scaledHeight;
+  imageCache->mode = srcMode;
+  imageCache->alpha = srcAlpha;
+  imageCache->interpolate = interpolate;
+  imageCache->vertFlip = gFalse;
+  imageCache->horizFlip = gFalse;
+  imageCache->image = new SplashBitmap(scaledWidth, scaledHeight, 1,
+				       srcMode, srcAlpha, gTrue, NULL);
   if (scaledHeight < srcHeight) {
     if (scaledWidth < srcWidth) {
       scaleImageYdXd(src, srcData, srcMode, nComps, srcAlpha,
-		     srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+		     srcWidth, srcHeight, scaledWidth, scaledHeight,
+		     imageCache->image);
     } else {
       scaleImageYdXu(src, srcData, srcMode, nComps, srcAlpha,
-		     srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+		     srcWidth, srcHeight, scaledWidth, scaledHeight,
+		     imageCache->image);
     }
   } else {
     if (scaledWidth < srcWidth) {
       scaleImageYuXd(src, srcData, srcMode, nComps, srcAlpha,
-		     srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+		     srcWidth, srcHeight, scaledWidth, scaledHeight,
+		     imageCache->image);
     } else {
       if (interpolate) {
 	scaleImageYuXuI(src, srcData, srcMode, nComps, srcAlpha,
-			srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+			srcWidth, srcHeight, scaledWidth, scaledHeight,
+			imageCache->image);
       } else {
 	scaleImageYuXu(src, srcData, srcMode, nComps, srcAlpha,
-		       srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+		       srcWidth, srcHeight, scaledWidth, scaledHeight,
+		       imageCache->image);
       }
     }
   }
-  return dest;
+  return imageCache->image;
 }
 
 void Splash::scaleImageYdXd(SplashImageSource src, void *srcData,
@@ -5177,7 +5792,7 @@
 	  pix0 += pixBuf[xx++];
 	}
 	// pix / xStep * yStep
-	pix0 = (pix0 * d) >> 23;
+	pix0 = (pix0 * d + (1 << 22)) >> 23;
 
 	// store the pixel
 	*destPtr++ = (Guchar)pix0;
@@ -5194,9 +5809,9 @@
 	  xx += 3;
 	}
 	// pix / xStep * yStep
-	pix0 = (pix0 * d) >> 23;
-	pix1 = (pix1 * d) >> 23;
-	pix2 = (pix2 * d) >> 23;
+	pix0 = (pix0 * d + (1 << 22)) >> 23;
+	pix1 = (pix1 * d + (1 << 22)) >> 23;
+	pix2 = (pix2 * d + (1 << 22)) >> 23;
 
 	// store the pixel
 	*destPtr++ = (Guchar)pix0;
@@ -5217,10 +5832,10 @@
 	  xx += 4;
 	}
 	// pix / xStep * yStep
-	pix0 = (pix0 * d) >> 23;
-	pix1 = (pix1 * d) >> 23;
-	pix2 = (pix2 * d) >> 23;
-	pix3 = (pix3 * d) >> 23;
+	pix0 = (pix0 * d + (1 << 22)) >> 23;
+	pix1 = (pix1 * d + (1 << 22)) >> 23;
+	pix2 = (pix2 * d + (1 << 22)) >> 23;
+	pix3 = (pix3 * d + (1 << 22)) >> 23;
 
 	// store the pixel
 	*destPtr++ = (Guchar)pix0;
@@ -5244,7 +5859,7 @@
 	  alpha += alphaPixBuf[xxa];
 	}
 	// alpha / xStep * yStep
-	alpha = (alpha * d) >> 23;
+	alpha = (alpha * d + (1 << 22)) >> 23;
 	*destAlphaPtr++ = (Guchar)alpha;
       }
     }
@@ -5343,7 +5958,7 @@
       // compute the final pixel
       for (i = 0; i < nComps; ++i) {
 	// pixBuf[] / yStep
-	pix[i] = (pixBuf[x * nComps + i] * d) >> 23;
+	pix[i] = (pixBuf[x * nComps + i] * d + (1 << 22)) >> 23;
       }
 
       // store the pixel
@@ -5379,7 +5994,7 @@
       // process alpha
       if (srcAlpha) {
 	// alphaPixBuf[] / yStep
-	alpha = (alphaPixBuf[x] * d) >> 23;
+	alpha = (alphaPixBuf[x] * d + (1 << 22)) >> 23;
 	for (i = 0; i < xStep; ++i) {
 	  *destAlphaPtr++ = (Guchar)alpha;
 	}
@@ -5474,7 +6089,7 @@
       }
       for (i = 0; i < nComps; ++i) {
 	// pix[] / xStep
-	pix[i] = (pix[i] * d) >> 23;
+	pix[i] = (pix[i] * d + (1 << 22)) >> 23;
       }
 
       // store the pixel
@@ -5517,7 +6132,7 @@
 	  alpha += alphaLineBuf[xxa];
 	}
 	// alpha / xStep
-	alpha = (alpha * d) >> 23;
+	alpha = (alpha * d + (1 << 22)) >> 23;
 	for (i = 0; i < yStep; ++i) {
 	  destAlphaPtr = destAlphaPtr0 + i * scaledWidth + x;
 	  *destAlphaPtr = (Guchar)alpha;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -18,6 +18,7 @@
 #include "SplashTypes.h"
 #include "SplashClip.h"
 
+class GString;
 class Splash;
 class SplashBitmap;
 struct SplashGlyphBitmap;
@@ -65,6 +66,34 @@
 };
 
 //------------------------------------------------------------------------
+// SplashImageCache
+//------------------------------------------------------------------------
+
+// This holds a cached image, and is shared by multiple Splash objects
+// in the same thread.
+class SplashImageCache {
+public:
+
+  SplashImageCache();
+  ~SplashImageCache();
+  void incRefCount();
+  void decRefCount();
+
+  GString *tag;
+  GBool isMask;
+  int width;
+  int height;
+  SplashColorMode mode;
+  GBool alpha;
+  GBool interpolate;
+  GBool vertFlip;
+  GBool horizFlip;
+  SplashBitmap *image;
+
+  int refCount;
+};
+
+//------------------------------------------------------------------------
 // Splash
 //------------------------------------------------------------------------
 
@@ -73,9 +102,10 @@
 
   // Create a new rasterizer object.
   Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
+	 SplashImageCache *imageCacheA,
 	 SplashScreenParams *screenParams = NULL);
   Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
-	 SplashScreen *screenA);
+	 SplashImageCache *imageCacheA, SplashScreen *screenA);
 
   ~Splash();
 
@@ -173,7 +203,8 @@
   // Note that the Splash y axis points downward, and the image source
   // is assumed to produce pixels in raster order, starting from the
   // top line.
-  SplashError fillImageMask(SplashImageMaskSource src, void *srcData,
+  SplashError fillImageMask(GString *imageTag,
+			    SplashImageMaskSource src, void *srcData,
 			    int w, int h, SplashCoord *mat,
 			    GBool glyphMode, GBool interpolate);
 
@@ -191,7 +222,8 @@
   //    BGR8         RGB8
   //    CMYK8        CMYK8
   // The matrix behaves as for fillImageMask.
-  SplashError drawImage(SplashImageSource src, void *srcData,
+  SplashError drawImage(GString *imageTag,
+			SplashImageSource src, void *srcData,
 			SplashColorMode srcMode, GBool srcAlpha,
 			int w, int h, SplashCoord *mat,
 			GBool interpolate);
@@ -255,6 +287,8 @@
   // Toggle debug mode on or off.
   void setDebugMode(GBool debugModeA) { debugMode = debugModeA; }
 
+  SplashImageCache *getImageCache() { return imageCache; }
+
 #if 1 //~tmp: turn off anti-aliasing temporarily
   void setInShading(GBool sh) { inShading = sh; }
 #endif
@@ -303,6 +337,16 @@
   void pipeRunAACMYK8(SplashPipe *pipe, int x0, int x1, int y,
 		      Guchar *shapePtr, SplashColorPtr cSrcPtr);
 #endif
+  void pipeRunNonIsoMono8(SplashPipe *pipe, int x0, int x1, int y,
+			  Guchar *shapePtr, SplashColorPtr cSrcPtr);
+  void pipeRunNonIsoRGB8(SplashPipe *pipe, int x0, int x1, int y,
+			 Guchar *shapePtr, SplashColorPtr cSrcPtr);
+  void pipeRunNonIsoBGR8(SplashPipe *pipe, int x0, int x1, int y,
+			 Guchar *shapePtr, SplashColorPtr cSrcPtr);
+#if SPLASH_CMYK
+  void pipeRunNonIsoCMYK8(SplashPipe *pipe, int x0, int x1, int y,
+			  Guchar *shapePtr, SplashColorPtr cSrcPtr);
+#endif
   void transform(SplashCoord *matrix, SplashCoord xi, SplashCoord yi,
 		 SplashCoord *xo, SplashCoord *yo);
   void updateModX(int x);
@@ -331,11 +375,13 @@
 		   int srcWidth, int srcHeight,
 		   SplashCoord *mat, GBool glyphMode,
 		   GBool interpolate);
-  void arbitraryTransformMask(SplashImageMaskSource src, void *srcData,
+  void arbitraryTransformMask(GString *imageTag,
+			      SplashImageMaskSource src, void *srcData,
 			      int srcWidth, int srcHeight,
 			      SplashCoord *mat, GBool glyphMode,
 			      GBool interpolate);
-  SplashBitmap *scaleMask(SplashImageMaskSource src, void *srcData,
+  SplashBitmap *scaleMask(GString *imageTag,
+			  SplashImageMaskSource src, void *srcData,
 			  int srcWidth, int srcHeight,
 			  int scaledWidth, int scaledHeight,
 			  GBool interpolate);
@@ -365,12 +411,14 @@
 		    SplashColorMode srcMode, int nComps,
 		    GBool srcAlpha, int srcWidth, int srcHeight,
 		    SplashCoord *mat, GBool interpolate);
-  void arbitraryTransformImage(SplashImageSource src, void *srcData,
+  void arbitraryTransformImage(GString *imageTag,
+			       SplashImageSource src, void *srcData,
 			       SplashColorMode srcMode, int nComps,
 			       GBool srcAlpha,
 			       int srcWidth, int srcHeight,
 			       SplashCoord *mat, GBool interpolate);
-  SplashBitmap *scaleImage(SplashImageSource src, void *srcData,
+  SplashBitmap *scaleImage(GString *imageTag,
+			   SplashImageSource src, void *srcData,
 			   SplashColorMode srcMode, int nComps,
 			   GBool srcAlpha, int srcWidth, int srcHeight,
 			   int scaledWidth, int scaledHeight,
@@ -432,6 +480,8 @@
   GBool vectorAntialias;
   GBool inShading;
   GBool debugMode;
+
+  SplashImageCache *imageCache;
 };
 
 #endif

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -25,7 +25,7 @@
 
 SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
 			   SplashColorMode modeA, GBool alphaA,
-			   GBool topDown) {
+			   GBool topDown, SplashBitmap *parentA) {
   // NB: this code checks that rowSize fits in a signed 32-bit
   // integer, because some code (outside this class) makes that
   // assumption
@@ -63,7 +63,21 @@
   }
   rowSize += rowPad - 1;
   rowSize -= rowSize % rowPad;
-  data = (SplashColorPtr)gmallocn64(height, rowSize);
+
+  parent = parentA;
+  oldData = NULL;
+  oldAlpha = NULL;
+  oldRowSize = 0;
+  oldAlphaRowSize = 0;
+  oldHeight = 0;
+  if (parent && parent->oldData &&
+      parent->oldRowSize == rowSize &&
+      parent->oldHeight == height) {
+    data = parent->oldData;
+    parent->oldData = NULL;
+  } else {
+    data = (SplashColorPtr)gmallocn64(height, rowSize);
+  }
   if (!topDown) {
     data += (height - 1) * rowSize;
     rowSize = -rowSize;
@@ -70,7 +84,14 @@
   }
   if (alphaA) {
     alphaRowSize = width;
-    alpha = (Guchar *)gmallocn64(height, alphaRowSize);
+    if (parent && parent->oldAlpha &&
+	parent->oldAlphaRowSize == alphaRowSize &&
+	parent->oldHeight == height) {
+      alpha = parent->oldAlpha;
+      parent->oldAlpha = NULL;
+    } else {
+      alpha = (Guchar *)gmallocn64(height, alphaRowSize);
+    }
   } else {
     alphaRowSize = 0;
     alpha = NULL;
@@ -78,14 +99,24 @@
 }
 
 SplashBitmap::~SplashBitmap() {
-  if (data) {
-    if (rowSize < 0) {
-      gfree(data + (height - 1) * rowSize);
-    } else {
-      gfree(data);
-    }
+  if (data && rowSize < 0) {
+    rowSize = -rowSize;
+    data -= (height - 1) * rowSize;
   }
-  gfree(alpha);
+  if (parent && rowSize > 10000000 / height) {
+    gfree(parent->oldData);
+    gfree(parent->oldAlpha);
+    parent->oldData = data;
+    parent->oldAlpha = alpha;
+    parent->oldRowSize = rowSize;
+    parent->oldAlphaRowSize = alphaRowSize;
+    parent->oldHeight = height;
+  } else {
+    gfree(data);
+    gfree(alpha);
+  }
+  gfree(oldData);
+  gfree(oldAlpha);
 }
 
 SplashError SplashBitmap::writePNMFile(char *fileName) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -44,7 +44,7 @@
   // upside-down, i.e., with the last row first in memory.
   SplashBitmap(int widthA, int heightA, int rowPad,
 	       SplashColorMode modeA, GBool alphaA,
-	       GBool topDown = gTrue);
+	       GBool topDown, SplashBitmap *parentA);
 
   ~SplashBitmap();
 
@@ -79,6 +79,14 @@
   Guchar *alpha;		// pointer to row zero of the alpha data
 				//   (always top-down)
 
+  // save the last-allocated (large) bitmap data and reuse if possible
+  SplashBitmap *parent;
+  SplashColorPtr oldData;
+  Guchar *oldAlpha;
+  SplashBitmapRowSize oldRowSize;
+  size_t oldAlphaRowSize;
+  int oldHeight;
+
   friend class Splash;
 };
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -132,10 +132,14 @@
 						 char *fileName,
 						 GBool deleteFile,
 #endif
+						 int *codeToGID,
 						 const char **enc) {
   SplashFontFile *fontFile;
 
   fontFile = NULL;
+  if (!fontFile) {
+    gfree(codeToGID);
+  }
 #if HAVE_FREETYPE_H
   if (!fontFile && ftEngine) {
     fontFile = ftEngine->loadType1CFont(idA,
@@ -168,10 +172,14 @@
 						      char *fileName,
 						      GBool deleteFile,
 #endif
+						      int *codeToGID,
 						      const char **enc) {
   SplashFontFile *fontFile;
 
   fontFile = NULL;
+  if (!fontFile) {
+    gfree(codeToGID);
+  }
 #if HAVE_FREETYPE_H
   if (!fontFile && ftEngine) {
     fontFile = ftEngine->loadOpenTypeT1CFont(idA,
@@ -221,6 +229,10 @@
   }
 #endif
 
+  if (!fontFile) {
+    gfree(codeToGID);
+  }
+
 #if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__)
   // delete the (temporary) font file -- with Unix hard link
   // semantics, this will remove the last link; otherwise it will
@@ -258,6 +270,10 @@
   }
 #endif
 
+  if (!fontFile) {
+    gfree(codeToGID);
+  }
+
 #if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__)
   // delete the (temporary) font file -- with Unix hard link
   // semantics, this will remove the last link; otherwise it will

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -68,7 +68,7 @@
 #else
 				 char *fileName, GBool deleteFile,
 #endif
-				 const char **enc);
+				 int *codeToGID, const char **enc);
   SplashFontFile *loadOpenTypeT1CFont(SplashFontFileID *idA,
 #if LOAD_FONTS_FROM_MEM
 				      GString *fontBuf,
@@ -75,7 +75,7 @@
 #else
 				      char *fileName, GBool deleteFile,
 #endif
-				      const char **enc);
+				      int *codeToGID, const char **enc);
   SplashFontFile *loadCIDFont(SplashFontFileID *idA,
 #if LOAD_FONTS_FROM_MEM
 			      GString *fontBuf,

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -47,17 +47,13 @@
   // NB: 64-bit x86 guarantees availability of SSE2.
 
   __m128d m1, m2;
-  __m128i m3;
-  int s, i;
+  int i, s;
 
-  m1 = _mm_set_sd(x);		// m1 = x
-  i = _mm_cvttsd_si32(m1);	// i = trunc(x)
-  m2 = _mm_cvtsi32_sd(m1, i);	// m2 = (double)trunc(x)
-  m1 = _mm_sub_sd(m1, m2);	// m1 = x - trunc(x)
-  m3 = _mm_castpd_si128(m1); 	// m3 = m1 (as 64-bit int)
-  m3 = _mm_srli_epi64(m3, 63);	// m3 = m3 >> 63
-  s = _mm_cvtsi128_si32(m3);	// s = m3 = sign bit of x - trunc(x)
-  return i - s;			// trunc(x) - sign bit
+  m1 = _mm_set_sd(x);
+  i = _mm_cvttsd_si32(m1);
+  m2 = _mm_cvtsi32_sd(m1, i);
+  s = _mm_ucomigt_sd(m2, m1);
+  return i - s;
 
 #elif defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__)
 
@@ -123,17 +119,13 @@
   // NB: 64-bit x86 guarantees availability of SSE2.
 
   __m128d m1, m2;
-  __m128i m3;
-  int s, i;
+  int i, s;
 
-  m1 = _mm_set_sd(x);		// m1 = x
-  i = _mm_cvttsd_si32(m1);	// i = trunc(x)
-  m2 = _mm_cvtsi32_sd(m1, i);	// m2 = (double)trunc(x)
-  m2 = _mm_sub_sd(m2, m1);	// m2 = trunc(x) - x
-  m3 = _mm_castpd_si128(m2); 	// m3 = m2 (as 64-bit int)
-  m3 = _mm_srli_epi64(m3, 63);	// m3 = m3 >> 63
-  s = _mm_cvtsi128_si32(m3);	// s = m3 = sign bit of x - trunc(x)
-  return i + s;			// trunc(x) + sign bit
+  m1 = _mm_set_sd(x);
+  i = _mm_cvttsd_si32(m1);
+  m2 = _mm_cvtsi32_sd(m1, i);
+  s = _mm_ucomilt_sd(m2, m1);
+  return i + s;
 
 #elif defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__)
 
@@ -315,6 +307,31 @@
 				      SplashCoord w = -1) {
   int x0, x1;
 
+  // make sure the coords fit in 32-bit ints
+#if USE_FIXEDPOINT
+  if (xMin < -32767) {
+    xMin = -32767;
+  } else if (xMin > 32767) {
+    xMin = 32767;
+  }
+  if (xMax < -32767) {
+    xMax = -32767;
+  } else if (xMax > 32767) {
+    xMax = 32767;
+  }
+#else
+  if (xMin < -1e9) {
+    xMin = -1e9;
+  } else if (xMin > 1e9) {
+    xMin = 1e9;
+  }
+  if (xMax < -1e9) {
+    xMax = -1e9;
+  } else if (xMax > 1e9) {
+    xMax = 1e9;
+  }
+#endif
+
   // this will never be called with strokeAdjMode == splashStrokeAdjustOff
   if (strokeAdjMode == splashStrokeAdjustCAD) {
     x0 = splashRound(xMin);

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -247,7 +247,7 @@
     x2 = pts[hint->ctrl1    ].x;    y2 = pts[hint->ctrl1    ].y;
     x3 = pts[hint->ctrl1 + 1].x;    y3 = pts[hint->ctrl1 + 1].y;
     w = -1;
-    if (x0 == x1 && x2 == x3) {
+    if (splashAbs(x0 - x1) < 0.01 && splashAbs(x2 - x3) < 0.01) {
       adjusts[i].vert = gTrue;
       adj0 = x0;
       adj1 = x2;
@@ -254,7 +254,7 @@
       if (hint->projectingCap) {
 	w = splashAbs(y1 - y0);
       }
-    } else if (y0 == y1 && y2 == y3) {
+    } else if (splashAbs(y0 - y1) < 0.01 && splashAbs(y2 - y3) < 0.01) {
       adjusts[i].vert = gFalse;
       adj0 = y0;
       adj1 = y2;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1542,10 +1542,11 @@
     fontSize = atof(tok->getCString());
   } else {
     error(errSyntaxError, -1, "Missing 'Tf' operator in field's DA string");
-    fontSize = 10;
+    fontSize = 0;
     if (!daToks) {
       daToks = new GList();
     }
+    tfPos = daToks->getLength();
     daToks->append(new GString("/xpdf_default_font"));
     daToks->append(new GString("10"));
     daToks->append(new GString("Tf"));
@@ -1583,7 +1584,7 @@
 
     // compute font autosize
     if (fontSize == 0) {
-      for (fontSize = 20; fontSize > 1; --fontSize) {
+      for (fontSize = 10; fontSize > 1; --fontSize) {
 	y = dy - 3;
 	w2 = 0;
 	i = 0;
@@ -1596,7 +1597,7 @@
 	  y -= fontSize;
 	}
 	// approximate the descender for the last line
-	if (y >= 0.33 * fontSize) {
+	if (y >= 0.33 * fontSize && w <= wMax) {
 	  break;
 	}
       }
@@ -1697,6 +1698,9 @@
 	  fontSize = w;
 	}
 	fontSize = floor(fontSize);
+	if (fontSize > 10) {
+	  fontSize = 10;
+	}
 	if (tfPos >= 0) {
 	  tok = (GString *)daToks->get(tfPos + 1);
 	  tok->clear();
@@ -1783,6 +1787,9 @@
 	  fontSize = fontSize2;
 	}
 	fontSize = floor(fontSize);
+	if (fontSize > 10) {
+	  fontSize = 10;
+	}
 	if (tfPos >= 0) {
 	  tok = (GString *)daToks->get(tfPos + 1);
 	  tok->clear();
@@ -1936,6 +1943,9 @@
       fontSize = fontSize2;
     }
     fontSize = floor(fontSize);
+    if (fontSize > 10) {
+      fontSize = 10;
+    }
     if (tfPos >= 0) {
       tok = (GString *)daToks->get(tfPos + 1);
       tok->clear();

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -845,7 +845,7 @@
   if (!colorObj->isArray()) {
     return gFalse;
   }
-  for (i = 0; i < colorObj->arrayGetLength(); ++i) {
+  for (i = 0; i < colorObj->arrayGetLength() && i < 4; ++i) {
     if (colorObj->arrayGet(i, &obj)->isNum()) {
       color[i] = obj.getNum();
     } else {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -51,6 +51,7 @@
       return gTrue;
     }
   }
+  *width = 0;
   return gFalse;
 }
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt	2019-09-29 10:00:12 UTC (rev 52203)
@@ -111,7 +111,9 @@
                         ${PAPER_LIBRARY}
                         ${FREETYPE_LIBRARY} ${FREETYPE_OTHER_LIBS}
                         ${DTYPE_LIBRARY}
-                        ${LCMS_LIBRARY})
+                        ${LCMS_LIBRARY}
+                        ${FONTCONFIG_LIBRARY}
+                        ${CMAKE_THREAD_LIBS_INIT})
 else ()
   add_executable(pdftops
     $<TARGET_OBJECTS:xpdf_objs>
@@ -119,7 +121,11 @@
     PSOutputDev.cc
     pdftops.cc
   )
-  target_link_libraries(pdftops goo fofi ${PAPER_LIBRARY} ${LCMS_LIBRARY})
+  target_link_libraries(pdftops goo fofi
+                        ${PAPER_LIBRARY}
+                        ${LCMS_LIBRARY}
+                        ${FONTCONFIG_LIBRARY}
+                        ${CMAKE_THREAD_LIBS_INIT})
 endif ()
 install(TARGETS pdftops RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftops.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
@@ -131,7 +137,11 @@
   TextOutputDev.cc
   pdftotext.cc
 )
-target_link_libraries(pdftotext goo fofi ${PAPER_LIBRARY} ${LCMS_LIBRARY})
+target_link_libraries(pdftotext goo fofi
+                      ${PAPER_LIBRARY}
+                      ${LCMS_LIBRARY}
+                      ${FONTCONFIG_LIBRARY}
+                      ${CMAKE_THREAD_LIBS_INIT})
 install(TARGETS pdftotext RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftotext.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
 
@@ -143,6 +153,7 @@
     HTMLGen.cc
     SplashOutputDev.cc
     TextOutputDev.cc
+    WebFont.cc
     pdftohtml.cc
   )
   target_link_libraries(pdftohtml goo fofi splash
@@ -149,7 +160,10 @@
                         ${PAPER_LIBRARY}
                         ${FREETYPE_LIBRARY} ${FREETYPE_OTHER_LIBS}
                         ${DTYPE_LIBRARY}
-                        ${LCMS_LIBRARY} ${PNG_LIBRARIES})
+                        ${LCMS_LIBRARY}
+                        ${PNG_LIBRARIES}
+                        ${FONTCONFIG_LIBRARY}
+                        ${CMAKE_THREAD_LIBS_INIT})
   install(TARGETS pdftohtml RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
   install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftohtml.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
 endif ()
@@ -160,7 +174,11 @@
   $<TARGET_OBJECTS:xpdf_objs>
   pdfinfo.cc
 )
-target_link_libraries(pdfinfo goo fofi ${PAPER_LIBRARY} ${LCMS_LIBRARY})
+target_link_libraries(pdfinfo goo fofi
+                      ${PAPER_LIBRARY}
+                      ${LCMS_LIBRARY}
+                      ${FONTCONFIG_LIBRARY}
+                      ${CMAKE_THREAD_LIBS_INIT})
 install(TARGETS pdfinfo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 install(FILES ${PROJECT_SOURCE_DIR}/doc/pdfinfo.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
 
@@ -170,7 +188,11 @@
   $<TARGET_OBJECTS:xpdf_objs>
   pdffonts.cc
 )
-target_link_libraries(pdffonts goo fofi ${PAPER_LIBRARY} ${LCMS_LIBRARY})
+target_link_libraries(pdffonts goo fofi
+                      ${PAPER_LIBRARY}
+                      ${LCMS_LIBRARY}
+                      ${FONTCONFIG_LIBRARY}
+                      ${CMAKE_THREAD_LIBS_INIT})
 install(TARGETS pdffonts RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 install(FILES ${PROJECT_SOURCE_DIR}/doc/pdffonts.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
 
@@ -180,7 +202,11 @@
   $<TARGET_OBJECTS:xpdf_objs>
   pdfdetach.cc
 )
-target_link_libraries(pdfdetach goo fofi ${PAPER_LIBRARY} ${LCMS_LIBRARY})
+target_link_libraries(pdfdetach goo fofi
+                      ${PAPER_LIBRARY}
+                      ${LCMS_LIBRARY}
+                      ${FONTCONFIG_LIBRARY}
+                      ${CMAKE_THREAD_LIBS_INIT})
 install(TARGETS pdfdetach RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 install(FILES ${PROJECT_SOURCE_DIR}/doc/pdfdetach.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
 
@@ -196,7 +222,9 @@
                         ${PAPER_LIBRARY}
                         ${FREETYPE_LIBRARY} ${FREETYPE_OTHER_LIBS}
                         ${DTYPE_LIBRARY}
-                        ${LCMS_LIBRARY})
+                        ${LCMS_LIBRARY}
+                        ${FONTCONFIG_LIBRARY}
+                        ${CMAKE_THREAD_LIBS_INIT})
   install(TARGETS pdftoppm RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
   install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftoppm.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
 endif ()
@@ -213,7 +241,10 @@
                         ${PAPER_LIBRARY}
                         ${FREETYPE_LIBRARY} ${FREETYPE_OTHER_LIBS}
                         ${DTYPE_LIBRARY}
-                        ${LCMS_LIBRARY} ${PNG_LIBRARIES})
+                        ${LCMS_LIBRARY}
+                        ${PNG_LIBRARIES}
+                        ${FONTCONFIG_LIBRARY}
+                        ${CMAKE_THREAD_LIBS_INIT})
   install(TARGETS pdftopng RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
   install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftopng.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
 endif ()
@@ -225,7 +256,11 @@
   ImageOutputDev.cc
   pdfimages.cc
 )
-target_link_libraries(pdfimages goo fofi ${PAPER_LIBRARY} ${LCMS_LIBRARY})
+target_link_libraries(pdfimages goo fofi
+                      ${PAPER_LIBRARY}
+                      ${LCMS_LIBRARY}
+                      ${FONTCONFIG_LIBRARY}
+                      ${CMAKE_THREAD_LIBS_INIT})
 install(TARGETS pdfimages RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 install(FILES ${PROJECT_SOURCE_DIR}/doc/pdfimages.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -89,6 +89,59 @@
 }
 
 //------------------------------------------------------------------------
+// PageLabelNode
+//------------------------------------------------------------------------
+
+class PageLabelNode {
+public:
+
+  PageLabelNode(int firstPageA, Dict *dict);
+  ~PageLabelNode();
+
+  int firstPage;		// first page number covered by this node
+  int lastPage;			// last page number covered by this node
+  TextString *prefix;		// label prefix (may be empty)
+  int start;			// value of the numeric portion of this
+				//   label for the first page in the range
+  char style;			// page label style
+};
+
+PageLabelNode::PageLabelNode(int firstPageA, Dict *dict) {
+  Object prefixObj, styleObj, startObj;
+
+  // convert page index to page number
+  firstPage = firstPageA + 1;
+
+  // lastPage will be filled in later
+  lastPage = -1;
+
+  if (dict->lookup("P", &prefixObj)->isString()) {
+    prefix = new TextString(prefixObj.getString());
+  } else {
+    prefix = new TextString();
+  }
+  prefixObj.free();
+
+  style = '\0';
+  if (dict->lookup("S", &styleObj)->isName()) {
+    if (strlen(styleObj.getName()) == 1) {
+      style = styleObj.getName()[0];
+    }
+  }
+  styleObj.free();
+
+  start = 1;
+  if (dict->lookup("St", &startObj)->isInt()) {
+    start = startObj.getInt();
+  }
+  startObj.free();
+}
+
+PageLabelNode::~PageLabelNode() {
+  delete prefix;
+}
+
+//------------------------------------------------------------------------
 // Catalog
 //------------------------------------------------------------------------
 
@@ -185,6 +238,15 @@
   // get the list of embedded files
   readEmbeddedFileList(catDict.getDict());
 
+  // get the ViewerPreferences object
+  catDict.dictLookupNF("ViewerPreferences", &viewerPrefs);
+
+  pageLabels = NULL;
+  if (catDict.dictLookup("PageLabels", &obj)->isDict()) {
+    readPageLabelTree(&obj);
+  }
+  obj.free();
+
   catDict.free();
   return;
 
@@ -229,6 +291,10 @@
   if (embeddedFiles) {
     deleteGList(embeddedFiles, EmbeddedFile);
   }
+  if (pageLabels) {
+    deleteGList(pageLabels, PageLabelNode);
+  }
+  viewerPrefs.free();
 }
 
 Page *Catalog::getPage(int i) {
@@ -833,107 +899,45 @@
   return strObj;
 }
 
-TextString *Catalog::getPageLabel(int pageNum) {
-  Object catDict, node, pageLabelObj, start, prefix, style;
-  GString *label, *s;
-  TextString *ts;
-  int firstPageIndex, pageRangeNum;
+void Catalog::readPageLabelTree(Object *root) {
+  PageLabelNode *label0, *label1;
+  int i;
 
-  if (!xref->getCatalog(&catDict)->isDict()) {
-    catDict.free();
-    return NULL;
+  pageLabels = new GList();
+  readPageLabelTree2(root);
+
+  if (pageLabels->getLength() == 0) {
+    deleteGList(pageLabels, PageLabelNode);
+    pageLabels = NULL;
+    return;
   }
 
-  label = NULL;
-  catDict.dictLookup("PageLabels", &node);
-  if (findPageLabel(&node, pageNum - 1, &pageLabelObj, &firstPageIndex)) {
-    if (pageLabelObj.isDict()) {
-      if (pageLabelObj.dictLookup("P", &prefix)->isString()) {
-	label = prefix.getString()->copy();
-      } else {
-	label = new GString();
-      }
-      prefix.free();
-
-      pageRangeNum = pageNum - firstPageIndex;
-      if (pageLabelObj.dictLookup("St", &start)->isInt()) {
-	pageRangeNum += start.getInt() - 1;
-      }
-      start.free();
-
-      if (pageLabelObj.dictLookup("S", &style)->isName()) {
-	if (style.isName("D")) {
-	  label->appendf("{0:d}", pageRangeNum);
-	} else if (style.isName("R")) {
-	  s = makeRomanNumeral(pageRangeNum, gTrue);
-	  label->append(s);
-	  delete s;
-	} else if (style.isName("r"))  {
-	  s = makeRomanNumeral(pageRangeNum, gFalse);
-	  label->append(s);
-	  delete s;
-	} else if (style.isName("A"))  {
-	  s = makeLetterLabel(pageRangeNum, gTrue);
-	  label->append(s);
-	  delete s;
-	} else if (style.isName("a"))  {
-	  s = makeLetterLabel(pageRangeNum, gFalse);
-	  label->append(s);
-	  delete s;
-	}
-      }
-      style.free();
-    }
-    pageLabelObj.free();
+  // set lastPage in each node
+  label0 = (PageLabelNode *)pageLabels->get(0);
+  for (i = 1; i < pageLabels->getLength(); ++i) {
+    label1 = (PageLabelNode *)pageLabels->get(i);
+    label0->lastPage = label1->firstPage - 1;
+    label0 = label1;
   }
-  node.free();
-  catDict.free();
-
-  ts = new TextString(label);
-  delete label;
-  return ts;
+  label0->lastPage = numPages;
 }
 
-GBool Catalog::findPageLabel(Object *node, int pageIndex,
-			     Object *pageLabelObj, int *firstPageIndex) {
-  Object limits, limit, nums, num, kids, kid;
+void Catalog::readPageLabelTree2(Object *node) {
+  Object nums, num, labelObj, kids, kid;
   int i;
 
   if (!node->isDict()) {
-    return gFalse;
+    return;
   }
 
-  // we only check the lower limit because page labels are organized
-  // into ranges based on their first page number -- the Nums and Kids
-  // arrays are searched backward for the same reason
-  if (node->dictLookup("Limits", &limits)->isArray() &&
-      limits.arrayGetLength() == 2)  {
-    if (limits.arrayGet(0, &limit)->isInt()) {
-      if (pageIndex < limit.getInt()) {
-	limit.free();
-	limits.free();
-	return gFalse;
-      }
-    }
-    limit.free();
-  }
-  limits.free();
-
   if (node->dictLookup("Nums", &nums)->isArray()) {
-    for (i = nums.arrayGetLength() / 2 - 1; i >= 0; --i) {
-      if (nums.arrayGet(2*i, &num)->isInt()) {
-	if (num.getInt() <= pageIndex) {
-	  nums.arrayGet(2*i + 1, pageLabelObj);
-	  *firstPageIndex = num.getInt();
-	  num.free();
-	  nums.free();
-	  return gTrue;
+    for (i = 0; i < nums.arrayGetLength() - 1; i += 2) {
+      if (nums.arrayGet(i, &num)->isInt()) {
+	if (nums.arrayGet(i+1, &labelObj)->isDict()) {
+	  pageLabels->append(new PageLabelNode(num.getInt(),
+					       labelObj.getDict()));
 	}
-      } else {
-	error(errSyntaxError, -1, "Invalid key in page label number tree");
-	num.free();
-	nums.free();
-	return gFalse;
+	labelObj.free();
       }
       num.free();
     }
@@ -941,22 +945,63 @@
   nums.free();
 
   if (node->dictLookup("Kids", &kids)->isArray()) {
-    for (i = kids.arrayGetLength() - 1; i >= 0; --i) {
-      if (kids.arrayGet(i, &kid)->isDict()) {
-	if (findPageLabel(&kid, pageIndex, pageLabelObj, firstPageIndex)) {
-	  kid.free();
-	  kids.free();
-	  return gTrue;
-	}
-      }
+    for (i = 0; i < kids.arrayGetLength(); ++i) {
+      kids.arrayGet(i, &kid);
+      readPageLabelTree2(&kid);
       kid.free();
     }
   }
   kids.free();
+}
 
-  return gFalse;
+TextString *Catalog::getPageLabel(int pageNum) {
+  PageLabelNode *label;
+  TextString *ts;
+  int pageRangeNum;
+  GString *suffix;
+
+  if (!pageLabels || !(label = findPageLabel(pageNum))) {
+    return NULL;
+  }
+
+  ts = new TextString(label->prefix);
+
+  pageRangeNum = label->start + (pageNum - label->firstPage);
+
+  suffix = NULL;
+  if (label->style == 'D') {
+    suffix = GString::format("{0:d}", pageRangeNum);
+  } else if (label->style == 'R') {
+    suffix = makeRomanNumeral(pageRangeNum, gTrue);
+  } else if (label->style == 'r') {
+    suffix = makeRomanNumeral(pageRangeNum, gFalse);
+  } else if (label->style == 'A') {
+    suffix = makeLetterLabel(pageRangeNum, gTrue);
+  } else if (label->style == 'a') {
+    suffix = makeLetterLabel(pageRangeNum, gFalse);
+  }
+  if (suffix) {
+    ts->append(suffix);
+    delete suffix;
+  }
+
+  return ts;
 }
 
+PageLabelNode *Catalog::findPageLabel(int pageNum) {
+  PageLabelNode *label;
+  int i;
+
+  //~ this could use a binary search
+  for (i = 0; i < pageLabels->getLength(); ++i) {
+    label = (PageLabelNode *)pageLabels->get(i);
+    if (pageNum >= label->firstPage && pageNum <= label->lastPage) {
+      return label;
+    }
+  }
+  return NULL;
+}
+
 GString *Catalog::makeRomanNumeral(int num, GBool uppercase) {
   GString *s;
 
@@ -1022,3 +1067,131 @@
   }
   return s;
 }
+
+int Catalog::getPageNumFromPageLabel(TextString *pageLabel) {
+  PageLabelNode *label;
+  int pageNum, prefixLength, i, n;
+
+  if (!pageLabels) {
+    return -1;
+  }
+  for (i = 0; i < pageLabels->getLength(); ++i) {
+    label = (PageLabelNode *)pageLabels->get(i);
+    prefixLength = label->prefix->getLength();
+    if (pageLabel->getLength() < prefixLength ||
+	memcmp(pageLabel->getUnicode(), label->prefix->getUnicode(),
+	       prefixLength * sizeof(Unicode))) {
+      continue;
+    }
+    if (label->style == '\0' && pageLabel->getLength() == prefixLength) {
+      return label->firstPage;
+    }
+    if (!convertPageLabelToInt(pageLabel, prefixLength, label->style, &n)) {
+      continue;
+    }
+    if (n < label->start) {
+      continue;
+    }
+    pageNum = label->firstPage + n - label->start;
+    if (pageNum <= label->lastPage) {
+      return pageNum;
+    }
+  }
+  return -1;
+}
+
+// Attempts to convert pageLabel[prefixLength .. end] to an integer,
+// following the specified page label style.  If successful, sets *n
+// and returns true; else returns false.
+GBool Catalog::convertPageLabelToInt(TextString *pageLabel, int prefixLength,
+				     char style, int *n) {
+  Unicode *u;
+  Unicode delta;
+  int len, i;
+
+  len = pageLabel->getLength();
+  if (len <= prefixLength) {
+    return gFalse;
+  }
+  u = pageLabel->getUnicode();
+  if (style == 'D') {
+    *n = 0;
+    for (i = prefixLength; i < len; ++i) {
+      if (u[i] < (Unicode)'0' || u[i] > (Unicode)'9') {
+	return gFalse;
+      }
+      *n = *n * 10 + (u[i] - (Unicode)'0');
+    }
+    return gTrue;
+  } else if (style == 'R' || style == 'r') {
+    delta = style - 'R';
+    *n = 0;
+    i = prefixLength;
+    while (i < len && u[i] == (Unicode)'M' + delta) {
+      *n += 1000;
+      ++i;
+    }
+    if (i+1 < len && u[i] == (Unicode)'C' + delta &&
+	u[i+1] == (Unicode)'M' + delta) {
+      *n += 900;
+      i += 2;
+    } else if (i < len && u[i] == (Unicode)'D' + delta) {
+      *n += 500;
+      ++i;
+    } else if (i+1 < len && u[i] == (Unicode)'C' + delta &&
+	       u[i+1] == (Unicode)'D' + delta) {
+      *n += 400;
+      i += 2;
+    }
+    while (i < len && u[i] == (Unicode)'C' + delta) {
+      *n += 100;
+      ++i;
+    }
+    if (i+1 < len && u[i] == (Unicode)'X' + delta &&
+	u[i+1] == (Unicode)'C' + delta) {
+      *n += 90;
+      i += 2;
+    } else if (i < len && u[i] == (Unicode)'L' + delta) {
+      *n += 50;
+      ++i;
+    } else if (i+1 < len && u[i] == (Unicode)'X' + delta &&
+	       u[i+1] == (Unicode)'L' + delta) {
+      *n += 40;
+      i += 2;
+    }
+    while (i < len && u[i] == (Unicode)'X' + delta) {
+      *n += 10;
+      ++i;
+    }
+    if (i+1 < len && u[i] == (Unicode)'I' + delta &&
+	u[i+1] == (Unicode)'X' + delta) {
+      *n += 9;
+      i += 2;
+    } else if (i < len && u[i] == (Unicode)'V' + delta) {
+      *n += 5;
+      ++i;
+    } else if (i+1 < len && u[i] == (Unicode)'I' + delta &&
+	       u[i+1] == (Unicode)'V' + delta) {
+      *n += 4;
+      i += 2;
+    }
+    while (i < len && u[i] == (Unicode)'I' + delta) {
+      *n += 1;
+      ++i;
+    }
+    return i == len;
+  } else if (style == 'A' || style == 'a') {
+    if (u[prefixLength] < (Unicode)style ||
+	u[prefixLength] > (Unicode)style + 25) {
+      return gFalse;
+    }
+    for (i = prefixLength + 1; i < len; ++i) {
+      if (u[i] != u[prefixLength]) {
+	return gFalse;
+      }
+    }
+    *n = (len - prefixLength - 1) * 26 + (u[i] - (Unicode)style) + 1;
+    return gTrue;
+  }
+  return gFalse;
+}

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -29,6 +29,7 @@
 struct Ref;
 class LinkDest;
 class PageTreeNode;
+class PageLabelNode;
 class Form;
 class TextString;
 
@@ -103,10 +104,20 @@
   Object *getEmbeddedFileStreamRef(int idx);
   Object *getEmbeddedFileStreamObj(int idx, Object *strObj);
 
+  // Return true if the document has page labels.
+  GBool hasPageLabels() { return pageLabels != NULL; }
+
   // Get the page label for page number [pageNum].  Returns NULL if
   // the PDF file doesn't have page labels.
   TextString *getPageLabel(int pageNum);
 
+  // Returns the page number corresponding to [pageLabel].  Returns -1
+  // if there is no matching page label, or if the document doesn't
+  // have page labels.
+  int getPageNumFromPageLabel(TextString *pageLabel);
+
+  Object *getViewerPreferences() { return &viewerPrefs; }
+
 private:
 
   PDFDoc *doc;
@@ -129,6 +140,8 @@
   Form *form;			// parsed form
   Object ocProperties;		// OCProperties dictionary
   GList *embeddedFiles;		// embedded file list [EmbeddedFile]
+  GList *pageLabels;		// page labels [PageLabelNode]
+  Object viewerPrefs;		// ViewerPreferences object
   GBool ok;			// true if catalog is valid
 
   Object *findDestInTree(Object *tree, GString *name, Object *obj);
@@ -141,10 +154,13 @@
   void readFileAttachmentAnnots(Object *pageNodeRef,
 				char *touchedObjs);
   void readEmbeddedFile(Object *fileSpec, Object *name1);
-  GBool findPageLabel(Object *node, int pageIndex,
-		      Object *pageLabelObj, int *firstPageIndex);
+  void readPageLabelTree(Object *root);
+  void readPageLabelTree2(Object *node);
+  PageLabelNode *findPageLabel(int pageNum);
   GString *makeRomanNumeral(int num, GBool uppercase);
   GString *makeLetterLabel(int num, GBool uppercase);
+  GBool convertPageLabelToInt(TextString *pageLabel, int prefixLength,
+			      char style, int *n);
 };
 
 #endif

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -41,7 +41,8 @@
 Function::~Function() {
 }
 
-Function *Function::parse(Object *funcObj, int recursion) {
+Function *Function::parse(Object *funcObj, int expectedInputs,
+			  int expectedOutputs, int recursion) {
   Function *func;
   Dict *dict;
   int funcType;
@@ -57,7 +58,11 @@
   } else if (funcObj->isDict()) {
     dict = funcObj->getDict();
   } else if (funcObj->isName("Identity")) {
-    return new IdentityFunction();
+    if (expectedInputs != expectedOutputs) {
+      error(errSyntaxError, -1, "Invalid use of identity function");
+      return NULL;
+    }
+    return new IdentityFunction(expectedInputs);
   } else {
     error(errSyntaxError, -1, "Expected function dictionary or stream");
     return NULL;
@@ -76,7 +81,8 @@
   } else if (funcType == 2) {
     func = new ExponentialFunction(funcObj, dict);
   } else if (funcType == 3) {
-    func = new StitchingFunction(funcObj, dict, recursion);
+    func = new StitchingFunction(funcObj, dict, expectedInputs,
+				 expectedOutputs, recursion);
   } else if (funcType == 4) {
     func = new PostScriptFunction(funcObj, dict);
   } else {
@@ -88,6 +94,14 @@
     return NULL;
   }
 
+  if (func->getInputSize() != expectedInputs ||
+      (expectedOutputs >= 0 && func->getOutputSize() != expectedOutputs)) {
+    error(errSyntaxError, -1,
+	  "Incorrect number of function inputs or outputs");
+    delete func;
+    return NULL;
+  }
+
   return func;
 }
 
@@ -169,14 +183,12 @@
 // IdentityFunction
 //------------------------------------------------------------------------
 
-IdentityFunction::IdentityFunction() {
+IdentityFunction::IdentityFunction(int nInputs) {
   int i;
 
-  // fill these in with arbitrary values just in case they get used
-  // somewhere
-  m = funcMaxInputs;
-  n = funcMaxOutputs;
-  for (i = 0; i < funcMaxInputs; ++i) {
+  m = n = nInputs;
+  // domain info shouldn't be used anywhere
+  for (i = 0; i < nInputs; ++i) {
     domain[i][0] = 0;
     domain[i][1] = 1;
   }
@@ -189,7 +201,7 @@
 void IdentityFunction::transform(double *in, double *out) {
   int i;
 
-  for (i = 0; i < funcMaxOutputs; ++i) {
+  for (i = 0; i < m; ++i) {
     out[i] = in[i];
   }
 }
@@ -347,8 +359,13 @@
 
   //----- samples
   nSamples = n;
-  for (i = 0; i < m; ++i)
+  for (i = 0; i < m; ++i) {
+    if (nSamples > INT_MAX / sampleSize[i]) {
+      error(errSyntaxError, -1, "Integer overflow in sampled function setup");
+      goto err1;
+    }
     nSamples *= sampleSize[i];
+  }
   samples = (double *)gmallocn(nSamples, sizeof(double));
   buf = 0;
   bits = 0;
@@ -623,6 +640,7 @@
 //------------------------------------------------------------------------
 
 StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict,
+				     int expectedInputs, int expectedOutputs,
 				     int recursion) {
   Object obj1, obj2;
   int i;
@@ -643,7 +661,8 @@
   }
 
   //----- Functions
-  if (!dict->lookup("Functions", &obj1)->isArray()) {
+  if (!dict->lookup("Functions", &obj1)->isArray() ||
+      obj1.arrayGetLength() < 1) {
     error(errSyntaxError, -1,
 	  "Missing 'Functions' entry in stitching function");
     goto err1;
@@ -658,11 +677,14 @@
   }
   for (i = 0; i < k; ++i) {
     if (!(funcs[i] = Function::parse(obj1.arrayGet(i, &obj2),
+				     expectedInputs, expectedOutputs,
 				     recursion + 1))) {
       goto err2;
     }
-    if (funcs[i]->getInputSize() != 1 ||
-	(i > 0 && funcs[i]->getOutputSize() != funcs[0]->getOutputSize())) {
+    if (i == 0) {
+      n = funcs[0]->getOutputSize();
+    }
+    if (funcs[i]->getInputSize() != 1 || funcs[i]->getOutputSize() != n) {
       error(errSyntaxError, -1,
 	    "Incompatible subfunctions in stitching function");
       goto err2;
@@ -1305,6 +1327,9 @@
       if (sp + 1 >= psStackSize) {
 	goto underflow;
       }
+      if (stack[sp] == 0) {
+	goto invalidArg;
+      }
       stack[sp + 1] = stack[sp + 1] / stack[sp];
       ++sp;
       break;
@@ -1371,7 +1396,11 @@
       if (sp + 1 >= psStackSize) {
 	goto underflow;
       }
-      stack[sp + 1] = (int)stack[sp + 1] / (int)stack[sp];
+      k = (int)stack[sp];
+      if (k == 0) {
+	goto invalidArg;
+      }
+      stack[sp + 1] = (int)stack[sp + 1] / k;
       ++sp;
       break;
     case psOpIndex:
@@ -1417,7 +1446,11 @@
       if (sp + 1 >= psStackSize) {
 	goto underflow;
       }
-      stack[sp + 1] = (int)stack[sp + 1] % (int)stack[sp];
+      k = (int)stack[sp];
+      if (k == 0) {
+	goto invalidArg;
+      }
+      stack[sp + 1] = (int)stack[sp + 1] % k;
       ++sp;
       break;
     case psOpMul:
@@ -1468,23 +1501,25 @@
       if (nn < 0) {
 	goto invalidArg;
       }
-      if (sp + nn > psStackSize) {
-	goto underflow;
-      }
-      if (k >= 0) {
-	k %= nn;
-      } else {
-	k = -k % nn;
-	if (k) {
-	  k = nn - k;
+      if (nn > 0) {
+	if (sp + nn > psStackSize) {
+	  goto underflow;
 	}
+	if (k >= 0) {
+	  k %= nn;
+	} else {
+	  k = -k % nn;
+	  if (k) {
+	    k = nn - k;
+	  }
+	}
+	for (i = 0; i < nn; ++i) {
+	  tmp[i] = stack[sp + i];
+	}
+	for (i = 0; i < nn; ++i) {
+	  stack[sp + i] = tmp[(i + k) % nn];
+	}
       }
-      for (i = 0; i < nn; ++i) {
-	tmp[i] = stack[sp + i];
-      }
-      for (i = 0; i < nn; ++i) {
-	stack[sp + i] = tmp[(i + k) % nn];
-      }
       break;
     case psOpRound:
       if (sp >= psStackSize) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -38,8 +38,11 @@
 
   virtual ~Function();
 
-  // Construct a function.  Returns NULL if unsuccessful.
-  static Function *parse(Object *funcObj, int recursion = 0);
+  // Construct a function, with [expectedInputs] inputs and
+  // [expectedOutputs] outputs.  [expectedOutputs] can be -1 to
+  // indicate unknown.  Returns NULL if unsuccessful.
+  static Function *parse(Object *funcObj, int expectedInputs,
+			 int expectedOutputs, int recursion = 0);
 
   // Initialize the entries common to all function types.
   GBool init(Dict *dict);
@@ -86,9 +89,9 @@
 class IdentityFunction: public Function {
 public:
 
-  IdentityFunction();
+  IdentityFunction(int nInputs);
   virtual ~IdentityFunction();
-  virtual Function *copy() { return new IdentityFunction(); }
+  virtual Function *copy() { return new IdentityFunction(m); }
   virtual int getType() { return -1; }
   virtual void transform(double *in, double *out);
   virtual GBool isOk() { return gTrue; }
@@ -173,7 +176,8 @@
 class StitchingFunction: public Function {
 public:
 
-  StitchingFunction(Object *funcObj, Dict *dict, int recursion);
+  StitchingFunction(Object *funcObj, Dict *dict, int expectedInputs,
+		    int expectedOutputs, int recursion);
   virtual ~StitchingFunction();
   virtual Function *copy() { return new StitchingFunction(this); }
   virtual int getType() { return 3; }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -919,12 +919,24 @@
 }
 
 void Gfx::opSetLineJoin(Object args[], int numArgs) {
-  state->setLineJoin(args[0].getInt());
+  int lineJoin;
+
+  lineJoin = args[0].getInt();
+  if (lineJoin < 0 || lineJoin > 2) {
+    lineJoin = 0;
+  }
+  state->setLineJoin(lineJoin);
   out->updateLineJoin(state);
 }
 
 void Gfx::opSetLineCap(Object args[], int numArgs) {
-  state->setLineCap(args[0].getInt());
+  int lineCap;
+
+  lineCap = args[0].getInt();
+  if (lineCap < 0 || lineCap > 2) {
+    lineCap = 0;
+  }
+  state->setLineCap(lineCap);
   out->updateLineCap(state);
 }
 
@@ -1041,17 +1053,17 @@
 
   // fill/stroke overprint, overprint mode
   if ((haveFillOP = (obj1.dictLookup("op", &obj2)->isBool()))) {
-    if (!state->getInCachedT3Char()) {
+    if (!state->getIgnoreColorOps()) {
       state->setFillOverprint(obj2.getBool());
       out->updateFillOverprint(state);
     } else {
-      error(errSyntaxWarning, getPos(),
-	    "Ignoring overprint setting in cached Type 3 character");
+      error(errSyntaxWarning, getPos(), "Ignoring overprint setting"
+	    " in uncolored Type 3 char or tiling pattern");
     }
   }
   obj2.free();
   if (obj1.dictLookup("OP", &obj2)->isBool()) {
-    if (!state->getInCachedT3Char()) {
+    if (!state->getIgnoreColorOps()) {
       state->setStrokeOverprint(obj2.getBool());
       out->updateStrokeOverprint(state);
       if (!haveFillOP) {
@@ -1059,18 +1071,18 @@
 	out->updateFillOverprint(state);
       }
     } else {
-      error(errSyntaxWarning, getPos(),
-	    "Ignoring overprint setting in cached Type 3 character");
+      error(errSyntaxWarning, getPos(), "Ignoring overprint setting"
+	    " in uncolored Type 3 char or tiling pattern");
     }
   }
   obj2.free();
   if (obj1.dictLookup("OPM", &obj2)->isInt()) {
-    if (!state->getInCachedT3Char()) {
+    if (!state->getIgnoreColorOps()) {
       state->setOverprintMode(obj2.getInt());
       out->updateOverprintMode(state);
     } else {
-      error(errSyntaxWarning, getPos(),
-	    "Ignoring overprint setting in cached Type 3 character");
+      error(errSyntaxWarning, getPos(), "Ignoring overprint setting"
+	    " in uncolored Type 3 char or tiling pattern");
     }
   }
   obj2.free();
@@ -1088,7 +1100,7 @@
     obj1.dictLookup("TR", &obj2);
   }
   if (!obj2.isNull()) {
-    if (!state->getInCachedT3Char()) {
+    if (!state->getIgnoreColorOps()) {
       if (obj2.isName("Default") ||
 	  obj2.isName("Identity")) {
 	funcs[0] = funcs[1] = funcs[2] = funcs[3] = NULL;
@@ -1097,7 +1109,7 @@
       } else if (obj2.isArray() && obj2.arrayGetLength() == 4) {
 	for (i = 0; i < 4; ++i) {
 	  obj2.arrayGet(i, &obj3);
-	  funcs[i] = Function::parse(&obj3);
+	  funcs[i] = Function::parse(&obj3, 1, 1);
 	  obj3.free();
 	  if (!funcs[i]) {
 	    break;
@@ -1108,7 +1120,7 @@
 	  out->updateTransfer(state);
 	}
       } else if (obj2.isName() || obj2.isDict() || obj2.isStream()) {
-	if ((funcs[0] = Function::parse(&obj2))) {
+	if ((funcs[0] = Function::parse(&obj2, 1, 1))) {
 	  funcs[1] = funcs[2] = funcs[3] = NULL;
 	  state->setTransfer(funcs);
 	  out->updateTransfer(state);
@@ -1118,8 +1130,8 @@
 	      "Invalid transfer function in ExtGState");
       }
     } else {
-      error(errSyntaxWarning, getPos(),
-	    "Ignoring transfer function setting in cached Type 3 character");
+      error(errSyntaxWarning, getPos(), "Ignoring transfer function setting"
+	    " in uncolored Type 3 char or tiling pattern");
     }
   }
   obj2.free();
@@ -1129,10 +1141,15 @@
     if (obj2.isName("None")) {
       out->clearSoftMask(state);
     } else if (obj2.isDict()) {
-      if (obj2.dictLookup("S", &obj3)->isName("Alpha")) {
+      obj2.dictLookup("S", &obj3);
+      if (obj3.isName("Alpha")) {
 	alpha = gTrue;
-      } else { // "Luminosity"
+      } else if (obj3.isName("Luminosity")) {
 	alpha = gFalse;
+      } else {
+	error(errSyntaxError, getPos(),
+	      "Missing S (subtype) entry in soft mask");
+	alpha = gFalse;
       }
       obj3.free();
       funcs[0] = NULL;
@@ -1141,9 +1158,7 @@
 	    obj3.isName("Identity")) {
 	  funcs[0] = NULL;
 	} else {
-	  funcs[0] = Function::parse(&obj3);
-	  if (funcs[0]->getInputSize() != 1 ||
-	      funcs[0]->getOutputSize() != 1) {
+	  if (!(funcs[0] = Function::parse(&obj3, 1, 1))) {
 	    error(errSyntaxError, getPos(),
 		  "Invalid transfer function in soft mask in ExtGState");
 	    delete funcs[0];
@@ -1290,9 +1305,9 @@
 void Gfx::opSetRenderingIntent(Object args[], int numArgs) {
   GfxRenderingIntent ri;
 
-  if (state->getInCachedT3Char()) {
-    error(errSyntaxWarning, getPos(),
-	  "Ignoring rendering intent setting in cached Type 3 character");
+  if (state->getIgnoreColorOps()) {
+    error(errSyntaxWarning, getPos(), "Ignoring rendering intent setting"
+	  " in uncolored Type 3 char or tiling pattern");
     return;
   }
   ri = parseRenderingIntent(args[0].getName());
@@ -1320,9 +1335,9 @@
 void Gfx::opSetFillGray(Object args[], int numArgs) {
   GfxColor color;
 
-  if (state->getInCachedT3Char()) {
-    error(errSyntaxWarning, getPos(),
-	  "Ignoring color setting in cached Type 3 character");
+  if (state->getIgnoreColorOps()) {
+    error(errSyntaxWarning, getPos(), "Ignoring color setting"
+	  " in uncolored Type 3 char or tiling pattern");
     return;
   }
   state->setFillPattern(NULL);
@@ -1336,9 +1351,9 @@
 void Gfx::opSetStrokeGray(Object args[], int numArgs) {
   GfxColor color;
 
-  if (state->getInCachedT3Char()) {
-    error(errSyntaxWarning, getPos(),
-	  "Ignoring color setting in cached Type 3 character");
+  if (state->getIgnoreColorOps()) {
+    error(errSyntaxWarning, getPos(), "Ignoring color setting"
+	  " in uncolored Type 3 char or tiling pattern");
     return;
   }
   state->setStrokePattern(NULL);
@@ -1353,9 +1368,9 @@
   GfxColor color;
   int i;
 
-  if (state->getInCachedT3Char()) {
-    error(errSyntaxWarning, getPos(),
-	  "Ignoring color setting in cached Type 3 character");
+  if (state->getIgnoreColorOps()) {
+    error(errSyntaxWarning, getPos(), "Ignoring color setting"
+	  " in uncolored Type 3 char or tiling pattern");
     return;
   }
   state->setFillPattern(NULL);
@@ -1372,9 +1387,9 @@
   GfxColor color;
   int i;
 
-  if (state->getInCachedT3Char()) {
-    error(errSyntaxWarning, getPos(),
-	  "Ignoring color setting in cached Type 3 character");
+  if (state->getIgnoreColorOps()) {
+    error(errSyntaxWarning, getPos(), "Ignoring color setting"
+	  " in uncolored Type 3 char or tiling pattern");
     return;
   }
   state->setStrokePattern(NULL);
@@ -1391,9 +1406,9 @@
   GfxColor color;
   int i;
 
-  if (state->getInCachedT3Char()) {
-    error(errSyntaxWarning, getPos(),
-	  "Ignoring color setting in cached Type 3 character");
+  if (state->getIgnoreColorOps()) {
+    error(errSyntaxWarning, getPos(), "Ignoring color setting"
+	  " in uncolored Type 3 char or tiling pattern");
     return;
   }
   state->setFillPattern(NULL);
@@ -1410,9 +1425,9 @@
   GfxColor color;
   int i;
 
-  if (state->getInCachedT3Char()) {
-    error(errSyntaxWarning, getPos(),
-	  "Ignoring color setting in cached Type 3 character");
+  if (state->getIgnoreColorOps()) {
+    error(errSyntaxWarning, getPos(), "Ignoring color setting"
+	  " in uncolored Type 3 char or tiling pattern");
     return;
   }
   state->setStrokePattern(NULL);
@@ -1430,9 +1445,9 @@
   GfxColorSpace *colorSpace;
   GfxColor color;
 
-  if (state->getInCachedT3Char()) {
-    error(errSyntaxWarning, getPos(),
-	  "Ignoring color space setting in cached Type 3 character");
+  if (state->getIgnoreColorOps()) {
+    error(errSyntaxWarning, getPos(), "Ignoring color space setting"
+	  " in uncolored Type 3 char or tiling pattern");
     return;
   }
   state->setFillPattern(NULL);
@@ -1461,9 +1476,9 @@
   GfxColorSpace *colorSpace;
   GfxColor color;
 
-  if (state->getInCachedT3Char()) {
-    error(errSyntaxWarning, getPos(),
-	  "Ignoring color space setting in cached Type 3 character");
+  if (state->getIgnoreColorOps()) {
+    error(errSyntaxWarning, getPos(), "Ignoring color space setting"
+	  " in uncolored Type 3 char or tiling pattern");
     return;
   }
   state->setStrokePattern(NULL);
@@ -1491,9 +1506,9 @@
   GfxColor color;
   int i;
 
-  if (state->getInCachedT3Char()) {
-    error(errSyntaxWarning, getPos(),
-	  "Ignoring color setting in cached Type 3 character");
+  if (state->getIgnoreColorOps()) {
+    error(errSyntaxWarning, getPos(), "Ignoring color setting"
+	  " in uncolored Type 3 char or tiling pattern");
     return;
   }
   if (numArgs != state->getFillColorSpace()->getNComps()) {
@@ -1531,9 +1546,9 @@
   GfxPattern *pattern;
   int i;
 
-  if (state->getInCachedT3Char()) {
-    error(errSyntaxWarning, getPos(),
-	  "Ignoring color setting in cached Type 3 character");
+  if (state->getIgnoreColorOps()) {
+    error(errSyntaxWarning, getPos(), "Ignoring color setting"
+	  " in uncolored Type 3 char or tiling pattern");
     return;
   }
   if (state->getFillColorSpace()->getMode() == csPattern) {
@@ -1585,9 +1600,9 @@
   GfxPattern *pattern;
   int i;
 
-  if (state->getInCachedT3Char()) {
-    error(errSyntaxWarning, getPos(),
-	  "Ignoring color setting in cached Type 3 character");
+  if (state->getIgnoreColorOps()) {
+    error(errSyntaxWarning, getPos(), "Ignoring color setting"
+	  " in uncolored Type 3 char or tiling pattern");
     return;
   }
   if (state->getStrokeColorSpace()->getMode() == csPattern) {
@@ -2068,6 +2083,7 @@
     state->setStrokeColor(state->getFillColor());
     out->updateFillColor(state);
     out->updateStrokeColor(state);
+    state->setIgnoreColorOps(gTrue);
   } else {
     state->setFillColorSpace(GfxColorSpace::create(csDeviceGray));
     out->updateFillColorSpace(state);
@@ -2223,6 +2239,7 @@
   if (stroke) {
     state->clipToStrokePath();
     out->clipToStrokePath(state);
+    state->setFillOverprint(state->getStrokeOverprint());
   } else if (!text) {
     state->clip();
     if (eoFill) {
@@ -2241,6 +2258,7 @@
   det = ctm[0] * ctm[3] - ctm[1] * ctm[2];
   if (fabs(det) <= 1e-10) {
     error(errSyntaxError, getPos(), "Singular matrix in shading pattern fill");
+    restoreStateStack(savedState);
     return;
   }
   det = 1 / det;
@@ -2338,9 +2356,9 @@
   GfxState *savedState;
   double xMin, yMin, xMax, yMax;
 
-  if (state->getInCachedT3Char()) {
-    error(errSyntaxWarning, getPos(),
-	  "Ignoring shaded fill in cached Type 3 character");
+  if (state->getIgnoreColorOps()) {
+    error(errSyntaxWarning, getPos(), "Ignoring shaded fill"
+	  " in uncolored Type 3 char or tiling pattern");
     return;
   }
 
@@ -4123,7 +4141,7 @@
   ocState = ocSaved;
 }
 
-void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
+GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
   Dict *dict, *maskDict;
   int width, height;
   int bits, maskBits;
@@ -4145,7 +4163,7 @@
 
   // check for optional content
   if (!ocState && !inlineImg) {
-    return;
+    return gTrue;
   }
 
   // get info from the stream
@@ -4309,6 +4327,11 @@
     if (!colorSpace) {
       goto err1;
     }
+    if (colorSpace->getMode() == csPattern) {
+      error(errSyntaxError, getPos(), "Image with a Pattern color space");
+      delete colorSpace;
+      goto err1;
+    }
     dict->lookup("Decode", &obj1);
     if (obj1.isNull()) {
       obj1.free();
@@ -4365,6 +4388,12 @@
       }
       maskHeight = obj1.getInt();
       obj1.free();
+      if (maskWidth <= 0 || maskHeight <= 0) {
+	delete colorMap;
+	maskObj.free();
+	smaskObj.free();
+	goto err1;
+      }
       maskDict->lookup("BitsPerComponent", &obj1);
       if (obj1.isNull()) {
 	obj1.free();
@@ -4378,6 +4407,12 @@
       }
       maskBits = obj1.getInt();
       obj1.free();
+      if (maskBits < 1 || maskBits > 16) {
+	delete colorMap;
+	maskObj.free();
+	smaskObj.free();
+	goto err1;
+      }
       maskDict->lookup("ColorSpace", &obj1);
       if (obj1.isNull()) {
 	obj1.free();
@@ -4501,6 +4536,12 @@
       }
       maskHeight = obj1.getInt();
       obj1.free();
+      if (maskWidth <= 0 || maskHeight <= 0) {
+	delete colorMap;
+	maskObj.free();
+	smaskObj.free();
+	goto err2;
+      }
       maskDict->lookup("ImageMask", &obj1);
       if (obj1.isNull()) {
 	obj1.free();
@@ -4534,10 +4575,10 @@
     }
 
     // if drawing is disabled, skip over inline image data
-    if (state->getInCachedT3Char() || !ocState) {
-      if (state->getInCachedT3Char()) {
-	error(errSyntaxWarning, getPos(),
-	      "Ignoring image in cached Type 3 character");
+    if (state->getIgnoreColorOps() || !ocState) {
+      if (state->getIgnoreColorOps()) {
+	error(errSyntaxWarning, getPos(), "Ignoring image"
+	      " in uncolored Type 3 char or tiling pattern");
       }
       if (inlineImg) {
 	str->reset();
@@ -4582,7 +4623,7 @@
   }
   opCounter += i;
 
-  return;
+  return gTrue;
 
  err2:
   obj1.free();
@@ -4594,6 +4635,8 @@
     state->setRenderingIntent(riSaved);
     out->updateRenderingIntent(state);
   }
+
+  return gFalse;
 }
 
 void Gfx::doForm(Object *strRef, Object *str) {
@@ -4826,11 +4869,12 @@
 
   // display the image
   if (str) {
-    doImage(NULL, str, gTrue);
+    if (!doImage(NULL, str, gTrue)) {
+      delete str;
   
     // if we have the stream length, skip to end-of-stream and then
     // skip 'EI' in the original stream
-    if (haveLength) {
+    } else if (haveLength) {
       while ((c1 = str->getChar()) != EOF) ;
       delete str;
       str = parser->getStream();
@@ -4935,7 +4979,7 @@
 }
 
 void Gfx::opSetCacheDevice(Object args[], int numArgs) {
-  state->setInCachedT3Char(gTrue);
+  state->setIgnoreColorOps(gTrue);
   out->type3D1(state, args[0].getNum(), args[1].getNum(),
 	       args[2].getNum(), args[3].getNum(),
 	       args[4].getNum(), args[5].getNum());

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -330,7 +330,7 @@
 
   // XObject operators
   void opXObject(Object args[], int numArgs);
-  void doImage(Object *ref, Stream *str, GBool inlineImg);
+  GBool doImage(Object *ref, Stream *str, GBool inlineImg);
   void doForm(Object *strRef, Object *str);
 
   // in-line image operators

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -164,7 +164,8 @@
 // GfxFont
 //------------------------------------------------------------------------
 
-GfxFont *GfxFont::makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict) {
+GfxFont *GfxFont::makeFont(XRef *xref, const char *tagA,
+			   Ref idA, Dict *fontDict) {
   GString *nameA;
   Ref embFontIDA;
   GfxFontType typeA;
@@ -197,7 +198,7 @@
   return font;
 }
 
-GfxFont::GfxFont(char *tagA, Ref idA, GString *nameA,
+GfxFont::GfxFont(const char *tagA, Ref idA, GString *nameA,
 		 GfxFontType typeA, Ref embFontIDA) {
   ok = gFalse;
   tag = new GString(tagA);
@@ -541,6 +542,7 @@
 GfxFontLoc *GfxFont::locateFont(XRef *xref, GBool ps) {
   GfxFontLoc *fontLoc;
   SysFontType sysFontType;
+  FoFiIdentifierType fft;
   GString *path, *base14Name, *substName;
   PSFontParam16 *psFont16;
   Object refObj, embFontObj;
@@ -635,32 +637,43 @@
   //----- system font
   if (name && (path = globalParams->findSystemFontFile(name, &sysFontType,
 						       &fontNum))) {
+    fontLoc = new GfxFontLoc();
+    fontLoc->locType = gfxFontLocExternal;
+    fontLoc->path = path;
+    fontLoc->fontNum = fontNum;
     if (isCIDFont()) {
       if (sysFontType == sysFontTTF || sysFontType == sysFontTTC) {
-	fontLoc = new GfxFontLoc();
-	fontLoc->locType = gfxFontLocExternal;
 	fontLoc->fontType = fontCIDType2;
-	fontLoc->path = path;
-	fontLoc->fontNum = fontNum;
 	return fontLoc;
+      } else if (sysFontType == sysFontOTF) {
+	fft = FoFiIdentifier::identifyFile(fontLoc->path->getCString());
+	if (fft == fofiIdOpenTypeCFFCID) {
+	  fontLoc->fontType = fontCIDType0COT;
+	  return fontLoc;
+	} else if (fft == fofiIdTrueType) {
+	  fontLoc->fontType = fontCIDType2;
+	  return fontLoc;
+	}
       }
     } else {
       if (sysFontType == sysFontTTF || sysFontType == sysFontTTC) {
-	fontLoc = new GfxFontLoc();
-	fontLoc->locType = gfxFontLocExternal;
 	fontLoc->fontType = fontTrueType;
-	fontLoc->path = path;
-	fontLoc->fontNum = fontNum;
 	return fontLoc;
       } else if (sysFontType == sysFontPFA || sysFontType == sysFontPFB) {
-	fontLoc = new GfxFontLoc();
-	fontLoc->locType = gfxFontLocExternal;
 	fontLoc->fontType = fontType1;
-	fontLoc->path = path;
 	return fontLoc;
+      } else if (sysFontType == sysFontOTF) {
+	fft = FoFiIdentifier::identifyFile(fontLoc->path->getCString());
+	if (fft == fofiIdOpenTypeCFF8Bit) {
+	  fontLoc->fontType = fontType1COT;
+	  return fontLoc;
+	} else if (fft == fofiIdTrueType) {
+	  fontLoc->fontType = fontTrueTypeOT;
+	  return fontLoc;
+	}
       }
     }
-    delete path;
+    delete fontLoc;
   }
 
   if (!isCIDFont()) {
@@ -863,7 +876,7 @@
 // Gfx8BitFont
 //------------------------------------------------------------------------
 
-Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
+Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
 			 GfxFontType typeA, Ref embFontIDA, Dict *fontDict):
   GfxFont(tagA, idA, nameA, typeA, embFontIDA)
 {
@@ -1490,6 +1503,33 @@
   return map;
 }
 
+int *Gfx8BitFont::getCodeToGIDMap(FoFiType1C *ff) {
+  int *map;
+  GHash *nameToGID;
+  int i, gid;
+
+  map = (int *)gmallocn(256, sizeof(int));
+  for (i = 0; i < 256; ++i) {
+    map[i] = 0;
+  }
+
+  nameToGID = ff->getNameToGIDMap();
+  for (i = 0; i < 256; ++i) {
+    if (!enc[i]) {
+      continue;
+    }
+    gid = nameToGID->lookupInt(enc[i]);
+    if (gid < 0 || gid >= 65536) {
+      continue;
+    }
+    map[i] = gid;
+  }
+
+  delete nameToGID;
+
+  return map;
+}
+
 Dict *Gfx8BitFont::getCharProcs() {
   return charProcs.isDict() ? charProcs.getDict() : (Dict *)NULL;
 }
@@ -1575,7 +1615,7 @@
 // GfxCIDFont
 //------------------------------------------------------------------------
 
-GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
+GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
 		       GfxFontType typeA, Ref embFontIDA, Dict *fontDict):
   GfxFont(tagA, idA, nameA, typeA, embFontIDA)
 {
@@ -2001,6 +2041,13 @@
   return cMap ? cMap->getCollection() : (GString *)NULL;
 }
 
+double GfxCIDFont::getWidth(CID cid) {
+  double w;
+
+  getHorizontalMetrics(cid, &w);
+  return w;
+}
+
 GBool GfxCIDFont::problematicForUnicode() {
   GString *nameLC;
   GBool symbolic;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -26,6 +26,7 @@
 class CMap;
 class CharCodeToUnicode;
 class FoFiTrueType;
+class FoFiType1C;
 struct GfxFontCIDWidths;
 struct Base14FontMapEntry;
 class FNVHash;
@@ -131,9 +132,10 @@
 public:
 
   // Build a GfxFont object.
-  static GfxFont *makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict);
+  static GfxFont *makeFont(XRef *xref, const char *tagA,
+			   Ref idA, Dict *fontDict);
 
-  GfxFont(char *tagA, Ref idA, GString *nameA,
+  GfxFont(const char *tagA, Ref idA, GString *nameA,
 	  GfxFontType typeA, Ref embFontIDA);
 
   virtual ~GfxFont();
@@ -243,7 +245,7 @@
 class Gfx8BitFont: public GfxFont {
 public:
 
-  Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
+  Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
 	      GfxFontType typeA, Ref embFontIDA, Dict *fontDict);
 
   virtual ~Gfx8BitFont();
@@ -274,6 +276,10 @@
   // (This is only useful for TrueType fonts.)
   int *getCodeToGIDMap(FoFiTrueType *ff);
 
+  // Return a char code-to-GID mapping for the provided font file.
+  // (This is only useful for Type1C fonts.)
+  int *getCodeToGIDMap(FoFiType1C *ff);
+
   // Return the Type 3 CharProc dictionary, or NULL if none.
   Dict *getCharProcs();
 
@@ -311,7 +317,7 @@
 class GfxCIDFont: public GfxFont {
 public:
 
-  GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
+  GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
 	     GfxFontType typeA, Ref embFontIDA, Dict *fontDict);
 
   virtual ~GfxCIDFont();
@@ -331,6 +337,9 @@
   // Get the collection name (<registry>-<ordering>).
   GString *getCollection();
 
+  // Return the horizontal width for <cid>.
+  double getWidth(CID cid);
+
   // Return the CID-to-GID mapping table.  These should only be called
   // if type is fontCIDType2.
   int *getCIDToGID() { return cidToGID; }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1281,7 +1281,7 @@
   }
   obj1.free();
   arr->get(3, &obj1);
-  if (!(funcA = Function::parse(&obj1))) {
+  if (!(funcA = Function::parse(&obj1, 1, altA->getNComps()))) {
     goto err4;
   }
   obj1.free();
@@ -1476,7 +1476,7 @@
   }
   obj1.free();
   arr->get(3, &obj1);
-  if (!(funcA = Function::parse(&obj1))) {
+  if (!(funcA = Function::parse(&obj1, nCompsA, altA->getNComps()))) {
     goto err4;
   }
   obj1.free();
@@ -2117,7 +2117,7 @@
     }
     for (i = 0; i < nFuncsA; ++i) {
       obj1.arrayGet(i, &obj2);
-      if (!(funcsA[i] = Function::parse(&obj2))) {
+      if (!(funcsA[i] = Function::parse(&obj2, 2, 1))) {
 	goto err2;
       }
       obj2.free();
@@ -2124,7 +2124,7 @@
     }
   } else {
     nFuncsA = 1;
-    if (!(funcsA[0] = Function::parse(&obj1))) {
+    if (!(funcsA[0] = Function::parse(&obj1, 2, -1))) {
       goto err1;
     }
   }
@@ -2137,6 +2137,16 @@
     delete shading;
     return NULL;
   }
+
+  for (i = 0; i < shading->nFuncs; ++i) {
+    if (shading->funcs[i]->getOutputSize()
+	!= shading->getColorSpace()->getNComps()) {
+      error(errSyntaxError, -1, "Invalid function in shading dictionary");
+      delete shading;
+      return NULL;
+    }
+  }
+
   return shading;
 
  err2:
@@ -2274,7 +2284,7 @@
     }
     for (i = 0; i < nFuncsA; ++i) {
       obj1.arrayGet(i, &obj2);
-      if (!(funcsA[i] = Function::parse(&obj2))) {
+      if (!(funcsA[i] = Function::parse(&obj2, 1, 1))) {
 	obj1.free();
 	obj2.free();
 	goto err1;
@@ -2283,7 +2293,7 @@
     }
   } else {
     nFuncsA = 1;
-    if (!(funcsA[0] = Function::parse(&obj1))) {
+    if (!(funcsA[0] = Function::parse(&obj1, 1, -1))) {
       obj1.free();
       goto err1;
     }
@@ -2307,6 +2317,16 @@
     delete shading;
     return NULL;
   }
+
+  for (i = 0; i < shading->nFuncs; ++i) {
+    if (shading->funcs[i]->getOutputSize()
+	!= shading->getColorSpace()->getNComps()) {
+      error(errSyntaxError, -1, "Invalid function in shading dictionary");
+      delete shading;
+      return NULL;
+    }
+  }
+
   return shading;
 
  err1:
@@ -2446,7 +2466,7 @@
     }
     for (i = 0; i < nFuncsA; ++i) {
       obj1.arrayGet(i, &obj2);
-      if (!(funcsA[i] = Function::parse(&obj2))) {
+      if (!(funcsA[i] = Function::parse(&obj2, 1, 1))) {
 	obj1.free();
 	obj2.free();
 	goto err1;
@@ -2455,7 +2475,7 @@
     }
   } else {
     nFuncsA = 1;
-    if (!(funcsA[0] = Function::parse(&obj1))) {
+    if (!(funcsA[0] = Function::parse(&obj1, 1, -1))) {
       obj1.free();
       goto err1;
     }
@@ -2479,6 +2499,16 @@
     delete shading;
     return NULL;
   }
+
+  for (i = 0; i < shading->nFuncs; ++i) {
+    if (shading->funcs[i]->getOutputSize()
+	!= shading->getColorSpace()->getNComps()) {
+      error(errSyntaxError, -1, "Invalid function in shading dictionary");
+      delete shading;
+      return NULL;
+    }
+  }
+
   return shading;
 
  err1:
@@ -2719,7 +2749,7 @@
       }
       for (i = 0; i < nFuncsA; ++i) {
 	obj1.arrayGet(i, &obj2);
-	if (!(funcsA[i] = Function::parse(&obj2))) {
+	if (!(funcsA[i] = Function::parse(&obj2, 1, 1))) {
 	  obj1.free();
 	  obj2.free();
 	  goto err1;
@@ -2728,7 +2758,7 @@
       }
     } else {
       nFuncsA = 1;
-      if (!(funcsA[0] = Function::parse(&obj1))) {
+      if (!(funcsA[0] = Function::parse(&obj1, 1, -1))) {
 	obj1.free();
 	goto err1;
       }
@@ -2832,6 +2862,16 @@
     delete shading;
     return NULL;
   }
+
+  for (i = 0; i < shading->nFuncs; ++i) {
+    if (shading->funcs[i]->getOutputSize()
+	!= shading->getColorSpace()->getNComps()) {
+      error(errSyntaxError, -1, "Invalid function in shading dictionary");
+      delete shading;
+      return NULL;
+    }
+  }
+
   return shading;
 
  err2:
@@ -3017,7 +3057,7 @@
       }
       for (i = 0; i < nFuncsA; ++i) {
 	obj1.arrayGet(i, &obj2);
-	if (!(funcsA[i] = Function::parse(&obj2))) {
+	if (!(funcsA[i] = Function::parse(&obj2, 1, 1))) {
 	  obj1.free();
 	  obj2.free();
 	  goto err1;
@@ -3026,7 +3066,7 @@
       }
     } else {
       nFuncsA = 1;
-      if (!(funcsA[0] = Function::parse(&obj1))) {
+      if (!(funcsA[0] = Function::parse(&obj1, 1, -1))) {
 	obj1.free();
 	goto err1;
       }
@@ -3044,6 +3084,12 @@
     if (!bitBuf->getBits(flagBits, &flag)) {
       break;
     }
+    flag &= 3;
+    if (flag != 0 && nPatchesA == 0) {
+      error(errSyntaxError, -1, "Invalid patch in patch mesh shading");
+      delete bitBuf;
+      goto err1;
+    }
     if (typeA == 6) {
       switch (flag) {
       case 0: nPts = 12; nColors = 4; break;
@@ -3445,6 +3491,16 @@
     delete shading;
     return NULL;
   }
+
+  for (i = 0; i < shading->nFuncs; ++i) {
+    if (shading->funcs[i]->getOutputSize()
+	!= shading->getColorSpace()->getNComps()) {
+      error(errSyntaxError, -1, "Invalid function in shading dictionary");
+      delete shading;
+      return NULL;
+    }
+  }
+
   return shading;
 
  err2:
@@ -4122,7 +4178,7 @@
   clipXMax = pageWidth;
   clipYMax = pageHeight;
 
-  inCachedT3Char = gFalse;
+  ignoreColorOps = gFalse;
 
   saved = NULL;
 }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -1183,7 +1183,7 @@
   void getUserClipBBox(double *xMin, double *yMin, double *xMax, double *yMax);
   double getLineX() { return lineX; }
   double getLineY() { return lineY; }
-  GBool getInCachedT3Char() { return inCachedT3Char; }
+  GBool getIgnoreColorOps() { return ignoreColorOps; }
 
   // Is there a current point/path?
   GBool isCurPt() { return path->isCurPt(); }
@@ -1280,8 +1280,9 @@
   void textShift(double tx, double ty);
   void shift(double dx, double dy);
   
-  // Cached Type 3 char status.
-  void setInCachedT3Char(GBool in) { inCachedT3Char = in; }
+  // Ignore color operators (in cached/uncolored Type 3 chars, and
+  // uncolored tiling patterns).  Cached Type 3 char status.
+  void setIgnoreColorOps(GBool ignore) { ignoreColorOps = ignore; }
 
   // Push/pop GfxState on/off stack.
   GfxState *save();
@@ -1344,7 +1345,9 @@
   double clipXMin, clipYMin,	// bounding box for clip region
          clipXMax, clipYMax;
 
-  GBool inCachedT3Char;		// in a cached (uncolored) Type 3 char
+  GBool ignoreColorOps;		// ignore color ops (in cached/uncolored
+				//   Type 3 chars, and uncolored tiling
+				//   patterns)
 
   GfxState *saved;		// next GfxState on stack
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -17,7 +17,9 @@
 
 #include <string.h>
 #include <stdio.h>
+#include <stdarg.h>
 #include <ctype.h>
+#include <time.h>
 #ifdef _WIN32
 #  include <shlobj.h>
 #endif
@@ -24,6 +26,9 @@
 #if HAVE_PAPER_H
 #include <paper.h>
 #endif
+#if HAVE_FONTCONFIG
+#  include <fontconfig/fontconfig.h>
+#endif
 #include "gmem.h"
 #include "gmempp.h"
 #include "GString.h"
@@ -91,14 +96,14 @@
   {"Courier-BoldOblique",   "n022024l.pfb", "courbi.ttf",  "Courier",      "Courier Bold Oblique",   "Courier-Bold",   0.212557},
   {"Courier-Oblique",       "n022023l.pfb", "couri.ttf",   "Courier",      "Courier Oblique",        "Courier",        0.212557},
   {"Helvetica",             "n019003l.pfb", "arial.ttf",   "Helvetica",    "Helvetica",              NULL,             0},
-  {"Helvetica-Bold",        "n019004l.pfb", "arialbd.ttf", "Helvetica",    "Helvetica-Bold",         NULL,             0},
+  {"Helvetica-Bold",        "n019004l.pfb", "arialbd.ttf", "Helvetica",    "Helvetica Bold",         NULL,             0},
   {"Helvetica-BoldOblique", "n019024l.pfb", "arialbi.ttf", "Helvetica",    "Helvetica Bold Oblique", "Helvetica-Bold", 0.212557},
   {"Helvetica-Oblique",     "n019023l.pfb", "ariali.ttf",  "Helvetica",    "Helvetica Oblique",      "Helvetica",      0.212557},
   {"Symbol",                "s050000l.pfb", NULL,          "Symbol",       "Symbol",                 NULL,             0},
-  {"Times-Bold",            "n021004l.pfb", "timesbd.ttf", "Times",        "Times-Bold",             NULL,             0},
-  {"Times-BoldItalic",      "n021024l.pfb", "timesbi.ttf", "Times",        "Times-BoldItalic",       NULL,             0},
-  {"Times-Italic",          "n021023l.pfb", "timesi.ttf",  "Times",        "Times-Italic",           NULL,             0},
-  {"Times-Roman",           "n021003l.pfb", "times.ttf",   "Times",        "Times-Roman",            NULL,             0},
+  {"Times-Bold",            "n021004l.pfb", "timesbd.ttf", "Times",        "Times Bold",             NULL,             0},
+  {"Times-BoldItalic",      "n021024l.pfb", "timesbi.ttf", "Times",        "Times Bold Italic",       NULL,             0},
+  {"Times-Italic",          "n021023l.pfb", "timesi.ttf",  "Times",        "Times Italic",           NULL,             0},
+  {"Times-Roman",           "n021003l.pfb", "times.ttf",   "Times",        "Times Roman",            NULL,             0},
   {"ZapfDingbats",          "d050000l.pfb", NULL,          "ZapfDingbats", "Zapf Dingbats",          NULL,             0},
   {NULL}
 };
@@ -226,6 +231,10 @@
   void scanWindowsFonts(char *winFontDir);
 #endif
 
+#if HAVE_FONTCONFIG
+  void scanFontconfigFonts();
+#endif
+
 private:
 
 #ifdef _WIN32
@@ -458,6 +467,8 @@
 
   if (!strcasecmp(path + strlen(path) - 4, ".ttc")) {
     type = sysFontTTC;
+  } else if (!strcasecmp(path + strlen(path) - 4, ".otf")) {
+    type = sysFontOTF;
   } else {
     type = sysFontTTF;
   }
@@ -465,6 +476,109 @@
 }
 #endif
 
+#if HAVE_FONTCONFIG
+void SysFontList::scanFontconfigFonts() {
+  FcPattern *pattern;
+  FcObjectSet *objSet;
+  FcFontSet *fontSet;
+  char *family, *file, *styleLang, *style;
+  GString *family2;
+  SysFontType type;
+  GBool bold, italic;
+  char c;
+  int fontNum, i, j, n;
+
+  FcInit();
+
+  pattern = FcPatternBuild(NULL,
+			   FC_OUTLINE, FcTypeBool, FcTrue,
+			   FC_SCALABLE, FcTypeBool, FcTrue,
+			   NULL);
+  objSet = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_STYLELANG,
+			    FC_FILE, FC_INDEX, NULL);
+  fontSet = FcFontList(NULL, pattern, objSet);
+  FcPatternDestroy(pattern);
+  FcObjectSetDestroy(objSet);
+
+  if (fontSet) {
+    for (i = 0; i < fontSet->nfont; ++i) {
+
+      //--- font file, font type
+      if (FcPatternGetString(fontSet->fonts[i], FC_FILE, 0,
+			     (FcChar8 **)&file)
+	  != FcResultMatch) {
+	continue;
+      }
+      n = (int)strlen(file);
+      if (n > 4 && !strcasecmp(file + n - 4, ".pfa")) {
+	type = sysFontPFA;
+      } else if (n > 4 && !strcasecmp(file + n - 4, ".pfb")) {
+	type = sysFontPFB;
+      } else if (n > 4 && !strcasecmp(file + n - 4, ".ttf")) {
+	type = sysFontTTF;
+      } else if (n > 4 && !strcasecmp(file + n - 4, ".otf")) {
+	type = sysFontOTF;
+      } else {
+	continue;
+      }
+
+      //--- font number
+      if (FcPatternGetInteger(fontSet->fonts[i], FC_INDEX, 0, &fontNum)
+	  != FcResultMatch) {
+	fontNum = 0;
+      }
+
+      //--- font family
+      if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0,
+			     (FcChar8 **)&family)
+	  != FcResultMatch) {
+	continue;
+      }
+
+      //----- normalize the font name
+      family2 = new GString(family);
+      j = 0;
+      while (j < family2->getLength()) {
+	c = family2->getChar(j);
+	if (c == ' ' || c == ',' || c == '-') {
+	  family2->del(j);
+	} else {
+	  ++j;
+	}
+      }
+
+      //--- font style
+      style = NULL;
+      for (j = 0;
+	   FcPatternGetString(fontSet->fonts[i], FC_STYLELANG, j,
+			      (FcChar8 **)&styleLang)
+	     == FcResultMatch;
+	   ++j) {
+	if (!strcmp(styleLang, "en")) {
+	  if (FcPatternGetString(fontSet->fonts[i], FC_STYLE, j,
+				 (FcChar8 **)&style)
+	      != FcResultMatch) {
+	    style = NULL;
+	  }
+	  break;
+	}
+	++j;
+      }
+      bold = style && strstr(style, "Bold") != NULL;
+      italic = style && (strstr(style, "Italic") != NULL ||
+			 strstr(style, "Oblique") != NULL);
+
+      fonts->append(new SysFontInfo(family2, bold, italic,
+				    new GString(file), type, fontNum));
+    }
+
+    FcFontSetDestroy(fontSet);
+  }
+
+  FcFini();
+}
+#endif // HAVE_FONTCONFIG
+
 //------------------------------------------------------------------------
 // KeyBinding
 //------------------------------------------------------------------------
@@ -619,7 +733,10 @@
   textKeepTinyChars = gTrue;
   initialZoom = new GString("125");
   defaultFitZoom = 0;
+  initialDisplayMode = new GString("continuous");
+  initialToolbarState = gTrue;
   initialSidebarState = gTrue;
+  initialSelectMode = new GString("linear");
   maxTileWidth = 1500;
   maxTileHeight = 1500;
   tileCacheSize = 10;
@@ -644,6 +761,7 @@
   paperColor = new GString("#ffffff");
   matteColor = new GString("#808080");
   fullScreenMatteColor = new GString("#000000");
+  reverseVideoInvertImages = gFalse;
   launchCommand = NULL;
   movieCommand = NULL;
   defaultPrinter = NULL;
@@ -657,6 +775,7 @@
   tabStateFile = appendToPath(getHomeDir(), ".xpdf.tab-state");
   printCommands = gFalse;
   errQuiet = gFalse;
+  debugLogFile = NULL;
 
   cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
   unicodeToUnicodeCache =
@@ -787,6 +906,9 @@
 				     xpdfKeyContextAny, "newWindow"));
   keyBindings->append(new KeyBinding('w', xpdfKeyModCtrl,
 				     xpdfKeyContextAny, "closeTabOrQuit"));
+  keyBindings->append(new KeyBinding('l', xpdfKeyModCtrl,
+				     xpdfKeyContextAny,
+				     "toggleFullScreenMode"));
   keyBindings->append(new KeyBinding('q', xpdfKeyModCtrl,
 				     xpdfKeyContextAny, "quit"));
   keyBindings->append(new KeyBinding(xpdfKeyCodeTab, xpdfKeyModCtrl,
@@ -1022,9 +1144,18 @@
       parseString("initialZoom", &initialZoom, tokens, fileName, line);
     } else if (!cmd->cmp("defaultFitZoom")) {
       parseInteger("defaultFitZoom", &defaultFitZoom, tokens, fileName, line);
+    } else if (!cmd->cmp("initialDisplayMode")) {
+      parseString("initialDisplayMode", &initialDisplayMode,
+		  tokens, fileName, line);
+    } else if (!cmd->cmp("initialToolbarState")) {
+      parseYesNo("initialToolbarState", &initialToolbarState,
+		 tokens, fileName, line);
     } else if (!cmd->cmp("initialSidebarState")) {
       parseYesNo("initialSidebarState", &initialSidebarState,
 		 tokens, fileName, line);
+    } else if (!cmd->cmp("initialSelectMode")) {
+      parseString("initialSelectMode", &initialSelectMode,
+		  tokens, fileName, line);
     } else if (!cmd->cmp("maxTileWidth")) {
       parseInteger("maxTileWidth", &maxTileWidth, tokens, fileName, line);
     } else if (!cmd->cmp("maxTileHeight")) {
@@ -1086,6 +1217,9 @@
     } else if (!cmd->cmp("fullScreenMatteColor")) {
       parseString("fullScreenMatteColor", &fullScreenMatteColor,
 		  tokens, fileName, line);
+    } else if (!cmd->cmp("reverseVideoInvertImages")) {
+      parseYesNo("reverseVideoInvertImages", &reverseVideoInvertImages,
+		 tokens, fileName, line);
     } else if (!cmd->cmp("launchCommand")) {
       parseString("launchCommand", &launchCommand, tokens, fileName, line);
     } else if (!cmd->cmp("movieCommand")) {
@@ -1118,6 +1252,8 @@
       parseYesNo("printCommands", &printCommands, tokens, fileName, line);
     } else if (!cmd->cmp("errQuiet")) {
       parseYesNo("errQuiet", &errQuiet, tokens, fileName, line);
+    } else if (!cmd->cmp("debugLogFile")) {
+      parseString("debugLogFile", &debugLogFile, tokens, fileName, line);
     } else {
       error(errConfig, -1, "Unknown config file command '{0:t}' ({1:t}:{2:d})",
 	    cmd, fileName, line);
@@ -1862,6 +1998,8 @@
   deleteGList(psResidentFontsCC, PSFontParam16);
   delete textEncoding;
   delete initialZoom;
+  delete initialDisplayMode;
+  delete initialSelectMode;
   if (paperColor) {
     delete paperColor;
   }
@@ -1943,6 +2081,7 @@
 	}
       }
     }
+    FreeLibrary(shell32Lib);
   }
   // if something went wrong, or we're on a Terminal Server, try using
   // %SYSTEMROOT%\Fonts
@@ -1958,6 +2097,40 @@
 }
 #endif
 
+#ifdef __APPLE__
+// Apple dfonts and ttc fonts seem to randomly and interchangeably use
+// space and hyphen, and sometimes drop the separator entirely.
+static GBool macFontNameMatches(GString *name1, const char *name2) {
+  const char *p1, *p2;
+  char c1, c2;
+
+  p1 = name1->getCString();
+  p2 = name2;
+  while (*p1 && *p2) {
+    c1 = *p1;
+    c2 = *p2;
+    if (c2 == ' ') {
+      // * space or hyphen matches a space in the pattern
+      // * separators can also be dropped, in which case we move to
+      //   the next char in the pattern
+      if (c1 == ' ' || c1 == '-') {
+	++p1;
+      }
+    } else {
+      if (c1 != c2) {
+	return gFalse;
+      }
+      ++p1;
+    }
+    ++p2;
+  }
+  if (*p1 || *p2) {
+    return gFalse;
+  }
+  return gTrue;
+}
+#endif
+
 void GlobalParams::setupBaseFonts(const char *dir) {
   GString *fontName;
   GString *fileName;
@@ -2036,8 +2209,8 @@
 	    }
 	    if (dfontFontNames) {
 	      for (k = 0; k < dfontFontNames->getLength(); ++k) {
-		if (!((GString *)dfontFontNames->get(k))
-		                     ->cmp(displayFontTab[i].macFontName)) {
+		if (macFontNameMatches((GString *)dfontFontNames->get(k),
+				       displayFontTab[i].macFontName)) {
 		  fontNum = k;
 		  found = gTrue;
 		  break;
@@ -2114,6 +2287,9 @@
     sysFonts->scanWindowsFonts(winFontDir);
   }
 #endif
+#if HAVE_FONTCONFIG
+  sysFonts->scanFontconfigFonts();
+#endif
 }
 
 //------------------------------------------------------------------------
@@ -2653,6 +2829,24 @@
   return z;
 }
 
+GString *GlobalParams::getInitialDisplayMode() {
+  GString *s;
+
+  lockGlobalParams;
+  s = initialDisplayMode->copy();
+  unlockGlobalParams;
+  return s;
+}
+
+GBool GlobalParams::getInitialToolbarState() {
+  GBool state;
+
+  lockGlobalParams;
+  state = initialToolbarState;
+  unlockGlobalParams;
+  return state;
+}
+
 GBool GlobalParams::getInitialSidebarState() {
   GBool state;
 
@@ -2662,6 +2856,15 @@
   return state;
 }
 
+GString *GlobalParams::getInitialSelectMode() {
+  GString *s;
+
+  lockGlobalParams;
+  s = initialSelectMode->copy();
+  unlockGlobalParams;
+  return s;
+}
+
 int GlobalParams::getMaxTileWidth() {
   int w;
 
@@ -2872,6 +3075,15 @@
   return s;
 }
 
+GBool GlobalParams::getReverseVideoInvertImages() {
+  GBool invert;
+
+  lockGlobalParams;
+  invert = reverseVideoInvertImages;
+  unlockGlobalParams;
+  return invert;
+}
+
 GString *GlobalParams::getDefaultPrinter() {
   GString *s;
 
@@ -2998,6 +3210,51 @@
   return errQuiet;
 }
 
+GString *GlobalParams::getDebugLogFile() {
+  return debugLogFile;
+}
+
+void GlobalParams::debugLogPrintf(char *fmt, ...) {
+  GString *path;
+  FILE *f;
+  GBool needClose;
+  time_t t;
+  struct tm tm;
+  va_list args;
+
+  if (!(path = getDebugLogFile())) {
+    return;
+  }
+  needClose = gFalse;
+  if (!path->cmp("-")) {
+    f = stdout;
+  } else if (!path->cmp("+")) {
+    f = stderr;
+  } else {
+    f = fopen(path->getCString(), "a");
+    needClose = gTrue;
+  }
+  if (!f) {
+    return;
+  }
+  t = time(NULL);
+#ifdef _WIN32
+  localtime_s(&tm, &t);
+#else
+  localtime_r(&t, &tm);
+#endif
+  fprintf(f, "[%04d-%02d-%02d %02d:%02d:%02d] ",
+	  tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+	  tm.tm_hour, tm.tm_min, tm.tm_sec);
+  va_start(args, fmt);
+  vfprintf(f, fmt, args);
+  va_end(args);
+  fflush(f);
+  if (needClose) {
+    fclose(f);
+  }
+}
+
 CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) {
   GString *fileName;
   CharCodeToUnicode *ctu;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -55,7 +55,8 @@
   sysFontPFA,
   sysFontPFB,
   sysFontTTF,
-  sysFontTTC
+  sysFontTTC,
+  sysFontOTF
 };
 
 //------------------------------------------------------------------------
@@ -283,7 +284,10 @@
   GBool getTextKeepTinyChars();
   GString *getInitialZoom();
   int getDefaultFitZoom();
+  GString *getInitialDisplayMode();
+  GBool getInitialToolbarState();
   GBool getInitialSidebarState();
+  GString *getInitialSelectMode();
   int getMaxTileWidth();
   int getMaxTileHeight();
   int getTileCacheSize();
@@ -308,6 +312,7 @@
   GString *getPaperColor();
   GString *getMatteColor();
   GString *getFullScreenMatteColor();
+  GBool getReverseVideoInvertImages();
   GString *getLaunchCommand() { return launchCommand; }
   GString *getMovieCommand() { return movieCommand; }
   GString *getDefaultPrinter();
@@ -322,6 +327,8 @@
   GString *getTabStateFile();
   GBool getPrintCommands();
   GBool getErrQuiet();
+  GString *getDebugLogFile();
+  void debugLogPrintf(char *fmt, ...);
 
   CharCodeToUnicode *getCIDToUnicode(GString *collection);
   CharCodeToUnicode *getUnicodeToUnicode(GString *fontName);
@@ -509,8 +516,13 @@
   GString *initialZoom;		// initial zoom level
   int defaultFitZoom;		// default zoom factor if initialZoom is
 				//   'page' or 'width'.
+  GString *initialDisplayMode;	// initial display mode (single,
+				//   continuous, etc.)
+  GBool initialToolbarState;	// initial toolbar state - open (true)
+				//   or closed (false)
   GBool initialSidebarState;	// initial sidebar state - open (true)
 				//   or closed (false)
+  GString *initialSelectMode;	// initial selection mode (block or linear)
   int maxTileWidth;		// maximum rasterization tile width
   int maxTileHeight;		// maximum rasterization tile height
   int tileCacheSize;		// number of rasterization tiles in cache
@@ -536,6 +548,7 @@
   GString *paperColor;		// paper (page background) color
   GString *matteColor;		// matte (background outside of page) color
   GString *fullScreenMatteColor; // matte color in full-screen mode
+  GBool reverseVideoInvertImages; // invert images in reverse video mode
   GString *launchCommand;	// command executed for 'launch' links
   GString *movieCommand;	// command executed for movie annotations
   GString *defaultPrinter;	// default printer (for interactive printing
@@ -551,6 +564,7 @@
   GString *tabStateFile;	// path for the tab state save file
   GBool printCommands;		// print the drawing commands
   GBool errQuiet;		// suppress error messages?
+  GString *debugLogFile;	// path for debug log file
 
   CharCodeToUnicodeCache *cidToUnicodeCache;
   CharCodeToUnicodeCache *unicodeToUnicodeCache;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -34,9 +34,11 @@
 #include "GList.h"
 #include "SplashBitmap.h"
 #include "PDFDoc.h"
+#include "GfxFont.h"
 #include "TextOutputDev.h"
 #include "SplashOutputDev.h"
 #include "ErrorCodes.h"
+#include "WebFont.h"
 #include "HTMLGen.h"
 
 #ifdef _WIN32
@@ -62,11 +64,14 @@
   {"CondensedBold",           13, gTrue,  gFalse},
   {"CondensedLight",          14, gFalse, gFalse},
   {"SemiBold",                 8, gTrue,  gFalse},
+  {"BoldItalicMT",            12, gTrue,  gTrue},
   {"BoldItalic",              10, gTrue,  gTrue},
   {"Bold_Italic",             11, gTrue,  gTrue},
   {"BoldOblique",             11, gTrue,  gTrue},
   {"Bold_Oblique",            12, gTrue,  gTrue},
+  {"BoldMT",                   6, gTrue,  gFalse},
   {"Bold",                     4, gTrue,  gFalse},
+  {"ItalicMT",                 8, gFalse, gTrue},
   {"Italic",                   6, gFalse, gTrue},
   {"Oblique",                  7, gFalse, gTrue},
   {"Light",                    5, gFalse, gFalse},
@@ -171,9 +176,29 @@
 
 //------------------------------------------------------------------------
 
+class HTMLGenFontDefn {
+public:
 
+  HTMLGenFontDefn(Ref fontIDA, GString *fontFaceA, GString *fontSpecA,
+		  double scaleA)
+    : fontID(fontIDA), fontFace(fontFaceA), fontSpec(fontSpecA)
+    , scale(scaleA), used(gFalse) {}
+  ~HTMLGenFontDefn() { delete fontFace; delete fontSpec; }
+  GBool match(Ref fontIDA)
+    { return fontIDA.num == fontID.num && fontIDA.gen == fontID.gen; }
+
+  Ref fontID;
+  GString *fontFace;		// NULL for substituted fonts
+  GString *fontSpec;
+  double scale;
+  GBool used;			// set when used (per page)
+};
+
 //------------------------------------------------------------------------
 
+
+//------------------------------------------------------------------------
+
 HTMLGen::HTMLGen(double backgroundResolutionA) {
   TextOutputControl textOutControl;
   SplashColor paperColor;
@@ -184,6 +209,7 @@
   zoom = 1.0;
   drawInvisibleText = gTrue;
   allTextInvisible = gFalse;
+  extractFontFiles = gFalse;
 
   // set up the TextOutputDev
   textOutControl.mode = textOutReadingOrder;
@@ -196,16 +222,27 @@
   // set up the SplashOutputDev
   paperColor[0] = paperColor[1] = paperColor[2] = 0xff;
   splashOut = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor);
+
+  fontDefns = NULL;
 }
 
 HTMLGen::~HTMLGen() {
   delete textOut;
   delete splashOut;
+  if (fontDefns) {
+    deleteGList(fontDefns, HTMLGenFontDefn);
+  }
 }
 
 void HTMLGen::startDoc(PDFDoc *docA) {
   doc = docA;
   splashOut->startDoc(doc->getXRef());
+
+  if (fontDefns) {
+    deleteGList(fontDefns, HTMLGenFontDefn);
+  }
+  fontDefns = new GList();
+  nextFontFaceIdx = 0;
 }
 
 static inline int pr(int (*writeFunc)(void *stream, const char *data, int size),
@@ -240,7 +277,7 @@
 }
 
 int HTMLGen::convertPage(
-		 int pg, const char *pngURL,
+		 int pg, const char *pngURL, const char *htmlDir,
 		 int (*writeHTML)(void *stream, const char *data, int size),
 		 void *htmlStream,
 		 int (*writePNG)(void *stream, const char *data, int size),
@@ -257,6 +294,7 @@
   TextColumn *col;
   TextParagraph *par;
   TextLine *line;
+  HTMLGenFontDefn *fontDefn;
   GString *s;
   double base;
   int primaryDir, spanDir;
@@ -269,7 +307,7 @@
 		   0, gFalse, gTrue, gFalse);
   bitmap = splashOut->getBitmap();
   if (!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
-				       NULL, NULL, NULL)) ||
+				      NULL, NULL, NULL)) ||
       !(pngInfo = png_create_info_struct(png))) {
     return errFileIO;
   }
@@ -314,11 +352,19 @@
   pr(writeHTML, htmlStream, ".txt { white-space:nowrap; }\n");
   fonts = text->getFonts();
   fontScales = (double *)gmallocn(fonts->getLength(), sizeof(double));
+  for (i = 0; i < fontDefns->getLength(); ++i) {
+    fontDefn = (HTMLGenFontDefn *)fontDefns->get(i);
+    fontDefn->used = gFalse;
+  }
   for (i = 0; i < fonts->getLength(); ++i) {
     font = (TextFontInfo *)fonts->get(i);
-    s = getFontDefn(font, &fontScales[i]);
-    pf(writeHTML, htmlStream, "#f{0:d} {{ {1:t} }}\n", i, s);
-    delete s;
+    fontDefn = getFontDefn(font, htmlDir);
+    if (!fontDefn->used && fontDefn->fontFace) {
+      pr(writeHTML, htmlStream, fontDefn->fontFace->getCString());
+    }
+    pf(writeHTML, htmlStream, "#f{0:d} {{ {1:t} }}\n", i, fontDefn->fontSpec);
+    fontScales[i] = fontDefn->scale;
+    fontDefn->used = gTrue;
   }
   pr(writeHTML, htmlStream, "</style>\n");
   pr(writeHTML, htmlStream, "</head>\n");
@@ -592,7 +638,112 @@
   }
 }
 
-GString *HTMLGen::getFontDefn(TextFontInfo *font, double *scale) {
+HTMLGenFontDefn *HTMLGen::getFontDefn(TextFontInfo *font,
+				      const char *htmlDir) {
+  Ref id;
+  HTMLGenFontDefn *fontDefn;
+  int i;
+
+  // check the existing font defns
+  id = font->getFontID();
+  if (id.num >= 0) {
+    for (i = 0; i < fontDefns->getLength(); ++i) {
+      fontDefn = (HTMLGenFontDefn *)fontDefns->get(i);
+      if (fontDefn->match(id)) {
+	return fontDefn;
+      }
+    }
+  }
+
+  // try to extract a font file
+  if (!extractFontFiles ||
+      !(fontDefn = getFontFile(font, htmlDir))) {
+
+    // get a substitute font
+    fontDefn = getSubstituteFont(font);
+  }
+
+  fontDefns->append(fontDefn);
+  return fontDefn;
+}
+
+HTMLGenFontDefn *HTMLGen::getFontFile(TextFontInfo *font,
+				      const char *htmlDir) {
+  Ref id;
+  HTMLGenFontDefn *fontDefn;
+  Object fontObj;
+  GfxFont *gfxFont;
+  WebFont *webFont;
+  GString *fontFile, *fontPath, *fontFace, *fontSpec;
+  const char *family, *weight, *style;
+  double scale;
+
+  id = font->getFontID();
+  if (id.num < 0) {
+    return NULL;
+  }
+
+  doc->getXRef()->fetch(id.num, id.gen, &fontObj);
+  if (!fontObj.isDict()) {
+    fontObj.free();
+    return NULL;
+  }
+
+  gfxFont = GfxFont::makeFont(doc->getXRef(), "F", id, fontObj.getDict());
+  webFont = new WebFont(gfxFont, doc->getXRef());
+  fontDefn = NULL;
+
+  if (webFont->canWriteTTF()) {
+    fontFile = GString::format("{0:d}.ttf", nextFontFaceIdx);
+    fontPath = GString::format("{0:s}/{1:t}", htmlDir, fontFile);
+    if (webFont->writeTTF(fontPath->getCString())) {
+      fontFace = GString::format("@font-face {{ font-family: ff{0:d}; src: url(\"{1:t}\"); }}\n",
+				 nextFontFaceIdx, fontFile);
+      getFontDetails(font, &family, &weight, &style, &scale);
+      fontSpec = GString::format("font-family:ff{0:d},{1:s}; font-weight:{2:s}; font-style:{3:s};",
+				 nextFontFaceIdx, family, weight, style);
+      ++nextFontFaceIdx;
+      fontDefn = new HTMLGenFontDefn(id, fontFace, fontSpec, 1.0);
+    }
+    delete fontPath;
+    delete fontFile;
+
+  } else if (webFont->canWriteOTF()) {
+    fontFile = GString::format("{0:d}.otf", nextFontFaceIdx);
+    fontPath = GString::format("{0:s}/{1:t}", htmlDir, fontFile);
+    if (webFont->writeOTF(fontPath->getCString())) {
+      fontFace = GString::format("@font-face {{ font-family: ff{0:d}; src: url(\"{1:t}\"); }}\n",
+				  nextFontFaceIdx, fontFile);
+      getFontDetails(font, &family, &weight, &style, &scale);
+      fontSpec = GString::format("font-family:ff{0:d},{1:s}; font-weight:{2:s}; font-style:{3:s};",
+				 nextFontFaceIdx, family, weight, style);
+      fontDefn = new HTMLGenFontDefn(id, fontFace, fontSpec, 1.0);
+    }
+    delete fontPath;
+    delete fontFile;
+  }
+
+  delete webFont;
+  delete gfxFont;
+  fontObj.free();
+
+  return fontDefn;
+}
+
+HTMLGenFontDefn *HTMLGen::getSubstituteFont(TextFontInfo *font) {
+  const char *family, *weight, *style;
+  double scale;
+  GString *fontSpec;
+
+  getFontDetails(font, &family, &weight, &style, &scale);
+  fontSpec = GString::format("font-family:{0:s}; font-weight:{1:s}; font-style:{2:s};",
+			     family, weight, style);
+  return new HTMLGenFontDefn(font->getFontID(), NULL, fontSpec, scale);
+}
+
+void HTMLGen::getFontDetails(TextFontInfo *font, const char **family,
+			     const char **weight, const char **style,
+			     double *scale) {
   GString *fontName;
   char *fontName2;
   FontStyleTagInfo *fst;
@@ -666,11 +817,7 @@
     }
   }
 
-  // generate the CSS markup
-  return GString::format("font-family:{0:s}; font-weight:{1:s}; font-style:{2:s};",
-			 fixedWidth ? "monospace"
-			            : serif ? "serif"
-			                    : "sans-serif",
-			 bold ? "bold" : "normal",
-			 italic ? "italic" : "normal");
+  *family = fixedWidth ? "monospace" : serif ? "serif" : "sans-serif";
+  *weight = bold ? "bold" : "normal";
+  *style = italic ? "italic" : "normal";
 }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -20,6 +20,7 @@
 class TextOutputDev;
 class TextFontInfo;
 class SplashOutputDev;
+class HTMLGenFontDefn;
 
 //------------------------------------------------------------------------
 
@@ -46,8 +47,11 @@
   void setAllTextInvisible(GBool allTextInvisibleA)
     { allTextInvisible = allTextInvisibleA; }
 
+  void setExtractFontFiles(GBool extractFontFilesA)
+    { extractFontFiles = extractFontFilesA; }
+
   void startDoc(PDFDoc *docA);
-  int convertPage(int pg, const char *pngURL,
+  int convertPage(int pg, const char *pngURL, const char *htmlDir,
 		  int (*writeHTML)(void *stream, const char *data, int size),
 		  void *htmlStream,
 		  int (*writePNG)(void *stream, const char *data, int size),
@@ -61,20 +65,29 @@
 		   int primaryDir, int spanDir,
 		   double base, GBool dropCapLine, GString *s);
   void appendUTF8(Unicode u, GString *s);
-  GString *getFontDefn(TextFontInfo *font, double *scale);
+  HTMLGenFontDefn *getFontDefn(TextFontInfo *font, const char *htmlDir);
+  HTMLGenFontDefn *getFontFile(TextFontInfo *font, const char *htmlDir);
+  HTMLGenFontDefn *getSubstituteFont(TextFontInfo *font);
+  void getFontDetails(TextFontInfo *font, const char **family,
+		      const char **weight, const char **style,
+		      double *scale);
 
   double backgroundResolution;
   double zoom;
   GBool drawInvisibleText;
   GBool allTextInvisible;
+  GBool extractFontFiles;
 
   PDFDoc *doc;
   TextOutputDev *textOut;
   SplashOutputDev *splashOut;
 
-  GList *fonts;
+  GList *fonts;			// [TextFontInfo]
   double *fontScales;
 
+  GList *fontDefns;		// [HTMLGenFontDefn]
+  int nextFontFaceIdx;
+
   GBool ok;
 };
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -838,6 +838,9 @@
   } else {
     y0 = 0;
   }
+  if (y > INT_MAX - bitmap->h) {
+    return;
+  }
   if (y + bitmap->h > h) {
     y1 = h - y;
   } else {
@@ -1202,10 +1205,13 @@
 }
 
 void JBIG2Stream::reset() {
+  GList *t;
+
+  segments = new GList();
+  globalSegments = new GList();
+
   // read the globals stream
-  globalSegments = new GList();
   if (globalsStream.isStream()) {
-    segments = globalSegments;
     curStr = globalsStream.getStream();
     curStr->reset();
     arithDecoder->setStream(curStr);
@@ -1213,10 +1219,13 @@
     mmrDecoder->setStream(curStr);
     readSegments();
     curStr->close();
+    // swap the newly read segments list into globalSegments
+    t = segments;
+    segments = globalSegments;
+    globalSegments = t;
   }
 
   // read the main stream
-  segments = new GList();
   curStr = str;
   curStr->reset();
   arithDecoder->setStream(curStr);
@@ -1280,7 +1289,8 @@
   return n;
 }
 
-GString *JBIG2Stream::getPSFilter(int psLevel, const char *indent) {
+GString *JBIG2Stream::getPSFilter(int psLevel, const char *indent,
+				  GBool okToReadStream) {
   return NULL;
 }
 
@@ -1506,7 +1516,7 @@
   Guint symHeight, symWidth, totalWidth, x, symID;
   int dh, dw, refAggNum, refDX, refDY, bmSize;
   GBool ex;
-  int run, cnt;
+  int run, prevRun, cnt;
   Guint i, j, k;
 
   symWidths = NULL;
@@ -1853,6 +1863,7 @@
   // exported symbol list
   i = j = 0;
   ex = gFalse;
+  prevRun = 1;
   while (i < numInputSyms + numNewSyms) {
     if (huff) {
       huffDecoder->decodeInt(&run, huffTableA);
@@ -1859,6 +1870,14 @@
     } else {
       arithDecoder->decodeInt(&run, iaexStats);
     }
+    if (run == 0 && prevRun == 0) {
+      // this avoids infinite loops with damaged files (consecutive
+      // zero runs are never useful)
+      error(errSyntaxError, getPos(),
+	    "Invalid exported symbol list in JBIG2 symbol dictionary");
+      delete symbolDict;
+      goto syntaxError;
+    }
     if (i + run > numInputSyms + numNewSyms ||
 	(ex && j + run > numExSyms)) {
       error(errSyntaxError, getPos(),
@@ -1874,6 +1893,7 @@
       i += run;
     }
     ex = !ex;
+    prevRun = run;
   }
   if (j != numExSyms) {
     error(errSyntaxError, getPos(), "Too few symbols in JBIG2 symbol dictionary");
@@ -2143,18 +2163,23 @@
       runLengthTab[i].val = i;
       runLengthTab[i].prefixLen = huffDecoder->readBits(4);
       runLengthTab[i].rangeLen = 0;
+      runLengthTab[i].prefix = 0;
     }
     runLengthTab[32].val = 0x103;
     runLengthTab[32].prefixLen = huffDecoder->readBits(4);
     runLengthTab[32].rangeLen = 2;
+    runLengthTab[32].prefix = 0;
     runLengthTab[33].val = 0x203;
     runLengthTab[33].prefixLen = huffDecoder->readBits(4);
     runLengthTab[33].rangeLen = 3;
+    runLengthTab[33].prefix = 0;
     runLengthTab[34].val = 0x20b;
     runLengthTab[34].prefixLen = huffDecoder->readBits(4);
     runLengthTab[34].rangeLen = 7;
+    runLengthTab[34].prefix = 0;
     runLengthTab[35].prefixLen = 0;
     runLengthTab[35].rangeLen = jbig2HuffmanEOT;
+    runLengthTab[35].prefix = 0;
     huffDecoder->buildTable(runLengthTab, 35);
     symCodeTab = (JBIG2HuffmanTable *)gmallocn(numSyms + 1,
 					       sizeof(JBIG2HuffmanTable));
@@ -2170,6 +2195,12 @@
 	  symCodeTab[i++].prefixLen = 0;
 	}
       } else if (j > 0x100) {
+	if (i == 0) {
+	  error(errSyntaxError, getPos(), "Invalid code in JBIG2 text region");
+	  gfree(syms);
+	  gfree(symCodeTab);
+	  return;
+	}
 	for (j -= 0x100; j && i < numSyms; --j) {
 	  symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
 	  ++i;
@@ -2226,8 +2257,8 @@
 
  codeTableError:
   error(errSyntaxError, getPos(), "Missing code table in JBIG2 text region");
-  gfree(codeTables);
-  delete syms;
+  delete codeTables;
+  gfree(syms);
   return;
 
  eofError:

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -42,7 +42,8 @@
   virtual int getChar();
   virtual int lookChar();
   virtual int getBlock(char *blk, int size);
-  virtual GString *getPSFilter(int psLevel, const char *indent);
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
 
 private:

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -414,18 +414,17 @@
     if (curY >= (img.ySize >> reduction)) {
       return;
     }
-    tileIdx = ((curY - img.yTileOffsetR) / img.yTileSizeR) * img.nXTiles
-              + (curX - img.xTileOffsetR) / img.xTileSizeR;
+    tileIdx = (((curY << reduction) - img.yTileOffset) / img.yTileSize)
+                * img.nXTiles
+              + ((curX << reduction) - img.xTileOffset) / img.xTileSize;
 #if 1 //~ ignore the palette, assume the PDF ColorSpace object is valid
     tileComp = &img.tiles[tileIdx].tileComps[curComp];
 #else
     tileComp = &img.tiles[tileIdx].tileComps[havePalette ? 0 : curComp];
 #endif
-    //~ can curX/curY be less than x/yTileOffsetR?
-    //~ if yes, we need to use tx = max(0, ....)
-    tx = jpxFloorDiv((curX - img.xTileOffsetR) % img.xTileSizeR,
+    tx = jpxFloorDiv(curX - jpxCeilDivPow2(img.tiles[tileIdx].x0, reduction),
 		     tileComp->hSep);
-    ty = jpxFloorDiv((curY - img.yTileOffsetR) % img.yTileSizeR,
+    ty = jpxFloorDiv(curY - jpxCeilDivPow2(img.tiles[tileIdx].y0, reduction),
 		     tileComp->vSep);
     pix = (int)tileComp->data[ty * tileComp->w + tx];
     pixBits = tileComp->prec;
@@ -463,7 +462,8 @@
   } while (readBufLen < 8);
 }
 
-GString *JPXStream::getPSFilter(int psLevel, const char *indent) {
+GString *JPXStream::getPSFilter(int psLevel, const char *indent,
+				GBool okToReadStream) {
   return NULL;
 }
 
@@ -960,10 +960,6 @@
       img.ySizeR = jpxCeilDivPow2(img.ySize, reduction);
       img.xOffsetR = jpxCeilDivPow2(img.xOffset, reduction);
       img.yOffsetR = jpxCeilDivPow2(img.yOffset, reduction);
-      img.xTileSizeR = jpxCeilDivPow2(img.xTileSize, reduction);
-      img.yTileSizeR = jpxCeilDivPow2(img.yTileSize, reduction);
-      img.xTileOffsetR = jpxCeilDivPow2(img.xTileOffset, reduction);
-      img.yTileOffsetR = jpxCeilDivPow2(img.yTileOffset, reduction);
       img.nXTiles = (img.xSize - img.xTileOffset + img.xTileSize - 1)
 	            / img.xTileSize;
       img.nYTiles = (img.ySize - img.yTileOffset + img.yTileSize - 1)
@@ -1449,8 +1445,7 @@
   ok = gTrue;
   while (1) {
     if (!readTilePart()) {
-      ok = gFalse;
-      break;
+      return jpxDecodeFatalError;
     }
     if (!readMarkerHdr(&segType, &segLen)) {
       error(errSyntaxError, getPos(), "Error in JPX codestream");
@@ -1913,6 +1908,7 @@
     tile->res = 0;
     tile->precinct = 0;
     tile->layer = 0;
+    tile->done = gFalse;
     tile->maxNDecompLevels = 0;
     for (comp = 0; comp < img.nComps; ++comp) {
       tileComp = &tile->tileComps[comp];
@@ -1925,8 +1921,15 @@
       tileComp->y1 = jpxCeilDiv(tile->y1, tileComp->vSep);
       tileComp->cbW = 1 << tileComp->codeBlockW;
       tileComp->cbH = 1 << tileComp->codeBlockH;
-      tileComp->w = jpxCeilDivPow2(tileComp->x1 - tileComp->x0, reduction);
-      tileComp->h = jpxCeilDivPow2(tileComp->y1 - tileComp->y0, reduction);
+      tileComp->w = jpxCeilDivPow2(tileComp->x1, reduction)
+	            - jpxCeilDivPow2(tileComp->x0, reduction);
+      tileComp->h = jpxCeilDivPow2(tileComp->y1, reduction)
+	            - jpxCeilDivPow2(tileComp->y0, reduction);
+      if (tileComp->w == 0 || tileComp->h == 0) {
+	error(errSyntaxError, getPos(),
+	      "Invalid tile size or sample separation in JPX stream");
+	return gFalse;
+      }
       tileComp->data = (int *)gmallocn(tileComp->w * tileComp->h, sizeof(int));
       if (tileComp->x1 - tileComp->x0 > tileComp->y1 - tileComp->y0) {
 	n = tileComp->x1 - tileComp->x0;
@@ -1942,13 +1945,20 @@
 	resLevel->y0 = jpxCeilDivPow2(tileComp->y0, k);
 	resLevel->x1 = jpxCeilDivPow2(tileComp->x1, k);
 	resLevel->y1 = jpxCeilDivPow2(tileComp->y1, k);
+	// the JPEG 2000 spec says that packets for empty res levels
+	// should all be present in the codestream (B.6, B.9, B.10),
+	// but it appears that encoders drop packets if the res level
+	// AND the subbands are all completely empty
+	resLevel->empty = resLevel->x0 == resLevel->x1 ||
+	                  resLevel->y0 == resLevel->y1;
 	if (r == 0) {
 	  resLevel->bx0[0] = resLevel->x0;
 	  resLevel->by0[0] = resLevel->y0;
 	  resLevel->bx1[0] = resLevel->x1;
 	  resLevel->by1[0] = resLevel->y1;
-	  resLevel->empty = resLevel->bx0[0] == resLevel->bx1[0] ||
-	                    resLevel->by0[0] == resLevel->by1[0];
+	  resLevel->empty = resLevel->empty &&
+	                    (resLevel->bx0[0] == resLevel->bx1[0] ||
+			     resLevel->by0[0] == resLevel->by1[0]);
 	} else {
 	  resLevel->bx0[0] = jpxCeilDivPow2(tileComp->x0 - (1 << (k-1)), k);
 	  resLevel->by0[0] = resLevel->y0;
@@ -1962,7 +1972,8 @@
 	  resLevel->by0[2] = jpxCeilDivPow2(tileComp->y0 - (1 << (k-1)), k);
 	  resLevel->bx1[2] = jpxCeilDivPow2(tileComp->x1 - (1 << (k-1)), k);
 	  resLevel->by1[2] = jpxCeilDivPow2(tileComp->y1 - (1 << (k-1)), k);
-	  resLevel->empty = (resLevel->bx0[0] == resLevel->bx1[0] ||
+	  resLevel->empty = resLevel->empty &&
+	                    (resLevel->bx0[0] == resLevel->bx1[0] ||
 			     resLevel->by0[0] == resLevel->by1[0]) &&
 	                    (resLevel->bx0[1] == resLevel->bx1[1] ||
 			     resLevel->by0[1] == resLevel->by1[1]) &&
@@ -2117,6 +2128,12 @@
 
   tile = &img.tiles[tileIdx];
 
+  // if the tile is finished, just skip this tile part
+  if (tile->done) {
+    bufStr->discardChars(tilePartLen);
+    return gTrue;
+  }
+
   // read all packets from this tile-part
   while (1) {
     if (tilePartToEOC) {
@@ -2373,6 +2390,7 @@
 	  tile->res = 0;
 	  if (++tile->layer == tile->nLayers) {
 	    tile->layer = 0;
+	    tile->done = gTrue;
 	  }
 	}
       }
@@ -2385,6 +2403,7 @@
 	  tile->layer = 0;
 	  if (++tile->res == tile->maxNDecompLevels + 1) {
 	    tile->res = 0;
+	    tile->done = gTrue;
 	  }
 	}
       }
@@ -2398,6 +2417,7 @@
 	  tile->comp = 0;
 	  if (++tile->res == tile->maxNDecompLevels + 1) {
 	    tile->res = 0;
+	    tile->done = gTrue;
 	  }
 	}
       }
@@ -2411,6 +2431,7 @@
 	  tile->res = 0;
 	  if (++tile->comp == img.nComps) {
 	    tile->comp = 0;
+	    tile->done = gTrue;
 	  }
 	}
       }
@@ -2424,6 +2445,7 @@
 	  tile->res = 0;
 	  if (++tile->comp == img.nComps) {
 	    tile->comp = 0;
+	    tile->done = gTrue;
 	  }
 	}
       }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -230,10 +230,11 @@
 				//   in any component in this tile
 
   //----- progression order loop counters
-  Guint comp;			//   component
-  Guint res;			//   resolution level
-  Guint precinct;		//   precinct
-  Guint layer;			//   layer
+  Guint comp;			// component
+  Guint res;			// resolution level
+  Guint precinct;		// precinct
+  Guint layer;			// layer
+  GBool done;			// set when this tile is done
 
   //----- tile part info
   Guint nextTilePart;		// next expected tile-part
@@ -253,9 +254,6 @@
         yTileOffset;
   Guint xSizeR, ySizeR;		// size of reference grid >> reduction
   Guint xOffsetR, yOffsetR;	// image offset >> reduction
-  Guint xTileSizeR, yTileSizeR;	// size of tiles >> reduction
-  Guint xTileOffsetR,		// offset of first tile >> reduction
-        yTileOffsetR;
   Guint nComps;			// number of components
 
   //----- computed
@@ -287,7 +285,8 @@
   virtual void close();
   virtual int getChar();
   virtual int lookChar();
-  virtual GString *getPSFilter(int psLevel, const char *indent);
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
   virtual void getImageParams(int *bitsPerComponent,
 			      StreamColorSpaceMode *csMode);

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -112,7 +112,7 @@
 Object *Lexer::getObj(Object *obj) {
   char *p;
   int c, c2;
-  GBool comment, neg, doubleMinus, done;
+  GBool comment, neg, doubleMinus, done, invalid;
   int numParen;
   int xi;
   double xf, scale;
@@ -343,6 +343,7 @@
     p = tokBuf;
     n = 0;
     s = NULL;
+    invalid = gFalse;
     while ((c = lookChar()) != EOF && !specialChars[c]) {
       getChar();
       if (c == '#') {
@@ -370,6 +371,9 @@
 	  goto notEscChar;
 	}
 	getChar();
+	if (c == 0) {
+	  invalid = gTrue;
+	}
       }
      notEscChar:
       // the PDF spec claims that names are limited to 127 chars, but
@@ -385,7 +389,13 @@
 	s->append((char)c);
       }
     }
-    if (n < tokBufSize) {
+    if (invalid) {
+      error(errSyntaxError, getPos(), "Null character in name");
+      obj->initError();
+      if (s) {
+	delete s;
+      }
+    } else if (n < tokBufSize) {
       *p = '\0';
       obj->initName(tokBuf);
     } else {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -39,7 +39,7 @@
 
 PDFCore::PDFCore(SplashColorMode colorMode, int bitmapRowPad,
 		 GBool reverseVideo, SplashColorPtr paperColor) {
-  GString *initialZoom;
+  GString *initialZoom, *initialDisplayMode;
   int z, i;
 
   doc = NULL;
@@ -81,6 +81,19 @@
     state->setZoom(z);
   }
   delete initialZoom;
+  initialDisplayMode = globalParams->getInitialDisplayMode();
+  if (!initialDisplayMode->cmp("single")) {
+    state->setDisplayMode(displaySingle);
+  } else if (!initialDisplayMode->cmp("sideBySideSingle")) {
+    state->setDisplayMode(displaySideBySideSingle);
+  } else if (!initialDisplayMode->cmp("sideBySideContinuous")) {
+    state->setDisplayMode(displaySideBySideContinuous);
+  } else if (!initialDisplayMode->cmp("horizontalContinuous")) {
+    state->setDisplayMode(displayHorizontalContinuous);
+  } else {
+    state->setDisplayMode(displayContinuous);
+  }
+  delete initialDisplayMode;
 
   selectMode = selectModeBlock;
   selectPage = 0;
@@ -615,8 +628,8 @@
   scrollTo(state->getScrollX() + nCols, state->getScrollY());
 }
 
-void PDFCore::scrollUp(int nLines) {
-  scrollTo(state->getScrollX(), state->getScrollY() - nLines);
+void PDFCore::scrollUp(int nLines, GBool snapToPage) {
+  scrollTo(state->getScrollX(), state->getScrollY() - nLines, snapToPage);
 }
 
 void PDFCore::scrollUpPrevPage(int nLines) {
@@ -624,12 +637,12 @@
       state->getScrollY() == 0) {
     gotoPrevPage(1, gFalse, gTrue);
   } else {
-    scrollUp(nLines);
+    scrollUp(nLines, gTrue);
   }
 }
 
-void PDFCore::scrollDown(int nLines) {
-  scrollTo(state->getScrollX(), state->getScrollY() + nLines);
+void PDFCore::scrollDown(int nLines, GBool snapToPage) {
+  scrollTo(state->getScrollX(), state->getScrollY() + nLines, snapToPage);
 }
 
 void PDFCore::scrollDownNextPage(int nLines) {
@@ -643,7 +656,7 @@
       scrollDown(nLines);
     }
   } else {
-    scrollDown(nLines);
+    scrollDown(nLines, gTrue);
   }
 }
 
@@ -655,9 +668,35 @@
   scrollDownNextPage(state->getWinH());
 }
 
-void PDFCore::scrollTo(int x, int y) {
+void PDFCore::scrollTo(int x, int y, GBool snapToPage) {
+  int next, topPage, topPageY, sy, dy;
+
   startUpdate();
   state->setScrollPosition(state->getScrollPage(), x, y);
+
+  if (snapToPage) {
+    if (state->getDisplayMode() == displayContinuous ||
+	state->getDisplayMode() == displaySideBySideContinuous) {
+      next = state->getDisplayMode() == displaySideBySideContinuous ? 2 : 1;
+      topPage = tileMap->getFirstPage();
+      topPageY = tileMap->getPageTopY(topPage);
+      sy = state->getScrollY();
+      dy = sy - topPageY;
+      // note: dy can be negative here if the inter-page gap is at the
+      // top of the window
+      if (-16 < dy && dy < 16) {
+	state->setScrollPosition(state->getScrollPage(), x, topPageY);
+      } else if (topPage + next <= doc->getNumPages()) {
+	topPage += next;
+	topPageY = tileMap->getPageTopY(topPage);
+	dy = sy - topPageY;
+	if (-16 < dy && dy < 0) {
+	  state->setScrollPosition(state->getScrollPage(), x, topPageY);
+	}
+      }
+    }
+  }
+
   finishUpdate(gTrue, gTrue);
 }
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -135,13 +135,13 @@
   virtual GBool goBackward();
   virtual void scrollLeft(int nCols = 16);
   virtual void scrollRight(int nCols = 16);
-  virtual void scrollUp(int nLines = 16);
+  virtual void scrollUp(int nLines = 16, GBool snapToPage = gFalse);
   virtual void scrollUpPrevPage(int nLines = 16);
-  virtual void scrollDown(int nLines = 16);
+  virtual void scrollDown(int nLines = 16, GBool snapToPage = gFalse);
   virtual void scrollDownNextPage(int nLines = 16);
   virtual void scrollPageUp();
   virtual void scrollPageDown();
-  virtual void scrollTo(int x, int y);
+  virtual void scrollTo(int x, int y, GBool snapToPage = gFalse);
   virtual void scrollToLeftEdge();
   virtual void scrollToRightEdge();
   virtual void scrollToTopEdge();

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -46,6 +46,15 @@
 #define headerSearchSize 1024	// read this many bytes at beginning of
 				//   file to look for '%PDF'
 
+// Avoid sharing files with child processes on Windows, where sharing
+// can cause problems.
+#ifdef _WIN32
+#  define fopenReadMode "rbN"
+#  define wfopenReadMode L"rbN"
+#else
+#  define fopenReadMode "rb"
+#endif
+
 //------------------------------------------------------------------------
 // PDFDoc
 //------------------------------------------------------------------------
@@ -75,18 +84,18 @@
   // try to open file
   fileName2 = NULL;
 #ifdef VMS
-  if (!(file = fopen(fileName1->getCString(), "rb", "ctx=stm"))) {
+  if (!(file = fopen(fileName1->getCString(), fopenReadMode, "ctx=stm"))) {
     error(errIO, -1, "Couldn't open file '{0:t}'", fileName1);
     errCode = errOpenFile;
     return;
   }
 #else
-  if (!(file = fopen(fileName1->getCString(), "rb"))) {
+  if (!(file = fopen(fileName1->getCString(), fopenReadMode))) {
     fileName2 = fileName->copy();
     fileName2->lowerCase();
-    if (!(file = fopen(fileName2->getCString(), "rb"))) {
+    if (!(file = fopen(fileName2->getCString(), fopenReadMode))) {
       fileName2->upperCase();
-      if (!(file = fopen(fileName2->getCString(), "rb"))) {
+      if (!(file = fopen(fileName2->getCString(), fopenReadMode))) {
 	error(errIO, -1, "Couldn't open file '{0:t}'", fileName);
 	delete fileName2;
 	errCode = errOpenFile;
@@ -127,9 +136,9 @@
   version.dwOSVersionInfoSize = sizeof(version);
   GetVersionEx(&version);
   if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-    file = _wfopen(fileNameU, L"rb");
+    file = _wfopen(fileNameU, wfopenReadMode);
   } else {
-    file = fopen(fileName->getCString(), "rb");
+    file = fopen(fileName->getCString(), fopenReadMode);
   }
   if (!file) {
     error(errIO, -1, "Couldn't open file '{0:t}'", fileName);
@@ -181,18 +190,17 @@
   version.dwOSVersionInfoSize = sizeof(version);
   GetVersionEx(&version);
   if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-    file = _wfopen(fileNameU, L"rb");
+    file = _wfopen(fileNameU, wfopenReadMode);
   } else {
 #endif /* 0 */
-    file = fopen(fileName->getCString(), "rb");
+    file = fopen(fileName->getCString(), fopenReadMode);
 #if 0
   }
 #endif /* 0 */
-
 #elif defined(VMS)
-  file = fopen(fileName->getCString(), "rb", "ctx=stm");
+  file = fopen(fileName->getCString(), fopenReadMode, "ctx=stm");
 #else
-  file = fopen(fileName->getCString(), "rb");
+  file = fopen(fileName->getCString(), fopenReadMode);
 #endif
 
   if (!file) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDocEncoding.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDocEncoding.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDocEncoding.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -6,6 +6,7 @@
 //
 //========================================================================
 
+#include <aconf.h>
 #include "gmempp.h"
 #include "PDFDocEncoding.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -77,6 +77,7 @@
   "    put",
   "  } for",
   "~123ngs",
+  "/bdef { bind def } bind def",
   "/pdfSetup {",
   "  /pdfDuplex exch def",
   "  /setpagedevice where {",
@@ -393,9 +394,9 @@
   "/f { fCol fill } def",
   "/f* { fCol eofill } def",
   "% clipping operators",
-  "/W { clip newpath } def",
-  "/W* { eoclip newpath } def",
-  "/Ws { strokepath clip newpath } def",
+  "/W { clip newpath } bdef",
+  "/W* { eoclip newpath } bdef",
+  "/Ws { strokepath clip newpath } bdef",
   "% text state operators",
   "/Tc { /pdfCharSpacing exch def } def",
   "/Tf { dup /pdfFontSize exch def",
@@ -985,7 +986,9 @@
     { return (bufIdx >= bufSize && !fillBuf()) ? EOF : buf[bufIdx++]; }
   virtual int lookChar()
     { return (bufIdx >= bufSize && !fillBuf()) ? EOF : buf[bufIdx]; }
-  virtual GString *getPSFilter(int psLevel, const char *indent) { return NULL; }
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream)
+    { return NULL; }
   virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
   virtual GBool isEncoder() { return gTrue; }
 
@@ -1084,7 +1087,9 @@
     { return (bufIdx >= width && !fillBuf()) ? EOF : buf[bufIdx++]; }
   virtual int lookChar()
     { return (bufIdx >= width && !fillBuf()) ? EOF : buf[bufIdx]; }
-  virtual GString *getPSFilter(int psLevel, const char *indent) { return NULL; }
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream)
+    { return NULL; }
   virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
   virtual GBool isEncoder() { return gTrue; }
 
@@ -1167,7 +1172,9 @@
     { return (bufIdx >= bufSize && !fillBuf()) ? EOF : buf[bufIdx++]; }
   virtual int lookChar()
     { return (bufIdx >= bufSize && !fillBuf()) ? EOF : buf[bufIdx]; }
-  virtual GString *getPSFilter(int psLevel, const char *indent) { return NULL; }
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream)
+    { return NULL; }
   virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
   virtual GBool isEncoder() { return gTrue; }
 
@@ -3841,7 +3848,7 @@
       useLZW = useRLE = gFalse;
       useCompressed = gFalse;
     } else {
-      s = str->getPSFilter(level < psLevel3 ? 2 : 3, "");
+      s = str->getPSFilter(level < psLevel3 ? 2 : 3, "", gTrue);
       if (s) {
 	useLZW = useRLE = gFalse;
 	useCompressed = gTrue;
@@ -4191,7 +4198,13 @@
     }
     sliceX = sliceY = 0;
     sliceW = (int)((box.x2 - box.x1) * hDPI2 / 72.0);
+    if (sliceW == 0) {
+      sliceW = 1;
+    }
     sliceH = (int)((box.y2 - box.y1) * vDPI2 / 72.0);
+    if (sliceH == 0) {
+      sliceH = 1;
+    }
   }
   nStripes = (int)ceil(((double)sliceW * (double)sliceH) /
 		       (double)globalParams->getPSRasterSliceSize());
@@ -5223,6 +5236,7 @@
 
   // set the pattern
   if (paintType == 2) {
+    writePS("fCol\n");
     writePS("currentcolor ");
   }
   writePSFmt("xpdfTile{0:d} setpattern\n", numTilingPatterns);
@@ -6315,7 +6329,7 @@
     useASCII = gFalse;
   } else {
     s = str->getPSFilter(level < psLevel2 ? 1 : level < psLevel3 ? 2 : 3,
-			 "    ");
+			 "    ", !inlineImg);
     if ((colorMap && (colorMap->getColorSpace()->getMode() == csDeviceN ||
 		      level == psLevel2Gray || level == psLevel3Gray)) ||
 	inlineImg || !s) {
@@ -6790,7 +6804,7 @@
       maskUseCompressed = gFalse;
       maskUseASCII = gFalse;
     } else {
-      s = maskStr->getPSFilter(3, "  ");
+      s = maskStr->getPSFilter(3, "  ", !inlineImg);
       if (!s) {
 	if (globalParams->getPSLZW()) {
 	  maskUseLZW = gTrue;
@@ -7018,7 +7032,7 @@
     useCompressed = gFalse;
     useASCII = gFalse;
   } else {
-    s = str->getPSFilter(3, "    ");
+    s = str->getPSFilter(3, "    ", !inlineImg);
     if ((colorMap && level == psLevel3Gray) || inlineImg || !s) {
       if (globalParams->getPSLZW()) {
 	useLZW = gTrue;
@@ -7557,7 +7571,7 @@
       }
       obj1.free();
       sepCSObj.arrayGet(3, &funcObj);
-      if (!(func = Function::parse(&funcObj))) {
+      if (!(func = Function::parse(&funcObj, 1, 4))) {
 	funcObj.free();
 	sepCSObj.free();
 	colorants.free();
@@ -7564,12 +7578,6 @@
 	return NULL;
       }
       funcObj.free();
-      if (func->getInputSize() != 1 || func->getOutputSize() != 4) {
-	delete func;
-	sepCSObj.free();
-	colorants.free();
-	return NULL;
-      }
       sepIn = 1;
       func->transform(&sepIn, cmyk[i]);
       delete func;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -28,6 +28,7 @@
 #include "BuiltinFont.h"
 #include "BuiltinFontTables.h"
 #include "FoFiTrueType.h"
+#include "FoFiType1C.h"
 #include "JPXStream.h"
 #include "SplashBitmap.h"
 #include "SplashGlyphBitmap.h"
@@ -498,6 +499,7 @@
   int cacheAssoc;		// cache associativity (glyphs per set)
   Guchar *cacheData;		// glyph pixmap cache
   T3FontCacheTag *cacheTags;	// cache tags, i.e., char codes
+  GBool inUse;			// set while this T3 font is in active use
 };
 
 T3FontCache::T3FontCache(Ref *fontIDA, double m11A, double m12A,
@@ -539,6 +541,7 @@
   for (i = 0; i < cacheSets * cacheAssoc; ++i) {
     cacheTags[i].mru = (Gushort)(i & (cacheAssoc - 1));
   }
+  inUse = gFalse;
 }
 
 T3FontCache::~T3FontCache() {
@@ -615,8 +618,8 @@
   xref = NULL;
 
   bitmap = new SplashBitmap(1, 1, bitmapRowPad, colorMode,
-			    colorMode != splashModeMono1, bitmapTopDown);
-  splash = new Splash(bitmap, vectorAntialias, &screenParams);
+			    colorMode != splashModeMono1, bitmapTopDown, NULL);
+  splash = new Splash(bitmap, vectorAntialias, NULL, &screenParams);
   splash->setMinLineWidth(globalParams->getMinLineWidth());
   splash->setStrokeAdjust(
 		 mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
@@ -761,9 +764,10 @@
       bitmap = NULL;
     }
     bitmap = new SplashBitmap(w, h, bitmapRowPad, colorMode,
-			      colorMode != splashModeMono1, bitmapTopDown);
+			      colorMode != splashModeMono1, bitmapTopDown,
+			      NULL);
   }
-  splash = new Splash(bitmap, vectorAntialias, &screenParams);
+  splash = new Splash(bitmap, vectorAntialias, NULL, &screenParams);
   splash->setMinLineWidth(globalParams->getMinLineWidth());
   splash->setEnablePathSimplification(
 		 globalParams->getEnablePathSimplification());
@@ -804,6 +808,7 @@
   splash->setStrokeAdjust(
 	      mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
   splash->clear(paperColor, 0);
+  reverseVideoInvertImages = globalParams->getReverseVideoInvertImages();
   if (startPageCbk) {
     (*startPageCbk)(startPageCbkData);
   }
@@ -1149,6 +1154,7 @@
   SplashFontFile *fontFile;
   int fontNum;
   FoFiTrueType *ff;
+  FoFiType1C *ffT1C;
   Ref embRef;
   Object refObj, strObj;
 #if LOAD_FONTS_FROM_MEM
@@ -1166,9 +1172,9 @@
   double fsx, fsy, w, fontScaleMin, fontScaleAvg, fontScale;
   Gushort ww;
   SplashCoord mat[4];
-  char *name;
+  char *name, *start;
   Unicode uBuf[8];
-  int substIdx, n, code, cmap, cmapPlatform, cmapEncoding, i;
+  int substIdx, n, code, cmap, cmapPlatform, cmapEncoding, length, i;
 
   needFontUpdate = gFalse;
   font = NULL;
@@ -1306,6 +1312,17 @@
       }
       break;
     case fontType1C:
+#if LOAD_FONTS_FROM_MEM
+      if ((ffT1C = FoFiType1C::make(fontBuf->getCString(),
+				    fontBuf->getLength()))) {
+#else
+      if ((ffT1C = FoFiType1C::load(fileName->getCString()))) {
+#endif
+	codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ffT1C);
+	delete ffT1C;
+      } else {
+	codeToGID = NULL;
+      }
       if (!(fontFile = fontEngine->loadType1CFont(
 		   id,
 #if LOAD_FONTS_FROM_MEM
@@ -1314,6 +1331,7 @@
 		   fileName->getCString(),
 		   fileName == tmpFileName,
 #endif
+		   codeToGID,
 		   (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
 	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
@@ -1323,6 +1341,21 @@
       }
       break;
     case fontType1COT:
+      codeToGID = NULL;
+#if LOAD_FONTS_FROM_MEM
+      if ((ff = FoFiTrueType::make(fontBuf->getCString(), fontBuf->getLength(),
+				   fontNum, gTrue))) {
+#else
+	if ((ff = FoFiTrueType::load(fileName->getCString(),
+				     fontNum, gTrue))) {
+#endif
+	if (ff->getCFFBlock(&start, &length) &&
+	    (ffT1C = FoFiType1C::make(start, length))) {
+	  codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ffT1C);
+	  delete ffT1C;
+	}
+	delete ff;
+      }
       if (!(fontFile = fontEngine->loadOpenTypeT1CFont(
 		   id,
 #if LOAD_FONTS_FROM_MEM
@@ -1331,6 +1364,7 @@
 		   fileName->getCString(),
 		   fileName == tmpFileName,
 #endif
+		   codeToGID,
 		   (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
 	error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
 	      gfxFont->getName() ? gfxFont->getName()->getCString()
@@ -1559,6 +1593,7 @@
       break;
     default:
       // this shouldn't happen
+      delete fontLoc;
       goto err2;
     }
 
@@ -1593,8 +1628,8 @@
 	   (name[0] >= 'a' && name[0] <= 'z') ||
 	   (name[0] >= '0' && name[0] <= '9'))) {
 	w = ((Gfx8BitFont *)gfxFont)->getWidth((Guchar)code);
-	builtinFontSubst[substIdx]->widths->getWidth(name, &ww);
-	if (w > 0.01 && ww > 10) {
+	if (builtinFontSubst[substIdx]->widths->getWidth(name, &ww) &&
+	    w > 0.01 && ww > 10) {
 	  w /= ww * 0.001;
 	  if (w < fontScaleMin) {
 	    fontScaleMin = w;
@@ -1780,7 +1815,10 @@
 
   // check for an excessively large tile size
   tileSize = tileW * tileH;
-  if (tileSize > 1000000 || tileSize < 0) {
+  if (tileXMax - tileXMin + 0.5 > (double)INT_MAX ||
+      tileYMax - tileYMin + 0.5 > (double)INT_MAX ||
+      tileW > INT_MAX / tileH ||
+      tileSize > 1000000) {
     mat1[0] = mat[0];
     mat1[1] = mat[1];
     mat1[2] = mat[2];
@@ -1932,8 +1970,10 @@
   origBitmap = bitmap;
   origSplash = splash;
   bitmap = tileBitmap = new SplashBitmap(tileW, tileH, bitmapRowPad,
-					 colorMode, gTrue, bitmapTopDown);
-  splash = new Splash(bitmap, vectorAntialias, origSplash->getScreen());
+					 colorMode, gTrue, bitmapTopDown,
+					 origBitmap);
+  splash = new Splash(bitmap, vectorAntialias,
+		      origSplash->getImageCache(), origSplash->getScreen());
   for (i = 0; i < splashMaxColorComps; ++i) {
     color[i] = 0;
   }
@@ -2085,7 +2125,7 @@
   bitmapWidth = ixMax - ixMin;
   bitmapHeight = iyMax - iyMin;
   tBitmap = new SplashBitmap(bitmapWidth, bitmapHeight, 1,
-			     srcMode, gTrue, gTrue);
+			     srcMode, gTrue, gTrue, bitmap);
   memset(tBitmap->getAlphaPtr(), 0, (size_t)bitmapWidth * bitmapHeight);
   nComps = splashColorModeNComps[srcMode];
 
@@ -2403,7 +2443,7 @@
   bitmapWidth = ixMax - ixMin;
   bitmapHeight = iyMax - iyMin;
   tBitmap = new SplashBitmap(bitmapWidth, bitmapHeight, 1,
-			     srcMode, gTrue, gTrue);
+			     srcMode, gTrue, gTrue, bitmap);
   memset(tBitmap->getAlphaPtr(), 0, tBitmap->getAlphaRowSize() * bitmapHeight);
   nComps = splashColorModeNComps[srcMode];
 
@@ -2908,13 +2948,26 @@
     if (i >= nT3Fonts) {
 
       // create new entry in the font cache
-      if (nT3Fonts == splashOutT3FontCacheSize) {
-	delete t3FontCache[nT3Fonts - 1];
+      if (nT3Fonts < splashOutT3FontCacheSize) {
+	for (j = nT3Fonts; j > 0; --j) {
+	  t3FontCache[j] = t3FontCache[j - 1];
+	}
+      } else {
+	for (j = nT3Fonts - 1; j >= 0; --j) {
+	  if (!t3FontCache[j]->inUse) {
+	    break;
+	  }
+	}
+	if (j < 0) {
+	  error(errSyntaxError, -1, "Type 3 fonts nested too deeply");
+	  return gTrue;
+	}
+	delete t3FontCache[j];
 	--nT3Fonts;
+	for (; j > 0; --j) {
+	  t3FontCache[j] = t3FontCache[j - 1];
+	}
       }
-      for (j = nT3Fonts; j > 0; --j) {
-	t3FontCache[j] = t3FontCache[j - 1];
-      }
       ++nT3Fonts;
       bbox = gfxFont->getFontBBox();
       if (bbox[0] == 0 && bbox[1] == 0 && bbox[2] == 0 && bbox[3] == 0) {
@@ -2985,6 +3038,8 @@
     }
   }
 
+  t3Font->inUse = gTrue;
+
   // push a new Type 3 glyph record
   t3gs = new T3GlyphStack();
   t3gs->next = t3GlyphStack;
@@ -3021,6 +3076,7 @@
   }
   t3gs = t3GlyphStack;
   t3GlyphStack = t3gs->next;
+  t3gs->cache->inUse = gFalse;
   delete t3gs;
 }
 
@@ -3131,8 +3187,10 @@
   if (colorMode == splashModeMono1) {
     colorMode = splashModeMono1;
     bitmap = new SplashBitmap(t3Font->glyphW, t3Font->glyphH, 1,
-			      splashModeMono1, gFalse);
-    splash = new Splash(bitmap, gFalse, t3GlyphStack->origSplash->getScreen());
+			      splashModeMono1, gFalse, gTrue, bitmap);
+    splash = new Splash(bitmap, gFalse,
+			t3GlyphStack->origSplash->getImageCache(), 
+			t3GlyphStack->origSplash->getScreen());
     color[0] = 0;
     splash->clear(color);
     color[0] = 0xff;
@@ -3139,8 +3197,9 @@
   } else {
     colorMode = splashModeMono8;
     bitmap = new SplashBitmap(t3Font->glyphW, t3Font->glyphH, 1,
-			      splashModeMono8, gFalse);
+			      splashModeMono8, gFalse, gTrue, bitmap);
     splash = new Splash(bitmap, vectorAntialias,
+			t3GlyphStack->origSplash->getImageCache(), 
 			t3GlyphStack->origSplash->getScreen());
     color[0] = 0x00;
     splash->clear(color);
@@ -3214,6 +3273,7 @@
   double *ctm;
   SplashCoord mat[6];
   SplashOutImageMaskData imgMaskData;
+  GString *imgTag;
 
   if (state->getFillColorSpace()->isNonMarking()) {
     return;
@@ -3239,8 +3299,11 @@
   imgMaskData.height = height;
   imgMaskData.y = 0;
 
-  splash->fillImageMask(&imageMaskSrc, &imgMaskData, width, height, mat,
+  imgTag = makeImageTag(ref);
+  splash->fillImageMask(imgTag,
+			&imageMaskSrc, &imgMaskData, width, height, mat,
 			t3GlyphStack != NULL, interpolate);
+
   if (inlineImg) {
     while (imgMaskData.y < height) {
       imgMaskData.imgStr->getLine();
@@ -3248,6 +3311,7 @@
     }
   }
 
+  delete imgTag;
   delete imgMaskData.imgStr;
   str->close();
 }
@@ -3264,6 +3328,7 @@
   SplashBitmap *maskBitmap;
   Splash *maskSplash;
   SplashColor maskColor;
+  GString *imgTag;
 
   ctm = state->getCTM();
   mat[0] = ctm[0];
@@ -3280,8 +3345,8 @@
   imgMaskData.height = height;
   imgMaskData.y = 0;
   maskBitmap = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
-				1, splashModeMono8, gFalse);
-  maskSplash = new Splash(maskBitmap, gTrue);
+				1, splashModeMono8, gFalse, gTrue, bitmap);
+  maskSplash = new Splash(maskBitmap, gTrue, splash->getImageCache());
   maskSplash->setStrokeAdjust(
 		     mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
   maskSplash->setEnablePathSimplification(
@@ -3289,8 +3354,10 @@
   clearMaskRegion(state, maskSplash, 0, 0, 1, 1);
   maskColor[0] = 0xff;
   maskSplash->setFillPattern(new SplashSolidColor(maskColor));
-  maskSplash->fillImageMask(&imageMaskSrc, &imgMaskData,
+  imgTag = makeImageTag(ref);
+  maskSplash->fillImageMask(imgTag, &imageMaskSrc, &imgMaskData,
 			    width, height, mat, gFalse, interpolate);
+  delete imgTag;
   delete imgMaskData.imgStr;
   str->close();
   delete maskSplash;
@@ -3304,6 +3371,7 @@
   SplashColorPtr lookup;
   int *maskColors;
   SplashColorMode colorMode;
+  GBool invert;
   int width, height, y;
 };
 
@@ -3312,7 +3380,7 @@
   SplashOutImageData *imgData = (SplashOutImageData *)data;
   Guchar *p;
   SplashColorPtr q, col;
-  int x;
+  int n, x;
 
   if (imgData->y == imgData->height ||
       !(p = imgData->imgStr->getLine())) {
@@ -3371,6 +3439,13 @@
     }
   }
 
+  if (imgData->invert) {
+    n = imgData->width * splashColorModeNComps[imgData->colorMode];
+    for (x = 0, p = colorLine; x < n; ++x, ++p) {
+      *p ^= 0xff;
+    }
+  }
+
   ++imgData->y;
   return gTrue;
 }
@@ -3381,7 +3456,7 @@
   Guchar *p0, *p, *aq;
   SplashColorPtr q, col;
   Guchar alpha;
-  int nComps, x, i;
+  int nComps, x, n, i;
 
   if (imgData->y == imgData->height ||
       !(p0 = imgData->imgStr->getLine())) {
@@ -3455,6 +3530,13 @@
     *aq++ = alpha;
   }
 
+  if (imgData->invert) {
+    n = imgData->width * splashColorModeNComps[imgData->colorMode];
+    for (x = 0, p = colorLine; x < n; ++x, ++p) {
+      *p ^= 0xff;
+    }
+  }
+
   ++imgData->y;
   return gTrue;
 }
@@ -3470,6 +3552,7 @@
   SplashOutImageData imgData;
   SplashColorMode srcMode;
   SplashImageSource src;
+  GString *imgTag;
   GfxGray gray;
   GfxRGB rgb;
 #if SPLASH_CMYK
@@ -3500,6 +3583,7 @@
   imgData.ri = state->getRenderingIntent();
   imgData.maskColors = maskColors;
   imgData.colorMode = colorMode;
+  imgData.invert = reverseVideo && reverseVideoInvertImages;
   imgData.width = width;
   imgData.height = height;
   imgData.y = 0;
@@ -3559,7 +3643,9 @@
     srcMode = colorMode;
   }
   src = maskColors ? &alphaImageSrc : &imageSrc;
-  splash->drawImage(src, &imgData, srcMode, maskColors ? gTrue : gFalse,
+  imgTag = makeImageTag(ref);
+  splash->drawImage(imgTag,
+		    src, &imgData, srcMode, maskColors ? gTrue : gFalse,
 		    width, height, mat, interpolate);
   if (inlineImg) {
     while (imgData.y < height) {
@@ -3568,6 +3654,7 @@
     }
   }
 
+  delete imgTag;
   gfree(imgData.lookup);
   delete imgData.imgStr;
   str->close();
@@ -3580,6 +3667,7 @@
   SplashBitmap *mask;
   SplashColorPtr lookup;
   SplashColorMode colorMode;
+  GBool invert;
   int width, height, y;
 };
 
@@ -3591,7 +3679,7 @@
   static Guchar bitToByte[2] = {0x00, 0xff};
   Guchar *maskPtr;
   int maskShift;
-  int x;
+  int n, x;
 
   if (imgData->y == imgData->height ||
       !(p = imgData->imgStr->getLine())) {
@@ -3672,6 +3760,13 @@
     }
   }
 
+  if (imgData->invert) {
+    n = imgData->width * splashColorModeNComps[imgData->colorMode];
+    for (x = 0, p = colorLine; x < n; ++x, ++p) {
+      *p ^= 0xff;
+    }
+  }
+
   ++imgData->y;
   return gTrue;
 }
@@ -3692,6 +3787,7 @@
   SplashColorMode srcMode;
   SplashBitmap *maskBitmap;
   Splash *maskSplash;
+  GString *imgTag;
   SplashColor maskColor;
   GfxGray gray;
   GfxRGB rgb;
@@ -3741,8 +3837,9 @@
     imgMaskData.width = maskWidth;
     imgMaskData.height = maskHeight;
     imgMaskData.y = 0;
-    maskBitmap = new SplashBitmap(width, height, 1, splashModeMono1, gFalse);
-    maskSplash = new Splash(maskBitmap, gFalse);
+    maskBitmap = new SplashBitmap(width, height, 1, splashModeMono1,
+				  gFalse, gTrue, bitmap);
+    maskSplash = new Splash(maskBitmap, gFalse, splash->getImageCache());
     maskSplash->setStrokeAdjust(
 		       mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
     maskSplash->setEnablePathSimplification(
@@ -3752,7 +3849,7 @@
     maskColor[0] = 0xff;
     maskSplash->setFillPattern(new SplashSolidColor(maskColor));
     // use "glyph mode" here to get the correct scaled size
-    maskSplash->fillImageMask(&imageMaskSrc, &imgMaskData,
+    maskSplash->fillImageMask(NULL, &imageMaskSrc, &imgMaskData,
 			      maskWidth, maskHeight, mat, gTrue, interpolate);
     delete imgMaskData.imgStr;
     maskStr->close();
@@ -3775,6 +3872,7 @@
     imgData.ri = state->getRenderingIntent();
     imgData.mask = maskBitmap;
     imgData.colorMode = colorMode;
+    imgData.invert = reverseVideo && reverseVideoInvertImages;
     imgData.width = width;
     imgData.height = height;
     imgData.y = 0;
@@ -3833,9 +3931,12 @@
     } else {
       srcMode = colorMode;
     }
-    splash->drawImage(&maskedImageSrc, &imgData, srcMode, gTrue,
+    imgTag = makeImageTag(ref);
+    splash->drawImage(imgTag,
+		      &maskedImageSrc, &imgData, srcMode, gTrue,
 		      width, height, mat, interpolate);
 
+    delete imgTag;
     delete maskBitmap;
     gfree(imgData.lookup);
     delete imgData.imgStr;
@@ -3850,6 +3951,7 @@
   GfxRenderingIntent ri;
   Guchar matte[gfxColorMaxComps];
   SplashColorMode colorMode;
+  GBool invert;
   int width, height, y;
 };
 
@@ -3866,7 +3968,7 @@
   GfxCMYK cmyk;
 #endif
   Guchar alpha;
-  int nComps, x;
+  int nComps, n, x;
 
   if (imgData->y == imgData->height ||
       !(p = imgData->imgStr->getLine()) ||
@@ -3938,6 +4040,13 @@
     *aq++ = alpha;
   }
 
+  if (imgData->invert) {
+    n = imgData->width * splashColorModeNComps[imgData->colorMode];
+    for (x = 0, p = colorLine; x < n; ++x, ++p) {
+      *p ^= 0xff;
+    }
+  }
+
   ++imgData->y;
   return gTrue;
 }
@@ -3955,6 +4064,7 @@
   SplashOutImageData imgData;
   SplashOutImageData imgMaskData;
   SplashOutSoftMaskMatteImageData matteImgData;
+  GString *imgTag;
   SplashColorMode srcMode;
   SplashBitmap *maskBitmap;
   Splash *maskSplash;
@@ -4044,11 +4154,14 @@
       n = 1 << 8;
     }
     matteImgData.colorMode = colorMode;
+    matteImgData.invert = reverseVideo && reverseVideoInvertImages;
     matteImgData.width = width;
     matteImgData.height = height;
     matteImgData.y = 0;
-    splash->drawImage(&softMaskMatteImageSrc, &matteImgData,
+    imgTag = makeImageTag(ref);
+    splash->drawImage(imgTag, &softMaskMatteImageSrc, &matteImgData,
 		      srcMode, gTrue, width, height, mat, interpolate);
+    delete imgTag;
     delete matteImgData.maskStr;
     delete matteImgData.imgStr;
     maskStr->close();
@@ -4069,6 +4182,7 @@
     imgMaskData.ri = state->getRenderingIntent();
     imgMaskData.maskColors = NULL;
     imgMaskData.colorMode = splashModeMono8;
+    imgMaskData.invert = gFalse;
     imgMaskData.width = maskWidth;
     imgMaskData.height = maskHeight;
     imgMaskData.y = 0;
@@ -4080,14 +4194,16 @@
       imgMaskData.lookup[i] = colToByte(gray);
     }
     maskBitmap = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
-				  1, splashModeMono8, gFalse);
-    maskSplash = new Splash(maskBitmap, vectorAntialias);
+				  1, splashModeMono8, gFalse, gTrue, bitmap);
+    maskSplash = new Splash(maskBitmap, vectorAntialias,
+			    splash->getImageCache());
     maskSplash->setStrokeAdjust(
 		       mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
     maskSplash->setEnablePathSimplification(
 		       globalParams->getEnablePathSimplification());
     clearMaskRegion(state, maskSplash, 0, 0, 1, 1);
-    maskSplash->drawImage(&imageSrc, &imgMaskData, splashModeMono8, gFalse,
+    maskSplash->drawImage(NULL,
+			  &imageSrc, &imgMaskData, splashModeMono8, gFalse,
 			  maskWidth, maskHeight, mat, interpolate);
     delete imgMaskData.imgStr;
     maskStr->close();
@@ -4105,6 +4221,7 @@
     imgData.ri = state->getRenderingIntent();
     imgData.maskColors = NULL;
     imgData.colorMode = colorMode;
+    imgData.invert = reverseVideo && reverseVideoInvertImages;
     imgData.width = width;
     imgData.height = height;
     imgData.y = 0;
@@ -4156,10 +4273,13 @@
       }
     }
 
-    splash->drawImage(&imageSrc, &imgData, srcMode, gFalse, width, height, mat,
+    imgTag = makeImageTag(ref);
+    splash->drawImage(imgTag,
+		      &imageSrc, &imgData, srcMode, gFalse, width, height, mat,
 		      interpolate);
 
     splash->setSoftMask(NULL);
+    delete imgTag;
     gfree(imgData.lookup);
     delete imgData.imgStr;
 
@@ -4168,6 +4288,13 @@
   }
 }
 
+GString *SplashOutputDev::makeImageTag(Object *ref) {
+  if (!ref || !ref->isRef()) {
+    return NULL;
+  }
+  return GString::format("{0:d}_{1:d}", ref->getRefNum(), ref->getRefGen());
+}
+
 void SplashOutputDev::reduceImageResolution(Stream *str, double *ctm,
 					    int *width, int *height) {
   double sw, sh;
@@ -4174,6 +4301,8 @@
   int reduction;
 
   if (str->getKind() == strJPX &&
+      *width >= 256 &&
+      *height >= 256 &&
       *width * *height > 10000000) {
     sw = (double)*width / (fabs(ctm[0]) + fabs(ctm[1]));
     sh = (double)*height / (fabs(ctm[2]) + fabs(ctm[3]));
@@ -4396,8 +4525,9 @@
 
   // create the temporary bitmap
   bitmap = new SplashBitmap(w, h, bitmapRowPad, colorMode, gTrue,
-			    bitmapTopDown); 
+			    bitmapTopDown, transpGroup->origBitmap); 
   splash = new Splash(bitmap, vectorAntialias,
+		      transpGroup->origSplash->getImageCache(),
 		      transpGroup->origSplash->getScreen());
   splash->setMinLineWidth(globalParams->getMinLineWidth());
   splash->setStrokeAdjust(
@@ -4415,11 +4545,12 @@
   }
   if (!isolated &&
       transpGroup->origBitmap->getAlphaPtr() &&
-      transpGroup->origSplash->getInNonIsolatedGroup()) {
+      transpGroup->origSplash->getInNonIsolatedGroup() &&
+      colorMode != splashModeMono1) {
     // when drawing a non-isolated group into another non-isolated group,
     // compute a backdrop bitmap with corrected alpha values
     backdropBitmap = new SplashBitmap(w, h, bitmapRowPad, colorMode, gTrue,
-				      bitmapTopDown);
+				      bitmapTopDown, transpGroup->origBitmap);
     transpGroup->origSplash->blitCorrectedAlpha(backdropBitmap,
 						tx, ty, 0, 0, w, h);
     transpGroup->backdropBitmap = backdropBitmap;
@@ -4521,6 +4652,7 @@
     //~ space is given
     if (transpGroupStack->blendingColorSpace) {
       tSplash = new Splash(tBitmap, vectorAntialias,
+			   transpGroupStack->origSplash->getImageCache(),
 			   transpGroupStack->origSplash->getScreen());
       tSplash->setStrokeAdjust(
 		      mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
@@ -4578,7 +4710,7 @@
   }
 
   softMask = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
-			      1, splashModeMono8, gFalse);
+			      1, splashModeMono8, gFalse, gTrue, bitmap);
   memset(softMask->getDataPtr(), (int)(backdrop2 * 255.0 + 0.5),
 	 softMask->getRowSize() * softMask->getHeight());
   if (tx < softMask->getWidth() && ty < softMask->getHeight()) {
@@ -4660,7 +4792,7 @@
 
   ret = bitmap;
   bitmap = new SplashBitmap(1, 1, bitmapRowPad, colorMode,
-			    colorMode != splashModeMono1, bitmapTopDown);
+			    colorMode != splashModeMono1, bitmapTopDown, NULL);
   return ret;
 }
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -279,6 +279,7 @@
   static GBool softMaskMatteImageSrc(void *data,
 				     SplashColorPtr colorLine,
 				     Guchar *alphaLine);
+  GString *makeImageTag(Object *ref);
   void reduceImageResolution(Stream *str, double *mat,
 			     int *width, int *height);
   void clearMaskRegion(GfxState *state,
@@ -295,6 +296,7 @@
   GBool allowAntialias;
   GBool vectorAntialias;
   GBool reverseVideo;		// reverse video mode
+  GBool reverseVideoInvertImages;
   SplashColor paperColor;	// paper color
   SplashScreenParams screenParams;
   GBool skipHorizText;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -121,7 +121,8 @@
   return count;
 }
 
-GString *Stream::getPSFilter(int psLevel, const char *indent) {
+GString *Stream::getPSFilter(int psLevel, const char *indent,
+			     GBool okToReadStream) {
   return new GString();
 }
 
@@ -132,15 +133,15 @@
   int i;
 
   str = this;
-  dict->dictLookup("Filter", &obj);
+  dict->dictLookup("Filter", &obj, recursion);
   if (obj.isNull()) {
     obj.free();
-    dict->dictLookup("F", &obj);
+    dict->dictLookup("F", &obj, recursion);
   }
-  dict->dictLookup("DecodeParms", &params);
+  dict->dictLookup("DecodeParms", &params, recursion);
   if (params.isNull()) {
     params.free();
-    dict->dictLookup("DP", &params);
+    dict->dictLookup("DP", &params, recursion);
   }
   if (obj.isName()) {
     str = makeFilter(obj.getName(), str, &params, recursion);
@@ -1096,13 +1097,14 @@
   return buf;
 }
 
-GString *ASCIIHexStream::getPSFilter(int psLevel, const char *indent) {
+GString *ASCIIHexStream::getPSFilter(int psLevel, const char *indent,
+				     GBool okToReadStream) {
   GString *s;
 
   if (psLevel < 2) {
     return NULL;
   }
-  if (!(s = str->getPSFilter(psLevel, indent))) {
+  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
     return NULL;
   }
   s->append(indent)->append("/ASCIIHexDecode filter\n");
@@ -1181,13 +1183,14 @@
   return b[index];
 }
 
-GString *ASCII85Stream::getPSFilter(int psLevel, const char *indent) {
+GString *ASCII85Stream::getPSFilter(int psLevel, const char *indent,
+				    GBool okToReadStream) {
   GString *s;
 
   if (psLevel < 2) {
     return NULL;
   }
-  if (!(s = str->getPSFilter(psLevel, indent))) {
+  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
     return NULL;
   }
   s->append(indent)->append("/ASCII85Decode filter\n");
@@ -1408,13 +1411,14 @@
   return code;
 }
 
-GString *LZWStream::getPSFilter(int psLevel, const char *indent) {
+GString *LZWStream::getPSFilter(int psLevel, const char *indent,
+				GBool okToReadStream) {
   GString *s;
 
   if (psLevel < 2 || pred) {
     return NULL;
   }
-  if (!(s = str->getPSFilter(psLevel, indent))) {
+  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
     return NULL;
   }
   s->append(indent)->append("<< ");
@@ -1474,13 +1478,14 @@
   return n;
 }
 
-GString *RunLengthStream::getPSFilter(int psLevel, const char *indent) {
+GString *RunLengthStream::getPSFilter(int psLevel, const char *indent,
+				      GBool okToReadStream) {
   GString *s;
 
   if (psLevel < 2) {
     return NULL;
   }
-  if (!(s = str->getPSFilter(psLevel, indent))) {
+  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
     return NULL;
   }
   s->append(indent)->append("/RunLengthDecode filter\n");
@@ -2012,7 +2017,7 @@
 	lookBits(1);
 	eatBits(1);
       }
-      if (encoding >= 0) {
+      if (encoding > 0) {
 	for (i = 0; i < 4; ++i) {
 	  code1 = lookBits(12);
 	  if (code1 != 0x001) {
@@ -2260,7 +2265,8 @@
   return (short)((inputBuf >> (inputBits - n)) & (0xffffffff >> (32 - n)));
 }
 
-GString *CCITTFaxStream::getPSFilter(int psLevel, const char *indent) {
+GString *CCITTFaxStream::getPSFilter(int psLevel, const char *indent,
+				     GBool okToReadStream) {
   GString *s;
   char s1[50];
 
@@ -2267,7 +2273,7 @@
   if (psLevel < 2) {
     return NULL;
   }
-  if (!(s = str->getPSFilter(psLevel, indent))) {
+  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
     return NULL;
   }
   s->append(indent)->append("<< ");
@@ -2384,6 +2390,11 @@
   jpeg_start_decompress(&decomp);
 }
 
+GBool DCTStream::checkSequentialInterleaved() {
+  //~ this is unimplemented
+  return gTrue;
+}
+
 void DCTStream::close() {
   // we don't call jpeg_finish_decompress() here because it will report
   // an error if the full image wasn't read
@@ -2754,6 +2765,28 @@
   }
 }
 
+GBool DCTStream::checkSequentialInterleaved() {
+  GBool headerOk;
+
+  str->reset();
+
+  progressive = interleaved = gFalse;
+  width = height = 0;
+  numComps = 0;
+  numQuantTables = 0;
+  numDCHuffTables = 0;
+  numACHuffTables = 0;
+  gotJFIFMarker = gFalse;
+  gotAdobeMarker = gFalse;
+  restartInterval = 0;
+
+  headerOk = readHeader(gTrue);
+
+  FilterStream::close();
+
+  return headerOk && !progressive && interleaved;
+}
+
 void DCTStream::close() {
   int i;
 
@@ -3755,7 +3788,7 @@
 
 GBool DCTStream::readHeader(GBool frame) {
   GBool doScan;
-  int n;
+  int n, i;
   int c = 0;
 
   // read headers
@@ -3850,6 +3883,13 @@
     }
   }
 
+  for (i = 0; i < numComps; ++i) {
+    if (compInfo[i].quantTable >= numQuantTables) {
+      error(errSyntaxError, getPos(), "Invalid DCT quant table selector");
+      return gFalse;
+    }
+  }
+
   return gTrue;
 }
 
@@ -3878,8 +3918,14 @@
     compInfo[i].hSample = (c >> 4) & 0x0f;
     compInfo[i].vSample = c & 0x0f;
     compInfo[i].quantTable = str->getChar();
-    if (compInfo[i].hSample < 1 || compInfo[i].hSample > 4 ||
-	compInfo[i].vSample < 1 || compInfo[i].vSample > 4) {
+    // a sampling factor of 3 is allowed by the spec, but requires
+    // messy upsampling, and appears not to be used in practice
+    if (!(compInfo[i].hSample == 1 ||
+	  compInfo[i].hSample == 2 ||
+	  compInfo[i].hSample == 4) ||
+	!(compInfo[i].vSample == 1 ||
+	  compInfo[i].vSample == 2 ||
+	  compInfo[i].vSample == 4)) {
       error(errSyntaxError, getPos(), "Bad DCT sampling factor");
       return gFalse;
     }
@@ -3917,8 +3963,14 @@
     compInfo[i].hSample = (c >> 4) & 0x0f;
     compInfo[i].vSample = c & 0x0f;
     compInfo[i].quantTable = str->getChar();
-    if (compInfo[i].hSample < 1 || compInfo[i].hSample > 4 ||
-	compInfo[i].vSample < 1 || compInfo[i].vSample > 4) {
+    // a sampling factor of 3 is allowed by the spec, but requires
+    // messy upsampling, and appears not to be used in practice
+    if (!(compInfo[i].hSample == 1 ||
+	  compInfo[i].hSample == 2 ||
+	  compInfo[i].hSample == 4) ||
+	!(compInfo[i].vSample == 1 ||
+	  compInfo[i].vSample == 2 ||
+	  compInfo[i].vSample == 4)) {
       error(errSyntaxError, getPos(), "Bad DCT sampling factor");
       return gFalse;
     }
@@ -4182,15 +4234,21 @@
 
 #endif // HAVE_JPEGLIB
 
-GString *DCTStream::getPSFilter(int psLevel, const char *indent) {
+GString *DCTStream::getPSFilter(int psLevel, const char *indent,
+				GBool okToReadStream) {
   GString *s;
 
   if (psLevel < 2) {
     return NULL;
   }
-  if (!(s = str->getPSFilter(psLevel, indent))) {
+  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
     return NULL;
   }
+  if (okToReadStream && !checkSequentialInterleaved()) {
+    // PostScript does not allow progressive or interleaved JPEG
+    delete s;
+    return NULL;
+  }
   s->append(indent)->append("<< >> /DCTDecode filter\n");
   return s;
 }
@@ -4982,13 +5040,14 @@
   return n;
 }
 
-GString *FlateStream::getPSFilter(int psLevel, const char *indent) {
+GString *FlateStream::getPSFilter(int psLevel, const char *indent,
+				  GBool okToReadStream) {
   GString *s;
 
   if (psLevel < 3 || pred) {
     return NULL;
   }
-  if (!(s = str->getPSFilter(psLevel, indent))) {
+  if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
     return NULL;
   }
   s->append(indent)->append("<< >> /FlateDecode filter\n");

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -117,7 +117,8 @@
   virtual void setPos(GFileOffset pos, int dir = 0) = 0;
 
   // Get PostScript command for the filter(s).
-  virtual GString *getPSFilter(int psLevel, const char *indent);
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream);
 
   // Does this stream type potentially contain non-printable chars?
   virtual GBool isBinary(GBool last = gTrue) = 0;
@@ -422,7 +423,8 @@
   virtual int getChar()
     { int c = lookChar(); buf = EOF; return c; }
   virtual int lookChar();
-  virtual GString *getPSFilter(int psLevel, const char *indent);
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
 
 private:
@@ -446,7 +448,8 @@
   virtual int getChar()
     { int ch = lookChar(); ++index; return ch; }
   virtual int lookChar();
-  virtual GString *getPSFilter(int psLevel, const char *indent);
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
 
 private:
@@ -474,7 +477,8 @@
   virtual int lookChar();
   virtual int getRawChar();
   virtual int getBlock(char *blk, int size);
-  virtual GString *getPSFilter(int psLevel, const char *indent);
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
 
 private:
@@ -520,7 +524,8 @@
   virtual int lookChar()
     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
   virtual int getBlock(char *blk, int size);
-  virtual GString *getPSFilter(int psLevel, const char *indent);
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
 
 private:
@@ -552,7 +557,8 @@
   virtual int getChar();
   virtual int lookChar();
   virtual int getBlock(char *blk, int size);
-  virtual GString *getPSFilter(int psLevel, const char *indent);
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
 
 private:
@@ -650,12 +656,15 @@
   virtual int getChar();
   virtual int lookChar();
   virtual int getBlock(char *blk, int size);
-  virtual GString *getPSFilter(int psLevel, const char *indent);
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
   Stream *getRawStream() { return str; }
 
 private:
 
+  GBool checkSequentialInterleaved();
+
 #if HAVE_JPEGLIB
 
   int colorXform;		// color transform: -1 = unspecified
@@ -785,7 +794,8 @@
   virtual int lookChar();
   virtual int getRawChar();
   virtual int getBlock(char *blk, int size);
-  virtual GString *getPSFilter(int psLevel, const char *indent);
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
 
 private:
@@ -840,7 +850,8 @@
   virtual int getChar() { return EOF; }
   virtual int lookChar() { return EOF; }
   virtual int getBlock(char *blk, int size) { return 0; }
-  virtual GString *getPSFilter(int psLevel, const char *indent)
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream)
     { return NULL; }
   virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
 };
@@ -859,7 +870,8 @@
   virtual void reset();
   virtual int getChar();
   virtual int lookChar();
-  virtual GString *getPSFilter(int psLevel, const char *indent)
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream)
     { return NULL; }
   virtual GBool isBinary(GBool last = gTrue);
 
@@ -885,7 +897,8 @@
   virtual void reset();
   virtual int getChar();
   virtual int lookChar();
-  virtual GString *getPSFilter(int psLevel, const char *indent)
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream)
     { return NULL; }
   virtual GBool isBinary(GBool last = gTrue);
   virtual GBool isEncoder() { return gTrue; }
@@ -912,7 +925,8 @@
     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
   virtual int lookChar()
     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
-  virtual GString *getPSFilter(int psLevel, const char *indent)
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream)
     { return NULL; }
   virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
   virtual GBool isEncoder() { return gTrue; }
@@ -944,7 +958,8 @@
     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
   virtual int lookChar()
     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
-  virtual GString *getPSFilter(int psLevel, const char *indent)
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream)
     { return NULL; }
   virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
   virtual GBool isEncoder() { return gTrue; }
@@ -976,7 +991,8 @@
     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
   virtual int lookChar()
     { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
-  virtual GString *getPSFilter(int psLevel, const char *indent)
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream)
     { return NULL; }
   virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
   virtual GBool isEncoder() { return gTrue; }
@@ -1012,7 +1028,8 @@
   virtual void reset();
   virtual int getChar();
   virtual int lookChar();
-  virtual GString *getPSFilter(int psLevel, const char *indent)
+  virtual GString *getPSFilter(int psLevel, const char *indent,
+			       GBool okToReadStream)
     { return NULL; }
   virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
   virtual GBool isEncoder() { return gTrue; }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -16,6 +16,7 @@
 #include <stdlib.h>
 #include <stddef.h>
 #include <math.h>
+#include <limits.h>
 #include <ctype.h>
 #ifdef _WIN32
 #include <fcntl.h> // for O_BINARY
@@ -111,7 +112,7 @@
 
 // In simple layout mode, lines are broken at gaps larger than this
 // value multiplied by font size.
-#define simpleLayoutGapThreshold 0.4
+#define simpleLayoutGapThreshold 0.7
 
 // Table cells (TextColumns) are allowed to overlap by this much
 // in table layout mode (as a fraction of cell width or height).
@@ -407,19 +408,52 @@
 }
 
 //------------------------------------------------------------------------
-// TextGap
+// TextGaps
 //------------------------------------------------------------------------
 
-class TextGap {
+struct TextGap {
+  double x;			// center of gap: x for vertical gaps,
+				//   y for horizontal gaps
+  double w;			// width/height of gap
+};
+
+class TextGaps {
 public:
 
-  TextGap(double aXY, double aW): xy(aXY), w(aW) {}
+  TextGaps();
+  ~TextGaps();
+  void addGap(double x, double w);
+  int getLength() { return length; }
+  double getX(int idx) { return gaps[idx].x; }
+  double getW(int idx) { return gaps[idx].w; }
 
-  double xy;			// center of gap: x for vertical gaps,
-				//   y for horizontal gaps
-  double w;			// width of gap
+private:
+
+  int length;
+  int size;
+  TextGap *gaps;
 };
 
+TextGaps::TextGaps() {
+  length = 0;
+  size = 16;
+  gaps = (TextGap *)gmallocn(size, sizeof(TextGap));
+}
+
+TextGaps::~TextGaps() {
+  gfree(gaps);
+}
+
+void TextGaps::addGap(double x, double w) {
+  if (length == size) {
+    size *= 2;
+    gaps = (TextGap *)greallocn(gaps, size, sizeof(TextGap));
+  }
+  gaps[length].x = x;
+  gaps[length].w = w;
+  ++length;
+}
+
 //------------------------------------------------------------------------
 // TextSuperLine
 //------------------------------------------------------------------------
@@ -508,6 +542,10 @@
   discardInvisibleText = gFalse;
   discardClippedText = gFalse;
   insertBOM = gFalse;
+  marginLeft = 0;
+  marginRight = 0;
+  marginTop = 0;
+  marginBottom = 0;
 }
 
 
@@ -1136,9 +1174,11 @@
       if (name && name[0] == 'm' && name[1] == '\0') {
 	mCode = code;
       }
-      if (letterCode < 0 && name && name[1] == '\0' &&
+      if (letterCode < 0 &&
+	  name &&
 	  ((name[0] >= 'A' && name[0] <= 'Z') ||
-	   (name[0] >= 'a' && name[0] <= 'z'))) {
+	   (name[0] >= 'a' && name[0] <= 'z')) &&
+	  name[1] == '\0') {
 	letterCode = code;
       }
       if (anyCode < 0 && name &&
@@ -1239,9 +1279,12 @@
   // throw away chars that aren't inside the page bounds
   // (and also do a sanity check on the character size)
   state->transform(x, y, &x1, &y1);
-  if (x1 + w1 < 0 || x1 > pageWidth ||
-      y1 + h1 < 0 || y1 > pageHeight ||
-      w1 > pageWidth || h1 > pageHeight) {
+  if (x1 + w1 < control.marginLeft ||
+      x1 > pageWidth - control.marginRight ||
+      y1 + h1 < control.marginTop ||
+      y1 > pageHeight - control.marginBottom ||
+      w1 > pageWidth ||
+      h1 > pageHeight) {
     charPos += nBytes;
     return;
   }
@@ -1876,8 +1919,9 @@
 	  if (fabs(ch2->yMin - ch->yMin) > rawModeLineDelta * ch->fontSize ||
 	      ch2->xMin - ch->xMax < -rawModeCharOverlap * ch->fontSize) {
 	    s->append(eol, eolLen);
-	  } else if (ch2->xMin - ch->xMax >
-		     rawModeWordSpacing * ch->fontSize) {
+	  } else if (ch->spaceAfter ||
+		     ch2->xMin - ch->xMax >
+		       rawModeWordSpacing * ch->fontSize) {
 	    s->append(space, spaceLen);
 	  }
 	  break;
@@ -1885,8 +1929,9 @@
 	  if (fabs(ch->xMax - ch2->xMax) > rawModeLineDelta * ch->fontSize ||
 	      ch2->yMin - ch->yMax < -rawModeCharOverlap * ch->fontSize) {
 	    s->append(eol, eolLen);
-	  } else if (ch2->yMin - ch->yMax >
-		     rawModeWordSpacing * ch->fontSize) {
+	  } else if (ch->spaceAfter ||
+		     ch2->yMin - ch->yMax >
+		       rawModeWordSpacing * ch->fontSize) {
 	    s->append(space, spaceLen);
 	  }
 	  break;
@@ -1894,8 +1939,9 @@
 	  if (fabs(ch->yMax - ch2->yMax) > rawModeLineDelta * ch->fontSize ||
 	      ch->xMin - ch2->xMax  < -rawModeCharOverlap * ch->fontSize) {
 	    s->append(eol, eolLen);
-	  } else if (ch->xMin - ch2->xMax >
-		     rawModeWordSpacing * ch->fontSize) {
+	  } else if (ch->spaceAfter ||
+		     ch->xMin - ch2->xMax >
+		       rawModeWordSpacing * ch->fontSize) {
 	    s->append(space, spaceLen);
 	  }
 	  break;
@@ -1903,8 +1949,9 @@
 	  if (fabs(ch2->xMin - ch->xMin) > rawModeLineDelta * ch->fontSize ||
 	      ch->yMin - ch2->yMax  < -rawModeCharOverlap * ch->fontSize) {
 	    s->append(eol, eolLen);
-	  } else if (ch->yMin - ch2->yMax >
-		     rawModeWordSpacing * ch->fontSize) {
+	  } else if (ch->spaceAfter ||
+		     ch->yMin - ch2->yMax >
+		       rawModeWordSpacing * ch->fontSize) {
 	    s->append(space, spaceLen);
 	  }
 	  break;
@@ -2693,12 +2740,11 @@
 TextBlock *TextPage::split(GList *charsA, int rot) {
   TextBlock *blk;
   GList *chars2, *chars3;
-  GList *horizGaps, *vertGaps;
-  TextGap *gap;
+  TextGaps *horizGaps, *vertGaps;
   TextChar *ch;
   double xMin, yMin, xMax, yMax, avgFontSize;
   double horizGapSize, vertGapSize, minHorizChunkWidth, minVertChunkWidth;
-  double nLines, vertGapThreshold, minChunk;
+  double gap, nLines, vertGapThreshold, minChunk;
   double largeCharSize;
   double x0, x1, y0, y1;
   int nHorizGaps, nVertGaps, nLargeChars;
@@ -2707,8 +2753,8 @@
 
   //----- find all horizontal and vertical gaps
 
-  horizGaps = new GList();
-  vertGaps = new GList();
+  horizGaps = new TextGaps();
+  vertGaps = new TextGaps();
   findGaps(charsA, rot, &xMin, &yMin, &xMax, &yMax, &avgFontSize,
 	   horizGaps, vertGaps);
 
@@ -2716,16 +2762,16 @@
 
   horizGapSize = 0;
   for (i = 0; i < horizGaps->getLength(); ++i) {
-    gap = (TextGap *)horizGaps->get(i);
-    if (gap->w > horizGapSize) {
-      horizGapSize = gap->w;
+    gap = horizGaps->getW(i);
+    if (gap > horizGapSize) {
+      horizGapSize = gap;
     }
   }
   vertGapSize = 0;
   for (i = 0; i < vertGaps->getLength(); ++i) {
-    gap = (TextGap *)vertGaps->get(i);
-    if (gap->w > vertGapSize) {
-      vertGapSize = gap->w;
+    gap = vertGaps->getW(i);
+    if (gap > vertGapSize) {
+      vertGapSize = gap;
     }
   }
 
@@ -2736,14 +2782,14 @@
   if (horizGaps->getLength() > 0) {
     y0 = yMin;
     for (i = 0; i < horizGaps->getLength(); ++i) {
-      gap = (TextGap *)horizGaps->get(i);
-      if (gap->w > horizGapSize - splitGapSlack * avgFontSize) {
+      gap = horizGaps->getW(i);
+      if (gap > horizGapSize - splitGapSlack * avgFontSize) {
 	++nHorizGaps;
-	y1 = gap->xy - 0.5 * gap->w;
+	y1 = horizGaps->getX(i) - 0.5 * gap;
 	if (y1 - y0 < minHorizChunkWidth) {
 	  minHorizChunkWidth = y1 - y0;
 	}
-	y0 = y1 + gap->w;
+	y0 = y1 + gap;
       }
     }
     y1 = yMax;
@@ -2756,14 +2802,14 @@
   if (vertGaps->getLength() > 0) {
     x0 = xMin;
     for (i = 0; i < vertGaps->getLength(); ++i) {
-      gap = (TextGap *)vertGaps->get(i);
-      if (gap->w > vertGapSize - splitGapSlack * avgFontSize) {
+      gap = vertGaps->getW(i);
+      if (gap > vertGapSize - splitGapSlack * avgFontSize) {
 	++nVertGaps;
-	x1 = gap->xy - 0.5 * gap->w;
+	x1 = vertGaps->getX(i) - 0.5 * gap;
 	if (x1 - x0 < minVertChunkWidth) {
 	  minVertChunkWidth = x1 - x0;
 	}
-	x0 = x1 + gap->w;
+	x0 = x1 + gap;
       }
     }
     x1 = xMax;
@@ -2881,9 +2927,8 @@
     printf("vert split xMin=%g yMin=%g xMax=%g yMax=%g small=%d\n",
 	   xMin, pageHeight - yMax, xMax, pageHeight - yMin, smallSplit);
     for (i = 0; i < vertGaps->getLength(); ++i) {
-      gap = (TextGap *)vertGaps->get(i);
-      if (gap->w > vertGapSize - splitGapSlack * avgFontSize) {
-	printf("    x=%g\n", gap->xy);
+      if (vertGaps->getW(i) > vertGapSize - splitGapSlack * avgFontSize) {
+	printf("    x=%g\n", vertGaps->getX(i));
       }
     }
 #endif
@@ -2891,9 +2936,8 @@
     blk->smallSplit = smallSplit;
     x0 = xMin - 1;
     for (i = 0; i < vertGaps->getLength(); ++i) {
-      gap = (TextGap *)vertGaps->get(i);
-      if (gap->w > vertGapSize - splitGapSlack * avgFontSize) {
-	x1 = gap->xy;
+      if (vertGaps->getW(i) > vertGapSize - splitGapSlack * avgFontSize) {
+	x1 = vertGaps->getX(i);
 	chars2 = getChars(charsA, x0, yMin - 1, x1, yMax + 1);
 	blk->addChild(split(chars2, rot));
 	delete chars2;
@@ -2910,9 +2954,8 @@
     printf("horiz split xMin=%g yMin=%g xMax=%g yMax=%g small=%d\n",
 	   xMin, pageHeight - yMax, xMax, pageHeight - yMin, smallSplit);
     for (i = 0; i < horizGaps->getLength(); ++i) {
-      gap = (TextGap *)horizGaps->get(i);
-      if (gap->w > horizGapSize - splitGapSlack * avgFontSize) {
-	printf("    y=%g\n", pageHeight - gap->xy);
+      if (horizGaps->getW(i) > horizGapSize - splitGapSlack * avgFontSize) {
+	printf("    y=%g\n", pageHeight - horizGaps->getX(i));
       }
     }
 #endif
@@ -2920,9 +2963,8 @@
     blk->smallSplit = smallSplit;
     y0 = yMin - 1;
     for (i = 0; i < horizGaps->getLength(); ++i) {
-      gap = (TextGap *)horizGaps->get(i);
-      if (gap->w > horizGapSize - splitGapSlack * avgFontSize) {
-	y1 = gap->xy;
+      if (horizGaps->getW(i) > horizGapSize - splitGapSlack * avgFontSize) {
+	y1 = horizGaps->getX(i);
 	chars2 = getChars(charsA, xMin - 1, y0, xMax + 1, y1);
 	blk->addChild(split(chars2, rot));
 	delete chars2;
@@ -2966,8 +3008,8 @@
     }
   }
 
-  deleteGList(horizGaps, TextGap);
-  deleteGList(vertGaps, TextGap);
+  delete horizGaps;
+  delete vertGaps;
 
   tagBlock(blk);
 
@@ -3001,11 +3043,12 @@
 			double *xMinOut, double *yMinOut,
 			double *xMaxOut, double *yMaxOut,
 			double *avgFontSizeOut,
-			GList *horizGaps, GList *vertGaps) {
+			TextGaps *horizGaps, TextGaps *vertGaps) {
   TextChar *ch;
-  int *horizProfile, *vertProfile;
+  char *horizProfile, *vertProfile;
   double xMin, yMin, xMax, yMax, w;
-  double minFontSize, avgFontSize, splitPrecision, ascentAdjust, descentAdjust;
+  double minFontSize, avgFontSize, splitPrecision, invSplitPrecision;
+  double ascentAdjust, descentAdjust;
   int xMinI, yMinI, xMaxI, yMaxI, xMinI2, yMinI2, xMaxI2, yMaxI2;
   int start, x, y, i;
 
@@ -3037,6 +3080,7 @@
   if (splitPrecision < minSplitPrecision) {
     splitPrecision = minSplitPrecision;
   }
+  invSplitPrecision = 1 / splitPrecision;
   *xMinOut = xMin;
   *yMinOut = yMin;
   *xMaxOut = xMax;
@@ -3045,16 +3089,22 @@
 
   //----- compute the horizontal and vertical profiles
 
+  if (xMin * invSplitPrecision < 0.5 * INT_MIN ||
+      xMax * invSplitPrecision > 0.5 * INT_MAX ||
+      yMin * invSplitPrecision < 0.5 * INT_MIN ||
+      xMax * invSplitPrecision > 0.5 * INT_MAX) {
+    return;
+  }
   // add some slack to the array bounds to avoid floating point
   // precision problems
-  xMinI = (int)floor(xMin / splitPrecision) - 1;
-  yMinI = (int)floor(yMin / splitPrecision) - 1;
-  xMaxI = (int)floor(xMax / splitPrecision) + 1;
-  yMaxI = (int)floor(yMax / splitPrecision) + 1;
-  horizProfile = (int *)gmallocn(yMaxI - yMinI + 1, sizeof(int));
-  vertProfile = (int *)gmallocn(xMaxI - xMinI + 1, sizeof(int));
-  memset(horizProfile, 0, (yMaxI - yMinI + 1) * sizeof(int));
-  memset(vertProfile, 0, (xMaxI - xMinI + 1) * sizeof(int));
+  xMinI = (int)floor(xMin * invSplitPrecision) - 1;
+  yMinI = (int)floor(yMin * invSplitPrecision) - 1;
+  xMaxI = (int)floor(xMax * invSplitPrecision) + 1;
+  yMaxI = (int)floor(yMax * invSplitPrecision) + 1;
+  horizProfile = (char *)gmalloc(yMaxI - yMinI + 1);
+  vertProfile = (char *)gmalloc(xMaxI - xMinI + 1);
+  memset(horizProfile, 0, yMaxI - yMinI + 1);
+  memset(vertProfile, 0, xMaxI - xMinI + 1);
   for (i = 0; i < charsA->getLength(); ++i) {
     ch = (TextChar *)charsA->get(i);
     // yMinI2 and yMaxI2 are adjusted to allow for slightly overlapping lines
@@ -3061,43 +3111,43 @@
     switch (rot) {
     case 0:
     default:
-      xMinI2 = (int)floor(ch->xMin / splitPrecision);
-      xMaxI2 = (int)floor(ch->xMax / splitPrecision);
+      xMinI2 = (int)floor(ch->xMin * invSplitPrecision);
+      xMaxI2 = (int)floor(ch->xMax * invSplitPrecision);
       ascentAdjust = ascentAdjustFactor * (ch->yMax - ch->yMin);
-      yMinI2 = (int)floor((ch->yMin + ascentAdjust) / splitPrecision);
+      yMinI2 = (int)floor((ch->yMin + ascentAdjust) * invSplitPrecision);
       descentAdjust = descentAdjustFactor * (ch->yMax - ch->yMin);
-      yMaxI2 = (int)floor((ch->yMax - descentAdjust) / splitPrecision);
+      yMaxI2 = (int)floor((ch->yMax - descentAdjust) * invSplitPrecision);
       break;
     case 1:
       descentAdjust = descentAdjustFactor * (ch->xMax - ch->xMin);
-      xMinI2 = (int)floor((ch->xMin + descentAdjust) / splitPrecision);
+      xMinI2 = (int)floor((ch->xMin + descentAdjust) * invSplitPrecision);
       ascentAdjust = ascentAdjustFactor * (ch->xMax - ch->xMin);
-      xMaxI2 = (int)floor((ch->xMax - ascentAdjust) / splitPrecision);
-      yMinI2 = (int)floor(ch->yMin / splitPrecision);
-      yMaxI2 = (int)floor(ch->yMax / splitPrecision);
+      xMaxI2 = (int)floor((ch->xMax - ascentAdjust) * invSplitPrecision);
+      yMinI2 = (int)floor(ch->yMin * invSplitPrecision);
+      yMaxI2 = (int)floor(ch->yMax * invSplitPrecision);
       break;
     case 2:
-      xMinI2 = (int)floor(ch->xMin / splitPrecision);
-      xMaxI2 = (int)floor(ch->xMax / splitPrecision);
+      xMinI2 = (int)floor(ch->xMin * invSplitPrecision);
+      xMaxI2 = (int)floor(ch->xMax * invSplitPrecision);
       descentAdjust = descentAdjustFactor * (ch->yMax - ch->yMin);
-      yMinI2 = (int)floor((ch->yMin + descentAdjust) / splitPrecision);
+      yMinI2 = (int)floor((ch->yMin + descentAdjust) * invSplitPrecision);
       ascentAdjust = ascentAdjustFactor * (ch->yMax - ch->yMin);
-      yMaxI2 = (int)floor((ch->yMax - ascentAdjust) / splitPrecision);
+      yMaxI2 = (int)floor((ch->yMax - ascentAdjust) * invSplitPrecision);
       break;
     case 3:
       ascentAdjust = ascentAdjustFactor * (ch->xMax - ch->xMin);
-      xMinI2 = (int)floor((ch->xMin + ascentAdjust) / splitPrecision);
+      xMinI2 = (int)floor((ch->xMin + ascentAdjust) * invSplitPrecision);
       descentAdjust = descentAdjustFactor * (ch->xMax - ch->xMin);
-      xMaxI2 = (int)floor((ch->xMax - descentAdjust) / splitPrecision);
-      yMinI2 = (int)floor(ch->yMin / splitPrecision);
-      yMaxI2 = (int)floor(ch->yMax / splitPrecision);
+      xMaxI2 = (int)floor((ch->xMax - descentAdjust) * invSplitPrecision);
+      yMinI2 = (int)floor(ch->yMin * invSplitPrecision);
+      yMaxI2 = (int)floor(ch->yMax * invSplitPrecision);
       break;
     }
     for (y = yMinI2; y <= yMaxI2; ++y) {
-      ++horizProfile[y - yMinI];
+      horizProfile[y - yMinI] = 1;
     }
     for (x = xMinI2; x <= xMaxI2; ++x) {
-      ++vertProfile[x - xMinI];
+      vertProfile[x - xMinI] = 1;
     }
   }
 
@@ -3112,8 +3162,7 @@
     } else {
       if (horizProfile[y + 1 - yMinI]) {
 	w = (y - start) * splitPrecision;
-	horizGaps->append(new TextGap((start + 1) * splitPrecision + 0.5 * w,
-				      w));
+	horizGaps->addGap((start + 1) * splitPrecision + 0.5 * w, w);
       }
     }
   }
@@ -3129,8 +3178,7 @@
     } else {
       if (vertProfile[x + 1 - xMinI]) {
 	w = (x - start) * splitPrecision;
-	vertGaps->append(new TextGap((start + 1) * splitPrecision + 0.5 * w,
-				     w));
+	vertGaps->addGap((start + 1) * splitPrecision + 0.5 * w, w);
       }
     }
   }
@@ -3818,18 +3866,27 @@
     minGap = 0;
   }
 
-  // if spacing is nearly uniform (minGap is close to maxGap), use the
-  // SpGap/AdjGap values if available, otherwise assume it's a single
-  // word (technically it could be either "ABC" or "A B C", but it's
-  // essentially impossible to tell)
+  // if spacing is nearly uniform (minGap is close to maxGap), there
+  // are three cases:
+  // (1) if the SpGap and AdjGap values are both available and
+  //     sensible, use them
+  // (2) if only the SpGap values are available, meaning that every
+  //     character in the line had a space after it, split after every
+  //     character
+  // (3) otherwise assume it's a single word (technically it could be
+  //     either "ABC" or "A B C", but it's essentially impossible to
+  //     tell)
   if (maxGap - minGap < uniformSpacing * avgFontSize) {
-    if (minAdjGap <= maxAdjGap &&
-	minSpGap <= maxSpGap &&
-	minSpGap - maxAdjGap > 0.01) {
-      return 0.5 * (maxAdjGap + minSpGap);
-    } else {
-      return maxGap + 1;
+    if (minSpGap <= maxSpGap) {
+      if (minAdjGap <= maxAdjGap &&
+	  minSpGap - maxAdjGap > 0.01) {
+	return 0.5 * (maxAdjGap + minSpGap);
+      } else if (minAdjGap > maxAdjGap &&
+		 maxSpGap - minSpGap < uniformSpacing * avgFontSize) {
+	return minSpGap - 1;
+      }
     }
+    return maxGap + 1;
 
   // if there is some variation in spacing, but it's small, assume
   // there are some inter-word spaces
@@ -4033,8 +4090,8 @@
 					   UnicodeMap *uMap) {
   GList *lines;
   TextLine *line0, *line1;
-  double xMin;
-  int px, sp, i, j;
+  double xMin, xMax;
+  int px, px2, sp, i, j;
 
   // build a list of lines and sort by x
   lines = new GList();
@@ -4048,21 +4105,25 @@
   for (i = 0; i < lines->getLength(); ++i) {
     line0 = (TextLine *)lines->get(i);
     computeLinePhysWidth(line0, uMap);
-    line0->px = (int)((line0->xMin - xMin) / (0.5 * line0->fontSize));
+    px = 0;
+    xMax = xMin;
     for (j = 0; j < i; ++j) {
       line1 = (TextLine *)lines->get(j);
       if (line0->xMin > line1->xMax) {
-	sp = (int)((line0->xMin - line1->xMax) /
-		   (0.5 * line0->fontSize) + 0.5);
-	if (sp < 1) {
-	  sp = 1;
+	if (line1->xMax > xMax) {
+	  xMax = line1->xMax;
 	}
-	px = line1->px + line1->pw + sp;
-	if (px > line0->px) {
-	  line0->px = px;
+	px2 = line1->px + line1->pw;
+	if (px2 > px) {
+	  px = px2;
 	}
       }
     }
+    sp = (int)((line0->xMin - xMax) / (0.5 * line0->fontSize) + 0.5);
+    if (sp < 1 && xMax > xMin) {
+      sp = 1;
+    }
+    line0->px = px + sp;
   }
 
   delete lines;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -26,6 +26,7 @@
 
 class TextBlock;
 class TextChar;
+class TextGaps;
 class TextLink;
 class TextPage;
 
@@ -69,6 +70,10 @@
   GBool discardClippedText;	// discard all clipped characters
   GBool insertBOM;		// insert a Unicode BOM at the start of
 				//   the text output
+  double marginLeft,		// characters outside the margins are
+         marginRight,		//   discarded
+         marginTop,
+         marginBottom;
 };
 
 //------------------------------------------------------------------------
@@ -502,7 +507,7 @@
 		double *xMinOut, double *yMinOut,
 		double *xMaxOut, double *yMaxOut,
 		double *avgFontSizeOut,
-		GList *horizGaps, GList *vertGaps);
+		TextGaps *horizGaps, TextGaps *vertGaps);
   void tagBlock(TextBlock *blk);
   void insertLargeChars(GList *largeChars, TextBlock *blk);
   void insertLargeCharsInFirstLeaf(GList *largeChars, TextBlock *blk);

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -67,7 +67,7 @@
     }
     bitmap = new SplashBitmap(state->getWinW(), state->getWinH(),
 			      state->getBitmapRowPad(), state->getColorMode(),
-			      gFalse);
+			      gFalse, gTrue, NULL);
   }
   clearBitmap();
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -592,6 +592,11 @@
       offsetY = 0;
     }
     *pg = findContinuousPage(yw - offsetY + state->getScrollY());
+    if (*pg < 1 || *pg > state->getDoc()->getNumPages()) {
+      *pg = 0;
+      *xd = *yd = 0;
+      return gFalse;
+    }
     pageW1 = pageW[*pg - 1];
     pageH1 = pageH[*pg - 1];
     if (maxW < state->getWinW()) {
@@ -655,6 +660,11 @@
       offsetY = 0;
     }
     *pg = findSideBySideContinuousPage(yw - offsetY + state->getScrollY());
+    if (*pg < 1 || *pg > state->getDoc()->getNumPages()) {
+      *pg = 0;
+      *xd = *yd = 0;
+      return gFalse;
+    }
     pageW1 = pageW[*pg - 1];
     pageH1 = pageH[*pg - 1];
     if (*pg + 1 <= state->getDoc()->getNumPages()) {
@@ -693,6 +703,11 @@
       offsetX = 0;
     }
     *pg = findHorizContinuousPage(xw - offsetX + state->getScrollX());
+    if (*pg < 1 || *pg > state->getDoc()->getNumPages()) {
+      *pg = 0;
+      *xd = *yd = 0;
+      return gFalse;
+    }
     pageW1 = pageW[*pg - 1];
     pageH1 = pageH[*pg - 1];
     if (maxH < state->getWinH()) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -6,6 +6,7 @@
 //
 //========================================================================
 
+#include <aconf.h>
 #include "UTF8.h"
 
 int mapUTF8(Unicode u, char *buf, int bufSize) {

Added: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc	                        (rev 0)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -0,0 +1,384 @@
+//========================================================================
+//
+// WebFont.cc
+//
+// Copyright 2019 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include "gmem.h"
+#include "gmempp.h"
+#include "GHash.h"
+#include "FoFiTrueType.h"
+#include "FoFiType1C.h"
+#include "CharCodeToUnicode.h"
+#include "WebFont.h"
+
+WebFont::WebFont(GfxFont *gfxFontA, XRef *xref) {
+  GfxFontType type;
+
+  gfxFont = gfxFontA;
+  fontBuf = NULL;
+  ffTrueType = NULL;
+  ffType1C = NULL;
+  isOpenType = gFalse;
+
+  type = gfxFont->getType();
+  if (type == fontTrueType ||
+      type == fontTrueTypeOT ||
+      type == fontCIDType2 ||
+      type == fontCIDType2OT) {
+    if ((fontBuf = gfxFont->readEmbFontFile(xref, &fontLength))) {
+      ffTrueType = FoFiTrueType::make(fontBuf, fontLength, 0);
+    }
+  } else if (type == fontType1C ||
+	     type == fontCIDType0C) {
+    if ((fontBuf = gfxFont->readEmbFontFile(xref, &fontLength))) {
+      ffType1C = FoFiType1C::make(fontBuf, fontLength);
+    }
+  } else if (type == fontType1COT ||
+	     type == fontCIDType0COT) {
+    if ((fontBuf = gfxFont->readEmbFontFile(xref, &fontLength))) {
+      isOpenType = gTrue;
+    }
+  }
+}
+
+WebFont::~WebFont() {
+  delete ffTrueType;
+  delete ffType1C;
+  gfree(fontBuf);
+}
+
+GBool WebFont::canWriteTTF() {
+  return ffTrueType != NULL;
+}
+
+GBool WebFont::canWriteOTF() {
+  return ffType1C || isOpenType;
+}
+
+static void writeToFile(void *stream, const char *data, int len) {
+  fwrite(data, 1, len, (FILE *)stream);
+}
+
+GBool WebFont::writeTTF(const char *fontFilePath) {
+  FILE *out;
+  int *codeToGID;
+  Guchar *cmapTable;
+  GBool freeCodeToGID;
+  int nCodes, cmapTableLength;
+
+  if (!ffTrueType) {
+    return gFalse;
+  }
+  if (gfxFont->isCIDFont()) {
+    codeToGID = ((GfxCIDFont *)gfxFont)->getCIDToGID();
+    nCodes = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+    if (!codeToGID) {
+      nCodes = ffTrueType->getNumGlyphs();
+    }
+    freeCodeToGID = gFalse;
+  } else {
+    codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ffTrueType);
+    nCodes = 256;
+    freeCodeToGID = gTrue;
+  }
+  cmapTable = makeUnicodeCmapTable(codeToGID, nCodes, &cmapTableLength);
+  if (freeCodeToGID) {
+    gfree(codeToGID);
+  }
+  if (!cmapTable) {
+    return gFalse;
+  }
+  if (!(out = fopen(fontFilePath, "wb"))) {
+    gfree(cmapTable);
+    return gFalse;
+  }
+  ffTrueType->writeTTF(writeToFile, out, NULL, NULL,
+		       cmapTable, cmapTableLength);
+  fclose(out);
+  gfree(cmapTable);
+  return gTrue;
+}
+
+GBool WebFont::writeOTF(const char *fontFilePath) {
+  int *codeToGID;
+  Gushort *widths;
+  Guchar *cmapTable;
+  FILE *out;
+  int nCodes, nWidths, cmapTableLength;
+
+  if (ffType1C) {
+    if (gfxFont->getType() == fontType1C) {
+      codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ffType1C);
+      if (!(cmapTable = makeUnicodeCmapTable(codeToGID, 256,
+					     &cmapTableLength))) {
+	gfree(codeToGID);
+	return gFalse;
+      }
+      widths = makeType1CWidths(codeToGID, 256, &nWidths);
+      gfree(codeToGID);
+    } else { // fontCIDType0C
+      codeToGID = ffType1C->getCIDToGIDMap(&nCodes);
+      if (!(cmapTable = makeUnicodeCmapTable(codeToGID, nCodes,
+					     &cmapTableLength))) {
+	gfree(codeToGID);
+	return gFalse;
+      }
+      widths = makeCIDType0CWidths(codeToGID, nCodes, &nWidths);
+      gfree(codeToGID);
+    }
+    if (!(out = fopen(fontFilePath, "wb"))) {
+      gfree(cmapTable);
+      gfree(widths);
+      return gFalse;
+    }
+    ffType1C->convertToOpenType(writeToFile, out,
+				nWidths, widths,
+				cmapTable, cmapTableLength);
+    fclose(out);
+    gfree(cmapTable);
+    gfree(widths);
+
+  } else if (isOpenType) {
+    if (!(out = fopen(fontFilePath, "wb"))) {
+      return gFalse;
+    }
+    if (fwrite(fontBuf, 1, fontLength, out) != (Guint)fontLength) {
+      fclose(out);
+      return gFalse;
+    }
+    fclose(out);
+
+  } else {
+    return gFalse;
+  }
+
+  return gTrue;
+}
+
+Gushort *WebFont::makeType1CWidths(int *codeToGID, int nCodes,
+				   int *nWidths) {
+  Gushort *widths;
+  Gushort width;
+  int widthsLen, gid, i;
+
+  widthsLen = ffType1C->getNumGlyphs();
+  widths = (Gushort *)gmallocn(widthsLen, sizeof(Gushort));
+  for (i = 0; i < widthsLen; ++i) {
+    widths[i] = 0;
+  }
+  for (i = 0; i < nCodes; ++i) {
+    gid = codeToGID[i];
+    if (gid < 0 || gid >= widthsLen) {
+      continue;
+    }
+    width = (Gushort)(((Gfx8BitFont *)gfxFont)->getWidth((Guchar)i)
+		      * 1000 + 0.5);
+    if (width == 0) {
+      continue;
+    }
+    widths[gid] = width;
+  }
+  *nWidths = widthsLen;
+  return widths;
+}
+
+Gushort *WebFont::makeCIDType0CWidths(int *codeToGID, int nCodes,
+				      int *nWidths) {
+  Gushort *widths;
+  Gushort width;
+  int widthsLen, gid, i;
+
+  widthsLen = ffType1C->getNumGlyphs();
+  widths = (Gushort *)gmallocn(widthsLen, sizeof(Gushort));
+  for (i = 0 ; i < widthsLen; ++i) {
+    widths[i] = 0;
+  }
+  for (i = 0; i < nCodes; ++i) {
+    gid = codeToGID[i];
+    if (gid < 0 || gid >= widthsLen) {
+      continue;
+    }
+    width = (Gushort)(((GfxCIDFont *)gfxFont)->getWidth((CID)i)
+		      * 1000 + 0.5);
+    if (width == 0) {
+      continue;
+    }
+    widths[gid] = width;
+  }
+  *nWidths = widthsLen;
+  return widths;
+}
+
+Guchar *WebFont::makeUnicodeCmapTable(int *codeToGID, int nCodes,
+				      int *unicodeCmapLength) {
+  int *unicodeToGID;
+  Guchar *cmapTable;
+  int unicodeToGIDLength, nMappings, len;
+  int nSegs, searchRange, entrySelector, rangeShift;
+  int glyphIdOffset, idRangeOffset;
+  int start, end, c, i;
+
+  if (!(unicodeToGID = makeUnicodeToGID(codeToGID, nCodes,
+					&unicodeToGIDLength))) {
+    return NULL;
+  }
+
+  // count the valid code-to-glyph mappings, and the sequences of
+  // consecutive valid mappings
+  // (note: char code 65535 is used to mark the end of table)
+  nMappings = 0;
+  nSegs = 1; // count the last segment, mapping 65535
+  for (c = 0; c < unicodeToGIDLength && c <= 65534; ++c) {
+    if (unicodeToGID[c]) {
+      ++nMappings;
+      if (c == 0 || !unicodeToGID[c-1]) {
+	++nSegs;
+      }
+    }
+  }
+
+  i = 1;
+  entrySelector = 0;
+  while (2 * i <= nSegs) {
+    i *= 2;
+    ++entrySelector;
+  }
+  searchRange = 1 << (entrySelector + 1);
+  rangeShift = 2 * nSegs - searchRange;
+
+  len = 28 + nSegs * 8 + nMappings * 2;
+  cmapTable = (Guchar *)gmalloc(len);
+
+  // header
+  cmapTable[ 0] = 0x00;	// table version
+  cmapTable[ 1] = 0x00;
+  cmapTable[ 2] = 0x00;	// number of cmaps
+  cmapTable[ 3] = 0x01;
+  cmapTable[ 4] = 0x00;	// platform[0]
+  cmapTable[ 5] = 0x03;
+  cmapTable[ 6] = 0x00;	// encoding[0]
+  cmapTable[ 7] = 0x01;
+  cmapTable[ 8] = 0x00;	// offset[0]
+  cmapTable[ 9] = 0x00;
+  cmapTable[10] = 0x00;
+  cmapTable[11] = 0x0c;
+
+  // table info
+  cmapTable[12] = 0x00;					// cmap format
+  cmapTable[13] = 0x04;
+  cmapTable[14] = (Guchar)((len - 12) >> 8);		// cmap length
+  cmapTable[15] = (Guchar)(len - 12);
+  cmapTable[16] = 0x00;					// cmap version
+  cmapTable[17] = 0x00;
+  cmapTable[18] = (Guchar)(nSegs >> 7);			// segCountX2
+  cmapTable[19] = (Guchar)(nSegs << 1);
+  cmapTable[20] = (Guchar)(searchRange >> 8);		// searchRange
+  cmapTable[21] = (Guchar)searchRange;
+  cmapTable[22] = (Guchar)(entrySelector >> 8);		// entrySelector
+  cmapTable[23] = (Guchar)entrySelector;
+  cmapTable[24] = (Guchar)(rangeShift >> 8);		// rangeShift
+  cmapTable[25] = (Guchar)rangeShift;
+  cmapTable[26 + nSegs*2    ] = 0;			// reservedPad
+  cmapTable[26 + nSegs*2 + 1] = 0;
+
+  i = 0;
+  glyphIdOffset = 28 + nSegs*8;
+  for (c = 0; c < unicodeToGIDLength && c <= 65534; ++c) {
+    if (unicodeToGID[c]) {
+      if (c == 0 || !unicodeToGID[c-1]) {
+	start = c;
+	cmapTable[28 + nSegs*2 + i*2    ] = (Guchar)(start >> 8);
+	cmapTable[28 + nSegs*2 + i*2 + 1] = (Guchar)start;
+	cmapTable[28 + nSegs*4 + i*2    ] = (Guchar)0;	// idDelta
+	cmapTable[28 + nSegs*4 + i*2 + 1] = (Guchar)0;
+	idRangeOffset = glyphIdOffset - (28 + nSegs*6 + i*2);
+	cmapTable[28 + nSegs*6 + i*2    ] = (Guchar)(idRangeOffset >> 8);
+	cmapTable[28 + nSegs*6 + i*2 + 1] = (Guchar)idRangeOffset;
+      }
+      if (c == 65534 || !unicodeToGID[c+1]) {
+	end = c;
+	cmapTable[26 + i*2    ] = (Guchar)(end >> 8);
+	cmapTable[26 + i*2 + 1] = (Guchar)end;
+	++i;
+      }
+      cmapTable[glyphIdOffset++] = (Guchar)(unicodeToGID[c] >> 8);
+      cmapTable[glyphIdOffset++] = (Guchar)unicodeToGID[c];
+    }
+  }
+
+  // last segment maps code 65535 to GID 0
+  cmapTable[26 + i*2    ] = (Guchar)0xff;		// end
+  cmapTable[26 + i*2 + 1] = (Guchar)0xff;
+  cmapTable[28 + nSegs*2 + i*2    ] = (Guchar)0xff;	// start
+  cmapTable[28 + nSegs*2 + i*2 + 1] = (Guchar)0xff;
+  cmapTable[28 + nSegs*4 + i*2    ] = (Guchar)0;	// idDelta
+  cmapTable[28 + nSegs*4 + i*2 + 1] = (Guchar)1;
+  cmapTable[28 + nSegs*6 + i*2    ] = (Guchar)0;	// idRangeOffset
+  cmapTable[28 + nSegs*6 + i*2 + 1] = (Guchar)0;
+
+  gfree(unicodeToGID);
+
+  *unicodeCmapLength = len;
+  return cmapTable;
+}
+
+int *WebFont::makeUnicodeToGID(int *codeToGID, int nCodes,
+			       int *unicodeToGIDLength) {
+  int *unicodeToGID;
+  CharCodeToUnicode *ctu;
+  Unicode u[2];
+  int len, size, newSize, uLen, c, gid;
+
+  if (gfxFont->isCIDFont()) {
+    if (!(ctu = ((GfxCIDFont *)gfxFont)->getToUnicode())) {
+      return NULL;
+    }
+  } else {
+    ctu = ((Gfx8BitFont *)gfxFont)->getToUnicode();
+  }
+
+  len = 0;
+  size = 256;
+  unicodeToGID = (int *)gmallocn(size, sizeof(int));
+  memset(unicodeToGID, 0, size * sizeof(int));
+  for (c = 0; c < nCodes; ++c) {
+    gid = codeToGID ? codeToGID[c] : c;
+    if (gid < 0 || gid >= 65536) {
+      continue;
+    }
+    uLen = ctu->mapToUnicode(c, u, 2);
+    if (uLen != 1) {
+      continue;
+    }
+    if (u[0] >= 65536) {    // sanity check
+      continue;
+    }
+    if ((int)u[0] >= size) {
+      newSize = 2 * size;
+      while ((int)u[0] >= newSize) {
+	newSize *= 2;
+      }
+      unicodeToGID = (int *)greallocn(unicodeToGID, newSize, sizeof(int));
+      memset(unicodeToGID + size, 0, (newSize - size) * sizeof(int));
+      size = newSize;
+    }
+    unicodeToGID[u[0]] = gid;
+    if ((int)u[0] >= len) {
+      len = u[0] + 1;
+    }
+  }
+
+  ctu->decRefCnt();
+
+  *unicodeToGIDLength = len;
+  return unicodeToGID;
+}

Added: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h	                        (rev 0)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -0,0 +1,69 @@
+//========================================================================
+//
+// WebFont.h
+//
+// Modify/convert embedded PDF fonts to a form usable by web browsers.
+//
+// Copyright 2019 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef WEBFONT_H
+#define WEBFONT_H
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include "gtypes.h"
+#include "GfxFont.h"
+
+class FoFiTrueType;
+class FoFiType1C;
+class XRef;
+
+//------------------------------------------------------------------------
+
+class WebFont {
+public:
+
+  WebFont(GfxFont *gfxFontA, XRef *xref);
+
+  ~WebFont();
+
+  // Returns true if the font is, or can be converted to, a TrueType
+  // font.
+  GBool canWriteTTF();
+
+  // Returns true if the font is, or can be converted to, an OpenType
+  // font.
+  GBool canWriteOTF();
+
+  // Write a TrueType (.ttf) file to [fontFilePath].  This can only be
+  // called if canWriteTTF() returns true.  Returns true on success.
+  GBool writeTTF(const char *fontFilePath);
+
+  // Write an OpenType (.otf) file to [fontFilePath].  This can only
+  // be called if canWriteOTF() returns true.  Returns true on
+  // success.
+  GBool writeOTF(const char *fontFilePath);
+
+private:
+
+  Gushort *makeType1CWidths(int *codeToGID, int nCodes, int *nWidths);
+  Gushort *makeCIDType0CWidths(int *codeToGID, int nCodes, int *nWidths);
+  Guchar *makeUnicodeCmapTable(int *codeToGID, int nCodes,
+			       int *unicodeCmapLength);
+  int *makeUnicodeToGID(int *codeToGID, int nCodes, int *unicodeToGIDLength);
+
+  GfxFont *gfxFont;
+  char *fontBuf;
+  int fontLength;
+  FoFiTrueType *ffTrueType;
+  FoFiType1C *ffType1C;
+  GBool isOpenType;
+};
+
+#endif


Property changes on: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -25,6 +25,7 @@
 #include "GfxFont.h"
 #include "Zoox.h"
 #include "PDF417Barcode.h"
+#include "UTF8.h"
 #include "XFAForm.h"
 
 #ifdef _WIN32
@@ -446,7 +447,7 @@
       fullNameIdx = new GHash();
       xfaForm->scanNode(tmpl, name, fullName, gFalse, NULL,
 			nameCount, nameIdx, fullNameCount, fullNameIdx,
-			catalog);
+			NULL, catalog);
       delete nameCount;
       delete nameIdx;
       delete fullNameCount;
@@ -504,11 +505,6 @@
   gfree(pageOffsetY);
 }
 
-//~ need to handle exclGroup
-//~ - fields in an exclGroup may/must(?) not have names
-//~ - each field has an items element with the the value when that
-//~   field is selected
-
 // Scan <elem>.  Constructs the node's name and full name.  If <elem>
 // is a field, creates an XFAFormField; else scans <elem>'s children.
 void XFAForm::scanNode(ZxElement *elem,
@@ -516,7 +512,7 @@
 		       GBool inPageSet, XFATableInfo *tableInfo,
 		       GHash *nameCount, GHash *nameIdx,
 		       GHash *fullNameCount, GHash *fullNameIdx,
-		       Catalog *catalog) {
+		       GString *exclGroupName, Catalog *catalog) {
   ZxAttr *attr;
   GString *name, *fullName, *namePart, *fullNamePart;
   GHash *childNameCount, *childNameIdx, *childFullNameCount, *childFullNameIdx;
@@ -575,7 +571,8 @@
   }
 
   if (elem->isElement("field")) {
-    scanField(elem, name, fullName, inPageSet, tableInfo, colSpan, catalog);
+    scanField(elem, name, fullName, exclGroupName,
+	      inPageSet, tableInfo, colSpan, catalog);
   } else {
     scanNonField(elem, name, fullName, inPageSet, tableInfo, colSpan,
 		 childNameCount, childNameIdx,
@@ -652,7 +649,7 @@
 }
 
 void XFAForm::scanField(ZxElement *elem, GString *name, GString *fullName,
-			GBool inPageSet,
+			GString *exclGroupName, GBool inPageSet,
 			XFATableInfo *tableInfo, int colSpan,
 			Catalog *catalog) {
   double xSubOffset, ySubOffset, columnWidth, rowHeight;
@@ -679,6 +676,8 @@
   }
 
   fields->append(new XFAFormField(this, elem, name->copy(), fullName->copy(),
+				  exclGroupName ? exclGroupName->copy()
+				                : (GString *)NULL,
 				  curPageNum, curXOffset, curYOffset,
 				  columnWidth, rowHeight));
 
@@ -699,6 +698,7 @@
   ZxNode *child;
   ZxAttr *attr;
   PDFRectangle *box;
+  GString *exclGroupName;
   double xSubOffset, ySubOffset;
   int savedPageNum;
 
@@ -744,7 +744,8 @@
     curXOffset += xSubOffset;
     curYOffset += ySubOffset;
 
-  } else if (elem->isElement("area")) {
+  } else if (elem->isElement("area") ||
+	     elem->isElement("exclGroup")) {
     xSubOffset = XFAFormField::getMeasurement(elem->findAttr("x"), 0);
     ySubOffset = XFAFormField::getMeasurement(elem->findAttr("y"), 0);
     curXOffset += xSubOffset;
@@ -780,11 +781,17 @@
     }
   }
 
+  if (elem->isElement("exclGroup")) {
+    exclGroupName = name;
+  } else {
+    exclGroupName = NULL;
+  }
+
   for (child = elem->getFirstChild(); child; child = child->getNextChild()) {
     if (child->isElement()) {
       scanNode((ZxElement *)child, name, fullName, inPageSet,
 	       newTableInfo, nameCount, nameIdx, fullNameCount, fullNameIdx,
-	       catalog);
+	       exclGroupName, catalog);
     }
   }
 
@@ -871,6 +878,7 @@
 
 XFAFormField::XFAFormField(XFAForm *xfaFormA, ZxElement *xmlA,
 			   GString *nameA, GString *fullNameA,
+			   GString *exclGroupNameA,
 			   int pageNumA, double xOffsetA, double yOffsetA,
 			   double columnWidthA, double rowHeightA) {
   xfaForm = xfaFormA;
@@ -877,6 +885,7 @@
   xml = xmlA;
   name = nameA;
   fullName = fullNameA;
+  exclGroupName = exclGroupNameA;
   pageNum = pageNumA;
   xOffset = xOffsetA;
   yOffset = yOffsetA;
@@ -887,6 +896,9 @@
 XFAFormField::~XFAFormField() {
   delete name;
   delete fullName;
+  if (exclGroupName) {
+    delete exclGroupName;
+  }
 }
 
 int XFAFormField::getPageNum() {
@@ -943,7 +955,9 @@
 	s = getFieldValue("text");
 	break;
       } else if (node->isElement("checkButton")) {
-	s = getFieldValue("integer");
+	if (!(s = getFieldValue("integer"))) {
+	  s = getFieldValue("text");
+	}
 	break;
       } else if (node->isElement("barcode")) {
 	s = getFieldValue("text");
@@ -1921,6 +1935,22 @@
       }
     }
   }
+  if (exclGroupName) {
+    p = exclGroupName->getCString();
+    if (xfaForm->xml->getRoot() && !strncmp(p, "form.",  5)) {
+      if ((datasets =
+	   xfaForm->xml->getRoot()->findFirstChildElement("xfa:datasets")) &&
+	  (data = datasets->findFirstChildElement("xfa:data"))) {
+	elem = findFieldInDatasets(data, p + 5);
+	if (elem &&
+	    elem->getFirstChild() &&
+	    elem->getFirstChild()->isCharData() &&
+	    ((ZxCharData *)elem->getFirstChild())->getData()->getLength() > 0) {
+	  return ((ZxCharData *)elem->getFirstChild())->getData();
+	}
+      }
+    }
+  }
 
   // check the <form> element
   p = fullName->getCString();
@@ -1955,7 +1985,9 @@
 
 ZxElement *XFAFormField::findFieldInDatasets(ZxElement *elem, char *partName) {
   ZxNode *node;
+  ZxElement *result;
   GString *nodeName;
+  char *next;
   int curIdx, idx, n;
 
   curIdx = 0;
@@ -1976,11 +2008,21 @@
 	if (!partName[n]) {
 	  return (ZxElement *)node;
 	} else if (partName[n] == '.') {
-	  return findFieldInDatasets((ZxElement *)node, partName + n + 1);
+	  if ((result = findFieldInDatasets((ZxElement *)node,
+					    partName + n + 1))) {
+	    return result;
+	  }
+	  break;
 	}
       }
     }
   }
+
+  // search for an "ancestor match"
+  if ((next = strchr(partName, '.'))) {
+    return findFieldInDatasets(elem, next + 1);
+  }
+
   return NULL;
 }
 
@@ -2054,14 +2096,26 @@
 			    double x, double y, double w, double h,
 			    GBool whiteBackground,
 			    GfxFontDict *fontDict, GString *appearBuf) {
+  GString *text2;
   GfxFont *font;
   const char *fontTag;
   GString *s;
+  Unicode u;
   double yTop, xx, yy, tw, charWidth, lineHeight;
   double ascent, descent, rectX, rectY, rectW, rectH, blkH;
   int nLines, line, i, j, k, c, rectI;
 
-  //~ deal with Unicode text (is it UTF-8?)
+  // convert UTF-8 to Latin1
+  //~ this currently drops all non-Latin1 characters
+  text2 = new GString();
+  i = 0;
+  while (getUTF8(text, &i, &u)) {
+    if (u <= 0xff) {
+      text2->append((char)u);
+    } else {
+      text2->append('?');
+    }
+  }
 
   // find the font
   if ((font = findFont(fontDict, fontName, bold, italic))) {
@@ -2093,8 +2147,8 @@
     if (vAlign == xfaVAlignBottom || vAlign == xfaVAlignMiddle) {
       nLines = 0;
       i = 0;
-      while (i < text->getLength()) {
-	getNextLine(text, i, font, fontSize, w, &j, &tw, &k);
+      while (i < text2->getLength()) {
+	getNextLine(text2, i, font, fontSize, w, &j, &tw, &k);
 	++nLines;
 	i = k;
       }
@@ -2114,9 +2168,9 @@
     // write a series of lines of text
     line = 0;
     i = 0;
-    while (i < text->getLength()) {
+    while (i < text2->getLength()) {
 
-      getNextLine(text, i, font, fontSize, w, &j, &tw, &k);
+      getNextLine(text2, i, font, fontSize, w, &j, &tw, &k);
       if (tw > rectW) {
 	rectW = tw;
       }
@@ -2140,7 +2194,7 @@
       appearBuf->appendf("1 0 0 1 {0:.4f} {1:.4f} Tm\n", xx, yy);
       appearBuf->append('(');
       for (; i < j; ++i) {
-	c = text->getChar(i) & 0xff;
+	c = text2->getChar(i) & 0xff;
 	if (c == '(' || c == ')' || c == '\\') {
 	  appearBuf->append('\\');
 	  appearBuf->append((char)c);
@@ -2172,13 +2226,13 @@
       xx = x;
       break;
     case xfaHAlignCenter:
-      xx = x + (int)(0.5 * (combCells - text->getLength())) * tw;
+      xx = x + (int)(0.5 * (combCells - text2->getLength())) * tw;
       break;
     case xfaHAlignRight:
-      xx = x + w - text->getLength() * tw;
+      xx = x + w - text2->getLength() * tw;
       break;
     }
-    rectW = text->getLength() * tw;
+    rectW = text2->getLength() * tw;
     switch (vAlign) {
     case xfaVAlignTop:
     default:
@@ -2195,8 +2249,8 @@
     rectH = ascent - descent;
 
     // write the text string
-    for (i = 0; i < text->getLength(); ++i) {
-      c = text->getChar(i) & 0xff;
+    for (i = 0; i < text2->getLength(); ++i) {
+      c = text2->getChar(i) & 0xff;
       if (font && !font->isCIDFont()) {
 	charWidth = fontSize * ((Gfx8BitFont *)font)->getWidth((Guchar)c);
 	appearBuf->appendf("1 0 0 1 {0:.4f} {1:.4f} Tm\n",
@@ -2223,12 +2277,12 @@
     // compute string width
     if (font && !font->isCIDFont()) {
       tw = 0;
-      for (i = 0; i < text->getLength(); ++i) {
-	tw += ((Gfx8BitFont *)font)->getWidth(text->getChar(i));
+      for (i = 0; i < text2->getLength(); ++i) {
+	tw += ((Gfx8BitFont *)font)->getWidth(text2->getChar(i));
       }
     } else {
       // otherwise, make a crude estimate
-      tw = text->getLength() * 0.5;
+      tw = text2->getLength() * 0.5;
     }
     tw *= fontSize;
     rectW = tw;
@@ -2264,8 +2318,8 @@
 
     // write the text string
     appearBuf->append('(');
-    for (i = 0; i < text->getLength(); ++i) {
-      c = text->getChar(i) & 0xff;
+    for (i = 0; i < text2->getLength(); ++i) {
+      c = text2->getChar(i) & 0xff;
       if (c == '(' || c == ')' || c == '\\') {
 	appearBuf->append('\\');
 	appearBuf->append((char)c);
@@ -2304,6 +2358,8 @@
     appearBuf->insert(rectI, s);
     delete s;
   }
+
+  delete text2;
 }
 
 // Searches <fontDict> for a font matching(<fontName>, <bold>,
@@ -2734,7 +2790,7 @@
 	      u <<= 4;
 	      if (c >= '0' && c <= '9') {
 		u += c - '0';
-	      } else if (c >= 'a' && c <= 'F') {
+	      } else if (c >= 'a' && c <= 'f') {
 		u += c - 'a' + 10;
 	      } else if (c >= 'A' && c <= 'F') {
 		u += c - 'A' + 10;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -63,11 +63,11 @@
 		GBool inPageSet, XFATableInfo *tableInfo,
 		GHash *nameCount, GHash *nameIdx,
 		GHash *fullNameCount, GHash *fullNameIdx,
-		Catalog *catalog);
+		GString *exclGroupName, Catalog *catalog);
   void scanNames(ZxElement *elem, GHash *nameCount);
   void scanFullNames(ZxElement *elem, GHash *fullNameCount);
   void scanField(ZxElement *elem, GString *name, GString *fullName,
-		 GBool inPageSet,
+		 GString *exclGroupName, GBool inPageSet,
 		 XFATableInfo *tableInfo, int colSpan,
 		 Catalog *catalog);
   void scanNonField(ZxElement *elem, GString *name, GString *fullName,
@@ -102,7 +102,7 @@
 public:
 
   XFAFormField(XFAForm *xfaFormA, ZxElement *xmlA,
-	       GString *nameA, GString *fullNameA,
+	       GString *nameA, GString *fullNameA, GString *exclGroupNameA,
 	       int pageNumA, double xOffsetA, double yOffsetA,
 	       double columnWidthA, double rowHeightA);
 
@@ -166,6 +166,7 @@
   ZxElement *xml;
   GString *name;
   GString *fullName;
+  GString *exclGroupName;
   int pageNum;
   double xOffset, yOffset;
   double columnWidth;		// column width, if this field is in a

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/config.h	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/config.h	2019-09-29 10:00:12 UTC (rev 52203)
@@ -14,14 +14,14 @@
 //------------------------------------------------------------------------
 
 // xpdf version
-#define xpdfVersion          "4.01.01"
-#define xpdfVersionNum       4.01
+#define xpdfVersion          "4.02"
+#define xpdfVersionNum       4.02
 #define xpdfMajorVersion     4
-#define xpdfMinorVersion     1
-#define xpdfUpdateVersion    1
+#define xpdfMinorVersion     2
+#define xpdfUpdateVersion    0
 #define xpdfMajorVersionStr  "4"
-#define xpdfMinorVersionStr  "1"
-#define xpdfUpdateVersionStr "1"
+#define xpdfMinorVersionStr  "2"
+#define xpdfUpdateVersionStr "0"
 
 // supported PDF version
 #define supportedPDFVersionStr "2.0"
@@ -31,7 +31,7 @@
 #define xpdfCopyright "Copyright 1996-2019 Glyph & Cog, LLC"
 
 // Windows resource file stuff
-#define winxpdfVersion "WinXpdf 4.01.01"
+#define winxpdfVersion "WinXpdf 4.02"
 #define xpdfCopyrightAmp "Copyright 1996-2019 Glyph && Cog, LLC"
 
 //------------------------------------------------------------------------

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -159,11 +159,11 @@
 
   // scan the fonts
   if (showFontLoc || showFontLocPS) {
-    printf("name                                 type              emb sub uni prob object ID location\n");
-    printf("------------------------------------ ----------------- --- --- --- ---- --------- --------\n");
+    printf("name                                           type              emb sub uni prob object ID location\n");
+    printf("---------------------------------------------- ----------------- --- --- --- ---- --------- --------\n");
   } else {
-    printf("name                                 type              emb sub uni prob object ID\n");
-    printf("------------------------------------ ----------------- --- --- --- ---- ---------\n");
+    printf("name                                           type              emb sub uni prob object ID\n");
+    printf("---------------------------------------------- ----------------- --- --- --- ---- ---------\n");
   }
   fonts = NULL;
   fontsLen = fontsSize = 0;
@@ -302,7 +302,7 @@
   resDict->lookupNF("ExtGState", &gsDict1);
   if (checkObject(&gsDict1, &gsDict2) && gsDict2.isDict()) {
     for (i = 0; i < gsDict2.dictGetLength(); ++i) {
-      gsDict1.dictGetValNF(i, &gs1);
+      gsDict2.dictGetValNF(i, &gs1);
       if (checkObject(&gs1, &gs2) && gs2.isDict()) {
 	gs2.dictLookupNF("SMask", &smask1);
 	if (checkObject(&smask1, &smask2) && smask2.isDict()) {
@@ -375,7 +375,7 @@
   }
 
   // print the font info
-  printf("%-36s %-17s %-3s %-3s %-3s %-4s",
+  printf("%-46s %-17s %-3s %-3s %-3s %-4s",
 	 name ? name->getCString() : "[none]",
 	 fontTypeNames[font->getType()],
 	 emb ? "yes" : "no",

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -171,6 +171,7 @@
   htmlGen->setZoom(zoom);
   htmlGen->setDrawInvisibleText(!skipInvisible);
   htmlGen->setAllTextInvisible(allInvisible);
+  htmlGen->setExtractFontFiles(gTrue);
   htmlGen->startDoc(doc);
 
   // convert the pages
@@ -191,7 +192,7 @@
       goto err2;
     }
     pngURL = GString::format("page{0:d}.png", pg);
-    err = htmlGen->convertPage(pg, pngURL->getCString(),
+    err = htmlGen->convertPage(pg, pngURL->getCString(), htmlDir,
 			       &writeToFile, htmlFile,
 			       &writeToFile, pngFile);
     delete pngURL;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -352,6 +352,7 @@
 
 
 
+
 static void finishPNG(png_structp *png, png_infop *pngInfo) {
   if (setjmp(png_jmpbuf(*png))) {
     exit(2);

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc	2019-09-28 23:53:36 UTC (rev 52202)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc	2019-09-29 10:00:12 UTC (rev 52203)
@@ -50,6 +50,10 @@
 static char textEOL[16] = "";
 static GBool noPageBreaks = gFalse;
 static GBool insertBOM = gFalse;
+static double marginLeft = 0;
+static double marginRight = 0;
+static double marginTop = 0;
+static double marginBottom = 0;
 static char ownerPassword[33] = "\001";
 static char userPassword[33] = "\001";
 static GBool quiet = gFalse;
@@ -88,6 +92,14 @@
    "don't insert page breaks between pages"},
   {"-bom",     argFlag,     &insertBOM,     0,
    "insert a Unicode BOM at the start of the text file"},
+  {"-marginl", argFP,       &marginLeft,    0,
+   "left page margin"},
+  {"-marginr", argFP,       &marginRight,   0,
+   "right page margin"},
+  {"-margint", argFP,       &marginTop,     0,
+   "top page margin"},
+  {"-marginb", argFP,       &marginBottom,  0,
+   "bottom page margin"},
   {"-opw",     argString,   ownerPassword,  sizeof(ownerPassword),
    "owner password (for encrypted files)"},
   {"-upw",     argString,   userPassword,   sizeof(userPassword),
@@ -247,6 +259,10 @@
   textOutControl.clipText = clipText;
   textOutControl.discardDiagonalText = discardDiag;
   textOutControl.insertBOM = insertBOM;
+  textOutControl.marginLeft = marginLeft;
+  textOutControl.marginRight = marginRight;
+  textOutControl.marginTop = marginTop;
+  textOutControl.marginBottom = marginBottom;
   textOut = new TextOutputDev(textFileName->getCString(), &textOutControl,
 			      gFalse);
   if (textOut->isOk()) {



More information about the tex-live-commits mailing list