texlive[69765] Build/source/libs: xpdf 4.05

commits+kakuto at tug.org commits+kakuto at tug.org
Sat Feb 10 07:55:23 CET 2024


Revision: 69765
          https://tug.org/svn/texlive?view=revision&revision=69765
Author:   kakuto
Date:     2024-02-10 07:55:23 +0100 (Sat, 10 Feb 2024)
Log Message:
-----------
xpdf 4.05

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/aconf-w32.h
    trunk/Build/source/libs/xpdf/aconf.h.in
    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/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/FoFiBase.h
    trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.cc
    trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.h
    trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.cc
    trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.h
    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/FoFiType1.h
    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.cc
    trunk/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h
    trunk/Build/source/libs/xpdf/xpdf-src/goo/GHash.cc
    trunk/Build/source/libs/xpdf/xpdf-src/goo/GHash.h
    trunk/Build/source/libs/xpdf/xpdf-src/goo/GList.cc
    trunk/Build/source/libs/xpdf/xpdf-src/goo/GList.h
    trunk/Build/source/libs/xpdf/xpdf-src/goo/GString.cc
    trunk/Build/source/libs/xpdf/xpdf-src/goo/GString.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/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/SplashClip.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.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/SplashFontFile.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.h
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.cc
    trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Array.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h
    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/CharCodeToUnicode.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Error.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/ImageOutputDev.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.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/Lexer.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Link.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Object.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.h
    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/PDFDoc.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.h
    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/TextString.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.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/pdftoppm.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc
    trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc

Removed Paths:
-------------
    trunk/Build/source/libs/xpdf/xpdf-src/aconf2.h

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/README	2024-02-10 06:55:23 UTC (rev 69765)
@@ -69,7 +69,7 @@
 teckit 2.5.12 - checked 26aug23
   https://github.com/silnrsi/teckit/archive/2.5.12.tar.gz
 
-xpdf 4.04 - checked 24apr22
+xpdf 4.05 - checked 10feb24
   https://www.xpdfreader.com/download.html
   with modifications for pdftex
 

Modified: trunk/Build/source/libs/xpdf/ChangeLog
===================================================================
--- trunk/Build/source/libs/xpdf/ChangeLog	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/ChangeLog	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,3 +1,8 @@
+2024-02-10  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	* Import xpdf-4.05.
+	* version.ac, aconf.h.in: Adjust.
+
 2022-04-24  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	* Import xpdf-4.04.

Modified: trunk/Build/source/libs/xpdf/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/xpdf/TLpatches/ChangeLog	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/TLpatches/ChangeLog	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,3 +1,7 @@
+2024-02-10  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
+
+	* patch-bunched: Adjust.
+
 2022-04-24  Akira Kakuto  <kakuto at jcom.zaq.ne.jp>
 
 	* patch-bunched: Adjust.

Modified: trunk/Build/source/libs/xpdf/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/xpdf/TLpatches/TL-Changes	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/TLpatches/TL-Changes	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,4 +1,4 @@
-Changes applied to the xpdf-4.04/ tree as obtained from:
+Changes applied to the xpdf-4.05/ 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	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/TLpatches/patch-bunched	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,6 +1,6 @@
-diff -ur xpdf-4.04/goo/gfile.cc xpdf-src/goo/gfile.cc
---- xpdf-4.04/goo/gfile.cc	Tue Apr 19 06:11:23 2022
-+++ xpdf-src/goo/gfile.cc	Sun Apr 24 10:45:35 2022
+diff -ur xpdf-4.05/goo/gfile.cc xpdf-src/goo/gfile.cc
+--- xpdf-4.05/goo/gfile.cc	Thu Feb 08 05:32:41 2024
++++ xpdf-src/goo/gfile.cc	Sat Feb 10 11:31:53 2024
 @@ -7,6 +7,9 @@
  // Copyright 1996-2003 Glyph & Cog, LLC
  //
@@ -11,7 +11,7 @@
  
  #include <aconf.h>
  
-@@ -429,6 +432,7 @@
+@@ -441,6 +444,7 @@
  #endif
  }
  
@@ -19,7 +19,7 @@
  GBool openTempFile(GString **name, FILE **f,
  		   const char *mode, const char *ext) {
  #if defined(_WIN32)
-@@ -543,6 +547,7 @@
+@@ -555,6 +559,7 @@
    return gTrue;
  #endif
  }
@@ -27,7 +27,7 @@
  
  GBool createDir(char *path, int mode) {
  #ifdef _WIN32
-@@ -626,6 +631,8 @@
+@@ -649,6 +654,8 @@
  
  FILE *openFile(const char *path, const char *mode) {
  #if defined(_WIN32)
@@ -36,7 +36,7 @@
    wchar_t wPath[winMaxLongPath + 1];
    wchar_t wMode[8];
    int i;
-@@ -637,6 +644,7 @@
+@@ -660,6 +667,7 @@
    wMode[i] = (wchar_t)0;
    readWindowsShortcut(wPath, winMaxLongPath + 1);
    return _wfopen(wPath, wMode);
@@ -44,7 +44,7 @@
  #elif defined(VMS)
    return fopen(path, mode, "ctx=stm");
  #else
-@@ -644,6 +652,7 @@
+@@ -667,6 +675,7 @@
  #endif
  }
  
@@ -52,7 +52,7 @@
  #ifdef _WIN32
  void readWindowsShortcut(wchar_t *wPath, size_t wPathSize) {
    size_t n = wcslen(wPath);
-@@ -689,11 +698,15 @@
+@@ -712,11 +721,15 @@
    wcscpy(wPath, target);
  }
  #endif
@@ -68,7 +68,7 @@
  #else
    return mkdir(path, (mode_t)mode);
  #endif
-@@ -752,6 +765,7 @@
+@@ -775,6 +788,7 @@
  #endif
  }
  
@@ -76,15 +76,15 @@
  void fixCommandLine(int *argc, char **argv[]) {
  #ifdef _WIN32
    int argcw;
-@@ -777,3 +791,4 @@
+@@ -800,3 +814,4 @@
    LocalFree(argvw);
  #endif
  }
 +#endif /* !PDF_PARSER_ONLY */
-diff -ur xpdf-4.04/goo/gfile.h xpdf-src/goo/gfile.h
---- xpdf-4.04/goo/gfile.h	Tue Apr 19 06:11:23 2022
-+++ xpdf-src/goo/gfile.h	Sun Apr 24 10:48:58 2022
-@@ -100,11 +100,13 @@
+diff -ur xpdf-4.05/goo/gfile.h xpdf-src/goo/gfile.h
+--- xpdf-4.05/goo/gfile.h	Thu Feb 08 05:32:41 2024
++++ xpdf-src/goo/gfile.h	Sat Feb 10 11:38:12 2024
+@@ -106,11 +106,13 @@
  // UCS-2 and calls _wfopen().  On other OSes, this simply calls fopen().
  extern FILE *openFile(const char *path, const char *mode);
  
@@ -98,7 +98,7 @@
  
  // Create a directory.  On Windows, this converts the path from UTF-8
  // to UCS-2 and calls _wmkdir(), ignoring the mode argument.  On other
-@@ -139,6 +141,8 @@
+@@ -145,6 +147,8 @@
  
  // On Windows, this gets the Unicode command line and converts it to
  // UTF-8.  On other systems, this is a nop.
@@ -107,10 +107,10 @@
 +#endif /* !PDF_PARSER_ONLY */
  
  #endif
-diff -ur xpdf-4.04/xpdf/Error.cc xpdf-src/xpdf/Error.cc
---- xpdf-4.04/xpdf/Error.cc	Tue Apr 19 06:11:23 2022
-+++ xpdf-src/xpdf/Error.cc	Sun Apr 24 11:27:58 2022
-@@ -77,11 +77,14 @@
+diff -ur xpdf-4.05/xpdf/Error.cc xpdf-src/xpdf/Error.cc
+--- xpdf-4.05/xpdf/Error.cc	Thu Feb 08 05:32:41 2024
++++ xpdf-src/xpdf/Error.cc	Sat Feb 10 11:42:28 2024
+@@ -73,11 +73,14 @@
      (*errorCbk)(errorCbkData, category, (int)pos, sanitized->getCString());
    } else {
      fflush(stdout);
@@ -127,13 +127,13 @@
  	      errorCategoryNames[category], sanitized->getCString());
      }
      fflush(stderr);
-diff -ur xpdf-4.04/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
---- xpdf-4.04/xpdf/GlobalParams.cc	Tue Apr 19 06:11:23 2022
-+++ xpdf-src/xpdf/GlobalParams.cc	Sun Apr 24 11:07:30 2022
-@@ -44,8 +44,12 @@
- #include "GlobalParams.h"
+diff -ur xpdf-4.05/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
+--- xpdf-4.05/xpdf/GlobalParams.cc	Thu Feb 08 05:32:41 2024
++++ xpdf-src/xpdf/GlobalParams.cc	Sat Feb 10 14:04:34 2024
+@@ -41,9 +41,13 @@
  
  #ifdef _WIN32
+ #ifndef __GNUC__
 -#  define strcasecmp stricmp
 -#  define strncasecmp strnicmp
 +#  undef strcasecmp
@@ -140,12 +140,23 @@
 +#  undef strncasecmp
 +#  define strcasecmp _stricmp
 +#  define strncasecmp _strnicmp
+ #endif
 +#else
 +#  include <strings.h>
  #endif
  
  #if MULTITHREADED
-@@ -794,6 +798,7 @@
+@@ -770,7 +774,9 @@
+   separateRotatedText = gFalse;
+   createDefaultKeyBindings();
+   popupMenuCmds = new GList();
++#ifndef PDF_PARSER_ONLY
+   initStateFilePaths();
++#endif
+   saveSessionOnQuit = gTrue;
+   savePageNumbers = gTrue;
+   printCommands = gFalse;
+@@ -811,6 +817,7 @@
    f = NULL;
    fileName = NULL;
    if (cfgFileName && cfgFileName[0]) {
@@ -153,7 +164,7 @@
      fileName = new GString(cfgFileName);
      if (!(f = fopen(fileName->getCString(), "r"))) {
        delete fileName;
-@@ -826,6 +831,7 @@
+@@ -843,6 +850,7 @@
      parseFile(fileName, f);
      delete fileName;
      fclose(f);
@@ -161,7 +172,23 @@
    }
  }
  
-@@ -2378,8 +2384,11 @@
+@@ -1028,6 +1036,7 @@
+ 				     xpdfKeyContextAny, "zoomFitWidth"));
+ }
+ 
++#ifndef PDF_PARSER_ONLY
+ void GlobalParams::initStateFilePaths() {
+ #ifdef _WIN32
+   char path[MAX_PATH];
+@@ -1046,6 +1055,7 @@
+   sessionFile = appendToPath(getHomeDir(), ".xpdf.session");
+ #endif
+ }
++#endif
+ 
+ void GlobalParams::parseFile(GString *fileName, FILE *f) {
+   int line;
+@@ -2487,8 +2497,11 @@
  				   base14->fontNum,
  				   displayFontTab[i].obliqueFactor));
        } else {
@@ -173,9 +200,9 @@
        }
      }
    }
-diff -ur xpdf-4.04/xpdf/GlobalParams.h xpdf-src/xpdf/GlobalParams.h
---- xpdf-4.04/xpdf/GlobalParams.h	Tue Apr 19 06:11:23 2022
-+++ xpdf-src/xpdf/GlobalParams.h	Sun Apr 24 11:08:50 2022
+diff -ur xpdf-4.05/xpdf/GlobalParams.h xpdf-src/xpdf/GlobalParams.h
+--- xpdf-4.05/xpdf/GlobalParams.h	Thu Feb 08 05:32:41 2024
++++ xpdf-src/xpdf/GlobalParams.h	Sat Feb 10 14:04:34 2024
 @@ -5,6 +5,9 @@
  // Copyright 2001-2003 Glyph & Cog, LLC
  //
@@ -186,7 +213,7 @@
  
  #ifndef GLOBALPARAMS_H
  #define GLOBALPARAMS_H
-@@ -237,7 +240,7 @@
+@@ -233,7 +236,7 @@
  
    // Initialize the global parameters by attempting to read a config
    // file.
@@ -195,10 +222,50 @@
  
    ~GlobalParams();
  
-diff -ur xpdf-4.04/xpdf/PDFDoc.cc xpdf-src/xpdf/PDFDoc.cc
---- xpdf-4.04/xpdf/PDFDoc.cc	Tue Apr 19 06:11:23 2022
-+++ xpdf-src/xpdf/PDFDoc.cc	Sun Apr 24 11:19:50 2022
-@@ -114,6 +114,7 @@
+@@ -423,7 +426,9 @@
+ 
+   void setDataDirVar();
+   void createDefaultKeyBindings();
++#ifndef PDF_PARSER_ONLY
+   void initStateFilePaths();
++#endif
+   void parseFile(GString *fileName, FILE *f);
+   GList *parseLineTokens(char *buf, GString *fileName, int line);
+   void parseNameToUnicode(GList *tokens, GString *fileName, int line);
+diff -ur xpdf-4.05/xpdf/PDFCore.h xpdf-src/xpdf/PDFCore.h
+--- xpdf-4.05/xpdf/PDFCore.h	Thu Feb 08 05:32:41 2024
++++ xpdf-src/xpdf/PDFCore.h	Sat Feb 10 13:12:11 2024
+@@ -12,7 +12,9 @@
+ #include <aconf.h>
+ 
+ #include <stdlib.h>
++#ifndef PDF_PARSER_ONLY
+ #include <atomic>
++#endif
+ #include "SplashTypes.h"
+ #include "CharTypes.h"
+ #include "DisplayState.h"
+@@ -75,7 +77,7 @@
+ //------------------------------------------------------------------------
+ // AsyncFindAll
+ //------------------------------------------------------------------------
+-
++#ifndef PDF_PARSER_ONLY
+ class AsyncFindAll {
+ public:
+ 
+@@ -98,6 +100,7 @@
+   PDFCore *core;
+   std::atomic<bool> canceled;
+ };
++#endif
+ 
+ //------------------------------------------------------------------------
+ // PDFCore
+diff -ur xpdf-4.05/xpdf/PDFDoc.cc xpdf-src/xpdf/PDFDoc.cc
+--- xpdf-4.05/xpdf/PDFDoc.cc	Thu Feb 08 05:32:41 2024
++++ xpdf-src/xpdf/PDFDoc.cc	Sat Feb 10 12:22:46 2024
+@@ -111,6 +111,7 @@
    ok = setup(ownerPassword, userPassword);
  }
  
@@ -206,7 +273,7 @@
  #ifdef _WIN32
  PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GString *ownerPassword,
  	       GString *userPassword, PDFCore *coreA) {
-@@ -161,23 +162,28 @@
+@@ -158,23 +159,29 @@
    ok = setup(ownerPassword, userPassword);
  }
  #endif
@@ -225,8 +292,8 @@
    Unicode u;
    int i, j;
  #endif
--
 +#endif /* 0 */
+ 
    init(coreA);
  
    fileName = new GString(fileNameA);
@@ -236,12 +303,13 @@
    wchar_t wPath[winMaxLongPath + 1];
    i = 0;
    j = 0;
-@@ -197,8 +203,11 @@
+@@ -194,8 +201,11 @@
    if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
      file = _wfopen(fileNameU, wfopenReadMode);
    } else {
+-    file = fopen(fileName->getCString(), fopenReadMode);
 +#endif /* 0 */
-     file = fopen(fileName->getCString(), fopenReadMode);
++  file = fopen(fileName->getCString(), fopenReadMode);
 +#if 0
    }
 +#endif /* 0 */
@@ -248,7 +316,7 @@
  #elif defined(VMS)
    file = fopen(fileName->getCString(), fopenReadMode, "ctx=stm");
  #else
-@@ -608,6 +617,7 @@
+@@ -613,6 +623,7 @@
    GBool ret;
  
    // NB: _wfopen is only available in NT
@@ -256,7 +324,7 @@
    version.dwOSVersionInfoSize = sizeof(version);
    GetVersionEx(&version);
    if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-@@ -617,12 +627,15 @@
+@@ -622,12 +633,15 @@
      path2w[i] = 0;
      f = _wfopen(path2w, L"wb");
    } else {
@@ -272,10 +340,10 @@
    if (!f) {
      return gFalse;
    }
-diff -ur xpdf-4.04/xpdf/Page.cc xpdf-src/xpdf/Page.cc
---- xpdf-4.04/xpdf/Page.cc	Tue Apr 19 06:11:23 2022
-+++ xpdf-src/xpdf/Page.cc	Sun Apr 24 11:22:49 2022
-@@ -531,9 +531,9 @@
+diff -ur xpdf-4.05/xpdf/Page.cc xpdf-src/xpdf/Page.cc
+--- xpdf-4.05/xpdf/Page.cc	Thu Feb 08 05:32:41 2024
++++ xpdf-src/xpdf/Page.cc	Sat Feb 10 12:25:57 2024
+@@ -525,9 +525,9 @@
    delete links;
  }
  
@@ -286,7 +354,7 @@
    GfxState *state;
    int i;
  
-@@ -550,5 +550,5 @@
+@@ -544,6 +544,6 @@
      ctm[i] = state->getCTM()[i];
    }
    delete state;
@@ -293,9 +361,10 @@
 -}
  #endif
 +}
-diff -ur xpdf-4.04/xpdf/config.h xpdf-src/xpdf/config.h
---- xpdf-4.04/xpdf/config.h	Tue Apr 19 06:11:23 2022
-+++ xpdf-src/xpdf/config.h	Sun Apr 24 11:24:23 2022
+ 
+diff -ur xpdf-4.05/xpdf/config.h xpdf-src/xpdf/config.h
+--- xpdf-4.05/xpdf/config.h	Thu Feb 08 05:32:41 2024
++++ xpdf-src/xpdf/config.h	Sat Feb 10 12:28:00 2024
 @@ -80,11 +80,6 @@
  // popen
  //------------------------------------------------------------------------

Modified: trunk/Build/source/libs/xpdf/aconf-w32.h
===================================================================
--- trunk/Build/source/libs/xpdf/aconf-w32.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/aconf-w32.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,8 +8,6 @@
 #ifndef ACONF_H
 #define ACONF_H
 
-#include <aconf2.h>
-
 /*
  * Use A4 paper size instead of Letter for PostScript output.
  */

Modified: trunk/Build/source/libs/xpdf/aconf.h.in
===================================================================
--- trunk/Build/source/libs/xpdf/aconf.h.in	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/aconf.h.in	2024-02-10 06:55:23 UTC (rev 69765)
@@ -9,8 +9,6 @@
 #ifndef ACONF_H
 #define ACONF_H
 
-#include <aconf2.h>
-
 /*
  * Enable C++ exceptions.
  */

Modified: trunk/Build/source/libs/xpdf/configure
===================================================================
--- trunk/Build/source/libs/xpdf/configure	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/configure	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.72 for xpdf (TeX Live) 4.04.
+# Generated by GNU Autoconf 2.72 for xpdf (TeX Live) 4.05.
 #
 # Report bugs to <tex-k at tug.org>.
 #
@@ -603,8 +603,8 @@
 # Identity of this package.
 PACKAGE_NAME='xpdf (TeX Live)'
 PACKAGE_TARNAME='xpdf--tex-live-'
-PACKAGE_VERSION='4.04'
-PACKAGE_STRING='xpdf (TeX Live) 4.04'
+PACKAGE_VERSION='4.05'
+PACKAGE_STRING='xpdf (TeX Live) 4.05'
 PACKAGE_BUGREPORT='tex-k at tug.org'
 PACKAGE_URL=''
 
@@ -1319,7 +1319,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.04 to adapt to many kinds of systems.
+'configure' configures xpdf (TeX Live) 4.05 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1386,7 +1386,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of xpdf (TeX Live) 4.04:";;
+     short | recursive ) echo "Configuration of xpdf (TeX Live) 4.05:";;
    esac
   cat <<\_ACEOF
 
@@ -1491,7 +1491,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-xpdf (TeX Live) configure 4.04
+xpdf (TeX Live) configure 4.05
 generated by GNU Autoconf 2.72
 
 Copyright (C) 2023 Free Software Foundation, Inc.
@@ -1755,7 +1755,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.04, which was
+It was created by xpdf (TeX Live) $as_me 4.05, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -4570,7 +4570,7 @@
 
 # Define the identity of the package.
  PACKAGE='xpdf--tex-live-'
- VERSION='4.04'
+ VERSION='4.05'
 
 
 # Some tools Automake needs.
@@ -7546,7 +7546,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.04, which was
+This file was extended by xpdf (TeX Live) $as_me 4.05, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -7618,7 +7618,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-xpdf (TeX Live) config.status 4.04
+xpdf (TeX Live) config.status 4.05
 configured by $0, generated by GNU Autoconf 2.72,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/xpdf/version.ac
===================================================================
--- trunk/Build/source/libs/xpdf/version.ac	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/version.ac	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current xpdf version
-m4_define([xpdf_version], [4.04])
+m4_define([xpdf_version], [4.05])

Modified: trunk/Build/source/libs/xpdf/xpdf-src/ANNOUNCE
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/ANNOUNCE	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/ANNOUNCE	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,4 +1,4 @@
-Subject: ANNOUNCE: Xpdf 4.04 - a PDF viewer and related tools
+Subject: ANNOUNCE: Xpdf 4.05 - 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
@@ -10,17 +10,30 @@
 Unix, Windows, MacOSX, and pretty much any other system with a decent
 C++ compiler.
 
-4.04 is primarily a bug fix release.  There are some new features:
+4.05 is primarily a bug fix release.  There are some new features:
 
+* New command line options/features:
+  - Added the '-overwrite' option to pdftohtml.
+  - Added the '-custom' flag to pdfinfo.
+  - Added the '-meta' flag to pdftohtml.
+  - Added the 'uses JavaScript' output to pdfinfo.
+
+* New configuration options:
+  - Added the 'ignoreWrongSizeToUnicode' xpdfrc setting.
+  - Added the zoomScaleFactor xpdfrc setting.
+  - Added the zoomValues xpdfrc setting.
+  - Added the separateRotatedText xpdfrc setting.
+  - Added the allowLinksToChangeZoom xpdfrc setting.
+
 * XpdfReader improvements:
-  - Implemented selection extension via shift-click, and word/line
-    selection via double/triple click.
-  - Added default bindings for ctrl-mousewheel-up/down to zoom in/out.
-  - Added a help menu item that shows all of the key bindings.
+  - Added the loadSession and saveSession commands, and the 'Load last
+    session' menu item.
+  - Added code to automatically save and restore the xpdf session
+    under control of a session manager.  (This has not been thoroughly
+    tested yet.)
+  - Added a 'smart case' option for search in xpdf.
+  - Added a color/gray/mono switch to the 'save image' dialog.
 
-* Various new command line options for pdftotext, pdftohtml, pdftoppm,
-  pdftopng, and xpdf.
-
 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	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/CHANGES	2024-02-10 06:55:23 UTC (rev 69765)
@@ -2810,3 +2810,83 @@
 The DCT (JPEG) decoder was allowing the 'interleaved' flag to be
   changed after the first scan of the image.  (CVE-2022-24106) [Thanks
   to Shin Ando @ Ricera Security for the bug report.]
+
+4.05 (2024-feb-08)
+------------------
+Added the '-overwrite' option to pdftohtml.
+Added the 'ignoreWrongSizeToUnicode' xpdfrc setting.
+Added the loadSession and saveSession commands, and the 'Load last
+  session' menu item.
+Added code to automatically save and restore the xpdf session under
+  control of a session manager.  This has not been thoroughly tested
+  yet.
+Added the zoomScaleFactor xpdfrc setting.
+Added the zoomValues xpdfrc setting.
+Added a 'smart case' option for search in xpdf.
+Added the '-custom' flag to pdfinfo.
+Added a color/gray/mono switch to the 'save image' dialog.
+Added the separateRotatedText xpdfrc setting.
+Added the '-meta' flag to pdftohtml.
+Added the allowLinksToChangeZoom xpdfrc setting.
+Added the 'uses JavaScript' output to pdfinfo.
+Implemented pattern stroking of text.  Also fixed the various
+  combinations of filling/stroking with color/pattern + clipping, some
+  of which weren't being handled correctly.
+Pdftops now (re)compresses any uncompressed or RLE-compressed images.
+On an out-of-memory error, the command line tools now exit with an
+  "out of memory" message, rather than an exception message.
+Add code to pdfimages to extract images from tiling patterns.
+Pdftops can now embed external 8-bit OpenType CFF fonts.
+Fixed a corner case in the text extractor related to characters drawn
+  at extremely large coordinates.  [Thanks to elvadisas for the bug
+  report.]
+Fixed an integer overflow in the transparency group code.  [Thanks to
+  elvadisas for the bug report.]
+Modify Annots::Annots() to skip annotations that have been turned into
+  AcroFormFields -- invalid Widget-type annots will now be rendered as
+  annots.
+Added a missing integer overflow check in the JBIG2 decoder.  [Thanks
+  to sangjun for the bug report.]
+Added some sanity checks to the JBIG2 decoder.  [Thanks to sangjun and
+  ycdxsb for the bug reports.]
+Tiling patterns that use non-Normal blend modes can't be cached.
+Fixed a bitmap size sanity check in the JBIG2 decoder.  [Thanks to Han
+  Zheng (NCNIPC of China, Hexhive), for the bug report.]
+Fixed a missing bounds check in FoFiType1C::convertToOpenType (used in
+  pdftohtml).  [Thanks to cyth for the bug report.]
+Fixed a use-after-free bug in pdftohtml.  [Thanks to FeRDNYC for the
+  bug report.]
+Merged aconf2.h into aconf.h; corrected the cmake config settings for
+  paths; added the BASE14_FONT_DIR config option.  [Thanks to FeRDNYC
+  for the suggestions.]
+Fixed a missing check for a zero-length index in the CFF (Type1C) font
+  parser.  [Thanks to Yuhang Huang (NCNIPC of China), Han Zheng
+  (NCNIPC of China, Hexhive), Wanying Cao, Jiayu Zhao (NCNIPC of
+  China) for the bug report.]
+Add an object loop check to Catalog::countPageTree().
+The DCT decoder wasn't checking for an SOF before the first SOS.
+  [Thanks to cyth for the bug report.]
+The inline image decoder was skipping to end-of-stream in the wrong
+  stream object.  [Thanks to cyth for the bug report.]
+Fixed a bug in the JPEG 2000 decoder when nLayers > 1 and the
+  'termination on each coding pass' flag is set.
+Removed the #pragma interface/implementation stuff (which is outdated
+  and useless at this point).
+Fixed a bug in the ICCBased color space parser that was allowing the
+  number of components to be zero.  (CVE-2023-2662)  [Thanks to
+  huckleberry for the bug report.]
+Added checks for PDF object loops in AcroForm::scanField()
+  (CVE-2018-7453, CVE-2018-16369, CVE-2022-36561, CVE-2022-41844),
+  Catalog::readPageLabelTree2() (CVE-2023-2663), and
+  Catalog::readEmbeddedFileTree() (CVE-2023-2664).
+The zero-width character problem can also happen if the page size is
+  very large -- that needs to be limited too, the same way as
+  character position coordinates.  (CVE-2023-3044) [Thanks to jlinliu
+  for the bug report.]
+Add some missing bounds check code in DCTStream.  [Thanks to Jiahao
+  Liu for the bug report.]
+Fix a deadlock when an object stream's length field is contained in
+  another object stream.  (CVE-2023-3436) [Thanks to Jiahao Liu for
+  the bug report.]
+Correctly handle tiling patterns with negative step values.
+Ignore overprint in soft masks (to match Adobe's behavior).

Modified: trunk/Build/source/libs/xpdf/xpdf-src/INSTALL
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/INSTALL	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/INSTALL	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,11 +1,11 @@
 Xpdf
 ====
 
-version 4.04
-2022-apr-18
+version 4.05
+2024-feb-08
 
 The Xpdf software and documentation are
-copyright 1996-2022 Glyph & Cog, LLC.
+copyright 1996-2024 Glyph & Cog, LLC.
 
 Email: xpdf at xpdfreader.com
 WWW: http://www.xpdfreader.com/
@@ -34,8 +34,8 @@
     - CMake 2.8.8 or newer
     - FreeType 2.0.5 or newer
     - Qt 5.x or 6.x (for xpdf only)
-    - libpng (for pdftoppm and pdftohtml)
-    - zlib (for pdftoppm and pdftohtml)
+    - libpng (for pdftopng and pdftohtml)
+    - zlib (for pdftopng and pdftohtml)
 
   If Qt isn't found, the GUI viewer (xpdf) won't be built, but the
   command line tools will still be built.
@@ -119,6 +119,12 @@
         The ${DATADIR} variable in xpdfrc config files will expand to
         this string.
 
+    -DBASE14_FONT_DIR="/usr/share/fonts/type1"
+        By default, Xpdf will look for the URW Type 1 fonts in several
+        quasi-standard directories on Linux/Mac systems.  This option
+        adds another directory to that search path.  On Windows, this
+        does the same thing, except for the system TrueType fonts.
+
     -DCMAKE_DISABLE_FIND_PACKAGE_Qt4=1
     -DCMAKE_DISABLE_FIND_PACKAGE_Qt5Widgets=1
         Do not search for the Qt4/Qt5 libraries.  This will disable
@@ -141,6 +147,11 @@
         Set the man directory, relative to CMAKE_INSTALL_PREFIX
         (typically "man" or "share/man").
 
+    -DCMAKE_CXX_FLAGS="... -DDISABLE_SESSION_MANAGEMENT"
+        Disable the session manager interface, i.e., do not
+        automatically save and restore sessions under control of the
+        session manager.
+
 * Build:
 
       make

Modified: trunk/Build/source/libs/xpdf/xpdf-src/README
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/README	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/README	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,11 +1,11 @@
 Xpdf
 ====
 
-version 4.04
-2022-apr-18
+version 4.05
+2024-feb-08
 
 The Xpdf software and documentation are
-copyright 1996-2022 Glyph & Cog, LLC.
+copyright 1996-2024 Glyph & Cog, LLC.
 
 Email: xpdf at xpdfreader.com
 WWW: http://www.xpdfreader.com/

Deleted: trunk/Build/source/libs/xpdf/xpdf-src/aconf2.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/aconf2.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/aconf2.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,41 +0,0 @@
-/*
- * aconf2.h
- *
- * This gets included by aconf.h, and contains miscellaneous global
- * settings not directly controlled by autoconf.  This is a separate
- * file because otherwise the configure script will munge any
- * #define/#undef constructs.
- *
- * Copyright 2002-2003 Glyph & Cog, LLC
- */
-
-#ifndef ACONF2_H
-#define ACONF2_H
-
-/*
- * This controls the use of the interface/implementation pragmas.
- */
-#if defined(__GNUC__) && !defined(__clang__)
-#define USE_GCC_PRAGMAS
-#endif
-/* There is a bug in the version of gcc which ships with MacOS X 10.2 */
-#if defined(__APPLE__) && defined(__MACH__)
-#  include <AvailabilityMacros.h>
-#endif
-#ifdef MAC_OS_X_VERSION_MAX_ALLOWED
-#  if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2
-#    undef USE_GCC_PRAGMAS
-#  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	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/cmake-config.txt	2024-02-10 06:55:23 UTC (rev 69765)
@@ -92,18 +92,6 @@
 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}\"")
-else ()
-  set(SYSTEM_XPDFRC_DEFINE "/* #undef SYSTEM_XPDFRC */")
-endif ()
-option(XPDFRC_DATADIR "directory to use for the DATADIR xpdfrc variable" "")
-if (XPDFRC_DATADIR)
-  set(XPDFRC_DATADIR_DEFINE "#define XPDFRC_DATADIR \"${XPDFRC_DATADIR}\"")
-else ()
-  set(XPDFRC_DATADIR_DEFINE "/* #undef XPDFRC_DATADIR */")
-endif ()
 if (WIN32)
   option(XPDFWIDGET_PRINTING "include printing support in XpdfWidget" OFF)
 else ()
@@ -110,6 +98,11 @@
   option(XPDFWIDGET_PRINTING "include printing support in XpdfWidget" ON)
 endif ()
 
+#--- paths
+set(SYSTEM_XPDFRC "${SYSTEM_XPDFRC}" CACHE FILEPATH "full path for system-wide xpdfrc file")
+set(XPDFRC_DATADIR "${XPDFRC_DATADIR}" CACHE PATH "directory to use for the DATADIR xpdfrc variable")
+set(BASE14_FONT_DIR "${BASE14_FONT_DIR}" CACHE PATH "directory where the Base14 fonts are installed")
+
 #--- check for various library functions
 check_function_exists(mkstemp HAVE_MKSTEMP)
 check_function_exists(mkstemps HAVE_MKSTEMPS)
@@ -208,11 +201,13 @@
 find_package(Qt6Widgets QUIET)
 if (Qt6Widgets_FOUND)
   find_package(Qt6Network)
+  find_package(Qt6Concurrent)
   find_package(Qt6PrintSupport)
 else ()
   find_package(Qt5Widgets QUIET)
   if (Qt5Widgets_FOUND)
     find_package(Qt5Network)
+    find_package(Qt5Concurrent)
     find_package(Qt5PrintSupport)
   else ()
     find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork)
@@ -221,12 +216,12 @@
 if (Qt5Widgets_FOUND)
   message(STATUS "Qt5 found")
   if (XPDFWIDGET_PRINTING)
-    set(QT_INCLUDES "${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5PrintSupport_INCLUDE_DIRS}")
-    set(QT_DEFINITIONS "${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS} ${Qt5PrintSupport_DEFINITIONS}")
+    set(QT_INCLUDES "${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5Concurrent_INCLUDE_DIRS} ${Qt5PrintSupport_INCLUDE_DIRS}")
+    set(QT_DEFINITIONS "${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS} ${Qt5Concurrent_DEFINITIONS} ${Qt5PrintSupport_DEFINITIONS}")
     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}")
+    set(QT_INCLUDES "${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5Concurrent_INCLUDE_DIRS}")
+    set(QT_DEFINITIONS "${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS} ${Qt5Concurrent_DEFINITIONS}")
     set(QT_LIBRARIES Qt5::Widgets Qt5::Network)
   endif ()
   if (XPDFWIDGET_PRINTING)
@@ -248,13 +243,13 @@
 elseif (Qt6Widgets_FOUND)
   message(STATUS "Qt6 found")
   if (XPDFWIDGET_PRINTING)
-    set(QT_INCLUDES "${Qt6Widgets_INCLUDE_DIRS} ${Qt6Network_INCLUDE_DIRS} ${Qt6PrintSupport_INCLUDE_DIRS}")
-    set(QT_DEFINITIONS "${Qt6Widgets_DEFINITIONS} ${Qt6Network_DEFINITIONS} ${Qt6PrintSupport_DEFINITIONS}")
-    set(QT_LIBRARIES Qt6::Widgets Qt6::Network Qt6::PrintSupport)
+    set(QT_INCLUDES ${Qt6Widgets_INCLUDE_DIRS} ${Qt6Network_INCLUDE_DIRS} ${Qt6Concurrent_INCLUDE_DIRS} ${Qt6PrintSupport_INCLUDE_DIRS})
+    set(QT_DEFINITIONS "${Qt6Widgets_DEFINITIONS} ${Qt6Network_DEFINITIONS} ${Qt6Concurrent_DEFINITIONS} ${Qt6PrintSupport_DEFINITIONS}")
+    set(QT_LIBRARIES Qt6::Widgets Qt6::Network Qt6::Concurrent Qt6::PrintSupport)
   else ()
-    set(QT_INCLUDES "${Qt6Widgets_INCLUDE_DIRS} ${Qt6Network_INCLUDE_DIRS}")
-    set(QT_DEFINITIONS "${Qt6Widgets_DEFINITIONS} ${Qt6Network_DEFINITIONS}")
-    set(QT_LIBRARIES Qt6::Widgets Qt6::Network)
+    set(QT_INCLUDES ${Qt6Widgets_INCLUDE_DIRS} ${Qt6Network_INCLUDE_DIRS} ${Qt6Concurrent_INCLUDE_DIRS})
+    set(QT_DEFINITIONS "${Qt6Widgets_DEFINITIONS} ${Qt6Network_DEFINITIONS} ${Qt6Concurrent_DEFINITIONS}")
+    set(QT_LIBRARIES Qt6::Widgets Qt6::Network Qt6::Concurrent)
   endif ()
   if (XPDFWIDGET_PRINTING)
     if (APPLE)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,8 +1,8 @@
-.\" Copyright 2013-2022 Glyph & Cog, LLC
-.TH pdfdetach 1 "18 Apr 2022"
+.\" Copyright 2013-2024 Glyph & Cog, LLC
+.TH pdfdetach 1 "08 Feb 2024"
 .SH NAME
 pdfdetach \- Portable Document Format (PDF) document embedded file
-extractor (version 4.04)
+extractor (version 4.05)
 .SH SYNOPSIS
 .B pdfdetach
 [options]
@@ -86,10 +86,13 @@
 3
 Error related to PDF permissions.
 .TP
+98
+Out of memory.
+.TP
 99
 Other error.
 .SH AUTHOR
-The pdfinfo software and documentation are copyright 1996-2022 Glyph &
+The pdfinfo software and documentation are copyright 1996-2024 Glyph &
 Cog, LLC.
 .SH "SEE ALSO"
 .BR xpdf (1),

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat	2024-02-10 06:55:23 UTC (rev 69765)
@@ -3,8 +3,8 @@
 
 
 NAME
-       pdfdetach  -  Portable  Document  Format  (PDF)  document embedded file
-       extractor (version 4.04)
+       pdfdetach  -  Portable Document Format (PDF) document embedded file ex-
+       tractor (version 4.05)
 
 SYNOPSIS
        pdfdetach [options] [PDF-file]
@@ -76,10 +76,12 @@
 
        3      Error related to PDF permissions.
 
+       98     Out of memory.
+
        99     Other error.
 
 AUTHOR
-       The pdfinfo software and documentation are copyright 1996-2022 Glyph  &
+       The pdfinfo software and documentation are copyright 1996-2024 Glyph  &
        Cog, LLC.
 
 SEE ALSO
@@ -89,4 +91,4 @@
 
 
 
-                                  18 Apr 2022                     pdfdetach(1)
+                                  08 Feb 2024                     pdfdetach(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.1	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.1	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,8 +1,8 @@
-.\" Copyright 1999-2022 Glyph & Cog, LLC
-.TH pdffonts 1 "18 Apr 2022"
+.\" Copyright 1999-2024 Glyph & Cog, LLC
+.TH pdffonts 1 "08 Feb 2024"
 .SH NAME
 pdffonts \- Portable Document Format (PDF) font analyzer (version
-4.04)
+4.05)
 .SH SYNOPSIS
 .B pdffonts
 [options]
@@ -143,10 +143,13 @@
 3
 Error related to PDF permissions.
 .TP
+98
+Out of memory.
+.TP
 99
 Other error.
 .SH AUTHOR
-The pdffonts software and documentation are copyright 1996-2022 Glyph
+The pdffonts software and documentation are copyright 1996-2024 Glyph
 & Cog, LLC.
 .SH "SEE ALSO"
 .BR xpdf (1),

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat	2024-02-10 06:55:23 UTC (rev 69765)
@@ -3,7 +3,7 @@
 
 
 NAME
-       pdffonts - Portable Document Format (PDF) font analyzer (version 4.04)
+       pdffonts - Portable Document Format (PDF) font analyzer (version 4.05)
 
 SYNOPSIS
        pdffonts [options] [PDF-file]
@@ -14,8 +14,8 @@
 
        The following information is listed for each font:
 
-       name   the font name, exactly as given in  the  PDF  file  (potentially
-              including a subset prefix)
+       name   the font name, exactly as given in the PDF file (potentially in-
+              cluding a subset prefix)
 
        type   the font type -- see below for details
 
@@ -102,10 +102,12 @@
 
        3      Error related to PDF permissions.
 
+       98     Out of memory.
+
        99     Other error.
 
 AUTHOR
-       The pdffonts software and documentation are copyright 1996-2022 Glyph &
+       The pdffonts software and documentation are copyright 1996-2024 Glyph &
        Cog, LLC.
 
 SEE ALSO
@@ -115,4 +117,4 @@
 
 
 
-                                  18 Apr 2022                      pdffonts(1)
+                                  08 Feb 2024                      pdffonts(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.1	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.1	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,8 +1,8 @@
-.\" Copyright 1998-2022 Glyph & Cog, LLC
-.TH pdfimages 1 "18 Apr 2022"
+.\" Copyright 1998-2024 Glyph & Cog, LLC
+.TH pdfimages 1 "08 Feb 2024"
 .SH NAME
 pdfimages \- Portable Document Format (PDF) image extractor
-(version 4.04)
+(version 4.05)
 .SH SYNOPSIS
 .B pdfimages
 [options]
@@ -78,6 +78,11 @@
 Don't print any messages or errors.
 .RB "[config file: " errQuiet ]
 .TP
+.BI \-cfg " config-file"
+Read
+.I config-file
+in place of ~/.xpdfrc or the system-wide config file.
+.TP
 .B \-v
 Print copyright and version information.
 .TP
@@ -102,10 +107,13 @@
 3
 Error related to PDF permissions.
 .TP
+98
+Out of memory.
+.TP
 99
 Other error.
 .SH AUTHOR
-The pdfimages software and documentation are copyright 1998-2022 Glyph
+The pdfimages software and documentation are copyright 1998-2024 Glyph
 & Cog, LLC.
 .SH "SEE ALSO"
 .BR xpdf (1),

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat	2024-02-10 06:55:23 UTC (rev 69765)
@@ -4,7 +4,7 @@
 
 NAME
        pdfimages  -  Portable  Document  Format (PDF) image extractor (version
-       4.04)
+       4.05)
 
 SYNOPSIS
        pdfimages [options] PDF-file image-root
@@ -71,6 +71,10 @@
 
        -q     Don't print any messages or errors.  [config file: errQuiet]
 
+       -cfg config-file
+              Read config-file in place of ~/.xpdfrc or the system-wide config
+              file.
+
        -v     Print copyright and version information.
 
        -h     Print usage information.  (-help and --help are equivalent.)
@@ -86,17 +90,19 @@
 
        3      Error related to PDF permissions.
 
+       98     Out of memory.
+
        99     Other error.
 
 AUTHOR
-       The pdfimages software and documentation are copyright 1998-2022  Glyph
+       The  pdfimages software and documentation are copyright 1998-2024 Glyph
        & Cog, LLC.
 
 SEE ALSO
-       xpdf(1),   pdftops(1),  pdftotext(1),  pdftohtml(1),  pdfinfo(1),  pdf-
+       xpdf(1),  pdftops(1),  pdftotext(1),  pdftohtml(1),  pdfinfo(1),   pdf-
        fonts(1), pdfdetach(1), pdftoppm(1), pdftopng(1), xpdfrc(5)
        http://www.xpdfreader.com/
 
 
 
-                                  18 Apr 2022                     pdfimages(1)
+                                  08 Feb 2024                     pdfimages(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.1	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.1	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,8 +1,8 @@
-.\" Copyright 1999-2022 Glyph & Cog, LLC
-.TH pdfinfo 1 "18 Apr 2022"
+.\" Copyright 1999-2024 Glyph & Cog, LLC
+.TH pdfinfo 1 "08 Feb 2024"
 .SH NAME
 pdfinfo \- Portable Document Format (PDF) document information
-extractor (version 4.04)
+extractor (version 4.05)
 .SH SYNOPSIS
 .B pdfinfo
 [options]
@@ -63,9 +63,12 @@
 file size
 .RE
 .RS
-linearized (yes/no)
+optimized (aka linearized) (yes/no)
 .RE
 .RS
+uses JavaScript (yes/no)
+.RE
+.RS
 PDF version
 .RE
 .RS
@@ -103,6 +106,9 @@
 .B \-rawdates
 Prints the raw (undecoded) date strings, directly from the PDF file.
 .TP
+.B \-custom
+Prints any custom (non-standard) entries in the \'Info' dictionary.
+.TP
 .BI \-enc " encoding-name"
 Sets the encoding to use for text output.  The
 .I encoding\-name
@@ -147,10 +153,13 @@
 3
 Error related to PDF permissions.
 .TP
+98
+Out of memory.
+.TP
 99
 Other error.
 .SH AUTHOR
-The pdfinfo software and documentation are copyright 1996-2022 Glyph &
+The pdfinfo software and documentation are copyright 1996-2024 Glyph &
 Cog, LLC.
 .SH "SEE ALSO"
 .BR xpdf (1),

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat	2024-02-10 06:55:23 UTC (rev 69765)
@@ -4,7 +4,7 @@
 
 NAME
        pdfinfo - Portable Document Format (PDF) document information extractor
-       (version 4.04)
+       (version 4.05)
 
 SYNOPSIS
        pdfinfo [options] [PDF-file]
@@ -33,7 +33,8 @@
               print and copy permissions (if encrypted)
               page size and rotation
               file size
-              linearized (yes/no)
+              optimized (aka linearized) (yes/no)
+              uses JavaScript (yes/no)
               PDF version
               metadata (only if requested)
 
@@ -50,10 +51,10 @@
        corresponding command line option.
 
        -f number
-              Specifies  the  first  page  to  examine.  If multiple pages are
-              requested using the "-f" and "-l"  options,  the  size  of  each
-              requested  page  (and,  optionally,  the bounding boxes for each
-              requested page) are printed.  Otherwise, only page one is  exam-
+              Specifies  the first page to examine.  If multiple pages are re-
+              quested using the "-f" and "-l" options, the size  of  each  re-
+              quested  page  (and, optionally, the bounding boxes for each re-
+              quested page) are printed.  Otherwise, only page  one  is  exam-
               ined.
 
        -l number
@@ -69,14 +70,18 @@
               Prints  the  raw (undecoded) date strings, directly from the PDF
               file.
 
+       -custom
+              Prints any custom (non-standard) entries in the  'Info'  dictio-
+              nary.
+
        -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]
 
        -opw password
-              Specify  the  owner  password  for the PDF file.  Providing this
+              Specify the owner password for the  PDF  file.   Providing  this
               will bypass all security restrictions.
 
        -upw password
@@ -101,17 +106,19 @@
 
        3      Error related to PDF permissions.
 
+       98     Out of memory.
+
        99     Other error.
 
 AUTHOR
-       The  pdfinfo software and documentation are copyright 1996-2022 Glyph &
+       The pdfinfo software and documentation are copyright 1996-2024 Glyph  &
        Cog, LLC.
 
 SEE ALSO
-       xpdf(1), pdftops(1), pdftotext(1),  pdftohtml(1),  pdffonts(1),  pdfde-
+       xpdf(1),  pdftops(1),  pdftotext(1),  pdftohtml(1), pdffonts(1), pdfde-
        tach(1), pdftoppm(1), pdftopng(1), pdfimages(1), xpdfrc(5)
        http://www.xpdfreader.com/
 
 
 
-                                  18 Apr 2022                       pdfinfo(1)
+                                  08 Feb 2024                       pdfinfo(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.1	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.1	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,8 +1,8 @@
-.\" Copyright 1997-2022 Glyph & Cog, LLC
-.TH pdftohtml 1 "18 Apr 2022"
+.\" Copyright 1997-2024 Glyph & Cog, LLC
+.TH pdftohtml 1 "08 Feb 2024"
 .SH NAME
 pdftohtml \- Portable Document Format (PDF) to HTML converter
-(version 4.04)
+(version 4.05)
 .SH SYNOPSIS
 .B pdftohtml
 [options]
@@ -84,6 +84,9 @@
 This also removes text (e.g., underscore characters) and erases
 background image content (e.g., lines or boxes) in the field areas.
 .TP
+.B \-meta
+Include PDF document metadata as 'meta' elements in the HTML header.
+.TP
 .B \-table
 Use table mode when performing the underlying text extraction.  This
 will generally produce better output when the PDF content is a
@@ -90,6 +93,12 @@
 full-page table.  NB: This does not generate HTML tables; it just
 changes the way text is split up.
 .TP
+.B \-overwrite
+By default pdftohtml will not overwrite the specified output
+directory.  If the directory already exists, pdftohtml will exit with
+an error.  This option tells pdftohtml to instead overwrite the
+existing directory.
+.TP
 .BI \-opw " password"
 Specify the owner password for the PDF file.  Providing this will
 bypass all security restrictions.
@@ -138,10 +147,13 @@
 3
 Error related to PDF permissions.
 .TP
+98
+Out of memory.
+.TP
 99
 Other error.
 .SH AUTHOR
-The pdftohtml software and documentation are copyright 1996-2022 Glyph
+The pdftohtml software and documentation are copyright 1996-2024 Glyph
 & Cog, LLC.
 .SH "SEE ALSO"
 .BR xpdf (1),

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat	2024-02-10 06:55:23 UTC (rev 69765)
@@ -4,7 +4,7 @@
 
 NAME
        pdftohtml  -  Portable Document Format (PDF) to HTML converter (version
-       4.04)
+       4.05)
 
 SYNOPSIS
        pdftohtml [options] PDF-file HTML-dir
@@ -59,8 +59,8 @@
               the HTML file, rather than storing it as a separate file.
 
        -nofonts
-              Disable extraction of embedded  fonts.   By  default,  pdftohtml
-              extracts  TrueType and OpenType fonts.  Disabling extraction can
+              Disable extraction of embedded fonts.  By default, pdftohtml ex-
+              tracts  TrueType  and  OpenType fonts.  Disabling extraction can
               work around problems with buggy fonts.
 
        -embedfonts
@@ -70,8 +70,8 @@
        -skipinvisible
               Don't draw invisible text.  By default, invisible text (commonly
               used in OCR'ed PDF files) is drawn as transparent (alpha=0) HTML
-              text.   This  option  tells  pdftohtml to discard invisible text
-              entirely.
+              text.  This option tells pdftohtml to discard invisible text en-
+              tirely.
 
        -allinvisible
               Treat all text as invisible.  By default,  regular  (non-invisi-
@@ -86,11 +86,20 @@
               erases background image content (e.g., lines or  boxes)  in  the
               field areas.
 
-       -table Use  table  mode when performing the underlying text extraction.
-              This will generally produce better output when the  PDF  content
-              is  a  full-page table.  NB: This does not generate HTML tables;
+       -meta  Include  PDF  document  metadata  as 'meta' elements in the HTML
+              header.
+
+       -table Use table mode when performing the underlying  text  extraction.
+              This  will  generally produce better output when the PDF content
+              is a full-page table.  NB: This does not generate  HTML  tables;
               it just changes the way text is split up.
 
+       -overwrite
+              By default pdftohtml will not overwrite the specified output di-
+              rectory.  If the directory already exists, pdftohtml  will  exit
+              with an error.  This option tells pdftohtml to instead overwrite
+              the existing directory.
+
        -opw password
               Specify the owner password for the  PDF  file.   Providing  this
               will bypass all security restrictions.
@@ -128,10 +137,12 @@
 
        3      Error related to PDF permissions.
 
+       98     Out of memory.
+
        99     Other error.
 
 AUTHOR
-       The  pdftohtml software and documentation are copyright 1996-2022 Glyph
+       The  pdftohtml software and documentation are copyright 1996-2024 Glyph
        & Cog, LLC.
 
 SEE ALSO
@@ -141,4 +152,4 @@
 
 
 
-                                  18 Apr 2022                     pdftohtml(1)
+                                  08 Feb 2024                     pdftohtml(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.1	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.1	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,8 +1,8 @@
-.\" Copyright 2017-2022 Glyph & Cog, LLC
-.TH pdftopng 1 "18 Apr 2022"
+.\" Copyright 2017-2024 Glyph & Cog, LLC
+.TH pdftopng 1 "08 Feb 2024"
 .SH NAME
 pdftopng \- Portable Document Format (PDF) to Portable Network Graphics
-(PNG) converter (version 4.04)
+(PNG) converter (version 4.05)
 .SH SYNOPSIS
 .B pdftopng
 [options]
@@ -86,6 +86,11 @@
 Don't print any messages or errors.
 .RB "[config file: " errQuiet ]
 .TP
+.BI \-cfg " config-file"
+Read
+.I config-file
+in place of ~/.xpdfrc or the system-wide config file.
+.TP
 .B \-v
 Print copyright and version information.
 .TP
@@ -110,10 +115,13 @@
 3
 Error related to PDF permissions.
 .TP
+98
+Out of memory.
+.TP
 99
 Other error.
 .SH AUTHOR
-The pdftopng software and documentation are copyright 1996-2022 Glyph
+The pdftopng software and documentation are copyright 1996-2024 Glyph
 & Cog, LLC.
 .SH "SEE ALSO"
 .BR xpdf (1),

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat	2024-02-10 06:55:23 UTC (rev 69765)
@@ -4,7 +4,7 @@
 
 NAME
        pdftopng  - Portable Document Format (PDF) to Portable Network Graphics
-       (PNG) converter (version 4.04)
+       (PNG) converter (version 4.05)
 
 SYNOPSIS
        pdftopng [options] PDF-file PNG-root
@@ -76,6 +76,10 @@
 
        -q     Don't print any messages or errors.  [config file: errQuiet]
 
+       -cfg config-file
+              Read config-file in place of ~/.xpdfrc or the system-wide config
+              file.
+
        -v     Print copyright and version information.
 
        -h     Print usage information.  (-help and --help are equivalent.)
@@ -91,17 +95,19 @@
 
        3      Error related to PDF permissions.
 
+       98     Out of memory.
+
        99     Other error.
 
 AUTHOR
-       The pdftopng software and documentation are copyright 1996-2022 Glyph &
+       The pdftopng software and documentation are copyright 1996-2024 Glyph &
        Cog, LLC.
 
 SEE ALSO
-       xpdf(1),   pdftops(1),  pdftotext(1),  pdftohtml(1),  pdfinfo(1),  pdf-
+       xpdf(1),  pdftops(1),  pdftotext(1),  pdftohtml(1),  pdfinfo(1),   pdf-
        fonts(1), pdfdetach(1), pdftoppm(1), pdfimages(1), xpdfrc(5)
        http://www.xpdfreader.com/
 
 
 
-                                  18 Apr 2022                      pdftopng(1)
+                                  08 Feb 2024                      pdftopng(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.1	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.1	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,8 +1,8 @@
-.\" Copyright 2005-2022 Glyph & Cog, LLC
-.TH pdftoppm 1 "18 Apr 2022"
+.\" Copyright 2005-2024 Glyph & Cog, LLC
+.TH pdftoppm 1 "08 Feb 2024"
 .SH NAME
 pdftoppm \- Portable Document Format (PDF) to Portable Pixmap (PPM)
-converter (version 4.04)
+converter (version 4.05)
 .SH SYNOPSIS
 .B pdftoppm
 [options]
@@ -86,6 +86,11 @@
 Don't print any messages or errors.
 .RB "[config file: " errQuiet ]
 .TP
+.BI \-cfg " config-file"
+Read
+.I config-file
+in place of ~/.xpdfrc or the system-wide config file.
+.TP
 .B \-v
 Print copyright and version information.
 .TP
@@ -110,10 +115,13 @@
 3
 Error related to PDF permissions.
 .TP
+98
+Out of memory.
+.TP
 99
 Other error.
 .SH AUTHOR
-The pdftoppm software and documentation are copyright 1996-2022 Glyph
+The pdftoppm software and documentation are copyright 1996-2024 Glyph
 & Cog, LLC.
 .SH "SEE ALSO"
 .BR xpdf (1),

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat	2024-02-10 06:55:23 UTC (rev 69765)
@@ -4,7 +4,7 @@
 
 NAME
        pdftoppm - Portable Document Format (PDF) to Portable Pixmap (PPM) con-
-       verter (version 4.04)
+       verter (version 4.05)
 
 SYNOPSIS
        pdftoppm [options] PDF-file PPM-root
@@ -75,6 +75,10 @@
 
        -q     Don't print any messages or errors.  [config file: errQuiet]
 
+       -cfg config-file
+              Read config-file in place of ~/.xpdfrc or the system-wide config
+              file.
+
        -v     Print copyright and version information.
 
        -h     Print usage information.  (-help and --help are equivalent.)
@@ -90,17 +94,19 @@
 
        3      Error related to PDF permissions.
 
+       98     Out of memory.
+
        99     Other error.
 
 AUTHOR
-       The pdftoppm software and documentation are copyright 1996-2022 Glyph &
+       The pdftoppm software and documentation are copyright 1996-2024 Glyph &
        Cog, LLC.
 
 SEE ALSO
-       xpdf(1),  pdftops(1),  pdftotext(1),  pdftohtml(1),  pdfinfo(1),   pdf-
+       xpdf(1),   pdftops(1),  pdftotext(1),  pdftohtml(1),  pdfinfo(1),  pdf-
        fonts(1), pdfdetach(1), pdftopng(1), pdfimages(1), xpdfrc(5)
        http://www.xpdfreader.com/
 
 
 
-                                  18 Apr 2022                      pdftoppm(1)
+                                  08 Feb 2024                      pdftoppm(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.1	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.1	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,8 +1,8 @@
-.\" Copyright 1996-2022 Glyph & Cog, LLC
-.TH pdftops 1 "18 Apr 2022"
+.\" Copyright 1996-2024 Glyph & Cog, LLC
+.TH pdftops 1 "08 Feb 2024"
 .SH NAME
 pdftops \- Portable Document Format (PDF) to PostScript converter
-(version 4.04)
+(version 4.05)
 .SH SYNOPSIS
 .B pdftops
 [options]
@@ -237,10 +237,13 @@
 3
 Error related to PDF permissions.
 .TP
+98
+Out of memory.
+.TP
 99
 Other error.
 .SH AUTHOR
-The pdftops software and documentation are copyright 1996-2022 Glyph &
+The pdftops software and documentation are copyright 1996-2024 Glyph &
 Cog, LLC.
 .SH "SEE ALSO"
 .BR xpdf (1),

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat	2024-02-10 06:55:23 UTC (rev 69765)
@@ -4,7 +4,7 @@
 
 NAME
        pdftops  - Portable Document Format (PDF) to PostScript converter (ver-
-       sion 4.04)
+       sion 4.05)
 
 SYNOPSIS
        pdftops [options] [PDF-file [PS-file]]
@@ -40,8 +40,8 @@
               Generate Level 1 PostScript.   The  resulting  PostScript  files
               will  be significantly larger (if they contain images), but will
               print on Level 1 printers.  This also  converts  all  images  to
-              black  and  white.   No  more  than  one of the PostScript level
-              options  (-level1,  -level1sep,  -level2,  -level2sep,  -level3,
+              black  and  white.  No more than one of the PostScript level op-
+              tions  (-level1,  -level1sep,  -level2,   -level2sep,   -level3,
               -level3sep) may be given.  [config file: psLevel]
 
        -level1sep
@@ -147,8 +147,8 @@
               maller]
 
        -noshrink
-              Don't scale PDF pages which  are  larger  than  the  paper.   By
-              default, pages larger than the paper are shrunk to fit.  [config
+              Don't scale PDF pages which are larger than the paper.   By  de-
+              fault,  pages  larger than the paper are shrunk to fit.  [config
               file: psShrinkLarger]
 
        -nocenter
@@ -162,8 +162,8 @@
               Box is used as the page size.  [config file: psUseCropBoxAsPage]
 
        -userunit
-              Honor  the  UserUnit  settings  on  PDF  pages  when   computing
-              page/paper size.  By default, pdftops ignores UserUnit.
+              Honor the UserUnit settings on PDF pages when computing page/pa-
+              per size.  By default, pdftops ignores UserUnit.
 
        -duplex
               Set  the  Duplex  pagedevice entry in the PostScript file.  This
@@ -202,10 +202,12 @@
 
        3      Error related to PDF permissions.
 
+       98     Out of memory.
+
        99     Other error.
 
 AUTHOR
-       The pdftops software and documentation are copyright 1996-2022 Glyph  &
+       The pdftops software and documentation are copyright 1996-2024 Glyph  &
        Cog, LLC.
 
 SEE ALSO
@@ -215,4 +217,4 @@
 
 
 
-                                  18 Apr 2022                       pdftops(1)
+                                  08 Feb 2024                       pdftops(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.1	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.1	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,8 +1,8 @@
-.\" Copyright 1997-2022 Glyph & Cog, LLC
-.TH pdftotext 1 "18 Apr 2022"
+.\" Copyright 1997-2024 Glyph & Cog, LLC
+.TH pdftotext 1 "08 Feb 2024"
 .SH NAME
 pdftotext \- Portable Document Format (PDF) to text converter
-(version 4.04)
+(version 4.05)
 .SH SYNOPSIS
 .B pdftotext
 [options]
@@ -202,10 +202,13 @@
 3
 Error related to PDF permissions.
 .TP
+98
+Out of memory.
+.TP
 99
 Other error.
 .SH AUTHOR
-The pdftotext software and documentation are copyright 1996-2022 Glyph
+The pdftotext software and documentation are copyright 1996-2024 Glyph
 & Cog, LLC.
 .SH "SEE ALSO"
 .BR xpdf (1),

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat	2024-02-10 06:55:23 UTC (rev 69765)
@@ -4,7 +4,7 @@
 
 NAME
        pdftotext  -  Portable Document Format (PDF) to text converter (version
-       4.04)
+       4.05)
 
 SYNOPSIS
        pdftotext [options] [PDF-file [text-file]]
@@ -55,8 +55,8 @@
        -table Table mode is similar to physical layout mode, but optimized for
               tabular data, with the goal of keeping rows and columns  aligned
               (at  the  expense of inserting extra whitespace).  If the -fixed
-              option is given, character spacing  within  each  line  will  be
-              determined by the specified character pitch.
+              option is given, character spacing within each line will be  de-
+              termined by the specified character pitch.
 
        -lineprinter
               Line  printer  mode  uses  a  strict  fixed-character-pitch  and
@@ -168,10 +168,12 @@
 
        3      Error related to PDF permissions.
 
+       98     Out of memory.
+
        99     Other error.
 
 AUTHOR
-       The  pdftotext software and documentation are copyright 1996-2022 Glyph
+       The  pdftotext software and documentation are copyright 1996-2024 Glyph
        & Cog, LLC.
 
 SEE ALSO
@@ -181,4 +183,4 @@
 
 
 
-                                  18 Apr 2022                     pdftotext(1)
+                                  08 Feb 2024                     pdftotext(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,7 +1,7 @@
-.\" Copyright 1996-2022 Glyph & Cog, LLC
-.TH xpdf 1 "18 Apr 2022"
+.\" Copyright 1996-2024 Glyph & Cog, LLC
+.TH xpdf 1 "08 Feb 2024"
 .SH NAME
-xpdf \- Portable Document Format (PDF) file viewer (version 4.04)
+xpdf \- Portable Document Format (PDF) file viewer (version 4.05)
 .SH SYNOPSIS
 .B xpdf
 [options]
@@ -146,7 +146,7 @@
 Open xpdf in full-screen mode, useful for presentations.
 .TP
 .BI \-remote " remote-name"
-Start Xpdf in remote server mode.  See the REMOVE SERVER MODE section.
+Start Xpdf in remote server mode.  See the REMOTE SERVER MODE section.
 .TP
 .BI \-display " display"
 Set the X display (only available with X11).
@@ -221,8 +221,9 @@
 Find the previous occurrence of the search string.
 .TP
 .B "find settings button"
-Display the current find settings: case sensitive (on/off), find whole
-words (on/off).
+Display the current find settings: case insensitive, case sensitive,
+smart case (case sensitive only if the search string contains
+uppercase characters), find whole words.
 .PP
 .SS Menu bar
 The menu bar is above the toolbar.  The menu items should be
@@ -564,6 +565,10 @@
 Set linear selection mode.  In this mode, the selection follows text.
 Non-text regions cannot be selected.
 .TP
+.B loadSession
+Load the session from the session save file.  The path for the session file is specified with the sessionFile setting (see
+.BR xpdfrc (5)).
+.TP
 .BI loadTabState
 Load the tab state file (which was written via the saveTabState
 command), and restore the tabs listed in that file.  The path for the
@@ -730,6 +735,13 @@
 .B saveImage
 Open the \'save image' dialog.
 .TP
+.B saveSession
+Save the current session, consisting of all open windows and tabs, to
+the session save file.  This file can be loaded later with the
+loadSession command.  The path for the session file is specified with
+the sessionFile setting (see
+.BR xpdfrc (5)).
+.TP
 .BI saveTabState
 Save a list of all tabs open in this window to the tab state file.
 For each tab, this writes the PDF file name and page number (on
@@ -948,7 +960,7 @@
 99
 Other error.
 .SH AUTHOR
-The xpdf software and documentation are copyright 1996-2022 Glyph &
+The xpdf software and documentation are copyright 1996-2024 Glyph &
 Cog, LLC.
 .SH "SEE ALSO"
 .BR pdftops (1),

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat	2024-02-10 06:55:23 UTC (rev 69765)
@@ -3,7 +3,7 @@
 
 
 NAME
-       xpdf - Portable Document Format (PDF) file viewer (version 4.04)
+       xpdf - Portable Document Format (PDF) file viewer (version 4.05)
 
 SYNOPSIS
        xpdf [options] [PDF-file [:page | +dest]] ...
@@ -45,12 +45,12 @@
        Xpdf reads a configuration file at startup.  It first tries to find the
        user's private config file, ~/.xpdfrc.  If that doesn't exist, it looks
        for a system-wide config file, typically /etc/xpdfrc (but this location
-       can be changed when xpdf is built).  See the  xpdfrc(5)  man  page  for
-       details.
+       can be changed when xpdf is built).  See the xpdfrc(5) man page for de-
+       tails.
 
 OPTIONS
-       The  following  command  line  options are available.  All command line
-       options must come before any PDF files to be opened.
+       The following command line options are available.  All command line op-
+       tions must come before any PDF files to be opened.
 
        Many of the options can be set with configuration file commands.  These
        are listed in square brackets with the description of the corresponding
@@ -124,7 +124,7 @@
               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  REMOTE  SERVER  MODE
               section.
 
        -display display
@@ -194,12 +194,13 @@
               Find the previous occurrence of the search string.
 
        find settings button
-              Display the current find settings: case sensitive (on/off), find
-              whole words (on/off).
+              Display the current find settings: case insensitive, case sensi-
+              tive,  smart case (case sensitive only if the search string con-
+              tains uppercase characters), find whole words.
 
    Menu bar
-       The  menu  bar  is  above  the toolbar.  The menu items should be self-
-       explanatory.
+       The menu bar is above the toolbar.  The menu items should  be  self-ex-
+       planatory.
 
    Tab list
        The tab list is on the left, just below the toolbar.  It lists all open
@@ -206,41 +207,41 @@
        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
-       In block selection mode, dragging the mouse with the left  button  held
+       In  block  selection mode, dragging the mouse with the left button held
        down will highlight an arbitrary rectangle.  Shift-clicking will extend
        the selection.
 
-       In linear selection mode, dragging with the left button will  highlight
-       text  in reading order.  Double-clicking or triple-clicking will select
-       a word or a line, respectively.  Shift-clicking will extend the  selec-
+       In  linear selection mode, dragging with the left button will highlight
+       text in reading order.  Double-clicking or triple-clicking will  select
+       a  word or a line, respectively.  Shift-clicking will extend the selec-
        tion.
 
-       Selected  text  can be copied to the clipboard (with the edit/copy menu
+       Selected text can be copied to the clipboard (with the  edit/copy  menu
        item).  On X11, selected text will be available in the X selection buf-
        fer.
 
    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
@@ -250,11 +251,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
@@ -261,8 +262,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
@@ -296,8 +297,8 @@
               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
@@ -332,11 +333,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>
@@ -344,7 +345,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.
@@ -358,26 +359,26 @@
        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.
 
-       In  commands  that take arguments (inside parentheses), special charac-
-       ters (namely '(', ')', ',', and '\x01') can  be  escaped  by  preceding
-       them  with  a  '\x01'  character.  This is mostly useful in things like
-       scripts that need to be able to open arbitrary  PDF  files,  using  the
+       In commands that take arguments (inside parentheses),  special  charac-
+       ters  (namely  '(',  ')',  ',', and '\x01') can be escaped by preceding
+       them with a '\x01' character.  This is mostly  useful  in  things  like
+       scripts  that  need  to  be able to open arbitrary PDF files, using the
        'openFile' command.
 
        The following commands are supported:
@@ -393,11 +394,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
@@ -425,7 +426,7 @@
        copy   Copy selected text to the clipboard.
 
        copyLinkTarget
-              Copy  the target of the link under the mouse cursor to the clip-
+              Copy the target of the link under the mouse cursor to the  clip-
               board.
 
        endPan End a pan operation.
@@ -455,30 +456,30 @@
               Set keyboard focus to the page number text box.
 
        followLink
-              Follow  a  hyperlink  (does  nothing  if the mouse is not over a
+              Follow a hyperlink (does nothing if the  mouse  is  not  over  a
               link).
 
        followLinkInNewTab
               Follow a hyperlink, opening PDF files in a new tab (does nothing
-              if  the  mouse is not over a link).  For links to non-PDF files,
+              if the mouse is not over a link).  For links to  non-PDF  files,
               this command is identical to followLink.
 
        followLinkInNewTabNoSel
-              Same as followLinkInNewTab, but does nothing if there is a  non-
+              Same  as followLinkInNewTab, but does nothing if there is a non-
               empty selection.  (This is useful as a mouse button binding.)
 
        followLinkInNewWin
-              Follow  a  hyperlink,  opening  PDF  files in a new window (does
-              nothing if the mouse is not over a link).  For links to  non-PDF
+              Follow a hyperlink, opening PDF files  in  a  new  window  (does
+              nothing  if the mouse is not over a link).  For links to non-PDF
               files, this command is identical to followLink.
 
        followLinkInNewWinNoSel
-              Same  as followLinkInNewWin, but does nothing if there is a non-
+              Same as followLinkInNewWin, but does nothing if there is a  non-
               empty selection.  (This is useful as a mouse button binding.)
 
        followLinkNoSel
-              Same as followLink, but does nothing if  there  is  a  non-empty
-              selection.  (This is useful as a mouse button binding.)
+              Same as followLink, but does nothing if there is a non-empty se-
+              lection.  (This is useful as a mouse button binding.)
 
        fullScreenMode
               Go to full-screen mode.
@@ -510,13 +511,18 @@
               Switch to horizontal continuous view mode.
 
        linearSelectMode
-              Set  linear selection mode.  In this mode, the selection follows
+              Set linear selection mode.  In this mode, the selection  follows
               text.  Non-text regions cannot be selected.
 
+       loadSession
+              Load  the  session from the session save file.  The path for the
+              session file is specified  with  the  sessionFile  setting  (see
+              xpdfrc(5)).
+
        loadTabState
-              Load the tab state file (which was written via the  saveTabState
-              command),  and  restore  the tabs listed in that file.  The path
-              for the tab state file is specified with the  tabStateFile  set-
+              Load  the tab state file (which was written via the saveTabState
+              command), and restore the tabs listed in that  file.   The  path
+              for  the  tab state file is specified with the tabStateFile set-
               ting (see xpdfrc(5)).
 
        newTab Open an empty new tab.
@@ -543,26 +549,26 @@
 
        openFile2(file,page,dest,passwd,location)
               Open the specified file.  If dest is not empty, go to the speci-
-              fied named destination.  Else, if page is not empty, go  to  the
-              specified  page number.  If password is not empty, it is used as
-              the PDF password.  If location is "win", open the file in a  new
-              window;  if  it  is  "tab", open in a new tab; if it is "check",
-              open in the current tab, but only  if  the  specified  PDF  file
-              isn't  already  open;  else open in the current tab.  Any/all of
+              fied  named  destination.  Else, if page is not empty, go to the
+              specified page number.  If password is not empty, it is used  as
+              the  PDF password.  If location is "win", open the file in a new
+              window; if it is "tab", open in a new tab;  if  it  is  "check",
+              open  in  the  current  tab,  but only if the specified PDF file
+              isn't already open; else open in the current  tab.   Any/all  of
               the arguments, other than file, can be empty strings.  For exam-
               ple:
               openFile2(test.pdf,7,,,tab)
 
        openFileAtDest(file,dest)
-              Open  the  specified  file  in  the current tab at the specified
+              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.
+              Open the specified file at the specified named destination.  Lo-
+              cation 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)
@@ -570,11 +576,11 @@
               "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-
+              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"
+              Open  a PDF file, using the open dialog.  Location must be "win"
               for a new window or "tab" for a new tab.
 
        openSidebar
@@ -581,12 +587,12 @@
               Open the sidebar.
 
        openSidebarMoveResizeWin
-              Open  the sidebar, resizing the window so that the document size
+              Open the sidebar, 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.
 
        openSidebarResizeWin
-              Open  the sidebar, resizing the window so that the document size
+              Open the sidebar, resizing the window so that the document  size
               doesn't change.
 
        pageDown
@@ -601,7 +607,7 @@
               Go to the previous page.
 
        prevPageNoScroll
-              Go to the previous page, with the current relative scroll  posi-
+              Go  to the previous page, with the current relative scroll posi-
               tion.
 
        prevTab
@@ -622,7 +628,7 @@
               Rotate the page 90 degrees clockwise.
 
        run(external-command-string)
-              Run  an  external command.  The following escapes are allowed in
+              Run an external command.  The following escapes are  allowed  in
               the command string:
 
                   %f => PDF file name (or an empty string if no
@@ -647,14 +653,14 @@
                   %k => y coordinate of the mouse pointer
                   %% => %
 
-              The external command string will often contain  spaces,  so  the
+              The  external  command  string will often contain spaces, so the
               whole command must be quoted in the xpdfrc file:
 
                   bind x "run(ls -l)"
 
               The command string may not be run through a shell.  It is recom-
-              mended to keep the command simple, so that it doesn't depend  on
-              specific  shell functionality.  For complex things, you can have
+              mended  to keep the command simple, so that it doesn't depend on
+              specific shell functionality.  For complex things, you can  have
               the command string run a shell script.
 
        saveAs Save PDF via a file requester.
@@ -662,6 +668,12 @@
        saveImage
               Open the 'save image' dialog.
 
+       saveSession
+              Save  the  current  session,  consisting of all open windows and
+              tabs, to the session save file.  This file can be  loaded  later
+              with  the loadSession command.  The path for the session file is
+              specified with the sessionFile setting (see xpdfrc(5)).
+
        saveTabState
               Save a list of all tabs open in this window  to  the  tab  state
               file.  For each tab, this writes the PDF file name and page num-
@@ -858,7 +870,7 @@
        99     Other error.
 
 AUTHOR
-       The  xpdf  software  and  documentation are copyright 1996-2022 Glyph &
+       The  xpdf  software  and  documentation are copyright 1996-2024 Glyph &
        Cog, LLC.
 
 SEE ALSO
@@ -868,4 +880,4 @@
 
 
 
-                                  18 Apr 2022                          xpdf(1)
+                                  08 Feb 2024                          xpdf(1)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5	2024-02-10 06:55:23 UTC (rev 69765)
@@ -1,7 +1,7 @@
-.\" Copyright 2002-2022 Glyph & Cog, LLC
-.TH xpdfrc 5 "18 Apr 202"
+.\" Copyright 2002-2024 Glyph & Cog, LLC
+.TH xpdfrc 5 "08 Feb 2024"
 .SH NAME
-xpdfrc \- configuration file for Xpdf tools (version 4.04)
+xpdfrc \- configuration file for Xpdf tools (version 4.05)
 .SH DESCRIPTION
 All of the Xpdf tools read a single configuration file.
 .PP
@@ -448,6 +448,12 @@
 the PDF ToUnicode maps.  Otherwise, the ToUnicode maps are always used
 when present.  This defaults to "no".
 .TP
+.BI ignoreWrongSizeToUnicode " yes | no"
+If set to "yes", Xpdf will ignore any ToUnicode CMaps that don't match
+the font type (8-bit vs 16-bit).  The PDF spec requires ToUnicode
+CMaps match, and Adobe appears to ignore CMaps that don't match.  This
+defaults to "no" (for backward compatibility).
+.TP
 .BI dropFont " font-name"
 Drop all text drawn in the specified font.  To drop text drawn in
 unnamed fonts, use:
@@ -457,6 +463,12 @@
 
 .fi
 There can be any number of dropFont commands.
+.TP
+.BI separateRotatedText " yes | no"
+If set to "no", pdftotext will attempt to place rotated text into the
+"correct" location in the output. If set to "yes", when using reading
+order mode, pdftotext will append rotated text to the end, after
+unrotated text. This defaults to "no".
 .SH RASTERIZER SETTINGS
 .TP
 .BR enableFreeType " yes | no"
@@ -569,6 +581,17 @@
 zoom factor (which must be a percentage).  The default value is
 based on the screen resolution.
 .TP
+.BI zoomScaleFactor " \fIratio\fR | actual"
+Zoom percentages will be scaled by this factor.  By default, 100% zoom
+corresponds to 72 dpi.  Setting zoomScaleFactor to 1.5 will make 100%
+zoom 1.5x larger, i.e., 108dpi.  If this is set to \'actual', the zoom
+scale factor will be computed based on the screen resolution. The
+default value is 1.0.
+.TP
+.BI zoomValues " zoom1 zoom2 zoom3 ..."
+Sets the list of zoom values (percentages) displayed in the zoom combo box.
+The default list is: 25 50 75 100 110 125 150 175 200 300 400 600 800.
+.TP
 .BR initialDisplayMode " single | continuous | sideBySideSingle | sideBySideContinuous | horizontalContinuous"
 Sets the initial display mode.  The default setting is "continuous".
 .TP
@@ -638,6 +661,12 @@
 Set the number of worker threads to be used by xpdf when rasterizing
 pages.  This defaults to 1.
 .TP
+.BI allowLinksToChangeZoom " yes | no"
+PDF links, including outline items, can include a new zoom level.  If
+this setting is "yes", Xpdf changes the zoom when links are clicked;
+if "no", Xpdf moves to the destination but does not change the zoom.
+This defaults to "yes".
+.TP
 .BI launchCommand " command"
 Sets the command executed when you click on a "launch"-type link.  The
 intent is for the command to be a program/script which determines the
@@ -740,7 +769,20 @@
 Sets the file used by the loadTabState and saveTabState commands (see
 the
 .BR xpdf (1)
-man page for more information).
+man page for more information).  The default path is ~/.xpdf.tabstate.
+.TP
+.BI sessionFile " path"
+Sets the file used by the saveSession and loadSession commands (see
+the
+.BR xpdf (1)
+man page for more information).  The default path is ~/.xpdf.session.
+When xpdf automatically saves the session via a session manager, it
+appends ".managed" to the path.
+.TP
+.BI saveSessionOnQuit " yes | no"
+If set to "yes", xpdf will automatically save the current session
+(equivalent to the saveSession command) when quitting (via the menu or
+a key binding).  The default value is "yes".
 .SH MISCELLANEOUS SETTINGS
 .TP
 .BI drawAnnotations " yes | no"
@@ -837,7 +879,7 @@
 This is the user's configuration file.  If it exists, it will be read
 in place of the system-wide file.
 .SH AUTHOR
-The Xpdf software and documentation are copyright 1996-2022 Glyph &
+The Xpdf software and documentation are copyright 1996-2024 Glyph &
 Cog, LLC.
 .SH "SEE ALSO"
 .BR xpdf (1),

Modified: trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat	2024-02-10 06:55:23 UTC (rev 69765)
@@ -3,7 +3,7 @@
 
 
 NAME
-       xpdfrc - configuration file for Xpdf tools (version 4.04)
+       xpdfrc - configuration file for Xpdf tools (version 4.05)
 
 DESCRIPTION
        All of the Xpdf tools read a single configuration file.
@@ -18,8 +18,8 @@
        (pdftotext.exe, xpdf.exe, etc.)
 
        The xpdfrc file consists of a series of configuration options, one  per
-       line.   Blank  lines  and  lines  starting  with  a  '#' (comments) are
-       ignored.
+       line.   Blank  lines  and  lines starting with a '#' (comments) are ig-
+       nored.
 
        Arguments can be single-quoted or double-quoted, e.g., for  file  names
        that contain spaces ("aaa bbb", 'aaa bbb').  This quoting does not pro-
@@ -49,8 +49,8 @@
 GENERAL FONT CONFIGURATION
        fontFile PDF-font-name font-file
               Maps  a  PDF font, PDF-font-name, to a font for display or Post-
-              Script output.  The  font  file,  font-file,  can  be  any  type
-              allowed  in  a  PDF file.  This command can be used for 8-bit or
+              Script output.  The font file, font-file, can be  any  type  al-
+              lowed  in  a  PDF  file.   This command can be used for 8-bit or
               16-bit (CID) fonts.
 
        fontDir dir
@@ -80,8 +80,8 @@
               When the 8-bit font PDF-font-name is used (without embedding) in
               a PDF file,  it  will  be  translated  to  the  PostScript  font
               PS-font-name,  which  is  assumed to be resident in the printer.
-              Typically, PDF-font-name and  PS-font-name  are  the  same.   By
-              default, only the Base-14 fonts are assumed to be resident.
+              Typically, PDF-font-name and PS-font-name are the same.  By  de-
+              fault, only the Base-14 fonts are assumed to be resident.
 
        psResidentFont16 PDF-font-name wMode PS-font-name encoding
               When the 16-bit (CID) font PDF-font-name with writing mode wMode
@@ -140,8 +140,8 @@
               gers  are the coordinates of the lower-left and upper-right cor-
               ners of the imageable region, specified in points (with the ori-
               gin being the lower-left corner of the paper).  This defaults to
-              the full paper size;  the  psPaperSize  option  will  reset  the
-              imageable area coordinates.
+              the full paper size; the psPaperSize option will reset  the  im-
+              ageable area coordinates.
 
        psCrop yes | no
               If  set  to  "yes",  PostScript output is cropped to the CropBox
@@ -166,8 +166,8 @@
        psCenter yes | no
               If  set  to yes, PDF pages smaller than the PostScript imageable
               area (after any scaling) are centered  in  the  imageable  area.
-              Otherwise,  they  are  aligned  at  the lower-left corner of the
-              imageable area.  This defaults to "yes".
+              Otherwise,  they are aligned at the lower-left corner of the im-
+              ageable area.  This defaults to "yes".
 
        psDuplex yes | no
               If set to "yes", the generated PostScript will set the  "Duplex"
@@ -187,9 +187,9 @@
               of a long document.  This defaults to "no".
 
        psOPI yes | no
-              If set to "yes",  generates  PostScript  OPI  comments  for  all
-              images  and  forms  which  have OPI information.  This option is
-              only available if the Xpdf tools were compiled with OPI support.
+              If set to "yes", generates PostScript OPI comments for  all  im-
+              ages  and forms which have OPI information.  This option is only
+              available if the Xpdf tools  were  compiled  with  OPI  support.
               This defaults to "no".
 
        psASCIIHex yes | no
@@ -237,8 +237,8 @@
               set to "yes", rasterization is disabled:  pages  will  never  be
               rasterized, even if they contain transparency.  This will likely
               result in incorrect output for PDF files that use  transparency,
-              and  a  warning  message  to  that effect will be printed.  This
-              defaults to "no".
+              and  a warning message to that effect will be printed.  This de-
+              faults to "no".
 
        fontDir dir
               See the description above, in the DISPLAY FONTS section.
@@ -251,8 +251,8 @@
               above).  This defaults to "Latin1".
 
        textEOL unix | dos | mac
-              Sets  the  end-of-line  convention  to use for text output.  The
-              options are:
+              Sets the end-of-line convention to use for text output.  The op-
+              tions are:
 
                   unix = LF
                   dos  = CR+LF
@@ -269,8 +269,8 @@
        textKeepTinyChars yes | no
               If  set  to "yes", text extraction will keep all characters.  If
               set to "no", text extraction will discard tiny (smaller  than  3
-              point)  characters  after  the  first  50000  per page, avoiding
-              extremely slow run times for PDF files that use special fonts to
+              point)  characters  after the first 50000 per page, avoiding ex-
+              tremely slow run times for PDF files that use special  fonts  to
               do shading or cross-hatching.  This defaults to "yes".
 
        nameToUnicode map-file
@@ -312,9 +312,9 @@
                   in-hex out-hex1 out-hex2 ...
 
               The in-hex field is an input (incorrect) Unicode index, and  the
-              rest  of  the  fields  are  one or more output (correct) Unicode
-              indexes.  Each occurrence of in-hex will  be  converted  to  the
-              specified output sequence.
+              rest  of the fields are one or more output (correct) Unicode in-
+              dexes.  Each occurrence of in-hex will be converted to the spec-
+              ified output sequence.
 
        unicodeRemapping remap-file
               Remap Unicode characters when doing text extraction.  This spec-
@@ -344,8 +344,8 @@
               The in-start-hex and in-end-hex fields  (or  the  single  in-hex
               field)  specify  the Unicode range.  The out-start-hex field (or
               the out-hex field) specifies the start of  the  output  encoding
-              range.   The  length  of  the  out-start-hex (or out-hex) string
-              determines the length of the output characters (e.g., UTF-8 uses
+              range.   The length of the out-start-hex (or out-hex) string de-
+              termines the length of the output characters (e.g.,  UTF-8  uses
               different  numbers of bytes to represent characters in different
               ranges).  Entries must be given  in  increasing  Unicode  order.
               Only  one  file is allowed per encoding; the last specified file
@@ -354,8 +354,8 @@
 
        cMapDir registry-ordering dir
               Specifies  a  search  directory,  dir,  for  CMaps  for the reg-
-              istry-ordering character  collection.   There  can  be  multiple
-              directories  for  a particular collection.  There are no default
+              istry-ordering character collection.  There can be multiple  di-
+              rectories  for  a  particular  collection.  There are no default
               CMap directories.
 
        toUnicodeDir dir
@@ -364,8 +364,8 @@
               ToUnicode directories.
 
        mapNumericCharNames yes | no
-              If set to "yes", the Xpdf tools  will  attempt  to  map  various
-              numeric character names sometimes used in font subsets.  In some
+              If set to "yes", the Xpdf tools will attempt to map various  nu-
+              meric  character  names sometimes used in font subsets.  In some
               cases this leads to usable text, and in other cases it leads  to
               gibberish -- there is no way for Xpdf to tell.  This defaults to
               "yes".
@@ -372,8 +372,8 @@
 
        mapUnknownCharNames yes | no
               If set to "yes", and mapNumericCharNames is  set  to  "no",  the
-              Xpdf  tools  will  apply  a simple pass-through mapping (Unicode
-              index = character code) for all unrecognized glyph names.   (For
+              Xpdf tools will apply a simple pass-through mapping (Unicode in-
+              dex = character code) for all unrecognized  glyph  names.   (For
               CID  fonts, setting mapNumericCharNames to "no" is unnecessary.)
               In some cases, this leads to usable text, and in other cases  it
               leads  to  gibberish  -- there is no way for Xpdf to tell.  This
@@ -395,6 +395,13 @@
               override  the PDF ToUnicode maps.  Otherwise, the ToUnicode maps
               are always used when present.  This defaults to "no".
 
+       ignoreWrongSizeToUnicode yes | no
+              If set to "yes", Xpdf will ignore any ToUnicode CMaps that don't
+              match  the  font  type (8-bit vs 16-bit).  The PDF spec requires
+              ToUnicode CMaps match, and Adobe appears to  ignore  CMaps  that
+              don't  match.   This  defaults to "no" (for backward compatibil-
+              ity).
+
        dropFont font-name
               Drop all text drawn in the specified font.  To drop  text  drawn
               in unnamed fonts, use:
@@ -403,104 +410,110 @@
 
               There can be any number of dropFont commands.
 
+       separateRotatedText yes | no
+              If  set  to  "no",  pdftotext will attempt to place rotated text
+              into the "correct" location in the output. If set to "yes", when
+              using  reading order mode, pdftotext will append rotated text to
+              the end, after unrotated text. This defaults to "no".
+
 RASTERIZER SETTINGS
        enableFreeType yes | no
-              Enables  or  disables  use of FreeType (a TrueType / Type 1 font
+              Enables or disables use of FreeType (a TrueType /  Type  1  font
               rasterizer).  This is only relevant if the Xpdf tools were built
               with  FreeType  support.   ("enableFreeType"  replaces  the  old
               "freetypeControl" option.)  This option defaults to "yes".
 
        disableFreeTypeHinting yes | no
-              If this is set to "yes", FreeType hinting will  be  forced  off.
+              If  this  is  set to "yes", FreeType hinting will be forced off.
               This option defaults to "no".
 
        antialias yes | no
-              Enables  or  disables  font anti-aliasing in the PDF rasterizer.
+              Enables or disables font anti-aliasing in  the  PDF  rasterizer.
               This option affects all font rasterizers.  ("antialias" replaces
               the anti-aliasing control provided by the old "t1libControl" and
               "freetypeControl" options.)  This default to "yes".
 
        vectorAntialias yes | no
-              Enables or disables anti-aliasing of vector graphics in the  PDF
+              Enables  or disables anti-aliasing of vector graphics in the PDF
               rasterizer.  This defaults to "yes".
 
        imageMaskAntialias yes | no
-              Enables  or disables anti-aliasing of image masks (when downsam-
-              pling or upsampling) in the PDF rasterizer.   This  defaults  to
+              Enables or disables anti-aliasing of image masks (when  downsam-
+              pling  or  upsampling)  in the PDF rasterizer.  This defaults to
               "yes".
 
        antialiasPrinting yes | no
-              If   this  is  "yes",  bitmaps  sent  to  the  printer  will  be
-              antialiased (according to the "antialias" and  "vectorAntialias"
-              settings).   If  this  is  "no",  printed  bitmaps  will  not be
-              antialiased.  This defaults to "no".
+              If this is "yes", bitmaps  sent  to  the  printer  will  be  an-
+              tialiased  (according  to  the "antialias" and "vectorAntialias"
+              settings).  If this is "no", printed bitmaps  will  not  be  an-
+              tialiased.  This defaults to "no".
 
        strokeAdjust yes | no | cad
-              Sets the stroke adjustment mode.  If  set  to  "no",  no  stroke
-              adjustment will be done.  If set to "yes", normal stroke adjust-
-              ment will be done: horizontal and vertical lines will  be  moved
-              by  up  to  half  a  pixel to make them look cleaner when vector
+              Sets  the stroke adjustment mode.  If set to "no", no stroke ad-
+              justment will be done.  If set to "yes", normal  stroke  adjust-
+              ment  will  be done: horizontal and vertical lines will be moved
+              by up to half a pixel to make  them  look  cleaner  when  vector
               anti-aliasing is enabled.  If set to "cad", a slightly different
               stroke adjustment algorithm will be used to ensure that lines of
               the same original width will always have the same adjusted width
-              (at  the  expense of allowing gaps and overlaps between adjacent
+              (at the expense of allowing gaps and overlaps  between  adjacent
               lines).  This defaults to "yes".
 
        forceAccurateTiling yes | no
-              If this is set to "yes", the TilingType is forced to 2 (no  dis-
-              tortion)  for  all tiling patterns, regardless of the setting in
+              If  this is set to "yes", the TilingType is forced to 2 (no dis-
+              tortion) for all tiling patterns, regardless of the  setting  in
               the pattern dictionary.  This defaults to "no".
 
        screenType dispersed | clustered | stochasticClustered
-              Sets the halftone screen type, which will be used when  generat-
-              ing  a  monochrome  (1-bit)  bitmap.  The three options are dis-
-              persed-dot dithering, clustered-dot dithering (with a round  dot
-              and   45-degree  screen  angle),  and  stochastic  clustered-dot
-              dithering.  By default, "stochasticClustered" is used for  reso-
+              Sets  the halftone screen type, which will be used when generat-
+              ing a monochrome (1-bit) bitmap.  The  three  options  are  dis-
+              persed-dot  dithering, clustered-dot dithering (with a round dot
+              and  45-degree  screen  angle),  and  stochastic   clustered-dot
+              dithering.   By default, "stochasticClustered" is used for reso-
               lutions of 300 dpi and higher, and "dispersed" is used for reso-
               lutions lower then 300 dpi.
 
        screenSize integer
-              Sets the size of the (square) halftone screen threshold  matrix.
-              By  default, this is 4 for dispersed-dot dithering, 10 for clus-
-              tered-dot  dithering,  and  100  for  stochastic   clustered-dot
+              Sets  the size of the (square) halftone screen threshold matrix.
+              By default, this is 4 for dispersed-dot dithering, 10 for  clus-
+              tered-dot   dithering,  and  100  for  stochastic  clustered-dot
               dithering.
 
        screenDotRadius integer
-              Sets  the  halftone  screen  dot radius.  This is only used when
-              screenType is set to stochasticClustered, and it defaults to  2.
-              In  clustered-dot  mode,  the  dot  radius is half of the screen
+              Sets the halftone screen dot radius.  This  is  only  used  when
+              screenType  is set to stochasticClustered, and it defaults to 2.
+              In clustered-dot mode, the dot radius  is  half  of  the  screen
               size.  Dispersed-dot dithering doesn't have a dot radius.
 
        screenGamma float
               Sets the halftone screen gamma correction parameter.  Gamma val-
-              ues  greater  than 1 make the output brighter; gamma values less
+              ues greater than 1 make the output brighter; gamma  values  less
               than 1 make it darker.  The default value is 1.
 
        screenBlackThreshold float
-              When halftoning, all values below this threshold are  forced  to
+              When  halftoning,  all values below this threshold are forced to
               solid black.  This parameter is a floating point value between 0
               (black) and 1 (white).  The default value is 0.
 
        screenWhiteThreshold float
-              When halftoning, all values above this threshold are  forced  to
+              When  halftoning,  all values above this threshold are forced to
               solid white.  This parameter is a floating point value between 0
               (black) and 1 (white).  The default value is 1.
 
        minLineWidth float
-              Set the minimum line width, in device pixels.  This affects  the
-              rasterizer  only,  not  the PostScript converter (except when it
-              uses rasterization to handle transparency).  The  default  value
+              Set  the minimum line width, in device pixels.  This affects the
+              rasterizer only, not the PostScript converter  (except  when  it
+              uses  rasterization  to handle transparency).  The default value
               is 0 (no minimum).
 
        enablePathSimplification yes | no
-              If  set  to  "yes",  simplify  paths by removing points where it
-              won't make a significant difference to the shape.   The  default
+              If set to "yes", simplify paths  by  removing  points  where  it
+              won't  make  a significant difference to the shape.  The default
               value is "no".
 
        overprintPreview yes | no
               If set to "yes", generate overprint preview output, honoring the
-              OP/op/OPM settings in the PDF file.  Ignored for  non-CMYK  out-
+              OP/op/OPM  settings  in the PDF file.  Ignored for non-CMYK out-
               put.  The default value is "no".
 
 VIEWER SETTINGS
@@ -507,19 +520,31 @@
        These settings only apply to the Xpdf GUI PDF viewer.
 
        initialZoom percentage | page | width
-              Sets  the  initial  zoom factor.  A number specifies a zoom per-
-              centage, where 100 means 72 dpi.  You may also  specify  'page',
-              to  fit the page to the window size, or 'width', to fit the page
+              Sets the initial zoom factor.  A number specifies  a  zoom  per-
+              centage,  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.
 
        defaultFitZoom percentage
               If xpdf is started with fit-page or fit-width zoom and no window
-              geometry,  it  will calculate a desired window size based on the
-              PDF page size and this defaultFitZoom value.  I.e.,  the  window
-              size  will  be chosen such that exactly one page will fit in the
-              window at this zoom factor (which must be  a  percentage).   The
+              geometry, it will calculate a desired window size based  on  the
+              PDF  page  size and this defaultFitZoom value.  I.e., the window
+              size will be chosen such that exactly one page will fit  in  the
+              window  at  this  zoom factor (which must be a percentage).  The
               default value is based on the screen resolution.
 
+       zoomScaleFactor ratio | actual
+              Zoom percentages will be scaled by  this  factor.   By  default,
+              100% zoom corresponds to 72 dpi.  Setting zoomScaleFactor to 1.5
+              will make 100% zoom 1.5x larger, i.e., 108dpi.  If this  is  set
+              to 'actual', the zoom scale factor will be computed based on the
+              screen resolution. The default value is 1.0.
+
+       zoomValues zoom1 zoom2 zoom3 ...
+              Sets the list of zoom values (percentages) displayed in the zoom
+              combo  box.   The  default list is: 25 50 75 100 110 125 150 175
+              200 300 400 600 800.
+
        initialDisplayMode single | continuous | sideBySideSingle | sideBySide-
        Continuous | horizontalContinuous
               Sets the initial display mode.  The default setting is "continu-
@@ -530,23 +555,23 @@
               "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".
 
        initialSidebarWidth width
-              Sets the initial sidebar width, in pixels.  This is  only  rele-
-              vant  if  initialSidebarState  is  "yes".   The default value is
+              Sets  the  initial sidebar width, in pixels.  This is only rele-
+              vant if initialSidebarState is  "yes".   The  default  value  is
               zero, which tells xpdf to use an internal default size.
 
        initialSelectMode block | linear
-              Sets the initial selection mode.  The default setting  is  "lin-
+              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
-              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.
 
        matteColor color
@@ -555,7 +580,7 @@
               a named color.
 
        fullScreenMatteColor color
-              Set the matte color for full-screen  mode.   The  color  can  be
+              Set  the  matte  color  for  full-screen mode.  The color can be
               #RRGGBB (hexadecimal) or a named color.
 
        selectionColor color
@@ -563,14 +588,14 @@
               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".
+              If  set to "no", xpdf's reverse-video mode inverts text and vec-
+              tor graphic content, but not images.  If set to "yes", xpdf  in-
+              verts 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-
-              MANDS section of the xpdf(1) man page  for  details).   Multiple
+              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-
+              MANDS  section  of  the xpdf(1) man page for details).  Multiple
               commands are separated by whitespace.
 
        maxTileWidth pixels
@@ -578,11 +603,11 @@
               ing pages.  This defaults to 1500.
 
        maxTileHeight pixels
-              Set the maximum height of tiles to be used by xpdf when  raster-
+              Set  the maximum height of tiles to be used by xpdf when raster-
               izing pages.  This defaults to 1500.
 
        tileCacheSize tiles
-              Set  the  maximum number of tiles to be cached by xpdf when ras-
+              Set the maximum number of tiles to be cached by xpdf  when  ras-
               terizing pages.  This defaults to 10.
 
        workerThreads numThreads
@@ -589,6 +614,12 @@
               Set the number of worker threads to be used by xpdf when raster-
               izing pages.  This defaults to 1.
 
+       allowLinksToChangeZoom yes | no
+              PDF links, including outline  items,  can  include  a  new  zoom
+              level.   If  this  setting  is "yes", Xpdf changes the zoom when
+              links are clicked; if "no", Xpdf moves to  the  destination  but
+              does not change the zoom.  This defaults to "yes".
+
        launchCommand command
               Sets  the  command  executed  when  you click on a "launch"-type
               link.  The intent is for the  command  to  be  a  program/script
@@ -676,8 +707,20 @@
 
        tabStateFile path
               Sets the file used by the loadTabState and saveTabState commands
-              (see the xpdf(1) man page for more information).
+              (see the xpdf(1) man page for more  information).   The  default
+              path is ~/.xpdf.tabstate.
 
+       sessionFile path
+              Sets  the  file used by the saveSession and loadSession commands
+              (see the xpdf(1) man page for more  information).   The  default
+              path is ~/.xpdf.session.  When xpdf automatically saves the ses-
+              sion via a session manager, it appends ".managed" to the path.
+
+       saveSessionOnQuit yes | no
+              If set to "yes", xpdf will automatically save the  current  ses-
+              sion  (equivalent to the saveSession command) when quitting (via
+              the menu or a key binding).  The default value is "yes".
+
 MISCELLANEOUS SETTINGS
        drawAnnotations yes | no
               If set to "no", annotations will not be drawn or  printed.   The
@@ -773,7 +816,7 @@
               read in place of the system-wide file.
 
 AUTHOR
-       The  Xpdf  software  and  documentation are copyright 1996-2022 Glyph &
+       The  Xpdf  software  and  documentation are copyright 1996-2024 Glyph &
        Cog, LLC.
 
 SEE ALSO
@@ -783,4 +826,4 @@
 
 
 
-                                  18 Apr 202                         xpdfrc(5)
+                                  08 Feb 2024                        xpdfrc(5)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <limits.h>
 #include "gmem.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 
 //------------------------------------------------------------------------

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include "gmempp.h"
 #include "FoFiEncodings.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 
 //------------------------------------------------------------------------

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <string.h>
 #include <limits.h>
@@ -843,6 +839,8 @@
       resNameListOffset >= resMapLength) {
     goto err2;
   }
+  nFonts = 0;
+  refListOffset = 0;
   for (i = 0; i < nTypes; ++i) {
     offset = resTypeListOffset + 2 + 8 * i;
     if (resMap[offset] == 0x73 &&    // 'sfnt'

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 class GList;
 
 //------------------------------------------------------------------------

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <string.h>
 #if HAVE_STD_SORT
@@ -405,7 +401,7 @@
       // to be 0xffff
       return 0;
     }
-    // invariant: seg[a].end < code <= seg[b].end
+    // invariant: seg[a].end < c <= seg[b].end
     while (b - a > 1 && ok) {
       m = (a + b) / 2;
       segEnd = getU16BE(pos + 14 + 2*m, &ok);
@@ -439,6 +435,31 @@
     }
     gid = getU16BE(pos + 10 + 2 * (c - cmapFirst), &ok);
     break;
+  case 12:
+    segCnt = getU32BE(pos + 12, &ok);
+    a = -1;
+    b = segCnt - 1;
+    segEnd = getU32BE(pos + 16 + 12*b + 4, &ok);
+    if (c > segEnd) {
+      return 0;
+    }
+    // invariant: seg[a].end < c <= seg[b].end
+    while (b - a > 1 && ok) {
+      m = (a + b) / 2;
+      segEnd = getU32BE(pos + 16 + 12*m + 4, &ok);
+      if (segEnd < c) {
+	a = m;
+      } else {
+	b = m;
+      }
+    }
+    segStart = getU32BE(pos + 16 + 12*b, &ok);
+    if (c < segStart) {
+      return 0;
+    }
+    segOffset = getU32BE(pos + 16 + 12*b + 8, &ok);
+    gid = segOffset + (c - segStart);
+    break;
   default:
     return 0;
   }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "FoFiBase.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <string.h>
 #include "gmem.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "FoFiBase.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
@@ -181,7 +177,7 @@
 
 GHash *FoFiType1C::getNameToGIDMap() {
   GHash *map;
-  char name[256];
+  char glyphName[256];
   GBool ok;
   int gid;
 
@@ -188,9 +184,9 @@
   map = new GHash(gTrue);
   for (gid = 0; gid < nGlyphs; ++gid) {
     ok = gTrue;
-    getString(charset[gid], name, &ok);
+    getString(charset[gid], glyphName, &ok);
     if (ok) {
-      map->add(new GString(name), gid);
+      map->add(new GString(glyphName), gid);
     }
   }
   return map;
@@ -1527,7 +1523,7 @@
 	if (nOps < 6 || nOps % 6 != 0) {
 	  //~ error(-1, "Wrong number of args (%d) to Type 2 rrcurveto", nOps);
 	}
-	for (k = 0; k < nOps; k += 6) {
+	for (k = 0; k+5 < nOps; k += 6) {
 	  cvtNum(ops[k], charBuf);
 	  cvtNum(ops[k+1], charBuf);
 	  cvtNum(ops[k+2], charBuf);
@@ -1696,9 +1692,11 @@
 	  cvtNum(ops[k+5], charBuf);
 	  charBuf->append((char)8);
 	}
-	cvtNum(ops[k], charBuf);
-	cvtNum(ops[k+1], charBuf);
-	charBuf->append((char)5);
+	if (k+1 < nOps) {
+	  cvtNum(ops[k], charBuf);
+	  cvtNum(ops[k+1], charBuf);
+	  charBuf->append((char)5);
+	}
 	nOps = 0;
 	openPath = gTrue;
 	break;
@@ -1711,13 +1709,15 @@
 	  cvtNum(ops[k+1], charBuf);
 	  charBuf->append((char)5);
 	}
-	cvtNum(ops[k], charBuf);
-	cvtNum(ops[k+1], charBuf);
-	cvtNum(ops[k+2], charBuf);
-	cvtNum(ops[k+3], charBuf);
-	cvtNum(ops[k+4], charBuf);
-	cvtNum(ops[k+5], charBuf);
-	charBuf->append((char)8);
+	if (k+5 < nOps) {
+	  cvtNum(ops[k], charBuf);
+	  cvtNum(ops[k+1], charBuf);
+	  cvtNum(ops[k+2], charBuf);
+	  cvtNum(ops[k+3], charBuf);
+	  cvtNum(ops[k+4], charBuf);
+	  cvtNum(ops[k+5], charBuf);
+	  charBuf->append((char)8);
+	}
 	nOps = 0;
 	openPath = gTrue;
 	break;
@@ -2251,43 +2251,7 @@
 				   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 os2Table[96], headTable[54], hheaTable[36], maxpTable[6];
   Guchar nameTable[26], postTable[32];
   Guchar *hmtxTable;
   static const char *tableTag[9] = {
@@ -2307,15 +2271,118 @@
   double mat[6];
   Gushort maxWidth;
   Guint checksum, fileChecksum;
-  int unitsPerEm, xMin, yMin, xMax, yMax, offset, i;
+  int unitsPerEm, xMin, yMin, xMax, yMax, ascent, descent, offset, i;
 
+  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);
+  ascent = yMax;
+  descent = -yMin;
+
   //--- CFF_ table
   tableData[0] = file;
   tableLength[0] = len;
 
   //--- OS/2 table
-  tableData[1] = os2Tab;
-  tableLength[1] = 86;
+  os2Table[ 0] = 0;		// version
+  os2Table[ 1] = 4;
+  os2Table[ 2] = 0;		// xAvgCharWidth
+  os2Table[ 3] = 1;
+  os2Table[ 4] = 0x01;		// usWeightClass
+  os2Table[ 5] = 0x90;
+  os2Table[ 6] = 0;		// usWidthClass
+  os2Table[ 7] = 5;
+  os2Table[ 8] = 0;		// fsType
+  os2Table[ 9] = 0;
+  os2Table[10] = 0;		// ySubscriptXSize
+  os2Table[11] = 0;
+  os2Table[12] = 0;		// ySubscriptYSize
+  os2Table[13] = 0;
+  os2Table[14] = 0;		// ySubscriptXOffset
+  os2Table[15] = 0;
+  os2Table[16] = 0;		// ySubscriptYOffset
+  os2Table[17] = 0;
+  os2Table[18] = 0;		// ySuperscriptXSize
+  os2Table[19] = 0;
+  os2Table[20] = 0;		// ySuperscriptYSize
+  os2Table[21] = 0;
+  os2Table[22] = 0;		// ySuperscriptXOffset
+  os2Table[23] = 0;
+  os2Table[24] = 0;		// ySuperscriptYOffset
+  os2Table[25] = 0;
+  os2Table[26] = 0;		// yStrikeoutSize
+  os2Table[27] = 0;
+  os2Table[28] = 0;		// yStrikeoutPosition
+  os2Table[29] = 0;
+  os2Table[30] = 0;		// sFamilyClass
+  os2Table[31] = 0;
+  os2Table[32] = 0;		// panose
+  os2Table[33] = 0;
+  os2Table[34] = 0;
+  os2Table[35] = 0;
+  os2Table[36] = 0;
+  os2Table[37] = 0;
+  os2Table[38] = 0;
+  os2Table[39] = 0;
+  os2Table[40] = 0;
+  os2Table[41] = 0;
+  os2Table[42] = 0;		// ulUnicodeRange1
+  os2Table[43] = 0;
+  os2Table[44] = 0;
+  os2Table[45] = 0;
+  os2Table[46] = 0;		// ulUnicodeRange2
+  os2Table[47] = 0;
+  os2Table[48] = 0;
+  os2Table[49] = 0;
+  os2Table[50] = 0;		// ulUnicodeRange3
+  os2Table[51] = 0;
+  os2Table[52] = 0;
+  os2Table[53] = 0;
+  os2Table[54] = 0;		// ulUnicodeRange4
+  os2Table[55] = 0;
+  os2Table[56] = 0;
+  os2Table[57] = 0;
+  os2Table[58] = 0;		// achVendID
+  os2Table[59] = 0;
+  os2Table[60] = 0;
+  os2Table[61] = 0;
+  os2Table[62] = 0;		// fsSelection
+  os2Table[63] = 0;
+  os2Table[64] = 0;		// usFirstCharIndex
+  os2Table[65] = 0;
+  os2Table[66] = 0;		// usLastCharIndex
+  os2Table[67] = 0;
+  os2Table[68] = 0;		// sTypoAscender
+  os2Table[69] = 0;
+  os2Table[70] = 0;		// sTypoDescender
+  os2Table[71] = 0;
+  os2Table[72] = 0;		// sTypoLineGap
+  os2Table[73] = 0;
+  os2Table[74] = (Guchar)(ascent >> 8);    // usWinAscent
+  os2Table[75] = (Guchar)ascent;
+  os2Table[76] = (Guchar)(descent >> 8);   // usWinDescent
+  os2Table[77] = (Guchar)descent;
+  os2Table[78] = 0;		// ulCodePageRange1
+  os2Table[79] = 0;
+  os2Table[80] = 0;
+  os2Table[81] = 1;
+  os2Table[82] = 0;		// ulCodePageRange2
+  os2Table[83] = 0;
+  os2Table[84] = 0;
+  os2Table[85] = 0;
+  os2Table[86] = 0;		// sxHeight
+  os2Table[87] = 0;
+  os2Table[88] = 0;		// sCapHeight
+  os2Table[89] = 0;
+  os2Table[90] = 0;		// usDefaultChar
+  os2Table[91] = 0;
+  os2Table[92] = 0;		// usBreakChar
+  os2Table[93] = 0;
+  os2Table[94] = 0;		// usMaxContext
+  os2Table[95] = 0;
+  tableData[1] = os2Table;
+  tableLength[1] = 96;
 
   //--- cmap table
   tableData[2] = cmapTable;
@@ -2328,18 +2395,14 @@
   } 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[ 5] = 0x01;				//   (needs to be non-zero)
   headTable[ 6] = 0x00;
-  headTable[ 7] = 0x00;
+  headTable[ 7] = 0x01;
   headTable[ 8] = 0x00;				// checksumAdjustment
   headTable[ 9] = 0x00;				//   (set later)
   headTable[10] = 0x00;
@@ -2390,8 +2453,8 @@
   tableLength[3] = 54;
 
   //--- hhea table
-  maxWidth = widths[0];
-  for (i = 1; i < nWidths; ++i) {
+  maxWidth = 0;
+  for (i = 0; i < nWidths; ++i) {
     if (widths[i] > maxWidth) {
       maxWidth = widths[i];
     }
@@ -2659,6 +2722,10 @@
 	return gFalse;
       }
       nFDs = fdIdx.len;
+      if (nFDs < 1) {
+	parsedOk = gFalse;
+	return gFalse;
+      }
       privateDicts = (Type1CPrivateDict *)
 	                 gmallocn(nFDs, sizeof(Type1CPrivateDict));
       for (i = 0; i < nFDs; ++i) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "FoFiBase.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -12,10 +12,6 @@
 
 #if USE_FIXEDPOINT
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include "gmempp.h"
 #include "FixedPoint.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -15,10 +15,6 @@
 
 #if USE_FIXEDPOINT
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include "gtypes.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/GHash.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/GHash.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/GHash.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include "gmem.h"
 #include "gmempp.h"
 #include "GString.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/GHash.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/GHash.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/GHash.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 
 class GString;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/GList.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/GList.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/GList.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <string.h>
 #include "gmem.h"
@@ -100,6 +96,11 @@
   qsort(data, length, sizeof(void *), cmp);
 }
 
+void GList::sort(int first, int n,
+		 int (*cmp)(const void *ptr1, const void *ptr2)) {
+  qsort(data + first, n, sizeof(void *), cmp);
+}
+
 void GList::reverse() {
   void *t;
   int n, i;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/GList.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/GList.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/GList.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 
 //------------------------------------------------------------------------
@@ -70,6 +66,9 @@
   // be double-dereferenced.
   void sort(int (*cmp)(const void *ptr1, const void *ptr2));
 
+  // Sort <n> items starting at <first>.
+  void sort(int first, int n, int (*cmp)(const void *ptr1, const void *ptr2));
+
   // Reverse the list.
   void reverse();
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/GString.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/GString.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/GString.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -10,10 +10,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <stddef.h>
 #include <string.h>
@@ -416,6 +412,8 @@
 
 	// format the argument
 	arg = args[idx];
+	str = NULL;
+	len = 0;
 	switch (ft) {
 	case fmtIntDecimal:
 	  formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 10, &str, &len);

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/GString.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/GString.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/GString.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -13,10 +13,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <limits.h> // for LLONG_MAX and ULLONG_MAX
 #include <stdarg.h>
 #include "gtypes.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -418,6 +418,18 @@
 #endif
 }
 
+GBool pathIsDir(const char *path) {
+#ifdef _WIN32
+  wchar_t wPath[winMaxLongPath + 1];
+  fileNameToUCS2(path, wPath, winMaxLongPath + 1);
+  DWORD attr = GetFileAttributesW(wPath);
+  return attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY);
+#else
+  struct stat statBuf;
+  return stat(path, &statBuf) == 0 && S_ISDIR(statBuf.st_mode);
+#endif
+}
+
 time_t getModTime(char *fileName) {
 #ifdef _WIN32
   //~ should implement this, but it's (currently) only used in xpdf
@@ -602,6 +614,17 @@
   return s;
 }
 
+GString *fileNameMultiByteToUTF8(char *path) {
+  wchar_t fileNameW[winMaxLongPath + 1];
+  if (MultiByteToWideChar(CP_OEMCP, 0, path, -1,
+			   fileNameW, sizeof(fileNameW) / sizeof(wchar_t))) {
+    return fileNameToUTF8(fileNameW);
+  } else {
+    // shouldn't happen, but just in case...
+    return new GString(path);
+  }
+}
+
 wchar_t *fileNameToUCS2(const char *path, wchar_t *out, size_t outSize) {
   const char *p;
   size_t i;
@@ -680,7 +703,7 @@
   }
   hres = persistFile->Load(wPath, STGM_READ);
   if (FAILED(hres)) {
-    fprintf(stderr, "IPersistFile.Load failed: 0x%08x\n", hres);
+    fprintf(stderr, "IPersistFile.Load failed: 0x%08lx\n", hres);
     exit(1);
   }
   wchar_t target[winMaxLongPath + 1];

Modified: trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/goo/gfile.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -64,6 +64,9 @@
 // Returns true if [path] exists and is a regular file.
 extern GBool pathIsFile(const char *path);
 
+// Returns true if [path] exists and is a directory.
+extern GBool pathIsDir(const char *path);
+
 // Get the modification time for <fileName>.  Returns 0 if there is an
 // error.
 extern time_t getModTime(char *fileName);
@@ -90,6 +93,9 @@
 // Convert a file name from UCS-2 to UTF-8.
 extern GString *fileNameToUTF8(wchar_t *path);
 
+// Convert a file name from the OEM code page to UTF-8.
+extern GString *fileNameMultiByteToUTF8(char *path);
+
 // Convert a file name from UTF-8 to UCS-2.  [out] has space for
 // [outSize] wchar_t elements (including the trailing zero).  Returns
 // [out].

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
@@ -4930,7 +4926,7 @@
 
 SplashError Splash::stroke(SplashPath *path) {
   SplashPath *path2, *dPath;
-  SplashCoord t0, t1, t2, t3, w, w2, lineDashMax, lineDashTotal;
+  SplashCoord w, w2, lineDashMax, lineDashTotal;
   int lineCap, lineJoin, i;
 
   if (debugMode) {
@@ -4942,6 +4938,9 @@
   if (path->length == 0) {
     return splashErrEmptyPath;
   }
+  if (pathAllOutside(path, gTrue)) {
+    return splashOk;
+  }
   path2 = flattenPath(path, state->matrix, state->flatness);
 
   // Compute an approximation of the transformed line width.
@@ -4953,15 +4952,13 @@
   //                                  [0 +/-s]     [+/-s 0]
   // well, and still does something reasonable for the uncommon
   // case transforms.
-  t0 = splashAbs(state->matrix[0]);
-  t1 = splashAbs(state->matrix[1]);
-  t2 = splashAbs(state->matrix[2]);
-  t3 = splashAbs(state->matrix[3]);
-  if (t0 * t3 >= t1 * t2) {
-    w = (t0 < t3) ? t0 : t3;
-  } else {
-    w = (t1 < t2) ? t1 : t2;
-  }
+  double t0 = splashAbs(state->matrix[0]);
+  double t1 = splashAbs(state->matrix[1]);
+  double t2 = splashAbs(state->matrix[2]);
+  double t3 = splashAbs(state->matrix[3]);
+  double t01 = t0 * t0 + t1 * t1;
+  double t23 = t2 * t2 + t3 * t3;
+  w = sqrt((t01 > t23) ? t01 : t23);
   w2 = w * state->lineWidth;
 
   // construct the dashed path
@@ -5056,7 +5053,7 @@
 
   xPath = new SplashXPath(path, state->matrix, state->flatness, gFalse,
 			  state->enablePathSimplification,
-			  state->strokeAdjust);
+			  state->strokeAdjust, state->clip);
 
   pipeInit(&pipe, state->strokePattern,
 	   (Guchar)splashRound(state->strokeAlpha * 255),
@@ -5074,6 +5071,44 @@
       x0 = splashFloor(seg->x1);
       x1 = splashFloor(seg->x0);
     }
+
+    // With CAD-mode stroke adjustment, and a simple rectangular clip
+    // region, horizontal and vertical stroke-adjusted edges that fall
+    // slightly outside the clip region are adjusted back inside the
+    // clip region.  This avoids problems with narrow lines in
+    // slightly mismatched clip rectangles, which appear to be
+    // generated somewhat commonly by buggy CAD software.  This is
+    // similar to the code in SplashXPath::strokeAdjust() -- narrow
+    // strokes aren't stroke-adjusted, so this tweak has to be done
+    // here.
+    if (y0 == y1 &&
+	seg->y0 == seg->y1 &&
+	state->clip->getIsSimple() &&
+	state->strokeAdjust == splashStrokeAdjustCAD) {
+      SplashCoord cy0 = state->clip->getYMin();
+      SplashCoord cy1 = state->clip->getYMax();
+      int cyi0 = state->clip->getYMinI(state->strokeAdjust);
+      int cyi1 = state->clip->getYMaxI(state->strokeAdjust);
+      if (y0 == cyi0 - 1 && cy0 - seg->y0 < 0.5) {
+	y0 = y1 = y0 + 1;
+      } else if (y0 == cyi1 + 1 && seg->y0 - cy1 < 0.5) {
+	y0 = y1 = y0 - 1;
+      }
+    } else if (x0 == x1 &&
+	seg->x0 == seg->x1 &&
+	state->clip->getIsSimple() &&
+	state->strokeAdjust == splashStrokeAdjustCAD) {
+      SplashCoord cx0 = state->clip->getXMin();
+      SplashCoord cx1 = state->clip->getXMax();
+      int cxi0 = state->clip->getXMinI(state->strokeAdjust);
+      int cxi1 = state->clip->getXMaxI(state->strokeAdjust);
+      if (x0 == cxi0 - 1 && cx0 - seg->x0 < 0.5) {
+	x0 = x1 = x0 + 1;
+      } else if (x0 == cxi1 + 1 && seg->x0 - cx1 < 0.5) {
+	x0 = x1 = x0 - 1;
+      }
+    }
+
     if ((clipRes = state->clip->testRect(x0 <= x1 ? x0 : x1, y0,
 					 x0 <= x1 ? x1 : x0, y1,
 					 state->strokeAdjust))
@@ -5084,6 +5119,18 @@
 	} else {
 	  drawStrokeSpan(&pipe, x1, x0, y0, clipRes == splashClipAllInside);
 	}
+      } else if (x0 == x1) {
+	y = state->clip->getYMinI(state->strokeAdjust);
+	if (y0 < y) {
+	  y0 = y;
+	}
+	y = state->clip->getYMaxI(state->strokeAdjust);
+	if (y1 > y) {
+	  y1 = y;
+	}
+	for (y = y0; y <= y1; ++y) {
+	  drawStrokeSpan(&pipe, x0, x0, y, clipRes == splashClipAllInside);
+	}
       } else {
 	dxdy = seg->dxdy;
 	y = state->clip->getYMinI(state->strokeAdjust);
@@ -5094,7 +5141,7 @@
 	y = state->clip->getYMaxI(state->strokeAdjust);
 	if (y1 > y) {
 	  y1 = y;
-	  x1 = splashFloor(seg->x0 + ((SplashCoord)y1 - seg->y0) * dxdy);
+	  x1 = splashFloor(seg->x0 + ((SplashCoord)y1 + 1 - seg->y0) * dxdy);
 	}
 	if (x0 <= x1) {
 	  xa = x0;
@@ -5135,6 +5182,7 @@
     }
     ++nClipRes[clipRes];
   }
+
   if (nClipRes[splashClipPartial] ||
       (nClipRes[splashClipAllInside] && nClipRes[splashClipAllOutside])) {
     opClipRes = splashClipPartial;
@@ -5326,16 +5374,14 @@
     return new SplashPath();
   }
   lineDashStartPhase = state->lineDashPhase;
-  if (lineDashStartPhase > lineDashTotal * 2) {
-    i = splashFloor(lineDashStartPhase / (lineDashTotal * 2));
-    lineDashStartPhase -= lineDashTotal * i * 2;
-  } else if (lineDashStartPhase < 0) {
-    i = splashCeil(-lineDashStartPhase / (lineDashTotal * 2));
-    lineDashStartPhase += lineDashTotal * i * 2;
+  if (lineDashStartPhase > 0) {
+    i = splashFloor(lineDashStartPhase / lineDashTotal);
+    lineDashStartPhase -= lineDashTotal * i;
+  } else {
+    i = splashCeil(-lineDashStartPhase / lineDashTotal);
+    lineDashStartPhase += lineDashTotal * i;
   }
-  i = splashFloor(lineDashStartPhase / lineDashTotal);
-  lineDashStartPhase -= (SplashCoord)i * lineDashTotal;
-  lineDashStartOn = gTrue;
+  lineDashStartOn = !((state->lineDashLength & 1) && (i & 1));
   lineDashStartIdx = 0;
   if (lineDashStartPhase > 0) {
     while (lineDashStartPhase >= state->lineDash[lineDashStartIdx]) {
@@ -5377,6 +5423,14 @@
       y1 = path->pts[k+1].y;
       segLen = splashDist(x0, y0, x1, y1);
 
+      // Special case for zero-length subpath: copy the zero-length
+      // segment into the dashed path so that the round line cap
+      // special case is handled.
+      if (j == i+1 && segLen == 0) {
+	dPath->moveTo(x0, y0);
+	dPath->lineTo(x0, y0);
+      }
+
       // process the segment
       while (segLen > 0) {
 
@@ -5477,6 +5531,13 @@
     printf("fill [eo:%d]:\n", eo);
     dumpPath(path);
   }
+  if (path->length == 0) {
+    return splashErrEmptyPath;
+  }
+  if (pathAllOutside(path, gFalse)) {
+    opClipRes = splashClipAllOutside;
+    return splashOk;
+  }
   return fillWithPattern(path, eo, state->fillPattern, state->fillAlpha);
 }
 
@@ -5490,19 +5551,11 @@
   int xMin, yMin, xMax, xMin2, xMax2, yMax, y, t;
   SplashClipResult clipRes;
 
-  if (path->length == 0) {
-    return splashErrEmptyPath;
-  }
-  if (pathAllOutside(path)) {
-    opClipRes = splashClipAllOutside;
-    return splashOk;
-  }
-
   path2 = tweakFillPath(path);
 
   xPath = new SplashXPath(path2, state->matrix, state->flatness, gTrue,
 			  state->enablePathSimplification,
-			  state->strokeAdjust);
+			  state->strokeAdjust, state->clip);
   if (path2 != path) {
     delete path2;
   }
@@ -5678,13 +5731,17 @@
   return path2;
 }
 
-GBool Splash::pathAllOutside(SplashPath *path) {
+// Returns true if [path] is entirely outside the current clipping
+// path.  The path coordinates have not been stroke adjusted, so we
+// compare against the floating point clip rect.  If [stroke] is true,
+// allow for the stroke width and miter limit.
+GBool Splash::pathAllOutside(SplashPath *path, GBool stroke) {
   SplashCoord xMin1, yMin1, xMax1, yMax1;
   SplashCoord xMin2, yMin2, xMax2, yMax2;
   SplashCoord x, y;
-  int xMinI, yMinI, xMaxI, yMaxI;
   int i;
 
+  //--- compute the path's bbox in user space
   xMin1 = xMax1 = path->pts[0].x;
   yMin1 = yMax1 = path->pts[0].y;
   for (i = 1; i < path->length; ++i) {
@@ -5700,6 +5757,19 @@
     }
   }
 
+  //--- allow for stroke width and miter limit
+  if (stroke && state->lineWidth > 0) {
+    SplashCoord w = state->lineWidth * 0.5;
+    if (state->lineJoin == splashLineJoinMiter) {
+      w *= state->miterLimit;
+    }
+    xMin1 -= w;
+    yMin1 -= w;
+    xMax1 += w;
+    yMax1 += w;
+  }
+
+  //--- convert path bbox to device space
   transform(state->matrix, xMin1, yMin1, &x, &y);
   xMin2 = xMax2 = x;
   yMin2 = yMax2 = y;
@@ -5736,18 +5806,20 @@
   } else if (y > yMax2) {
     yMax2 = y;
   }
-  // sanity-check the coordinates - xMinI/yMinI/xMaxI/yMaxI are
-  // 32-bit integers, so coords need to be < 2^31
-  SplashXPath::clampCoords(&xMin2, &yMin2);
-  SplashXPath::clampCoords(&xMax2, &yMax2);
-  xMinI = splashFloor(xMin2);
-  yMinI = splashFloor(yMin2);
-  xMaxI = splashFloor(xMax2);
-  yMaxI = splashFloor(yMax2);
 
-  return state->clip->testRect(xMinI, yMinI, xMaxI, yMaxI,
-			       state->strokeAdjust) ==
-         splashClipAllOutside;
+  //--- handle zero-width strokes
+  if (stroke && state->lineWidth == 0) {
+    xMin1 -= 1;
+    yMin1 -= 1;
+    xMax1 += 1;
+    yMax1 += 1;
+  }
+
+  //--- check against the clip rect
+  return xMin2 > state->clip->getXMax() ||
+         xMax2 < state->clip->getXMin() ||
+         yMin2 > state->clip->getYMax() ||
+         yMax2 < state->clip->getYMin();
 }
 
 SplashError Splash::fillChar(SplashCoord x, SplashCoord y,
@@ -6022,6 +6094,9 @@
   SplashClipResult clipRes =
       state->clip->testRect(xMin, yMin, xMax - 1, yMax - 1,
 			    state->strokeAdjust);
+  if (clipRes == splashClipAllOutside) {
+    return splashOk;
+  }
   // If the scaled mask is much wider and/or taller than the clip
   // region, we use the "arbitrary" scaling path, to avoid a
   // potentially very slow loop in the flips-only path (which scans
@@ -6054,93 +6129,89 @@
 
   //--- horizontal/vertical flips only
   if (flipsOnly && !veryLarge) {
-    if (clipRes != splashClipAllOutside) {
-      int scaledWidth = xMax - xMin;
-      int scaledHeight = yMax - yMin;
-      ImageMaskScaler scaler(src, srcData, w, h,
-			     scaledWidth, scaledHeight, interpolate, antialias);
-      Guchar *tmpLine = NULL;
-      if (horizFlip) {
-	tmpLine = (Guchar *)gmalloc(scaledWidth);
+    int scaledWidth = xMax - xMin;
+    int scaledHeight = yMax - yMin;
+    ImageMaskScaler scaler(src, srcData, w, h,
+			   scaledWidth, scaledHeight, interpolate, antialias);
+    Guchar *tmpLine = NULL;
+    if (horizFlip) {
+      tmpLine = (Guchar *)gmalloc(scaledWidth);
+    }
+    if (vertFlip) {
+      if (horizFlip) {    // bottom-up, mirrored
+	for (int y = 0; y < scaledHeight; ++y) {
+	  scaler.nextLine();
+	  mirrorImageMaskRow(scaler.data(), tmpLine, scaledWidth);
+	  (this->*drawRowFunc)(&dd, tmpLine,
+			       xMin, yMax - 1 - y, scaledWidth);
+	}
+      } else {            // bottom-up
+	for (int y = 0; y < scaledHeight; ++y) {
+	  scaler.nextLine();
+	  (this->*drawRowFunc)(&dd, scaler.data(),
+			       xMin, yMax - 1 - y, scaledWidth);
+	}
       }
-      if (vertFlip) {
-	if (horizFlip) {    // bottom-up, mirrored
-	  for (int y = 0; y < scaledHeight; ++y) {
-	    scaler.nextLine();
-	    mirrorImageMaskRow(scaler.data(), tmpLine, scaledWidth);
-	    (this->*drawRowFunc)(&dd, tmpLine,
-				 xMin, yMax - 1 - y, scaledWidth);
-	  }
-	} else {            // bottom-up
-	  for (int y = 0; y < scaledHeight; ++y) {
-	    scaler.nextLine();
-	    (this->*drawRowFunc)(&dd, scaler.data(),
-				 xMin, yMax - 1 - y, scaledWidth);
-	  }
+    } else {
+      if (horizFlip) {    // top-down, mirrored
+	for (int y = 0; y < scaledHeight; ++y) {
+	  scaler.nextLine();
+	  mirrorImageMaskRow(scaler.data(), tmpLine, scaledWidth);
+	  (this->*drawRowFunc)(&dd, tmpLine,
+			       xMin, yMin + y, scaledWidth);
 	}
-      } else {
-	if (horizFlip) {    // top-down, mirrored
-	  for (int y = 0; y < scaledHeight; ++y) {
-	    scaler.nextLine();
-	    mirrorImageMaskRow(scaler.data(), tmpLine, scaledWidth);
-	    (this->*drawRowFunc)(&dd, tmpLine,
-				 xMin, yMin + y, scaledWidth);
-	  }
-	} else {            // top-down
-	  for (int y = 0; y < scaledHeight; ++y) {
-	    scaler.nextLine();
-	    (this->*drawRowFunc)(&dd, scaler.data(),
-				 xMin, yMin + y, scaledWidth);
-	  }
+      } else {            // top-down
+	for (int y = 0; y < scaledHeight; ++y) {
+	  scaler.nextLine();
+	  (this->*drawRowFunc)(&dd, scaler.data(),
+			       xMin, yMin + y, scaledWidth);
 	}
       }
-      gfree(tmpLine);
     }
+    gfree(tmpLine);
 
   //--- 90/270 rotation
   } else if (rot90Only && !veryLarge) {
-    if (clipRes != splashClipAllOutside) {
 
-      // scale the mask
-      int scaledWidth = yMax - yMin;
-      int scaledHeight = xMax - xMin;
-      ImageMaskScaler scaler(src, srcData, w, h,
-			     scaledWidth, scaledHeight, interpolate, antialias);
-      Guchar *scaledMask = (Guchar *)gmallocn(scaledHeight, scaledWidth);
-      Guchar *ptr = scaledMask;
-      for (int y = 0; y < scaledHeight; ++y) {
-	scaler.nextLine();
-	memcpy(ptr, scaler.data(), scaledWidth);
-	ptr += scaledWidth;
+    // scale the mask
+    int scaledWidth = yMax - yMin;
+    int scaledHeight = xMax - xMin;
+    ImageMaskScaler scaler(src, srcData, w, h,
+			   scaledWidth, scaledHeight, interpolate, antialias);
+    Guchar *scaledMask = (Guchar *)gmallocn64(scaledHeight, scaledWidth);
+    Guchar *ptr = scaledMask;
+    for (int y = 0; y < scaledHeight; ++y) {
+      scaler.nextLine();
+      memcpy(ptr, scaler.data(), scaledWidth);
+      ptr += scaledWidth;
+    }
+
+    // draw it
+    Guchar *tmpLine = (Guchar *)gmalloc(scaledHeight);
+    for (int y = 0; y < scaledWidth; ++y) {
+      if (vertFlip) {
+	ptr = scaledMask + (scaledWidth - 1 - y);
+      } else {
+	ptr = scaledMask + y;
       }
-
-      // draw it
-      Guchar *tmpLine = (Guchar *)gmalloc(scaledHeight);
-      for (int y = 0; y < scaledWidth; ++y) {
-	if (vertFlip) {
-	  ptr = scaledMask + (scaledWidth - 1 - y);
-	} else {
-	  ptr = scaledMask + y;
+      if (horizFlip) {
+	ptr += (scaledHeight - 1) * scaledWidth;
+	for (int x = 0; x < scaledHeight; ++x) {
+	  tmpLine[x] = *ptr;
+	  ptr -= scaledWidth;
 	}
-	if (horizFlip) {
-	  ptr += (scaledHeight - 1) * scaledWidth;
-	  for (int x = 0; x < scaledHeight; ++x) {
-	    tmpLine[x] = *ptr;
-	    ptr -= scaledWidth;
-	  }
-	} else {
-	  for (int x = 0; x < scaledHeight; ++x) {
-	    tmpLine[x] = *ptr;
-	    ptr += scaledWidth;
-	  }
+      } else {
+	for (int x = 0; x < scaledHeight; ++x) {
+	  tmpLine[x] = *ptr;
+	  ptr += scaledWidth;
 	}
-	(this->*drawRowFunc)(&dd, tmpLine, xMin, yMin + y, scaledHeight);
       }
-
-      gfree(tmpLine);
-      gfree(scaledMask);
+      (this->*drawRowFunc)(&dd, tmpLine, xMin, yMin + y, scaledHeight);
     }
 
+    gfree(tmpLine);
+    gfree(scaledMask);
+
   //--- arbitrary transform
   } else {
     // estimate of size of scaled image
@@ -6189,7 +6260,7 @@
 
     // if downscaling: store the downscaled image mask
     // if upscaling: store the unscaled image mask
-    Guchar *scaledMask = (Guchar *)gmallocn(scaledHeight, scaledWidth);
+    Guchar *scaledMask = (Guchar *)gmallocn64(scaledHeight, scaledWidth);
     if (downscaling) {
       ImageMaskScaler scaler(src, srcData, w, h,
 			     scaledWidth, scaledHeight, interpolate, antialias);
@@ -6271,7 +6342,7 @@
 			   + (SplashCoord)y * invMat[3] + invMat[5]);
       if (xx >= 0 && xx < scaledWidth &&
 	  yy >= 0 && yy < scaledHeight) {
-	Guchar *p = scaledMask + (yy * scaledWidth + xx);
+	Guchar *p = scaledMask + (yy * (SplashBitmapRowSize)scaledWidth + xx);
 	Guchar *q = buf + (x - xMin);
 	*q = *p;
 	if (x < rowMin) {
@@ -6349,10 +6420,10 @@
 	if (y1 >= scaledHeight) {
 	  y1 = scaledHeight - 1;
 	}
-	Guchar *p00 = scaledMask + (y0 * scaledWidth + x0);
-	Guchar *p10 = scaledMask + (y0 * scaledWidth + x1);
-	Guchar *p01 = scaledMask + (y1 * scaledWidth + x0);
-	Guchar *p11 = scaledMask + (y1 * scaledWidth + x1);
+	Guchar *p00 = scaledMask + (y0 * (SplashBitmapRowSize)scaledWidth + x0);
+	Guchar *p10 = scaledMask + (y0 * (SplashBitmapRowSize)scaledWidth + x1);
+	Guchar *p01 = scaledMask + (y1 * (SplashBitmapRowSize)scaledWidth + x0);
+	Guchar *p11 = scaledMask + (y1 * (SplashBitmapRowSize)scaledWidth + x1);
 	Guchar *q = buf + (x - xMin);
 	*q = (Guchar)(int)(sx0 * (sy0 * (int)*p00 + sy1 * (int)*p01) +
 			   sx1 * (sy0 * (int)*p10 + sy1 * (int)*p11));
@@ -6569,6 +6640,9 @@
   SplashClipResult clipRes =
       state->clip->testRect(xMin, yMin, xMax - 1, yMax - 1,
 			    state->strokeAdjust);
+  if (clipRes == splashClipAllOutside) {
+    return splashOk;
+  }
   // If the scaled image is much wider and/or taller than the clip
   // region, we use the arbitrary transform path, to avoid a
   // potentially very slow loop in the flips-only path (which scans
@@ -6616,136 +6690,133 @@
 
   //--- horizontal/vertical flips only
   if (flipsOnly && !veryLarge) {
-    if (clipRes != splashClipAllOutside) {
-      int scaledWidth = xMax - xMin;
-      int scaledHeight = yMax - yMin;
-      ImageScaler *scaler = getImageScaler(imageTag, src, srcData,
-					   w, h, nComps,
-					   scaledWidth, scaledHeight,
-					   srcMode, srcAlpha, interpolate);
-      Guchar *tmpLine = NULL;
-      Guchar *tmpAlphaLine = NULL;
-      if (horizFlip) {
-	tmpLine = (Guchar *)gmallocn(scaledWidth, nComps);
-	if (srcAlpha) {
-	  tmpAlphaLine = (Guchar *)gmalloc(scaledWidth);
+    int scaledWidth = xMax - xMin;
+    int scaledHeight = yMax - yMin;
+    ImageScaler *scaler = getImageScaler(imageTag, src, srcData,
+					 w, h, nComps,
+					 scaledWidth, scaledHeight,
+					 srcMode, srcAlpha, interpolate);
+    Guchar *tmpLine = NULL;
+    Guchar *tmpAlphaLine = NULL;
+    if (horizFlip) {
+      tmpLine = (Guchar *)gmallocn(scaledWidth, nComps);
+      if (srcAlpha) {
+	tmpAlphaLine = (Guchar *)gmalloc(scaledWidth);
+      }
+    }
+    if (vertFlip) {
+      if (horizFlip) {    // bottom-up, mirrored
+	for (int y = 0; y < scaledHeight; ++y) {
+	  scaler->nextLine();
+	  mirrorImageRow(scaler->colorData(), scaler->alphaData(),
+			 tmpLine, tmpAlphaLine,
+			 scaledWidth, nComps, srcAlpha);
+	  (this->*drawRowFunc)(&dd, tmpLine, tmpAlphaLine,
+			       xMin, yMax - 1 - y, scaledWidth);
 	}
+      } else {            // bottom-up
+	for (int y = 0; y < scaledHeight; ++y) {
+	  scaler->nextLine();
+	  (this->*drawRowFunc)(&dd, scaler->colorData(), scaler->alphaData(),
+			       xMin, yMax - 1 - y, scaledWidth);
+	}
       }
-      if (vertFlip) {
-	if (horizFlip) {    // bottom-up, mirrored
-	  for (int y = 0; y < scaledHeight; ++y) {
-	    scaler->nextLine();
-	    mirrorImageRow(scaler->colorData(), scaler->alphaData(),
-			   tmpLine, tmpAlphaLine,
-			   scaledWidth, nComps, srcAlpha);
-	    (this->*drawRowFunc)(&dd, tmpLine, tmpAlphaLine,
-				 xMin, yMax - 1 - y, scaledWidth);
-	  }
-	} else {            // bottom-up
-	  for (int y = 0; y < scaledHeight; ++y) {
-	    scaler->nextLine();
-	    (this->*drawRowFunc)(&dd, scaler->colorData(), scaler->alphaData(),
-				 xMin, yMax - 1 - y, scaledWidth);
-	  }
+    } else {
+      if (horizFlip) {    // top-down, mirrored
+	for (int y = 0; y < scaledHeight; ++y) {
+	  scaler->nextLine();
+	  mirrorImageRow(scaler->colorData(), scaler->alphaData(),
+			 tmpLine, tmpAlphaLine,
+			 scaledWidth, nComps, srcAlpha);
+	  (this->*drawRowFunc)(&dd, tmpLine, tmpAlphaLine,
+			       xMin, yMin + y, scaledWidth);
 	}
-      } else {
-	if (horizFlip) {    // top-down, mirrored
-	  for (int y = 0; y < scaledHeight; ++y) {
-	    scaler->nextLine();
-	    mirrorImageRow(scaler->colorData(), scaler->alphaData(),
-			   tmpLine, tmpAlphaLine,
-			   scaledWidth, nComps, srcAlpha);
-	    (this->*drawRowFunc)(&dd, tmpLine, tmpAlphaLine,
-				 xMin, yMin + y, scaledWidth);
-	  }
-	} else {            // top-down
-	  for (int y = 0; y < scaledHeight; ++y) {
-	    scaler->nextLine();
-	    (this->*drawRowFunc)(&dd, scaler->colorData(), scaler->alphaData(),
-				 xMin, yMin + y, scaledWidth);
-	  }
+      } else {            // top-down
+	for (int y = 0; y < scaledHeight; ++y) {
+	  scaler->nextLine();
+	  (this->*drawRowFunc)(&dd, scaler->colorData(), scaler->alphaData(),
+			       xMin, yMin + y, scaledWidth);
 	}
       }
-      gfree(tmpLine);
-      gfree(tmpAlphaLine);
-      delete scaler;
     }
+    gfree(tmpLine);
+    gfree(tmpAlphaLine);
+    delete scaler;
 
   //--- 90/270 rotation
   } else if (rot90Only && !veryLarge) {
-    if (clipRes != splashClipAllOutside) {
 
-      // scale the image
-      int scaledWidth = yMax - yMin;
-      int scaledHeight = xMax - xMin;
-      Guchar *scaledColor, *scaledAlpha;
-      GBool freeScaledImage;
-      getScaledImage(imageTag, src, srcData, w, h, nComps,
-		     scaledWidth, scaledHeight, srcMode, srcAlpha, interpolate,
-		     &scaledColor, &scaledAlpha, &freeScaledImage);
+    // scale the image
+    int scaledWidth = yMax - yMin;
+    int scaledHeight = xMax - xMin;
+    Guchar *scaledColor, *scaledAlpha;
+    GBool freeScaledImage;
+    getScaledImage(imageTag, src, srcData, w, h, nComps,
+		   scaledWidth, scaledHeight, srcMode, srcAlpha, interpolate,
+		   &scaledColor, &scaledAlpha, &freeScaledImage);
 
-      // draw it
-      Guchar *tmpLine = (Guchar *)gmallocn(scaledHeight, nComps);
-      Guchar *tmpAlphaLine = NULL;
-      if (srcAlpha) {
-	tmpAlphaLine = (Guchar *)gmalloc(scaledHeight);
+    // draw it
+    Guchar *tmpLine = (Guchar *)gmallocn(scaledHeight, nComps);
+    Guchar *tmpAlphaLine = NULL;
+    if (srcAlpha) {
+      tmpAlphaLine = (Guchar *)gmalloc(scaledHeight);
+    }
+    for (int y = 0; y < scaledWidth; ++y) {
+      Guchar *ptr = NULL;
+      Guchar *alphaPtr = NULL;
+      if (vertFlip) {
+	ptr = scaledColor + ((SplashBitmapRowSize)scaledWidth - 1 - y) * nComps;
+	if (srcAlpha) {
+	  alphaPtr = scaledAlpha + (scaledWidth - 1 - y);
+	}
+      } else {
+	ptr = scaledColor + y * nComps;
+	if (srcAlpha) {
+	  alphaPtr = scaledAlpha + y;
+	}
       }
-      for (int y = 0; y < scaledWidth; ++y) {
-	Guchar *ptr, *alphaPtr;
-	if (vertFlip) {
-	  ptr = scaledColor + (scaledWidth - 1 - y) * nComps;
-	  if (srcAlpha) {
-	    alphaPtr = scaledAlpha + (scaledWidth - 1 - y);
+      if (horizFlip) {
+	ptr += (scaledHeight - 1) * (SplashBitmapRowSize)scaledWidth * nComps;
+	Guchar *q = tmpLine;
+	for (int x = 0; x < scaledHeight; ++x) {
+	  for (int i = 0; i < nComps; ++i) {
+	    *q++ = ptr[i];
 	  }
-	} else {
-	  ptr = scaledColor + y * nComps;
-	  if (srcAlpha) {
-	    alphaPtr = scaledAlpha + y;
-	  }
+	  ptr -= scaledWidth * nComps;
 	}
-	if (horizFlip) {
-	  ptr += (scaledHeight - 1) * scaledWidth * nComps;
-	  Guchar *q = tmpLine;
+	if (srcAlpha) {
+	  alphaPtr += (scaledHeight - 1) * (SplashBitmapRowSize)scaledWidth;
+	  q = tmpAlphaLine;
 	  for (int x = 0; x < scaledHeight; ++x) {
-	    for (int i = 0; i < nComps; ++i) {
-	      *q++ = ptr[i];
-	    }
-	    ptr -= scaledWidth * nComps;
+	    *q++ = *alphaPtr;
+	    alphaPtr -= scaledWidth;
 	  }
-	  if (srcAlpha) {
-	    alphaPtr += (scaledHeight - 1) * scaledWidth;
-	    q = tmpAlphaLine;
-	    for (int x = 0; x < scaledHeight; ++x) {
-	      *q++ = *alphaPtr;
-	      alphaPtr -= scaledWidth;
-	    }
+	}
+      } else {
+	Guchar *q = tmpLine;
+	for (int x = 0; x < scaledHeight; ++x) {
+	  for (int i = 0; i < nComps; ++i) {
+	    *q++ = ptr[i];
 	  }
-	} else {
-	  Guchar *q = tmpLine;
+	  ptr += scaledWidth * nComps;
+	}
+	if (srcAlpha) {
+	  q = tmpAlphaLine;
 	  for (int x = 0; x < scaledHeight; ++x) {
-	    for (int i = 0; i < nComps; ++i) {
-	      *q++ = ptr[i];
-	    }
-	    ptr += scaledWidth * nComps;
+	    *q++ = *alphaPtr;
+	    alphaPtr += scaledWidth;
 	  }
-	  if (srcAlpha) {
-	    q = tmpAlphaLine;
-	    for (int x = 0; x < scaledHeight; ++x) {
-	      *q++ = *alphaPtr;
-	      alphaPtr += scaledWidth;
-	    }
-	  }
 	}
-	(this->*drawRowFunc)(&dd, tmpLine, tmpAlphaLine,
-			     xMin, yMin + y, scaledHeight);
       }
+      (this->*drawRowFunc)(&dd, tmpLine, tmpAlphaLine,
+			   xMin, yMin + y, scaledHeight);
+    }
 
-      gfree(tmpLine);
-      gfree(tmpAlphaLine);
-      if (freeScaledImage) {
-	gfree(scaledColor);
-	gfree(scaledAlpha);
-      }
+    gfree(tmpLine);
+    gfree(tmpAlphaLine);
+    if (freeScaledImage) {
+      gfree(scaledColor);
+      gfree(scaledAlpha);
     }
 
   //--- arbitrary transform
@@ -6851,9 +6922,9 @@
       } else {
 	lineSize = -1;
       }
-      imageCache->colorData = (Guchar *)gmallocn(scaledHeight, lineSize);
+      imageCache->colorData = (Guchar *)gmallocn64(scaledHeight, lineSize);
       if (srcAlpha) {
-	imageCache->alphaData = (Guchar *)gmallocn(scaledHeight, scaledWidth);
+	imageCache->alphaData = (Guchar *)gmallocn64(scaledHeight, scaledWidth);
       }
       return new SavingImageScaler(src, srcData,
 				   w, h, nComps, srcAlpha,
@@ -6894,9 +6965,9 @@
     } else {
       lineSize = -1;
     }
-    *scaledColor = (Guchar *)gmallocn(scaledHeight, lineSize);
+    *scaledColor = (Guchar *)gmallocn64(scaledHeight, lineSize);
     if (srcAlpha) {
-      *scaledAlpha = (Guchar *)gmallocn(scaledHeight, scaledWidth);
+      *scaledAlpha = (Guchar *)gmallocn64(scaledHeight, scaledWidth);
     } else {
       *scaledAlpha = NULL;
     }
@@ -6938,9 +7009,9 @@
       } else {
 	lineSize = -1;
       }
-      imageCache->colorData = (Guchar *)gmallocn(scaledHeight, lineSize);
+      imageCache->colorData = (Guchar *)gmallocn64(scaledHeight, lineSize);
       if (srcAlpha) {
-	imageCache->alphaData = (Guchar *)gmallocn(scaledHeight, scaledWidth);
+	imageCache->alphaData = (Guchar *)gmallocn64(scaledHeight, scaledWidth);
       }
       if (scaledWidth == w && scaledHeight == h) {
 	Guchar *colorPtr = imageCache->colorData;
@@ -7021,13 +7092,15 @@
 			   + (SplashCoord)y * invMat[3] + invMat[5]);
       if (xx >= 0 && xx < scaledWidth &&
 	  yy >= 0 && yy < scaledHeight) {
-	Guchar *p = scaledColor + (yy * scaledWidth + xx) * nComps;
+	Guchar *p = scaledColor +
+	              (yy * (SplashBitmapRowSize)scaledWidth + xx) * nComps;
 	Guchar *q = colorBuf + (x - xMin) * nComps;
 	for (int i = 0; i < nComps; ++i) {
 	  *q++ = *p++;
 	}
 	if (srcAlpha) {
-	  alphaBuf[x - xMin] = scaledAlpha[yy * scaledWidth + xx];
+	  alphaBuf[x - xMin] =
+	      scaledAlpha[yy * (SplashBitmapRowSize)scaledWidth + xx];
 	}
 	if (x < rowMin) {
 	  rowMin = x;
@@ -7111,10 +7184,14 @@
 	if (y1 >= scaledHeight) {
 	  y1 = scaledHeight - 1;
 	}
-	Guchar *p00 = scaledColor + (y0 * scaledWidth + x0) * nComps;
-	Guchar *p10 = scaledColor + (y0 * scaledWidth + x1) * nComps;
-	Guchar *p01 = scaledColor + (y1 * scaledWidth + x0) * nComps;
-	Guchar *p11 = scaledColor + (y1 * scaledWidth + x1) * nComps;
+	Guchar *p00 = scaledColor +
+	                (y0 * (SplashBitmapRowSize)scaledWidth + x0) * nComps;
+	Guchar *p10 = scaledColor +
+	                (y0 * (SplashBitmapRowSize)scaledWidth + x1) * nComps;
+	Guchar *p01 = scaledColor +
+	                (y1 * (SplashBitmapRowSize)scaledWidth + x0) * nComps;
+	Guchar *p11 = scaledColor +
+	                (y1 * (SplashBitmapRowSize)scaledWidth + x1) * nComps;
 	Guchar *q = colorBuf + (x - xMin) * nComps;
 	for (int i = 0; i < nComps; ++i) {
 	  *q++ = (Guchar)(int)(sx0 * (sy0 * (int)*p00++ + sy1 * (int)*p01++) +
@@ -7121,10 +7198,10 @@
 			       sx1 * (sy0 * (int)*p10++ + sy1 * (int)*p11++));
 	}
 	if (srcAlpha) {
-	  p00 = scaledAlpha + (y0 * scaledWidth + x0);
-	  p10 = scaledAlpha + (y0 * scaledWidth + x1);
-	  p01 = scaledAlpha + (y1 * scaledWidth + x0);
-	  p11 = scaledAlpha + (y1 * scaledWidth + x1);
+	  p00 = scaledAlpha + (y0 * (SplashBitmapRowSize)scaledWidth + x0);
+	  p10 = scaledAlpha + (y0 * (SplashBitmapRowSize)scaledWidth + x1);
+	  p01 = scaledAlpha + (y1 * (SplashBitmapRowSize)scaledWidth + x0);
+	  p11 = scaledAlpha + (y1 * (SplashBitmapRowSize)scaledWidth + x1);
 	  q = alphaBuf + (x - xMin);
 	  *q = (Guchar)(int)(sx0 * (sy0 * (int)*p00 + sy1 * (int)*p01) +
 			     sx1 * (sy0 * (int)*p10 + sy1 * (int)*p11));

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/Splash.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "SplashTypes.h"
 #include "SplashClip.h"
 
@@ -425,7 +421,7 @@
   SplashError fillWithPattern(SplashPath *path, GBool eo,
 			      SplashPattern *pattern, SplashCoord alpha);
   SplashPath *tweakFillPath(SplashPath *path);
-  GBool pathAllOutside(SplashPath *path);
+  GBool pathAllOutside(SplashPath *path, GBool stroke);
   SplashError fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph);
   void getImageBounds(SplashCoord xyMin, SplashCoord xyMax,
 		      int *xyMinI, int *xyMaxI);

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <limits.h>
 #include "gmem.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <stdio.h>
 #include <limits.h>
 // older compilers won't define SIZE_MAX in stdint.h without this

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <string.h>
 #include "gmem.h"
@@ -210,7 +206,7 @@
 
   xPath = new SplashXPath(path, matrix, flatness, gTrue,
 			  enablePathSimplification,
-			  strokeAdjust);
+			  strokeAdjust, NULL);
 
   // check for an empty path
   if (xPath->length == 0) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "SplashTypes.h"
 #include "SplashMath.h"
 
@@ -100,6 +96,9 @@
   // Get the number of arbitrary paths used by the clip region.
   int getNumPaths();
 
+  // Return true if the clip path is a simple rectangle.
+  GBool getIsSimple() { return isSimple; }
+
 private:
 
   SplashClip(SplashClip *clip);
@@ -110,10 +109,11 @@
       hardXMax, hardYMax;	//   [hardXMin, hardXMax), [hardYMin, hardYMax)
 
   SplashCoord xMin, yMin,	// current clip bounding rectangle
-              xMax, yMax;	//   (these coordinates may be adjusted if
+              xMax, yMax;
+
+  int xMinI, yMinI,		// integer clip bounding rectangle
+      xMaxI, yMaxI;		//   (these coordinates are adjusted if
 				//   stroke adjustment is enabled)
-
-  int xMinI, yMinI, xMaxI, yMaxI;
   GBool intBoundsValid;		// true if xMinI, etc. are valid
   GBool intBoundsStrokeAdjust;	// value of strokeAdjust used to compute
 				//   xMinI, etc.

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -10,10 +10,6 @@
 
 #if HAVE_FREETYPE_H
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <ft2build.h>
 #include FT_OUTLINE_H
 #include FT_SIZES_H

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -13,10 +13,6 @@
 
 #if HAVE_FREETYPE_H
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #include "SplashFont.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -10,10 +10,6 @@
 
 #if HAVE_FREETYPE_H
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #ifndef _WIN32
 #  include <unistd.h>

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -13,10 +13,6 @@
 
 #if HAVE_FREETYPE_H
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #include "gtypes.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -10,10 +10,6 @@
 
 #if HAVE_FREETYPE_H
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include "gmem.h"
 #include "gmempp.h"
 #include "GString.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -13,10 +13,6 @@
 
 #if HAVE_FREETYPE_H
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #include "SplashFontFile.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <string.h>
 #include "gmem.h"
 #include "gmempp.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "SplashTypes.h"
 #include "SplashMath.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <stdio.h>
 #ifndef _WIN32

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 class GString;
 class GList;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #ifndef _WIN32
 #  include <unistd.h>

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "SplashTypes.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include "gmempp.h"
 #include "SplashFontFileID.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 
 //------------------------------------------------------------------------

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <string.h>
 #include "gmem.h"
 #include "gmempp.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "SplashTypes.h"
 
 //------------------------------------------------------------------------

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include "gmempp.h"
 #include "SplashMath.h"
 #include "SplashScreen.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "SplashTypes.h"
 
 class SplashScreen;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <string.h>
 #if HAVE_STD_SORT

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "SplashTypes.h"
 
 //------------------------------------------------------------------------

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <string.h>
 #include "gmem.h"
 #include "gmempp.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "SplashTypes.h"
 
 class SplashPattern;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <string.h>
 #if HAVE_STD_SORT
@@ -21,6 +17,7 @@
 #include "gmempp.h"
 #include "SplashMath.h"
 #include "SplashPath.h"
+#include "SplashClip.h"
 #include "SplashXPath.h"
 
 //------------------------------------------------------------------------
@@ -83,7 +80,8 @@
 SplashXPath::SplashXPath(SplashPath *path, SplashCoord *matrix,
 			 SplashCoord flatness, GBool closeSubpaths,
 			 GBool simplify,
-			 SplashStrokeAdjustMode strokeAdjMode) {
+			 SplashStrokeAdjustMode strokeAdjMode,
+			 SplashClip *clip) {
   SplashXPathPoint *pts;
   SplashCoord x0, y0, x1, y1, x2, y2, x3, y3, xsp, ysp, t;
   int curSubpath, firstSegInSubpath, i;
@@ -99,7 +97,7 @@
   //--- do stroke adjustment
   if (path->hints) {
     adjusted = strokeAdjust(pts, path->hints, path->hintsLength,
-			    strokeAdjMode);
+			    strokeAdjMode, clip);
   } else {
     adjusted = gFalse;
   }
@@ -227,7 +225,8 @@
 
 GBool SplashXPath::strokeAdjust(SplashXPathPoint *pts,
 				SplashPathHint *hints, int nHints,
-				SplashStrokeAdjustMode strokeAdjMode) {
+				SplashStrokeAdjustMode strokeAdjMode,
+				SplashClip *clip) {
   SplashXPathAdjust *adjusts, *adjust;
   SplashPathHint *hint;
   SplashCoord x0, y0, x1, y1, x2, y2, x3, y3;
@@ -238,6 +237,28 @@
 
   adjusted = gFalse;
 
+  // With CAD-mode stroke adjustment, and a simple rectangular clip
+  // region, stroke-adjusted edges that fall slightly outside the clip
+  // region are adjusted back inside the clip region.  This avoids
+  // problems with narrow lines in slightly mismatched clip
+  // rectangles, which appear to be generated somewhat commonly by
+  // buggy CAD software.  (Note: [clip] is NULL when called to build a
+  // clip path.)
+  GBool clipTweak = clip && clip->getIsSimple() &&
+                    strokeAdjMode == splashStrokeAdjustCAD;
+  SplashCoord cx0 = 0, cx1 = 0, cy0 = 0, cy1 = 0;
+  int cxi0 = 0, cxi1 = 0, cyi0 = 0, cyi1 = 0;
+  if (clipTweak) {
+    cx0 = clip->getXMin();
+    cx1 = clip->getXMax();
+    cy0 = clip->getYMin();
+    cy1 = clip->getYMax();
+    cxi0 = clip->getXMinI(strokeAdjMode);
+    cxi1 = clip->getXMaxI(strokeAdjMode);
+    cyi0 = clip->getYMinI(strokeAdjMode);
+    cyi1 = clip->getYMaxI(strokeAdjMode);
+  }
+
   // set up the stroke adjustment hints
   adjusts = (SplashXPathAdjust *)gmallocn(nHints, sizeof(SplashXPathAdjust));
   for (i = 0; i < nHints; ++i) {
@@ -282,6 +303,32 @@
     adjusts[i].x1a = adj1 - d;
     adjusts[i].x1b = adj1 + d;
     splashStrokeAdjust(adj0, adj1, &xi0, &xi1, strokeAdjMode, w);
+    if (clipTweak) {
+      SplashCoord c0, c1;
+      int ci0, ci1;
+      if (adjusts[i].vert) {
+	c0 = cx0;
+	c1 = cx1;
+	ci0 = cxi0;
+	ci1 = cxi1;
+      } else {
+	c0 = cy0;
+	c1 = cy1;
+	ci0 = cyi0;
+	ci1 = cyi1;
+      }
+      if (adj0 < c0 && c0 < adj1 && adj1 < c1 &&
+	  adj1 - c0 > (adj1 - adj0) * 0.2 &&
+	  xi1 <= ci0) {
+	xi0 = ci0;
+	xi1 = xi0 + 1;
+      } else if (c0 < adj0 && adj0 < c1 && c1 < adj1 &&
+		 c1 - adj0 > (adj1 - adj0) * 0.2 &&
+		 ci1 < xi0) {
+	xi0 = ci1;
+	xi1 = ci1 + 1;
+      }
+    }
     adjusts[i].x0 = (SplashCoord)xi0;
     // the "minus epsilon" thing here is needed when vector
     // antialiasing is turned off -- otherwise stroke adjusted lines

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,13 +11,10 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "SplashTypes.h"
 
 class SplashPath;
+class SplashClip;
 struct SplashXPathPoint;
 struct SplashPathHint;
 
@@ -94,7 +91,8 @@
   // subpaths.
   SplashXPath(SplashPath *path, SplashCoord *matrix,
 	      SplashCoord flatness, GBool closeSubpaths,
-	      GBool simplify, SplashStrokeAdjustMode strokeAdjMode);
+	      GBool simplify, SplashStrokeAdjustMode strokeAdjMode,
+	      SplashClip *clip);
 
   // Copy an expanded path.
   SplashXPath *copy() { return new SplashXPath(this); }
@@ -114,7 +112,8 @@
 		 SplashCoord *xo, SplashCoord *yo);
   GBool strokeAdjust(SplashXPathPoint *pts,
 		     SplashPathHint *hints, int nHints,
-		     SplashStrokeAdjustMode strokeAdjMode);
+		     SplashStrokeAdjustMode strokeAdjMode,
+		     SplashClip *clip);
   void grow(int nSegs);
   void addCurve(SplashCoord x0, SplashCoord y0,
 		SplashCoord x1, SplashCoord y1,

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <string.h>
 #if HAVE_STD_SORT

Modified: trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "SplashTypes.h"
 #include "SplashXPath.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <math.h>
 #include "gmem.h"
@@ -343,8 +339,12 @@
   AcroForm *acroForm;
   AcroFormField *field;
   Object xfaObj, fieldsObj, annotsObj, annotRef, annotObj, obj1, obj2;
+  char *touchedObjs;
   int pageNum, i, j;
 
+  touchedObjs = (char *)gmalloc(docA->getXRef()->getNumObjects());
+  memset(touchedObjs, 0, docA->getXRef()->getNumObjects());
+
   // this is the normal case: acroFormObj is a dictionary, as expected
   if (acroFormObjA->isDict()) {
     acroForm = new AcroForm(docA, acroFormObjA);
@@ -372,11 +372,12 @@
       }
       obj1.free();
       delete acroForm;
+      gfree(touchedObjs);
       return NULL;
     }
     for (i = 0; i < obj1.arrayGetLength(); ++i) {
       obj1.arrayGetNF(i, &obj2);
-      acroForm->scanField(&obj2);
+      acroForm->scanField(&obj2, touchedObjs);
       obj2.free();
     }
     obj1.free();
@@ -400,7 +401,7 @@
 	      annotRef.fetch(acroForm->doc->getXRef(), &annotObj);
 	      if (annotObj.isDict()) {
 		if (annotObj.dictLookup("Subtype", &obj1)->isName("Widget")) {
-		  acroForm->scanField(&annotRef);
+		  acroForm->scanField(&annotRef, touchedObjs);
 		}
 		obj1.free();
 	      }
@@ -431,7 +432,7 @@
 	    annotRef.fetch(acroForm->doc->getXRef(), &annotObj);
 	    if (annotObj.isDict()) {
 	      if (annotObj.dictLookup("Subtype", &obj1)->isName("Widget")) {
-		acroForm->scanField(&annotRef);
+		acroForm->scanField(&annotRef, touchedObjs);
 	      }
 	      obj1.free();
 	    }
@@ -449,6 +450,8 @@
     }
   }
 
+  gfree(touchedObjs);
+
   return acroForm;
 }
 
@@ -512,12 +515,22 @@
   return 0;
 }
 
-void AcroForm::scanField(Object *fieldRef) {
+void AcroForm::scanField(Object *fieldRef, char *touchedObjs) {
   AcroFormField *field;
   Object fieldObj, kidsObj, kidRef, kidObj, subtypeObj;
   GBool isTerminal;
   int i;
 
+  // check for an object loop
+  if (fieldRef->isRef()) {
+    if (fieldRef->getRefNum() < 0 ||
+	fieldRef->getRefNum() >= doc->getXRef()->getNumObjects() ||
+	touchedObjs[fieldRef->getRefNum()]) {
+      return;
+    }
+    touchedObjs[fieldRef->getRefNum()] = 1;
+  }
+
   fieldRef->fetch(doc->getXRef(), &fieldObj);
   if (!fieldObj.isDict()) {
     error(errSyntaxError, -1, "AcroForm field object is wrong type");
@@ -545,7 +558,7 @@
     if (!isTerminal) {
       for (i = 0; !isTerminal && i < kidsObj.arrayGetLength(); ++i) {
 	kidsObj.arrayGetNF(i, &kidRef);
-	scanField(&kidRef);
+	scanField(&kidRef, touchedObjs);
 	kidRef.free();
       }
     }
@@ -2033,7 +2046,6 @@
 
     wMax = dx - 2 * border - 4;
 
-#if 1 //~tmp
     // this is a kludge that appears to match Adobe's behavior
     if (height > 15) {
       topBorder = 5;
@@ -2040,14 +2052,12 @@
     } else {
       topBorder = 2;
     }
-#else
-    topBorder = 5;
-#endif
 
     // compute font autosize
     if (fontSize == 0) {
       for (fontSize = 10; fontSize > 1; --fontSize) {
 	yy = dy - topBorder;
+	w = 0;
 	i = 0;
 	while (i < text2->getLength()) {
 	  getNextLine(text2, i, font, fontSize, wMax, &j, &w, &k);
@@ -3183,7 +3193,7 @@
     return gFalse;
   }
   for (int i = 0; i < unicodeLength; ++i) {
-    if ((s->getChar(i) & 0xff) != u[i]) {
+    if ((Unicode)(s->getChar(i) & 0xff) != u[i]) {
       return gFalse;
     }
   }
@@ -3193,7 +3203,7 @@
 GBool AcroFormField::unicodeStringEqual(Unicode *u, int unicodeLength,
 					const char *s) {
   for (int i = 0; i < unicodeLength; ++i) {
-    if (!s[i] || (s[i] & 0xff) != u[i]) {
+    if (!s[i] || (Unicode)(s[i] & 0xff) != u[i]) {
       return gFalse;
     }
   }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 class TextString;
 class Gfx;
 class GfxFont;
@@ -47,7 +43,7 @@
   AcroForm(PDFDoc *docA, Object *acroFormObjA);
   void buildAnnotPageList(Catalog *catalog);
   int lookupAnnotPage(Object *annotRef);
-  void scanField(Object *fieldRef);
+  void scanField(Object *fieldRef, char *touchedObjs);
 
   PDFDoc *doc;
   Object acroFormObj;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -2,18 +2,15 @@
 //
 // Annot.cc
 //
-// Copyright 2000-2003 Glyph & Cog, LLC
+// Copyright 2000-2022 Glyph & Cog, LLC
 //
 //========================================================================
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <math.h>
+#include <limits.h>
 #include "gmem.h"
 #include "gmempp.h"
 #include "GList.h"
@@ -278,6 +275,8 @@
       obj3.free();
     } else if (obj2.isRef()) {
       obj2.copy(&appearance);
+    } else if (obj2.isStream()) {
+      obj2.copy(&appearance);
     }
     obj1.free();
     obj2.free();
@@ -306,29 +305,48 @@
   ocObj.free();
 }
 
-void Annot::generateAnnotAppearance() {
+void Annot::generateAnnotAppearance(Object *annotObj) {
   Object obj;
-
   appearance.fetch(doc->getXRef(), &obj);
-  if (!obj.isStream()) {
-    if (type) {
-      if (!type->cmp("Line")) {
-	generateLineAppearance();
-      } else if (!type->cmp("PolyLine")) {
-	generatePolyLineAppearance();
-      } else if (!type->cmp("Polygon")) {
-	generatePolygonAppearance();
-      } else if (!type->cmp("FreeText")) {
-	generateFreeTextAppearance();
-      }
-    }
+  GBool alreadyHaveAppearance = obj.isStream();
+  obj.free();
+  if (alreadyHaveAppearance) {
+    return;
   }
-  obj.free();
+
+  if (!type || (type->cmp("Line") &&
+		type->cmp("PolyLine") &&
+		type->cmp("Polygon") &&
+		type->cmp("FreeText"))) {
+    return;
+  }
+
+  Object annotObj2;
+  if (!annotObj) {
+    getObject(&annotObj2);
+    annotObj = &annotObj2;
+  }
+  if (!annotObj->isDict()) {
+    annotObj2.free();
+    return;
+  }
+
+  if (!type->cmp("Line")) {
+    generateLineAppearance(annotObj);
+  } else if (!type->cmp("PolyLine")) {
+    generatePolyLineAppearance(annotObj);
+  } else if (!type->cmp("Polygon")) {
+    generatePolygonAppearance(annotObj);
+  } else if (!type->cmp("FreeText")) {
+    generateFreeTextAppearance(annotObj);
+  }
+
+  annotObj2.free();
 }
 
 //~ this doesn't draw the caption
-void Annot::generateLineAppearance() {
-  Object annotObj, gfxStateDict, appearDict, obj1, obj2;
+void Annot::generateLineAppearance(Object *annotObj) {
+  Object gfxStateDict, appearDict, obj1, obj2;
   MemStream *appearStream;
   double x1, y1, x2, y2, dx, dy, len, w;
   double lx1, ly1, lx2, ly2;
@@ -339,15 +357,10 @@
   AnnotLineEndType lineEnd1, lineEnd2;
   GBool fill;
 
-  if (!getObject(&annotObj)->isDict()) {
-    annotObj.free();
-    return;
-  }
-
   appearBuf = new GString();
 
   //----- check for transparency
-  if (annotObj.dictLookup("CA", &obj1)->isNum()) {
+  if (annotObj->dictLookup("CA", &obj1)->isNum()) {
     gfxStateDict.initDict(doc->getXRef());
     gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2));
     appearBuf->append("/GS1 gs\n");
@@ -358,7 +371,7 @@
   setLineStyle(borderStyle, &w);
   setStrokeColor(borderStyle->getColor(), borderStyle->getNumColorComps());
   fill = gFalse;
-  if (annotObj.dictLookup("IC", &obj1)->isArray()) {
+  if (annotObj->dictLookup("IC", &obj1)->isArray()) {
     if (setFillColor(&obj1)) {
       fill = gTrue;
     }
@@ -366,7 +379,7 @@
   obj1.free();
 
   //----- get line properties
-  if (annotObj.dictLookup("L", &obj1)->isArray() &&
+  if (annotObj->dictLookup("L", &obj1)->isArray() &&
       obj1.arrayGetLength() == 4) {
     if (obj1.arrayGet(0, &obj2)->isNum()) {
       x1 = obj2.getNum();
@@ -373,7 +386,7 @@
     } else {
       obj2.free();
       obj1.free();
-      goto err1;
+      return;
     }
     obj2.free();
     if (obj1.arrayGet(1, &obj2)->isNum()) {
@@ -381,7 +394,7 @@
     } else {
       obj2.free();
       obj1.free();
-      goto err1;
+      return;
     }
     obj2.free();
     if (obj1.arrayGet(2, &obj2)->isNum()) {
@@ -389,7 +402,7 @@
     } else {
       obj2.free();
       obj1.free();
-      goto err1;
+      return;
     }
     obj2.free();
     if (obj1.arrayGet(3, &obj2)->isNum()) {
@@ -397,16 +410,16 @@
     } else {
       obj2.free();
       obj1.free();
-      goto err1;
+      return;
     }
     obj2.free();
   } else {
     obj1.free();
-    goto err1;
+    return;
   }
   obj1.free();
   lineEnd1 = lineEnd2 = annotLineEndNone;
-  if (annotObj.dictLookup("LE", &obj1)->isArray() &&
+  if (annotObj->dictLookup("LE", &obj1)->isArray() &&
       obj1.arrayGetLength() == 2) {
     lineEnd1 = parseLineEndType(obj1.arrayGet(0, &obj2));
     obj2.free();
@@ -414,19 +427,19 @@
     obj2.free();
   }
   obj1.free();
-  if (annotObj.dictLookup("LL", &obj1)->isNum()) {
+  if (annotObj->dictLookup("LL", &obj1)->isNum()) {
     leaderLen = obj1.getNum();
   } else {
     leaderLen = 0;
   }
   obj1.free();
-  if (annotObj.dictLookup("LLE", &obj1)->isNum()) {
+  if (annotObj->dictLookup("LLE", &obj1)->isNum()) {
     leaderExtLen = obj1.getNum();
   } else {
     leaderExtLen = 0;
   }
   obj1.free();
-  if (annotObj.dictLookup("LLO", &obj1)->isNum()) {
+  if (annotObj->dictLookup("LLO", &obj1)->isNum()) {
     leaderOffLen = obj1.getNum();
   } else {
     leaderOffLen = 0;
@@ -513,27 +526,19 @@
 			       appearBuf->getLength(), &appearDict);
   appearance.free();
   appearance.initStream(appearStream);
-
- err1:
-  annotObj.free();
 }
 
 //~ this doesn't handle line ends (arrows)
-void Annot::generatePolyLineAppearance() {
-  Object annotObj, gfxStateDict, appearDict, obj1, obj2;
+void Annot::generatePolyLineAppearance(Object *annotObj) {
+  Object gfxStateDict, appearDict, obj1, obj2;
   MemStream *appearStream;
   double x1, y1, w;
   int i;
 
-  if (!getObject(&annotObj)->isDict()) {
-    annotObj.free();
-    return;
-  }
-
   appearBuf = new GString();
 
   //----- check for transparency
-  if (annotObj.dictLookup("CA", &obj1)->isNum()) {
+  if (annotObj->dictLookup("CA", &obj1)->isNum()) {
     gfxStateDict.initDict(doc->getXRef());
     gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2));
     appearBuf->append("/GS1 gs\n");
@@ -544,7 +549,7 @@
   setLineStyle(borderStyle, &w);
   setStrokeColor(borderStyle->getColor(), borderStyle->getNumColorComps());
   // fill = gFalse;
-  // if (annotObj.dictLookup("IC", &obj1)->isArray()) {
+  // if (annotObj->dictLookup("IC", &obj1)->isArray()) {
   //   if (setFillColor(&obj1)) {
   //     fill = gTrue;
   //   }
@@ -552,15 +557,15 @@
   // obj1.free();
 
   //----- draw line
-  if (!annotObj.dictLookup("Vertices", &obj1)->isArray()) {
+  if (!annotObj->dictLookup("Vertices", &obj1)->isArray()) {
     obj1.free();
-    goto err1;
+    return;
   }
   for (i = 0; i+1 < obj1.arrayGetLength(); i += 2) {
     if (!obj1.arrayGet(i, &obj2)->isNum()) {
       obj2.free();
       obj1.free();
-      goto err1;
+      return;
     }
     x1 = obj2.getNum();
     obj2.free();
@@ -567,7 +572,7 @@
     if (!obj1.arrayGet(i+1, &obj2)->isNum()) {
       obj2.free();
       obj1.free();
-      goto err1;
+      return;
     }
     y1 = obj2.getNum();
     obj2.free();
@@ -606,26 +611,18 @@
 			       appearBuf->getLength(), &appearDict);
   appearance.free();
   appearance.initStream(appearStream);
-
- err1:
-  annotObj.free();
 }
 
-void Annot::generatePolygonAppearance() {
-  Object annotObj, gfxStateDict, appearDict, obj1, obj2;
+void Annot::generatePolygonAppearance(Object *annotObj) {
+  Object gfxStateDict, appearDict, obj1, obj2;
   MemStream *appearStream;
   double x1, y1;
   int i;
 
-  if (!getObject(&annotObj)->isDict()) {
-    annotObj.free();
-    return;
-  }
-
   appearBuf = new GString();
 
   //----- check for transparency
-  if (annotObj.dictLookup("CA", &obj1)->isNum()) {
+  if (annotObj->dictLookup("CA", &obj1)->isNum()) {
     gfxStateDict.initDict(doc->getXRef());
     gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2));
     appearBuf->append("/GS1 gs\n");
@@ -633,23 +630,23 @@
   obj1.free();
 
   //----- set fill color
-  if (!annotObj.dictLookup("IC", &obj1)->isArray()  ||
+  if (!annotObj->dictLookup("IC", &obj1)->isArray()  ||
       !setFillColor(&obj1)) {
     obj1.free();
-    goto err1;
+    return;
   }
   obj1.free();
 
   //----- fill polygon
-  if (!annotObj.dictLookup("Vertices", &obj1)->isArray()) {
+  if (!annotObj->dictLookup("Vertices", &obj1)->isArray()) {
     obj1.free();
-    goto err1;
+    return;
   }
   for (i = 0; i+1 < obj1.arrayGetLength(); i += 2) {
     if (!obj1.arrayGet(i, &obj2)->isNum()) {
       obj2.free();
       obj1.free();
-      goto err1;
+      return;
     }
     x1 = obj2.getNum();
     obj2.free();
@@ -656,7 +653,7 @@
     if (!obj1.arrayGet(i+1, &obj2)->isNum()) {
       obj2.free();
       obj1.free();
-      goto err1;
+      return;
     }
     y1 = obj2.getNum();
     obj2.free();
@@ -695,16 +692,13 @@
 			       appearBuf->getLength(), &appearDict);
   appearance.free();
   appearance.initStream(appearStream);
-
- err1:
-  annotObj.free();
 }
 
 //~ this doesn't handle rich text
 //~ this doesn't handle the callout
 //~ this doesn't handle the RD field
-void Annot::generateFreeTextAppearance() {
-  Object annotObj, gfxStateDict, appearDict, obj1, obj2;
+void Annot::generateFreeTextAppearance(Object *annotObj) {
+  Object gfxStateDict, appearDict, obj1, obj2;
   Object resources, gsResources, fontResources, defaultFont;
   GString *text, *da;
   double lineWidth;
@@ -711,15 +705,10 @@
   int quadding, rot;
   MemStream *appearStream;
 
-  if (!getObject(&annotObj)->isDict()) {
-    annotObj.free();
-    return;
-  }
-
   appearBuf = new GString();
 
   //----- check for transparency
-  if (annotObj.dictLookup("CA", &obj1)->isNum()) {
+  if (annotObj->dictLookup("CA", &obj1)->isNum()) {
     gfxStateDict.initDict(doc->getXRef());
     gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2));
     appearBuf->append("/GS1 gs\n");
@@ -727,19 +716,19 @@
   obj1.free();
 
   //----- draw the text
-  if (annotObj.dictLookup("Contents", &obj1)->isString()) {
+  if (annotObj->dictLookup("Contents", &obj1)->isString()) {
     text = obj1.getString()->copy();
   } else {
     text = new GString();
   }
   obj1.free();
-  if (annotObj.dictLookup("Q", &obj1)->isInt()) {
+  if (annotObj->dictLookup("Q", &obj1)->isInt()) {
     quadding = obj1.getInt();
   } else {
     quadding = 0;
   }
   obj1.free();
-  if (annotObj.dictLookup("DA", &obj1)->isString()) {
+  if (annotObj->dictLookup("DA", &obj1)->isString()) {
     da = obj1.getString()->copy();
   } else {
     da = new GString();
@@ -747,7 +736,7 @@
   obj1.free();
   // the "Rotate" field is not defined in the PDF spec, but Acrobat
   // looks at it
-  if (annotObj.dictLookup("Rotate", &obj1)->isInt()) {
+  if (annotObj->dictLookup("Rotate", &obj1)->isInt()) {
     rot = obj1.getInt();
   } else {
     rot = 0;
@@ -797,8 +786,6 @@
 			       appearBuf->getLength(), &appearDict);
   appearance.free();
   appearance.initStream(appearStream);
-
-  annotObj.free();
 }
 
 void Annot::setLineStyle(AnnotBorderStyle *bs, double *lineWidth) {
@@ -1344,84 +1331,164 @@
 }
 
 //------------------------------------------------------------------------
+// PageAnnots
+//------------------------------------------------------------------------
+
+class PageAnnots {
+public:
+
+  PageAnnots();
+  ~PageAnnots();
+
+  GList *annots;		// list of annots on the page [Annot]
+  GBool appearancesGenerated;	// set after appearances have been generated
+};
+
+PageAnnots::PageAnnots() {
+  annots = new GList();
+  appearancesGenerated = gFalse;
+}
+
+PageAnnots::~PageAnnots() {
+  deleteGList(annots, Annot);
+}
+
+//------------------------------------------------------------------------
 // Annots
 //------------------------------------------------------------------------
 
-Annots::Annots(PDFDoc *docA, Object *annotsObj) {
-  Annot *annot;
-  Object obj1, obj2;
-  Ref ref;
-  GBool drawWidgetAnnots;
-  int size;
-  int i;
-
+Annots::Annots(PDFDoc *docA) {
   doc = docA;
-  annots = NULL;
-  size = 0;
-  nAnnots = 0;
+  pageAnnots = (PageAnnots **)gmallocn(doc->getNumPages(), sizeof(PageAnnots*));
+  for (int page = 1; page <= doc->getNumPages(); ++page) {
+    pageAnnots[page - 1] = NULL;
+  }
+  formFieldRefsSize = 0;
+  formFieldRefs = NULL;
+}
 
-  if (annotsObj->isArray()) {
-    // Kludge: some PDF files define an empty AcroForm, but still
-    // include Widget-type annotations -- in that case, we want to
-    // draw the widgets (since the form code won't).  This really
-    // ought to look for Widget-type annotations that are not included
-    // in any form field.
-    drawWidgetAnnots = !doc->getCatalog()->getForm() ||
-                       doc->getCatalog()->getForm()->getNumFields() == 0;
-    for (i = 0; i < annotsObj->arrayGetLength(); ++i) {
-      if (annotsObj->arrayGetNF(i, &obj1)->isRef()) {
-	ref = obj1.getRef();
-	obj1.free();
-	annotsObj->arrayGet(i, &obj1);
-      } else {
-	ref.num = ref.gen = -1;
+Annots::~Annots() {
+  for (int page = 1; page <= doc->getNumPages(); ++page) {
+    delete pageAnnots[page - 1];
+  }
+  gfree(pageAnnots);
+  gfree(formFieldRefs);
+}
+
+void Annots::loadAnnots(int page) {
+  if (pageAnnots[page - 1]) {
+    return;
+  }
+
+  pageAnnots[page - 1] = new PageAnnots();
+
+  Object annotsObj;
+  doc->getCatalog()->getPage(page)->getAnnots(&annotsObj);
+  if (!annotsObj.isArray()) {
+    annotsObj.free();
+    return;
+  }
+
+  loadFormFieldRefs();
+
+  for (int i = 0; i < annotsObj.arrayGetLength(); ++i) {
+    Object annotObj;
+    Ref annotRef;
+    if (annotsObj.arrayGetNF(i, &annotObj)->isRef()) {
+      annotRef = annotObj.getRef();
+      annotObj.free();
+      annotsObj.arrayGet(i, &annotObj);
+    } else {
+      annotRef.num = annotRef.gen = -1;
+    }
+    if (!annotObj.isDict()) {
+      annotObj.free();
+      continue;
+    }
+
+    // skip any annotations which are used as AcroForm fields --
+    // they'll be rendered by the AcroForm module
+    if (annotRef.num >= 0 && annotRef.num < formFieldRefsSize &&
+	formFieldRefs[annotRef.num]) {
+      annotObj.free();
+      continue;
+    }
+
+    Annot *annot = new Annot(doc, annotObj.getDict(), &annotRef);
+    annotObj.free();
+    if (annot->isOk()) {
+      pageAnnots[page - 1]->annots->append(annot);
+    } else {
+      delete annot;
+    }
+  }
+
+  annotsObj.free();
+}
+
+// Build a set of object refs for AcroForm fields.
+void Annots::loadFormFieldRefs() {
+  if (formFieldRefs) {
+    return;
+  }
+
+  AcroForm *form = doc->getCatalog()->getForm();
+  if (!form) {
+    return;
+  }
+
+  int newFormFieldRefsSize = 256;
+  for (int i = 0; i < form->getNumFields(); ++i) {
+    AcroFormField *field = form->getField(i);
+    Object fieldRef;
+    field->getFieldRef(&fieldRef);
+    if (fieldRef.getRefNum() >= formFieldRefsSize) {
+      while (fieldRef.getRefNum() >= newFormFieldRefsSize &&
+	     newFormFieldRefsSize <= INT_MAX / 2) {
+	newFormFieldRefsSize *= 2;
       }
-      if (obj1.isDict()) {
-	if (drawWidgetAnnots ||
-	    !obj1.dictLookup("Subtype", &obj2)->isName("Widget")) {
-	  annot = new Annot(doc, obj1.getDict(), &ref);
-	  if (annot->isOk()) {
-	    if (nAnnots >= size) {
-	      size += 16;
-	      annots = (Annot **)greallocn(annots, size, sizeof(Annot *));
-	    }
-	    annots[nAnnots++] = annot;
-	  } else {
-	    delete annot;
-	  }
-	}
-	obj2.free();
+      if (fieldRef.getRefNum() >= newFormFieldRefsSize) {
+	continue;
       }
-      obj1.free();
+      formFieldRefs = (char *)grealloc(formFieldRefs, newFormFieldRefsSize);
+      for (int j = formFieldRefsSize; j < newFormFieldRefsSize; ++j) {
+	formFieldRefs[j] = (char)0;
+      }
+      formFieldRefsSize = newFormFieldRefsSize;
     }
+    formFieldRefs[fieldRef.getRefNum()] = (char)1;
+    fieldRef.free();
   }
 }
 
-Annots::~Annots() {
-  int i;
+int Annots::getNumAnnots(int page) {
+  loadAnnots(page);
+  return pageAnnots[page - 1]->annots->getLength();
+}
 
-  for (i = 0; i < nAnnots; ++i) {
-    delete annots[i];
-  }
-  gfree(annots);
+Annot *Annots::getAnnot(int page, int idx) {
+  loadAnnots(page);
+  return (Annot *)pageAnnots[page - 1]->annots->get(idx);
 }
 
-Annot *Annots::find(double x, double y) {
-  int i;
-
-  for (i = nAnnots - 1; i >= 0; --i) {
-    if (annots[i]->inRect(x, y)) {
-      return annots[i];
+Annot *Annots::find(int page, double x, double y) {
+  loadAnnots(page);
+  PageAnnots *pa = pageAnnots[page - 1];
+  for (int i = pa->annots->getLength() - 1; i >= 0; --i) {
+    Annot *annot = (Annot *)pa->annots->get(i);
+    if (annot->inRect(x, y)) {
+      return annot;
     }
   }
   return NULL;
 }
 
-int Annots::findIdx(double x, double y) {
-  int i;
-
-  for (i = nAnnots - 1; i >= 0; --i) {
-    if (annots[i]->inRect(x, y)) {
+int Annots::findIdx(int page, double x, double y) {
+  loadAnnots(page);
+  PageAnnots *pa = pageAnnots[page - 1];
+  for (int i = pa->annots->getLength() - 1; i >= 0; --i) {
+    Annot *annot = (Annot *)pa->annots->get(i);
+    if (annot->inRect(x, y)) {
       return i;
     }
   }
@@ -1428,21 +1495,28 @@
   return -1;
 }
 
-void Annots::generateAnnotAppearances() {
-  int i;
-
-  for (i = 0; i < nAnnots; ++i) {
-    annots[i]->generateAnnotAppearance();
+void Annots::add(int page, Object *annotObj) {
+  if (!annotObj->isDict()) {
+    return;
   }
+  Ref annotRef = {-1, -1};
+  Annot *annot = new Annot(doc, annotObj->getDict(), &annotRef);
+  if (annot->isOk()) {
+    annot->generateAnnotAppearance(annotObj);
+    pageAnnots[page - 1]->annots->append(annot);
+  } else {
+    delete annot;
+  }
 }
 
-Annot *Annots::findAnnot(Ref *ref) {
-  int i;
-
-  for (i = 0; i < nAnnots; ++i) {
-    if (annots[i]->match(ref)) {
-      return annots[i];
+void Annots::generateAnnotAppearances(int page) {
+  loadAnnots(page);
+  PageAnnots *pa = pageAnnots[page - 1];
+  if (!pa->appearancesGenerated) {
+    for (int i = 0; i < pa->annots->getLength(); ++i) {
+      Annot *annot = (Annot *)pa->annots->get(i);
+      annot->generateAnnotAppearance(NULL);
     }
+    pa->appearancesGenerated = gTrue;
   }
-  return NULL;
 }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -2,7 +2,7 @@
 //
 // Annot.h
 //
-// Copyright 2000-2003 Glyph & Cog, LLC
+// Copyright 2000-2022 Glyph & Cog, LLC
 //
 //========================================================================
 
@@ -11,15 +11,12 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 class XRef;
 class Catalog;
 class Gfx;
 class GfxFontDict;
 class PDFDoc;
+class PageAnnots;
 
 //------------------------------------------------------------------------
 // AnnotBorderStyle
@@ -105,14 +102,14 @@
   GBool match(Ref *refA)
     { return ref.num == refA->num && ref.gen == refA->gen; }
 
-  void generateAnnotAppearance();
+  void generateAnnotAppearance(Object *annotObj);
 
 private:
  
-  void generateLineAppearance();
-  void generatePolyLineAppearance();
-  void generatePolygonAppearance();
-  void generateFreeTextAppearance();
+  void generateLineAppearance(Object *annotObj);
+  void generatePolyLineAppearance(Object *annotObj);
+  void generatePolygonAppearance(Object *annotObj);
+  void generateFreeTextAppearance(Object *annotObj);
   void setLineStyle(AnnotBorderStyle *bs, double *lineWidth);
   void setStrokeColor(double *color, int nComps);
   GBool setFillColor(Object *colorObj);
@@ -152,34 +149,35 @@
 class Annots {
 public:
 
-  // Build a list of Annot objects.
-  Annots(PDFDoc *docA, Object *annotsObj);
+  Annots(PDFDoc *docA);
 
   ~Annots();
 
-  // Iterate through list of annotations.
-  int getNumAnnots() { return nAnnots; }
-  Annot *getAnnot(int i) { return annots[i]; }
+  // Iterate over annotations on a specific page.
+  int getNumAnnots(int page);
+  Annot *getAnnot(int page, int idx);
 
-  // If point <x>,<y> is in an annotation, return the associated
-  // annotation; else return NULL.
-  Annot *find(double x, double y);
-  int findIdx(double x, double y);
+  // If point (<x>,<y>) is in an annotation, return the associated
+  // annotation (or annotation index); else return NULL (or -1).
+  Annot *find(int page, double x, double y);
+  int findIdx(int page, double x, double y);
 
+  // Add an annotation [annotObj] on page [page].
+  void add(int page, Object *annotObj);
+
   // Generate an appearance stream for any non-form-field annotation
-  // that is missing it.
-  void generateAnnotAppearances();
+  // on the specified page that is missing an appearance.
+  void generateAnnotAppearances(int page);
 
 private:
 
-  void scanFieldAppearances(Dict *node, Ref *ref, Dict *parent,
-			    Dict *acroForm);
+  void loadAnnots(int page);
+  void loadFormFieldRefs();
 
-  Annot *findAnnot(Ref *ref);
-
   PDFDoc *doc;
-  Annot **annots;
-  int nAnnots;
+  PageAnnots **pageAnnots;	// list of annots for each page
+  int formFieldRefsSize;	// number of entries in formFieldRefs[]
+  char *formFieldRefs;		// set of AcroForm field refs
 };
 
 #endif

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <stddef.h>
 #include "gmem.h"
@@ -53,7 +49,7 @@
 
 Object *Array::get(int i, Object *obj, int recursion) {
   if (i < 0 || i >= length) {
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
     abort();
 #else
     return obj->initNull();
@@ -64,7 +60,7 @@
 
 Object *Array::getNF(int i, Object *obj) {
   if (i < 0 || i >= length) {
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
     abort();
 #else
     return obj->initNull();

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Array.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Array.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Array.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #if MULTITHREADED
 #include "GMutex.h"
 #endif

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <string.h>
 #include "gmem.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 
 struct BuiltinFont;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "CharTypes.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <string.h>
 #include <stddef.h>
 #include <limits.h>
@@ -526,7 +522,10 @@
       //    because other code tries to fetch pages 1 through n.
       // In both cases: ignore the given page count and scan the tree
       // instead.
-      numPages = countPageTree(&topPagesObj);
+      char *touchedObjs = (char *)gmalloc(xref->getNumObjects());
+      memset(touchedObjs, 0, xref->getNumObjects());
+      numPages = countPageTree(&topPagesRef, touchedObjs);
+      gfree(touchedObjs);
     }
   } else {
     // assume we got a Page node instead of a Pages node
@@ -553,30 +552,53 @@
   return gTrue;
 }
 
-int Catalog::countPageTree(Object *pagesObj) {
-  Object kids, kid;
-  int n, n2, i;
-
-  if (!pagesObj->isDict()) {
+int Catalog::countPageTree(Object *pagesNodeRef, char *touchedObjs) {
+  // check for invalid reference
+  if (pagesNodeRef->isRef() &&
+      (pagesNodeRef->getRefNum() < 0 ||
+       pagesNodeRef->getRefNum() >= xref->getNumObjects())) {
     return 0;
   }
-  if (pagesObj->dictLookup("Kids", &kids)->isArray()) {
-    n = 0;
-    for (i = 0; i < kids.arrayGetLength(); ++i) {
-      kids.arrayGet(i, &kid);
-      n2 = countPageTree(&kid);
-      if (n2 < INT_MAX - n) {
-	n += n2;
-      } else {
-	error(errSyntaxError, -1, "Page tree contains too many pages");
-	n = INT_MAX;
-      }
-      kid.free();
+
+  // check for a page tree loop; fetch the node object
+  Object pagesNode;
+  if (pagesNodeRef->isRef()) {
+    if (touchedObjs[pagesNodeRef->getRefNum()]) {
+      error(errSyntaxError, -1, "Loop in Pages tree");
+      return 0;
     }
+    touchedObjs[pagesNodeRef->getRefNum()] = 1;
+    xref->fetch(pagesNodeRef->getRefNum(), pagesNodeRef->getRefGen(),
+		&pagesNode);
   } else {
-    n = 1;
+    pagesNodeRef->copy(&pagesNode);
   }
-  kids.free();
+
+  // count the subtree
+  int n = 0;
+  if (pagesNode.isDict()) {
+    Object kids;
+    if (pagesNode.dictLookup("Kids", &kids)->isArray()) {
+      for (int i = 0; i < kids.arrayGetLength(); ++i) {
+	Object kid;
+	kids.arrayGetNF(i, &kid);
+	int n2 = countPageTree(&kid, touchedObjs);
+	if (n2 < INT_MAX - n) {
+	  n += n2;
+	} else {
+	  error(errSyntaxError, -1, "Page tree contains too many pages");
+	  n = INT_MAX;
+	}
+	kid.free();
+      }
+    } else {
+      n = 1;
+    }
+    kids.free();
+  }
+
+  pagesNode.free();
+
   return n;
 }
 
@@ -738,37 +760,55 @@
   Object obj1, obj2;
   char *touchedObjs;
 
+  touchedObjs = (char *)gmalloc(xref->getNumObjects());
+  memset(touchedObjs, 0, xref->getNumObjects());
+
   // read the embedded file name tree
   if (catDict->lookup("Names", &obj1)->isDict()) {
-    if (obj1.dictLookup("EmbeddedFiles", &obj2)->isDict()) {
-      readEmbeddedFileTree(&obj2);
-    }
+    obj1.dictLookupNF("EmbeddedFiles", &obj2);
+    readEmbeddedFileTree(&obj2, touchedObjs);
     obj2.free();
   }
   obj1.free();
 
   // look for file attachment annotations
-  touchedObjs = (char *)gmalloc(xref->getNumObjects());
-  memset(touchedObjs, 0, xref->getNumObjects());
   readFileAttachmentAnnots(catDict->lookupNF("Pages", &obj1), touchedObjs);
   obj1.free();
+
   gfree(touchedObjs);
 }
 
-void Catalog::readEmbeddedFileTree(Object *node) {
-  Object kidsObj, kidObj;
+void Catalog::readEmbeddedFileTree(Object *nodeRef, char *touchedObjs) {
+  Object node, kidsObj, kidObj;
   Object namesObj, nameObj, fileSpecObj;
   int i;
 
-  if (node->dictLookup("Kids", &kidsObj)->isArray()) {
+  // check for an object loop
+  if (nodeRef->isRef()) {
+    if (nodeRef->getRefNum() < 0 ||
+	nodeRef->getRefNum() >= xref->getNumObjects() ||
+	touchedObjs[nodeRef->getRefNum()]) {
+      return;
+    }
+    touchedObjs[nodeRef->getRefNum()] = 1;
+    xref->fetch(nodeRef->getRefNum(), nodeRef->getRefGen(), &node);
+  } else {
+    nodeRef->copy(&node);
+  }
+
+  if (!node.isDict()) {
+    node.free();
+    return;
+  }
+
+  if (node.dictLookup("Kids", &kidsObj)->isArray()) {
     for (i = 0; i < kidsObj.arrayGetLength(); ++i) {
-      if (kidsObj.arrayGet(i, &kidObj)->isDict()) {
-	readEmbeddedFileTree(&kidObj);
-      }
+      kidsObj.arrayGetNF(i, &kidObj);
+      readEmbeddedFileTree(&kidObj, touchedObjs);
       kidObj.free();
     }
   } else {
-    if (node->dictLookup("Names", &namesObj)->isArray()) {
+    if (node.dictLookup("Names", &namesObj)->isArray()) {
       for (i = 0; i+1 < namesObj.arrayGetLength(); ++i) {
 	namesObj.arrayGet(i, &nameObj);
 	namesObj.arrayGet(i+1, &fileSpecObj);
@@ -780,6 +820,8 @@
     namesObj.free();
   }
   kidsObj.free();
+
+  node.free();
 }
 
 void Catalog::readFileAttachmentAnnots(Object *pageNodeRef,
@@ -788,8 +830,9 @@
   int i;
 
   // check for an invalid object reference (e.g., in a damaged PDF file)
-  if (pageNodeRef->getRefNum() < 0 ||
-      pageNodeRef->getRefNum() >= xref->getNumObjects()) {
+  if (pageNodeRef->isRef() &&
+      (pageNodeRef->getRefNum() < 0 ||
+       pageNodeRef->getRefNum() >= xref->getNumObjects())) {
     return;
   }
 
@@ -901,10 +944,14 @@
 
 void Catalog::readPageLabelTree(Object *root) {
   PageLabelNode *label0, *label1;
+  char *touchedObjs;
   int i;
 
+  touchedObjs = (char *)gmalloc(xref->getNumObjects());
+  memset(touchedObjs, 0, xref->getNumObjects());
   pageLabels = new GList();
-  readPageLabelTree2(root);
+  readPageLabelTree2(root, touchedObjs);
+  gfree(touchedObjs);
 
   if (pageLabels->getLength() == 0) {
     deleteGList(pageLabels, PageLabelNode);
@@ -922,15 +969,29 @@
   label0->lastPage = numPages;
 }
 
-void Catalog::readPageLabelTree2(Object *node) {
-  Object nums, num, labelObj, kids, kid;
+void Catalog::readPageLabelTree2(Object *nodeRef, char *touchedObjs) {
+  Object node, nums, num, labelObj, kids, kid;
   int i;
 
-  if (!node->isDict()) {
+  // check for an object loop
+  if (nodeRef->isRef()) {
+    if (nodeRef->getRefNum() < 0 ||
+	nodeRef->getRefNum() >= xref->getNumObjects() ||
+	touchedObjs[nodeRef->getRefNum()]) {
+      return;
+    }
+    touchedObjs[nodeRef->getRefNum()] = 1;
+    xref->fetch(nodeRef->getRefNum(), nodeRef->getRefGen(), &node);
+  } else {
+    nodeRef->copy(&node);
+  }
+
+  if (!node.isDict()) {
+    node.free();
     return;
   }
 
-  if (node->dictLookup("Nums", &nums)->isArray()) {
+  if (node.dictLookup("Nums", &nums)->isArray()) {
     for (i = 0; i < nums.arrayGetLength() - 1; i += 2) {
       if (nums.arrayGet(i, &num)->isInt()) {
 	if (nums.arrayGet(i+1, &labelObj)->isDict()) {
@@ -944,14 +1005,16 @@
   }
   nums.free();
 
-  if (node->dictLookup("Kids", &kids)->isArray()) {
+  if (node.dictLookup("Kids", &kids)->isArray()) {
     for (i = 0; i < kids.arrayGetLength(); ++i) {
-      kids.arrayGet(i, &kid);
-      readPageLabelTree2(&kid);
+      kids.arrayGetNF(i, &kid);
+      readPageLabelTree2(&kid, touchedObjs);
       kid.free();
     }
   }
   kids.free();
+
+  node.free();
 }
 
 TextString *Catalog::getPageLabel(int pageNum) {
@@ -1195,3 +1258,130 @@
   }
   return gFalse;
 }
+
+GBool Catalog::usesJavaScript() {
+  Object catDict;
+  if (!xref->getCatalog(&catDict)->isDict()) {
+    catDict.free();
+    return gFalse;
+  }
+
+  GBool usesJS = gFalse;
+
+  // check for Catalog.Names.JavaScript
+  Object namesObj;
+  if (catDict.dictLookup("Names", &namesObj)->isDict()) {
+    Object jsNamesObj;
+    namesObj.dictLookup("JavaScript", &jsNamesObj);
+    if (jsNamesObj.isDict()) {
+      usesJS = gTrue;
+    }
+    jsNamesObj.free();
+  }
+  namesObj.free();
+
+  // look for JavaScript actionas in Page.AA
+  if (!usesJS) {
+    char *touchedObjs = (char *)gmalloc(xref->getNumObjects());
+    memset(touchedObjs, 0, xref->getNumObjects());
+    Object pagesObj;
+    usesJS = scanPageTreeForJavaScript(catDict.dictLookupNF("Pages", &pagesObj),
+				       touchedObjs);
+    pagesObj.free();
+    gfree(touchedObjs);
+  }
+
+  catDict.free();
+
+  return usesJS;
+}
+
+GBool Catalog::scanPageTreeForJavaScript(Object *pageNodeRef,
+					 char *touchedObjs) {
+  // check for an invalid object reference (e.g., in a damaged PDF file)
+  if (pageNodeRef->isRef() &&
+      (pageNodeRef->getRefNum() < 0 ||
+       pageNodeRef->getRefNum() >= xref->getNumObjects())) {
+    return gFalse;
+  }
+
+  // check for a page tree loop
+  Object pageNode;
+  if (pageNodeRef->isRef()) {
+    if (touchedObjs[pageNodeRef->getRefNum()]) {
+      return gFalse;
+    }
+    touchedObjs[pageNodeRef->getRefNum()] = 1;
+    xref->fetch(pageNodeRef->getRefNum(), pageNodeRef->getRefGen(), &pageNode);
+  } else {
+    pageNodeRef->copy(&pageNode);
+  }
+
+  // scan the page tree node
+  GBool usesJS = gFalse;
+  if (pageNode.isDict()) {
+    Object kids;
+    if (pageNode.dictLookup("Kids", &kids)->isArray()) {
+      for (int i = 0; i < kids.arrayGetLength() && !usesJS; ++i) {
+	Object kid;
+	if (scanPageTreeForJavaScript(kids.arrayGetNF(i, &kid), touchedObjs)) {
+	  usesJS = gTrue;
+	}
+	kid.free();
+      }
+    } else {
+
+      // scan Page.AA
+      Object pageAA;
+      if (pageNode.dictLookup("AA", &pageAA)->isDict()) {
+	if (scanAAForJavaScript(&pageAA)) {
+	  usesJS = gTrue;
+	}
+      }
+      pageAA.free();
+
+      // scanPage.Annots
+      if (!usesJS) {
+	Object annots;
+	if (pageNode.dictLookup("Annots", &annots)->isArray()) {
+	  for (int i = 0; i < annots.arrayGetLength() && !usesJS; ++i) {
+	    Object annot;
+	    if (annots.arrayGet(i, &annot)->isDict()) {
+	      Object annotAA;
+	      if (annot.dictLookup("AA", &annotAA)->isDict()) {
+		if (scanAAForJavaScript(&annotAA)) {
+		  usesJS = gTrue;
+		}
+	      }
+	      annotAA.free();
+	    }
+	    annot.free();
+	  }
+	}
+        annots.free();
+      }
+    }
+    kids.free();
+  }
+
+  pageNode.free();
+
+  return usesJS;
+}
+
+GBool Catalog::scanAAForJavaScript(Object *aaObj) {
+  GBool usesJS = gFalse;
+  for (int i = 0; i < aaObj->dictGetLength() && !usesJS; ++i) {
+    Object action;
+    if (aaObj->dictGetVal(i, &action)->isDict()) {
+      Object js;
+      if (!action.dictLookupNF("JS", &js)->isNull()) {
+	usesJS = gTrue;
+      }
+      js.free();
+    }
+    action.free();
+  }
+  return usesJS;
+}
+

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #if MULTITHREADED
 #include "GMutex.h"
 #endif
@@ -118,6 +114,9 @@
 
   Object *getViewerPreferences() { return &viewerPrefs; }
 
+  // Return true if the document uses JavaScript.
+  GBool usesJavaScript();
+
 private:
 
   PDFDoc *doc;
@@ -146,21 +145,23 @@
 
   Object *findDestInTree(Object *tree, GString *name, Object *obj);
   GBool readPageTree(Object *catDict);
-  int countPageTree(Object *pagesObj);
+  int countPageTree(Object *pagesNodeRef, char *touchedObjs);
   void loadPage(int pg);
   void loadPage2(int pg, int relPg, PageTreeNode *node);
   void readEmbeddedFileList(Dict *catDict);
-  void readEmbeddedFileTree(Object *node);
+  void readEmbeddedFileTree(Object *nodeRef, char *touchedObjs);
   void readFileAttachmentAnnots(Object *pageNodeRef,
 				char *touchedObjs);
   void readEmbeddedFile(Object *fileSpec, Object *name1);
   void readPageLabelTree(Object *root);
-  void readPageLabelTree2(Object *node);
+  void readPageLabelTree2(Object *node, char *touchedObjs);
   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);
+  GBool scanPageTreeForJavaScript(Object *pageNodeRef, char *touchedObjs);
+  GBool scanAAForJavaScript(Object *aaObj);
 };
 
 #endif

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <string.h>
 #include "gmem.h"
@@ -274,7 +270,18 @@
   pst = new PSTokenizer(getCharFunc, data);
   pst->getToken(tok1, sizeof(tok1), &n1);
   while (pst->getToken(tok2, sizeof(tok2), &n2)) {
-    if (!strcmp(tok2, "usecmap")) {
+    if (!strcmp(tok1, "begincodespacerange")) {
+      if (globalParams->getIgnoreWrongSizeToUnicode() &&
+	  tok2[0] == '<' && tok2[n2 - 1] == '>' &&
+	  n2 - 2 != nBits / 4) {
+	error(errSyntaxWarning, -1,
+	      "Incorrect character size in ToUnicode CMap");
+	ok = gFalse;
+	break;
+      }
+      while (pst->getToken(tok1, sizeof(tok1), &n1) &&
+	     strcmp(tok1, "endcodespacerange")) ;
+    } else if (!strcmp(tok2, "usecmap")) {
       if (tok1[0] == '/') {
 	name = new GString(tok1 + 1);
 	if ((f = globalParams->findToUnicodeFile(name))) {
@@ -465,6 +472,7 @@
       pst->getToken(tok1, sizeof(tok1), &n1);
     } else {
       strcpy(tok1, tok2);
+      n1 = n2;
     }
   }
   delete pst;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -13,10 +13,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "CharTypes.h"
 
 #if MULTITHREADED

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <string.h>
 #include "gmem.h"
 #include "gmempp.h"
@@ -1492,14 +1488,14 @@
   SHA512Uint64 H[8];
   int blkLen, i;
 
-  H[0] = 0x6a09e667f3bcc908LL;
-  H[1] = 0xbb67ae8584caa73bLL;
-  H[2] = 0x3c6ef372fe94f82bLL;
-  H[3] = 0xa54ff53a5f1d36f1LL;
-  H[4] = 0x510e527fade682d1LL;
-  H[5] = 0x9b05688c2b3e6c1fLL;
-  H[6] = 0x1f83d9abfb41bd6bLL;
-  H[7] = 0x5be0cd19137e2179LL;
+  H[0] = 0x6a09e667f3bcc908ULL;
+  H[1] = 0xbb67ae8584caa73bULL;
+  H[2] = 0x3c6ef372fe94f82bULL;
+  H[3] = 0xa54ff53a5f1d36f1ULL;
+  H[4] = 0x510e527fade682d1ULL;
+  H[5] = 0x9b05688c2b3e6c1fULL;
+  H[6] = 0x1f83d9abfb41bd6bULL;
+  H[7] = 0x5be0cd19137e2179ULL;
 
   blkLen = 0;
   for (i = 0; i + 128 <= msgLen; i += 128) {
@@ -1558,14 +1554,14 @@
   SHA512Uint64 H[8];
   int blkLen, i;
 
-  H[0] = 0xcbbb9d5dc1059ed8LL;
-  H[1] = 0x629a292a367cd507LL;
-  H[2] = 0x9159015a3070dd17LL;
-  H[3] = 0x152fecd8f70e5939LL;
-  H[4] = 0x67332667ffc00b31LL;
-  H[5] = 0x8eb44a8768581511LL;
-  H[6] = 0xdb0c2e0d64f98fa7LL;
-  H[7] = 0x47b5481dbefa4fa4LL;
+  H[0] = 0xcbbb9d5dc1059ed8ULL;
+  H[1] = 0x629a292a367cd507ULL;
+  H[2] = 0x9159015a3070dd17ULL;
+  H[3] = 0x152fecd8f70e5939ULL;
+  H[4] = 0x67332667ffc00b31ULL;
+  H[5] = 0x8eb44a8768581511ULL;
+  H[6] = 0xdb0c2e0d64f98fa7ULL;
+  H[7] = 0x47b5481dbefa4fa4ULL;
 
   blkLen = 0;
   for (i = 0; i + 128 <= msgLen; i += 128) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "GString.h"
 #include "Object.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stddef.h>
 #include <string.h>
 #include "gmem.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #if MULTITHREADED
 #include "GMutex.h"
 #endif

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include "gmempp.h"
 #include "GString.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "SplashTypes.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <stddef.h>
 #include <stdarg.h>

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Error.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Error.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Error.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <stdio.h>
 #include "config.h"
 #include "gfile.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "Object.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <stddef.h>
@@ -536,6 +532,7 @@
   out = outA;
   state = new GfxState(hDPI, vDPI, box, rotate, out->upsideDown());
   fontChanged = gFalse;
+  haveSavedClipPath = gFalse;
   clip = clipNone;
   ignoreUndef = 0;
   out->startPage(pageNum, state);
@@ -584,6 +581,7 @@
   out = outA;
   state = new GfxState(72, 72, box, 0, gFalse);
   fontChanged = gFalse;
+  haveSavedClipPath = gFalse;
   clip = clipNone;
   ignoreUndef = 0;
   for (i = 0; i < 6; ++i) {
@@ -1829,16 +1827,21 @@
   }
   if (state->isPath()) {
     if (ocState) {
-      if (state->getFillColorSpace()->getMode() == csPattern) {
-	doPatternFill(gFalse);
+      if (state->getFillColorSpace()->getMode() == csPattern ||
+	  state->getStrokeColorSpace()->getMode() == csPattern) {
+	if (state->getFillColorSpace()->getMode() == csPattern) {
+	  doPatternFill(gFalse);
+	} else {
+	  out->fill(state);
+	}
+	if (state->getStrokeColorSpace()->getMode() == csPattern) {
+	  doPatternStroke();
+	} else {
+	  out->stroke(state);
+	}
       } else {
-	out->fill(state);
+	out->fillStroke(state, gFalse);
       }
-      if (state->getStrokeColorSpace()->getMode() == csPattern) {
-	doPatternStroke();
-      } else {
-	out->stroke(state);
-      }
     }
   }
   doEndPath();
@@ -1852,16 +1855,21 @@
   if (state->isPath()) {
     state->closePath();
     if (ocState) {
-      if (state->getFillColorSpace()->getMode() == csPattern) {
-	doPatternFill(gFalse);
+      if (state->getFillColorSpace()->getMode() == csPattern ||
+	  state->getStrokeColorSpace()->getMode() == csPattern) {
+	if (state->getFillColorSpace()->getMode() == csPattern) {
+	  doPatternFill(gFalse);
+	} else {
+	  out->fill(state);
+	}
+	if (state->getStrokeColorSpace()->getMode() == csPattern) {
+	  doPatternStroke();
+	} else {
+	  out->stroke(state);
+	}
       } else {
-	out->fill(state);
+	out->fillStroke(state, gFalse);
       }
-      if (state->getStrokeColorSpace()->getMode() == csPattern) {
-	doPatternStroke();
-      } else {
-	out->stroke(state);
-      }
     }
   }
   doEndPath();
@@ -1874,16 +1882,21 @@
   }
   if (state->isPath()) {
     if (ocState) {
-      if (state->getFillColorSpace()->getMode() == csPattern) {
-	doPatternFill(gTrue);
+      if (state->getFillColorSpace()->getMode() == csPattern ||
+	  state->getStrokeColorSpace()->getMode() == csPattern) {
+	if (state->getFillColorSpace()->getMode() == csPattern) {
+	  doPatternFill(gTrue);
+	} else {
+	  out->eoFill(state);
+	}
+	if (state->getStrokeColorSpace()->getMode() == csPattern) {
+	  doPatternStroke();
+	} else {
+	  out->stroke(state);
+	}
       } else {
-	out->eoFill(state);
+	out->fillStroke(state, gTrue);
       }
-      if (state->getStrokeColorSpace()->getMode() == csPattern) {
-	doPatternStroke();
-      } else {
-	out->stroke(state);
-      }
     }
   }
   doEndPath();
@@ -1897,16 +1910,21 @@
   if (state->isPath()) {
     state->closePath();
     if (ocState) {
-      if (state->getFillColorSpace()->getMode() == csPattern) {
-	doPatternFill(gTrue);
+      if (state->getFillColorSpace()->getMode() == csPattern ||
+	  state->getStrokeColorSpace()->getMode() == csPattern) {
+	if (state->getFillColorSpace()->getMode() == csPattern) {
+	  doPatternFill(gTrue);
+	} else {
+	  out->eoFill(state);
+	}
+	if (state->getStrokeColorSpace()->getMode() == csPattern) {
+	  doPatternStroke();
+	} else {
+	  out->stroke(state);
+	}
       } else {
-	out->eoFill(state);
+	out->fillStroke(state, gTrue);
       }
-      if (state->getStrokeColorSpace()->getMode() == csPattern) {
-	doPatternStroke();
-      } else {
-	out->stroke(state);
-      }
     }
   }
   doEndPath();
@@ -1966,7 +1984,7 @@
   }
 }
 
-void Gfx::doPatternText() {
+void Gfx::doPatternText(GBool stroke) {
   GfxPattern *pattern;
 
   // this is a bit of a kludge -- patterns can be really slow, so we
@@ -1976,7 +1994,8 @@
     return;
   }
 
-  if (!(pattern = state->getFillPattern())) {
+  pattern = stroke ? state->getStrokePattern() : state->getFillPattern();
+  if (!pattern) {
     return;
   }
   switch (pattern->getType()) {
@@ -2193,16 +2212,30 @@
   if (bbox[1] > bbox[3]) {
     t = bbox[1]; bbox[1] = bbox[3]; bbox[3] = t;
   }
-  xstep = fabs(tPat->getXStep());
-  ystep = fabs(tPat->getYStep());
-  xi0 = (int)ceil((xMin - bbox[2]) / xstep);
-  xi1 = (int)floor((xMax - bbox[0]) / xstep) + 1;
-  yi0 = (int)ceil((yMin - bbox[3]) / ystep);
-  yi1 = (int)floor((yMax - bbox[1]) / ystep) + 1;
+  xstep = tPat->getXStep();
+  ystep = tPat->getYStep();
+  if (xstep == 0 || ystep == 0) {
+    error(errSyntaxError, getPos(), "Zero x or y step in tiling pattern fill");
+    goto err;
+  }
+  if (xstep > 0) {
+    xi0 = (int)ceil((xMin - bbox[2]) / xstep);
+    xi1 = (int)floor((xMax - bbox[0]) / xstep) + 1;
+  } else {
+    xi0 = (int)ceil((xMax - bbox[0]) / xstep);
+    xi1 = (int)floor((xMin - bbox[2]) / xstep) + 1;
+  }
+  if (ystep > 0) {
+    yi0 = (int)ceil((yMin - bbox[3]) / ystep);
+    yi1 = (int)floor((yMax - bbox[1]) / ystep) + 1;
+  } else {
+    yi0 = (int)ceil((yMax - bbox[1]) / ystep);
+    yi1 = (int)floor((yMin - bbox[3]) / ystep) + 1;
+  }
   for (i = 0; i < 4; ++i) {
     m1[i] = m[i];
   }
-  if (out->useTilingPatternFill()) {
+  if (out->useTilingPatternFill() && !tPat->usesBlendMode(xref)) {
     m1[4] = m[4];
     m1[5] = m[5];
     out->tilingPatternFill(state, this, tPat->getContentStreamRef(),
@@ -3521,12 +3554,16 @@
 }
 
 void Gfx::doEndPath() {
-  if (state->isCurPt() && clip != clipNone) {
-    state->clip();
-    if (clip == clipNormal) {
-      out->clip(state);
+  if (clip != clipNone) {
+    if (state->isCurPt()) {
+      state->clip();
+      if (clip == clipNormal) {
+	out->clip(state);
+      } else {
+	out->eoClip(state);
+      }
     } else {
-      out->eoClip(state);
+      error(errSyntaxError, getPos(), "Empty path in clip");
     }
   }
   clip = clipNone;
@@ -3555,9 +3592,15 @@
   out->updateTextMat(state);
   out->updateTextPos(state);
   fontChanged = gTrue;
+  haveSavedClipPath = gFalse;
 }
 
 void Gfx::opEndText(Object args[], int numArgs) {
+  if (haveSavedClipPath) {
+    out->clipToSavedClipPath(state);
+    haveSavedClipPath = gFalse;
+  }
+
   out->endTextObject(state);
 }
 
@@ -3786,28 +3829,9 @@
 }
 
 void Gfx::doShowText(GString *s) {
-  GfxFont *font;
-  int wMode;
-  double riseX, riseY;
-  CharCode code;
-  Unicode u[8];
-  double x, y, dx, dy, dx2, dy2, curX, curY, tdx, tdy, ddx, ddy;
-  double originX, originY, tOriginX, tOriginY;
-  double x0, y0, x1, y1;
-  double oldCTM[6], newCTM[6];
-  double *mat;
-  Object charProcRef, charProc;
-  Dict *resDict;
-  Parser *oldParser;
-  GfxState *savedState;
-  char *p;
-  int render;
-  GBool patternFill;
-  int len, n, uLen, nChars, nSpaces, i;
+  GfxFont *font = state->getFont();
+  int wMode = font->getWMode();
 
-  font = state->getFont();
-  wMode = font->getWMode();
-
   if (globalParams->isDroppedFont(font->getName()
 				    ? font->getName()->getCString() : "")) {
     doIncCharCount(s);
@@ -3818,35 +3842,63 @@
     out->beginString(state, s);
   }
 
-  // if we're doing a pattern fill, set up clipping
-  render = state->getRender();
-  if (!(render & 1) &&
-      state->getFillColorSpace()->getMode() == csPattern) {
-    patternFill = gTrue;
-    saveState();
-    // disable fill, enable clipping, leave stroke unchanged
-    if ((render ^ (render >> 1)) & 1) {
-      render = 5;
+  // figure out the drawing mode
+  // note: clipping, pattern fill, and pattern stroke are all handled
+  //       by saving the path and then performing the appropriate
+  //       actions in opEndText()
+  GBool doFill = gFalse;
+  GBool doStroke = gFalse;
+  GBool doMakePath = gFalse;
+  int render = state->getRender() & 7;
+  switch (render & 7) {
+  case 0:			// fill
+    if (state->getFillColorSpace()->getMode() == csPattern) {
+      doMakePath = gTrue;
     } else {
-      render = 7;
+      doFill = gTrue;
     }
-    state->setRender(render);
-    out->updateRender(state);
-  } else {
-    patternFill = gFalse;
+    break;
+  case 1:			// stroke
+    if (state->getStrokeColorSpace()->getMode() == csPattern) {
+      doMakePath = gTrue;
+    } else {
+      doStroke = gTrue;
+    }
+    break;
+  case 2:			// fill + stroke
+    if (state->getFillColorSpace()->getMode() == csPattern ||
+	state->getStrokeColorSpace()->getMode() == csPattern) {
+      doMakePath = gTrue;
+    } else {
+      doFill = gTrue;
+      doStroke = gTrue;
+    }
+    break;
+  case 3:			// invisible
+    // nothing
+    break;
+  case 4:			// fill + clip
+  case 5:			// stroke + clip
+  case 6:			// fill + stroke + clip
+  case 7:			// clip
+    doMakePath = gTrue;
+    break;
   }
 
+  double riseX, riseY;
   state->textTransformDelta(0, state->getRise(), &riseX, &riseY);
-  x0 = state->getCurX() + riseX;
-  y0 = state->getCurY() + riseY;
+  double xMin = state->getCurX() + riseX;
+  double yMin = state->getCurY() + riseY;
 
   // handle a Type 3 char
   if (font->getType() == fontType3 && out->interpretType3Chars()) {
-    mat = state->getCTM();
-    for (i = 0; i < 6; ++i) {
+    double *mat = state->getCTM();
+    double oldCTM[6];
+    for (int i = 0; i < 6; ++i) {
       oldCTM[i] = mat[i];
     }
     mat = state->getTextMat();
+    double newCTM[6];
     newCTM[0] = mat[0] * oldCTM[0] + mat[1] * oldCTM[2];
     newCTM[1] = mat[0] * oldCTM[1] + mat[1] * oldCTM[3];
     newCTM[2] = mat[2] * oldCTM[0] + mat[3] * oldCTM[2];
@@ -3862,15 +3914,19 @@
     newCTM[3] *= state->getFontSize();
     newCTM[0] *= state->getHorizScaling();
     newCTM[1] *= state->getHorizScaling();
-    curX = state->getCurX();
-    curY = state->getCurY();
-    oldParser = parser;
-    p = s->getCString();
-    len = s->getLength();
+    double curX = state->getCurX();
+    double curY = state->getCurY();
+    Parser *oldParser = parser;
+    char *p = s->getCString();
+    int len = s->getLength();
     while (len > 0) {
-      n = font->getNextChar(p, len, &code,
-			    u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
-			    &dx, &dy, &originX, &originY);
+      CharCode code;
+      Unicode u[8];
+      int uLen;
+      double dx, dy, originX, originY;
+      int n = font->getNextChar(p, len, &code,
+				u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
+				&dx, &dy, &originX, &originY);
       dx = dx * state->getFontSize() + state->getCharSpace();
       if (n == 1 && *p == ' ') {
 	dx += state->getWordSpace();
@@ -3877,9 +3933,10 @@
       }
       dx *= state->getHorizScaling();
       dy *= state->getFontSize();
+      double tdx, tdy, ddx, ddy, x, y;
       state->textTransformDelta(dx, dy, &tdx, &tdy);
       state->transform(curX + riseX, curY + riseY, &x, &y);
-      savedState = saveStateStack();
+      GfxState *savedState = saveStateStack();
       state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y);
       //~ the CTM concat values here are wrong (but never used)
       out->updateCTM(state, 1, 0, 0, 1, 0, 0);
@@ -3899,9 +3956,11 @@
 #endif
       if (!out->beginType3Char(state, curX + riseX, curY + riseY, ddx, ddy,
 			       code, u, uLen)) {
+	Object charProcRef, charProc;
 	((Gfx8BitFont *)font)->getCharProcNF(code, &charProcRef);
 	charProcRef.fetch(xref, &charProc);
-	if ((resDict = ((Gfx8BitFont *)font)->getResources())) {
+	Dict *resDict = ((Gfx8BitFont *)font)->getResources();
+	if (resDict) {
 	  pushResources(resDict);
 	}
 	if (charProc.isStream()) {
@@ -3927,12 +3986,16 @@
     parser = oldParser;
 
   } else if (out->useDrawChar()) {
-    p = s->getCString();
-    len = s->getLength();
+    char *p = s->getCString();
+    int len = s->getLength();
     while (len > 0) {
-      n = font->getNextChar(p, len, &code,
-			    u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
-			    &dx, &dy, &originX, &originY);
+      CharCode code;
+      Unicode u[8];
+      int uLen;
+      double dx, dy, originX, originY;
+      int n = font->getNextChar(p, len, &code,
+				u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
+				&dx, &dy, &originX, &originY);
       if (wMode) {
 	dx *= state->getFontSize();
 	dy = dy * state->getFontSize() + state->getCharSpace();
@@ -3947,12 +4010,14 @@
 	dx *= state->getHorizScaling();
 	dy *= state->getFontSize();
       }
+      double tdx, tdy, tOriginX, tOriginY;
       state->textTransformDelta(dx, dy, &tdx, &tdy);
       originX *= state->getFontSize();
       originY *= state->getFontSize();
       state->textTransformDelta(originX, originY, &tOriginX, &tOriginY);
       out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY,
-		    tdx, tdy, tOriginX, tOriginY, code, n, u, uLen);
+		    tdx, tdy, tOriginX, tOriginY, code, n, u, uLen,
+		    doFill, doStroke, doMakePath);
       state->shift(tdx, tdy);
       p += n;
       len -= n;
@@ -3959,14 +4024,18 @@
     }
 
   } else {
-    dx = dy = 0;
-    p = s->getCString();
-    len = s->getLength();
-    nChars = nSpaces = 0;
+    double dx = 0, dy = 0;
+    char *p = s->getCString();
+    int len = s->getLength();
+    int nChars = 0, nSpaces = 0;
     while (len > 0) {
-      n = font->getNextChar(p, len, &code,
-			    u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
-			    &dx2, &dy2, &originX, &originY);
+      CharCode code;
+      Unicode u[8];
+      int uLen;
+      double dx2, dy2, originX, originY;
+      int n = font->getNextChar(p, len, &code,
+				u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
+				&dx2, &dy2, &originX, &originY);
       dx += dx2;
       dy += dy2;
       if (n == 1 && *p == ' ') {
@@ -3988,8 +4057,9 @@
       dx *= state->getHorizScaling();
       dy *= state->getFontSize();
     }
+    double tdx, tdy;
     state->textTransformDelta(dx, dy, &tdx, &tdy);
-    out->drawString(state, s);
+    out->drawString(state, s, doFill, doStroke, doMakePath);
     state->shift(tdx, tdy);
   }
 
@@ -3997,40 +4067,70 @@
     out->endString(state);
   }
 
-  if (patternFill) {
-    out->saveTextPos(state);
-    // tell the OutputDev to do the clipping
-    out->endTextObject(state);
-    // set up a clipping bbox so doPatternText will work -- assume
+  if (doMakePath) {
+    // compute the clipping bbox for the saved text path -- assume
     // that the text bounding box does not extend past the baseline in
     // any direction by more than twice the font size
-    x1 = state->getCurX() + riseX;
-    y1 = state->getCurY() + riseY;
-    if (x0 > x1) {
-      x = x0; x0 = x1; x1 = x;
+    double xMax = state->getCurX() + riseX;
+    double yMax = state->getCurY() + riseY;
+    double t;
+    if (xMin > xMax) {
+      t = xMin; xMin = xMax; xMax = t;
     }
-    if (y0 > y1) {
-      y = y0; y0 = y1; y1 = y;
+    if (yMin > yMax) {
+      t = yMin; yMin = yMax; yMax = t;
     }
-    state->textTransformDelta(0, state->getFontSize(), &dx, &dy);
+    double dx1, dy1, dx2, dy2;
+    state->textTransformDelta(0, state->getFontSize(), &dx1, &dy1);
     state->textTransformDelta(state->getFontSize(), 0, &dx2, &dy2);
-    dx = fabs(dx);
+    dx1 = fabs(dx1);
     dx2 = fabs(dx2);
-    if (dx2 > dx) {
-      dx = dx2;
+    if (dx2 > dx1) {
+      dx1 = dx2;
     }
-    dy = fabs(dy);
+    dy1 = fabs(dy1);
     dy2 = fabs(dy2);
-    if (dy2 > dy) {
-      dy = dy2;
+    if (dy2 > dy1) {
+      dy1 = dy2;
     }
-    state->clipToRect(x0 - 2 * dx, y0 - 2 * dy, x1 + 2 * dx, y1 + 2 * dy);
-    // set render mode to fill-only
-    state->setRender(0);
-    out->updateRender(state);
-    doPatternText();
-    restoreState();
-    out->restoreTextPos(state);
+    xMin -= 2 * dx1;
+    yMin -= 2 * dy1;
+    xMax += 2 * dx1;
+    yMax += 2 * dy1;
+
+    //--- fill
+    if ((render & 3) == 0 || (render & 3) == 2) {
+      if (state->getFillColorSpace()->getMode() == csPattern) {
+	saveState();
+	state->clipToRect(xMin, yMin, xMax, yMax);
+	out->clipToTextPath(state);
+	doPatternText(gFalse);
+	restoreState();
+      } else {
+	out->fillTextPath(state);
+      }
+    }
+
+    //--- stroke
+    if ((render & 3) == 1 || (render & 3) == 2) {
+      if (state->getStrokeColorSpace()->getMode() == csPattern) {
+	saveState();
+	state->clipToRect(xMin, yMin, xMax, yMax);
+	out->clipToTextStrokePath(state);
+	doPatternText(gTrue);
+	restoreState();
+      } else {
+	out->strokeTextPath(state);
+      }
+    }
+
+    //--- clip
+    if (render & 4) {
+      out->addTextPathToSavedClipPath(state);
+      haveSavedClipPath = gTrue;
+    } else {
+      out->clearTextPath(state);
+    }
   }
 
   opCounter += 10 * s->getLength();
@@ -4116,6 +4216,7 @@
 	xObj.streamGetDict()->lookup("Level1", &obj3);
 	out->psXObject(xObj.getStream(),
 		       obj3.isStream() ? obj3.getStream() : (Stream *)NULL);
+	obj3.free();
       }
     } else if (obj2.isName()) {
       error(errSyntaxError, getPos(),
@@ -4191,10 +4292,14 @@
     obj1.free();
     dict->lookup("W", &obj1);
   }
-  if (!obj1.isInt()) {
+  if (obj1.isInt()) {
+    width = obj1.getInt();
+  } else if (obj1.isReal()) {
+    error(errSyntaxWarning, getPos(), "Non-integer image width");
+    width = (int)obj1.getReal();
+  } else {
     goto err2;
   }
-  width = obj1.getInt();
   obj1.free();
   if (width <= 0) {
     goto err1;
@@ -4204,10 +4309,14 @@
     obj1.free();
     dict->lookup("H", &obj1);
   }
-  if (!obj1.isInt()) {
+  if (obj1.isInt()) {
+    height = obj1.getInt();
+  } else if (obj1.isReal()) {
+    error(errSyntaxWarning, getPos(), "Non-integer image height");
+    height = (int)obj1.getReal();
+  } else {
     goto err2;
   }
-  height = obj1.getInt();
   obj1.free();
   if (height <= 0) {
     goto err1;
@@ -4233,8 +4342,14 @@
       obj1.free();
       dict->lookup("BPC", &obj1);
     }
-    if (obj1.isInt()) {
-      bits = obj1.getInt();
+    if (obj1.isNum()) {
+      if (obj1.isInt()) {
+	bits = obj1.getInt();
+      } else if (obj1.isReal()) {
+	error(errSyntaxWarning, getPos(),
+	      "Non-integer image bits per component");
+	bits = (int)obj1.getReal();
+      }
       if (bits < 1 || bits > 16) {
 	goto err2;
       }
@@ -4377,13 +4492,17 @@
 	obj1.free();
 	maskDict->lookup("W", &obj1);
       }
-      if (!obj1.isInt()) {
+      if (obj1.isInt()) {
+	maskWidth = obj1.getInt();
+      } else if (obj1.isReal()) {
+	error(errSyntaxWarning, getPos(), "Non-integer image mask width");
+	maskWidth = (int)obj1.getReal();
+      } else {
 	delete colorMap;
 	maskObj.free();
 	smaskObj.free();
 	goto err2;
       }
-      maskWidth = obj1.getInt();
       obj1.free();
       maskDict->lookup("Height", &obj1);
       if (obj1.isNull()) {
@@ -4390,13 +4509,17 @@
 	obj1.free();
 	maskDict->lookup("H", &obj1);
       }
-      if (!obj1.isInt()) {
+      if (obj1.isInt()) {
+	maskHeight = obj1.getInt();
+      } else if (obj1.isReal()) {
+	error(errSyntaxWarning, getPos(), "Non-integer image mask height");
+	maskHeight = (int)obj1.getReal();
+      } else {
 	delete colorMap;
 	maskObj.free();
 	smaskObj.free();
 	goto err2;
       }
-      maskHeight = obj1.getInt();
       obj1.free();
       if (maskWidth <= 0 || maskHeight <= 0) {
 	delete colorMap;
@@ -4409,13 +4532,18 @@
 	obj1.free();
 	maskDict->lookup("BPC", &obj1);
       }
-      if (!obj1.isInt()) {
+      if (obj1.isInt()) {
+	maskBits = obj1.getInt();
+      } else if (obj1.isReal()) {
+	error(errSyntaxWarning, getPos(),
+	      "Non-integer image mask bits per component");
+	maskBits = (int)obj1.getReal();
+      } else {
 	delete colorMap;
 	maskObj.free();
 	smaskObj.free();
 	goto err2;
       }
-      maskBits = obj1.getInt();
       obj1.free();
       if (maskBits < 1 || maskBits > 16) {
 	delete colorMap;
@@ -4512,6 +4640,7 @@
       }
     } else if (maskObj.isStream()) {
       // explicit mask
+      haveExplicitMask = gTrue;
       if (inlineImg) {
 	delete colorMap;
 	maskObj.free();
@@ -4526,13 +4655,14 @@
 	obj1.free();
 	maskDict->lookup("W", &obj1);
       }
-      if (!obj1.isInt()) {
-	delete colorMap;
-	maskObj.free();
-	smaskObj.free();
-	goto err2;
+      if (obj1.isInt()) {
+	maskWidth = obj1.getInt();
+      } else if (obj1.isReal()) {
+	error(errSyntaxWarning, getPos(), "Non-integer image mask width");
+	maskWidth = (int)obj1.getReal();
+      } else {
+	haveExplicitMask = gFalse;
       }
-      maskWidth = obj1.getInt();
       obj1.free();
       maskDict->lookup("Height", &obj1);
       if (obj1.isNull()) {
@@ -4539,19 +4669,17 @@
 	obj1.free();
 	maskDict->lookup("H", &obj1);
       }
-      if (!obj1.isInt()) {
-	delete colorMap;
-	maskObj.free();
-	smaskObj.free();
-	goto err2;
+      if (obj1.isInt()) {
+	maskHeight = obj1.getInt();
+      } else if (obj1.isReal()) {
+	error(errSyntaxWarning, getPos(), "Non-integer image mask height");
+	maskHeight = (int)obj1.getReal();
+      } else {
+	haveExplicitMask = gFalse;
       }
-      maskHeight = obj1.getInt();
       obj1.free();
       if (maskWidth <= 0 || maskHeight <= 0) {
-	delete colorMap;
-	maskObj.free();
-	smaskObj.free();
-	goto err2;
+	haveExplicitMask = gFalse;
       }
       maskDict->lookup("ImageMask", &obj1);
       if (obj1.isNull()) {
@@ -4559,10 +4687,7 @@
 	maskDict->lookup("IM", &obj1);
       }
       if (!obj1.isBool() || !obj1.getBool()) {
-	delete colorMap;
-	maskObj.free();
-	smaskObj.free();
-	goto err2;
+	haveExplicitMask = gFalse;
       }
       obj1.free();
       maskInvert = gFalse;
@@ -4576,13 +4701,12 @@
 	maskInvert = obj2.isNum() && obj2.getNum() == 1;
 	obj2.free();
       } else if (!obj1.isNull()) {
-	delete colorMap;
-	maskObj.free();
-	smaskObj.free();
-	goto err2;
+	haveExplicitMask = gFalse;
       }
       obj1.free();
-      haveExplicitMask = gTrue;
+      if (!haveExplicitMask) {
+	error(errSyntaxError, getPos(), "Bad image parameters");
+      }
     }
 
     // if drawing is disabled, skip over inline image data
@@ -4768,6 +4892,8 @@
   double oldBaseMatrix[6];
   int i;
 
+  out->startStream(strRef->getRef(), state);
+
   // push new resources on stack
   pushResources(resDict);
 
@@ -4897,7 +5023,7 @@
     delete blendingColorSpace;
   }
 
-  return;
+  out->endStream(strRef->getRef());
 }
 
 void Gfx::takeContentStreamStack(Gfx *oldGfx) {
@@ -4936,7 +5062,9 @@
     // if we have the stream length, skip to end-of-stream and then
     // skip 'EI' in the original stream
     } else if (haveLength) {
-      while ((c1 = str->getChar()) != EOF) ;
+      // NB: getUndecodedStream() returns the EmbedStream created by
+      // buildImageStream()
+      while ((c1 = str->getUndecodedStream()->getChar()) != EOF) ;
       delete str;
       str = parser->getStream();
       c1 = str->getChar();
@@ -5091,15 +5219,28 @@
     }
     obj.free();
     mcKind = gfxMCOptionalContent;
-  } else if (args[0].isName("Span") && numArgs == 2 && args[1].isDict()) {
-    if (args[1].dictLookup("ActualText", &obj)->isString()) {
-      s = new TextString(obj.getString());
-      out->beginActualText(state, s->getUnicode(), s->getLength());
-      delete s;
-      mcKind = gfxMCActualText;
+  } else if (numArgs == 2 && args[1].isDict()) {
+    if (args[0].isName("Span")) {
+      if (args[1].dictLookup("ActualText", &obj)->isString()) {
+	s = new TextString(obj.getString());
+	out->beginActualText(state, s->getUnicode(), s->getLength());
+	delete s;
+	mcKind = gfxMCActualText;
+      }
+      obj.free();
     }
+    if (args[1].dictLookup("MCID", &obj)->isInt()) {
+      out->beginStructureItem(args[0].getName(), obj.getInt(),
+			      args[1].getDict());
+      if (mcKind == gfxMCActualText) {
+	mcKind = gfxMCStructureItemAndActualText;
+      } else {
+	mcKind = gfxMCStructureItem;
+      }
+    }
     obj.free();
   }
+
   mc = new GfxMarkedContent(mcKind, ocState);
   markedContentStack->append(mc);
 }
@@ -5123,6 +5264,11 @@
       }
     } else if (mcKind == gfxMCActualText) {
       out->endActualText(state);
+    } else if (mcKind == gfxMCStructureItem) {
+      out->endStructureItem();
+    } else if (mcKind == gfxMCStructureItemAndActualText) {
+      out->endStructureItem();
+      out->endActualText(state);
     }
   } else {
     error(errSyntaxWarning, getPos(), "Mismatched EMC operator");

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "gfile.h"
 #include "GfxState.h"
@@ -106,6 +102,8 @@
 enum GfxMarkedContentKind {
   gfxMCOptionalContent,
   gfxMCActualText,
+  gfxMCStructureItem,
+  gfxMCStructureItemAndActualText,
   gfxMCOther
 };
 
@@ -194,6 +192,7 @@
 
   GfxState *state;		// current graphics state
   GBool fontChanged;		// set if font or text matrix has changed
+  GBool haveSavedClipPath;
   GfxClipType clip;		// do a clip?
   int ignoreUndef;		// current BX/EX nesting level
   double baseMatrix[6];		// default matrix for most recent
@@ -273,7 +272,7 @@
   void opCloseEOFillStroke(Object args[], int numArgs);
   void doPatternFill(GBool eoFill);
   void doPatternStroke();
-  void doPatternText();
+  void doPatternText(GBool stroke);
   void doPatternImageMask(Object *ref, Stream *str, int width, int height,
 			  GBool invert, GBool inlineImg, GBool interpolate);
   void doTilingPatternFill(GfxTilingPattern *tPat,

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -307,27 +303,11 @@
     obj2.initNull();
   }
 
+  // NB: the PDF spec doesn't say anything about precedence, but Adobe
+  // uses FontFile3 over FontFile2 if both are present.
   if (fontDict2->lookup("FontDescriptor", &fontDesc)->isDict()) {
-    if (fontDesc.dictLookupNF("FontFile", &obj3)->isRef()) {
+    if (fontDesc.dictLookupNF("FontFile3", &obj3)->isRef()) {
       *embID = obj3.getRef();
-      if (expectedType != fontType1) {
-	err = gTrue;
-      }
-    }
-    obj3.free();
-    if (embID->num == -1 &&
-	fontDesc.dictLookupNF("FontFile2", &obj3)->isRef()) {
-      *embID = obj3.getRef();
-      if (isType0) {
-	expectedType = fontCIDType2;
-      } else if (expectedType != fontTrueType) {
-	err = gTrue;
-      }
-    }
-    obj3.free();
-    if (embID->num == -1 &&
-	fontDesc.dictLookupNF("FontFile3", &obj3)->isRef()) {
-      *embID = obj3.getRef();
       if (obj3.fetch(xref, &obj4)->isStream()) {
 	obj4.streamGetDict()->lookup("Subtype", &subtype);
 	if (subtype.isName("Type1")) {
@@ -375,6 +355,26 @@
       obj4.free();
     }
     obj3.free();
+    if (embID->num == -1) {
+      if (fontDesc.dictLookupNF("FontFile2", &obj3)->isRef()) {
+	*embID = obj3.getRef();
+	if (isType0) {
+	  expectedType = fontCIDType2;
+	} else if (expectedType != fontTrueType) {
+	  err = gTrue;
+	}
+      }
+      obj3.free();
+    }
+    if (embID->num == -1) {
+      if (fontDesc.dictLookupNF("FontFile", &obj3)->isRef()) {
+	*embID = obj3.getRef();
+	if (expectedType != fontType1) {
+	  err = gTrue;
+	}
+      }
+      obj3.free();
+    }
   }
   fontDesc.free();
 
@@ -533,6 +533,33 @@
 
   }
   obj1.free();
+
+  // scan font name for bold/italic tags and update the flags
+  if (name) {
+    i = name->getLength();
+    if (i > 2 && !strncmp(name->getCString() + i - 2, "MT", 2)) {
+      i -= 2;
+    }
+    if (i > 6 && !strncmp(name->getCString() + i - 6, "Italic", 6)) {
+      flags |= fontItalic;
+      i -= 6;
+    } else if (i > 2 && !strncmp(name->getCString() + i - 2, "It", 2)) {
+      flags |= fontItalic;
+      i -= 2;
+    } else if (i > 7 && !strncmp(name->getCString() + i - 7, "Oblique", 7)) {
+      flags |= fontItalic;
+      i -= 7;
+    }
+    char c = name->getChar(i-1);
+    if (!((c >= 'A' && c <= 'Z') ||
+	  (c >= 'a' && c <= 'z') ||
+	  (c >= '0' && c <= '9'))) {
+      --i;
+    }
+    if (i > 4 && !strncmp(name->getCString() + i - 4, "Bold", 4)) {
+      flags |= fontBold;
+    }
+  }
 }
 
 CharCodeToUnicode *GfxFont::readToUnicodeCMap(Dict *fontDict, int nBits,
@@ -1436,7 +1463,7 @@
 int *Gfx8BitFont::getCodeToGIDMap(FoFiTrueType *ff) {
   int *map;
   int cmapPlatform, cmapEncoding;
-  int unicodeCmap, macRomanCmap, msSymbolCmap, cmap;
+  int unicodeCmap, macRomanCmap, macUnicodeCmap, msSymbolCmap, cmap;
   GBool nonsymbolic, useMacRoman, useUnicode;
   char *charName;
   Unicode u;
@@ -1450,15 +1477,16 @@
   // This is based on the cmap/encoding selection algorithm in the PDF
   // 2.0 spec, but with some differences to match up with Adobe's
   // behavior.
-  unicodeCmap = macRomanCmap = msSymbolCmap = -1;
+  unicodeCmap = macRomanCmap = macUnicodeCmap = msSymbolCmap = -1;
   for (i = 0; i < ff->getNumCmaps(); ++i) {
     cmapPlatform = ff->getCmapPlatform(i);
     cmapEncoding = ff->getCmapEncoding(i);
-    if ((cmapPlatform == 3 && cmapEncoding == 1) ||
-	(cmapPlatform == 0 && cmapEncoding <= 4)) {
+    if (cmapPlatform == 3 && cmapEncoding == 1) {
       unicodeCmap = i;
     } else if (cmapPlatform == 1 && cmapEncoding == 0) {
       macRomanCmap = i;
+    } else if (cmapPlatform == 0 && cmapEncoding <= 4) {
+      macUnicodeCmap = i;
     } else if (cmapPlatform == 3 && cmapEncoding == 0) {
       msSymbolCmap = i;
     }
@@ -1466,24 +1494,25 @@
   useMacRoman = gFalse;
   useUnicode = gFalse;
   nonsymbolic = !(flags & fontSymbolic);
-  if (usesMacRomanEnc && macRomanCmap >= 0) {
-    cmap = macRomanCmap;
-    useMacRoman = gTrue;
-  } else if (embFontID.num < 0 && hasEncoding && unicodeCmap >= 0) { 
+  if (embFontID.num < 0 && hasEncoding && unicodeCmap >= 0) { 
     cmap = unicodeCmap;
     useUnicode = gTrue;
-  } else if (nonsymbolic && unicodeCmap >= 0) {
+  } else if (!nonsymbolic && msSymbolCmap >= 0) {
+    cmap = msSymbolCmap;
+  } else if (unicodeCmap >= 0) {
     cmap = unicodeCmap;
-    useUnicode = gTrue;
-  } else if (nonsymbolic && macRomanCmap >= 0) {
+    useUnicode = nonsymbolic;
+  } else if (usesMacRomanEnc && macRomanCmap >= 0) {
+    // MacRoman cmap has higher precedence than Mac Unicode only if
+    // the font uses the MacRoman encoding
     cmap = macRomanCmap;
     useMacRoman = gTrue;
-  } else if (msSymbolCmap >= 0) {
-    cmap = msSymbolCmap;
-  } else if (unicodeCmap >= 0) {
-    cmap = unicodeCmap;
+  } else if (macUnicodeCmap >= 0) {
+    cmap = macUnicodeCmap;
+    useUnicode = nonsymbolic;
   } else if (macRomanCmap >= 0) {
     cmap = macRomanCmap;
+    useMacRoman = nonsymbolic;
   } else {
     cmap = 0;
   }
@@ -2229,69 +2258,92 @@
 // GfxFontDict
 //------------------------------------------------------------------------
 
-GfxFontDict::GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict) {
-  GfxFont *font;
-  char *tag;
-  Object obj1, obj2;
-  Ref r;
-  int i;
+class GfxFontDictEntry {
+public:
 
+  GfxFontDictEntry(Ref refA, Object *fontObjA);
+  ~GfxFontDictEntry();
+  void load(GfxFont *fontA);
+
+  GBool loaded;
+  Ref ref;
+  Object fontObj;		// valid if unloaded
+  GfxFont *font;		// valid if loaded
+};
+
+GfxFontDictEntry::GfxFontDictEntry(Ref refA, Object *fontObjA) {
+  loaded = gFalse;
+  ref = refA;
+  fontObjA->copy(&fontObj);
+  font = NULL;
+}
+
+GfxFontDictEntry::~GfxFontDictEntry() {
+  // NB: If the font has been loaded, font is non-NULL and is owned by
+  // GfxFontDict.uniqueFonts.
+  if (!loaded) {
+    fontObj.free();
+  }
+}
+
+void GfxFontDictEntry::load(GfxFont *fontA) {
+  loaded = gTrue;
+  font = fontA;
+  fontObj.free();
+}
+
+GfxFontDict::GfxFontDict(XRef *xrefA, Ref *fontDictRef, Dict *fontDict) {
+  xref = xrefA;
   fonts = new GHash(gTrue);
   uniqueFonts = new GList();
-  for (i = 0; i < fontDict->getLength(); ++i) {
-    tag = fontDict->getKey(i);
-    fontDict->getValNF(i, &obj1);
-    obj1.fetch(xref, &obj2);
-    if (!obj2.isDict()) {
-      error(errSyntaxError, -1, "font resource is not a dictionary");
-    } else if (obj1.isRef() && (font = lookupByRef(obj1.getRef()))) {
-      fonts->add(new GString(tag), font);
+
+  for (int i = 0; i < fontDict->getLength(); ++i) {
+    char *tag = fontDict->getKey(i);
+    Object fontObj;
+    fontDict->getValNF(i, &fontObj);
+    Ref r;
+    if (fontObj.isRef()) {
+      r = fontObj.getRef();
+    } else if (fontDictRef) {
+      // legal generation numbers are five digits, so we use a
+      // 6-digit number here
+      r.gen = 100000 + fontDictRef->num;
+      r.num = i;
     } else {
-      if (obj1.isRef()) {
-	r = obj1.getRef();
-      } else if (fontDictRef) {
-	// legal generation numbers are five digits, so we use a
-	// 6-digit number here
-	r.gen = 100000 + fontDictRef->num;
-	r.num = i;
-      } else {
-	// no indirect reference for this font, or for the containing
-	// font dict, so hash the font and use that
-	r.gen = 100000;
-	r.num = hashFontObject(&obj2);
-      }
-      if ((font = GfxFont::makeFont(xref, tag, r, obj2.getDict()))) {
-	if (!font->isOk()) {
-	  delete font;
-	} else {
-	  uniqueFonts->append(font);
-	  fonts->add(new GString(tag), font);
-	}
-      }
+      // no indirect reference for this font, or for the containing
+      // font dict, so hash the font and use that
+      r.gen = 100000;
+      r.num = hashFontObject(&fontObj);
     }
-    obj1.free();
-    obj2.free();
+    fonts->add(new GString(tag), new GfxFontDictEntry(r, &fontObj));
+    fontObj.free();
   }
 }
 
 GfxFontDict::~GfxFontDict() {
   deleteGList(uniqueFonts, GfxFont);
-  delete fonts;
+  deleteGHash(fonts, GfxFontDictEntry);
 }
 
 GfxFont *GfxFontDict::lookup(char *tag) {
-  return (GfxFont *)fonts->lookup(tag);
+  GfxFontDictEntry *entry = (GfxFontDictEntry *)fonts->lookup(tag);
+  if (!entry) {
+    return NULL;
+  }
+  load(tag, entry);
+  return entry->font;
 }
 
 GfxFont *GfxFontDict::lookupByRef(Ref ref) {
-  GfxFont *font;
-  int i;
-
-  for (i = 0; i < uniqueFonts->getLength(); ++i) {
-    font = (GfxFont *)uniqueFonts->get(i);
-    if (font->getID()->num == ref.num &&
-	font->getID()->gen == ref.gen) {
-      return font;
+  GHashIter *iter;
+  GString *tag;
+  GfxFontDictEntry *entry;
+  fonts->startIter(&iter);
+  while (fonts->getNext(&iter, &tag, (void **)&entry)) {
+    if (entry->ref.num == ref.num && entry->ref.gen == ref.gen) {
+      fonts->killIter(&iter);
+      load(tag->getCString(), entry);
+      return entry->font;
     }
   }
   return NULL;
@@ -2298,6 +2350,7 @@
 }
 
 int GfxFontDict::getNumFonts() {
+  loadAll();
   return uniqueFonts->getLength();
 }
 
@@ -2305,6 +2358,52 @@
   return (GfxFont *)uniqueFonts->get(i);
 }
 
+void GfxFontDict::loadAll() {
+  GHashIter *iter;
+  GString *tag;
+  GfxFontDictEntry *entry;
+  fonts->startIter(&iter);
+  while (fonts->getNext(&iter, &tag, (void **)&entry)) {
+    load(tag->getCString(), entry);
+  }
+}
+
+void GfxFontDict::load(char *tag, GfxFontDictEntry *entry) {
+  if (entry->loaded) {
+    return;
+  }
+
+  // check for a duplicate that has already been loaded
+  // (don't do this for "synthetic" refs)
+  if (entry->fontObj.isRef()) {
+    for (int i = 0; i < uniqueFonts->getLength(); ++i) {
+      GfxFont *font = (GfxFont *)uniqueFonts->get(i);
+      if (font->getID()->num == entry->ref.num &&
+	  font->getID()->gen == entry->ref.gen) {
+	entry->load(font);
+	return;
+      }
+    }
+  }
+
+  GfxFont *font = NULL;
+  Object obj;
+  entry->fontObj.fetch(xref, &obj);
+  if (obj.isDict()) {
+    font = GfxFont::makeFont(xref, tag, entry->ref, obj.getDict());
+    if (font->isOk()) {
+      uniqueFonts->append(font);
+    } else {
+      delete font;
+      font = NULL;
+    }
+  } else {
+    error(errSyntaxError, -1, "font resource is not a dictionary");
+  }
+  obj.free();
+  entry->load(font);
+}
+
 // FNV-1a hash
 class FNVHash {
 public:

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "GString.h"
 #include "Object.h"
@@ -29,6 +25,7 @@
 class FoFiType1C;
 struct GfxFontCIDWidths;
 struct Base14FontMapEntry;
+class GfxFontDictEntry;
 class FNVHash;
 
 //------------------------------------------------------------------------
@@ -388,7 +385,7 @@
 public:
 
   // Build the font dictionary, given the PDF font dictionary.
-  GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict);
+  GfxFontDict(XRef *xrefA, Ref *fontDictRef, Dict *fontDict);
 
   // Destructor.
   ~GfxFontDict();
@@ -405,13 +402,18 @@
 
   friend class GfxFont;
 
+  void loadAll();
+  void load(char *tag, GfxFontDictEntry *entry);
   static int hashFontObject(Object *obj);
   static void hashFontObject1(Object *obj, FNVHash *h);
 
-  GHash *fonts;			// hash table of fonts -- this may
-				//   include duplicates, i.e., when
-				//   two tags map to the same font
+  XRef *xref;
+  GHash *fonts;			// hash table of fonts, mapping from
+				//   tag to GfxFontDictEntry; this may
+				//   contain duplicates, i.e., two
+				//   tags that map to the same font
   GList *uniqueFonts;		// list of all unique font objects (no dups)
+				//   that have been loaded
 };
 
 #endif

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stddef.h>
 #include <math.h>
 #include <string.h>
@@ -936,15 +932,15 @@
   }
   nCompsA = obj2.getInt();
   obj2.free();
-  if (nCompsA > 4) {
-    error(errSyntaxError, -1,
-	  "ICCBased color space with too many ({0:d} > 4) components",
-	  nCompsA);
-    nCompsA = 4;
-  }
-  if (dict->lookup("Alternate", &obj2)->isNull() ||
-      !(altA = GfxColorSpace::parse(&obj2,
-				    recursion + 1))) {
+  if (!dict->lookup("Alternate", &obj2)->isNull() &&
+      (altA = GfxColorSpace::parse(&obj2,
+				   recursion + 1))) {
+    if (altA->getNComps() != nCompsA) {
+      error(errSyntaxError, -1,
+	    "Number of components in ICCBased color space doesn't match alternate color space");
+      nCompsA = altA->getNComps();
+    }
+  } else {
     switch (nCompsA) {
     case 1:
       altA = GfxColorSpace::create(csDeviceGray);
@@ -1784,6 +1780,258 @@
 			      &resDict, matrix, &contentStreamRef);
 }
 
+GBool GfxTilingPattern::usesBlendMode(XRef *xref) {
+  char *scannedObjs = (char *)gmalloc(xref->getNumObjects());
+  memset(scannedObjs, 0, xref->getNumObjects());
+  GBool ret = scanResourcesForBlendMode(&resDict, scannedObjs, xref);
+  gfree(scannedObjs);
+  return ret;
+}
+
+GBool GfxTilingPattern::scanResourcesForBlendMode(Object *resDict2,
+						  char *scannedObjs,
+						  XRef *xref) {
+  Object ref1, obj1, obj2;
+
+  if (!resDict2->isDict()) {
+    return gFalse;
+  }
+
+  //----- ExtGStates
+  resDict2->dictLookupNF("ExtGState", &ref1);
+  if (!ref1.isRef() || (ref1.getRefNum() < xref->getNumObjects() &&
+			!scannedObjs[ref1.getRefNum()])) {
+    if (ref1.isRef()) {
+      scannedObjs[ref1.getRefNum()] = 1;
+      ref1.fetch(xref, &obj1);
+    } else {
+      ref1.copy(&obj1);
+    }
+    if (obj1.isDict()) {
+      for (int i = 0; i < obj1.dictGetLength(); ++i) {
+	if (scanExtGStateForBlendMode(obj1.dictGetValNF(i, &obj2),
+				      scannedObjs, xref)) {
+	  obj2.free();
+	  obj1.free();
+	  ref1.free();
+	  return gTrue;
+	}
+	obj2.free();
+      }
+    }
+    obj1.free();
+  }
+  ref1.free();
+
+  //----- patterns
+  resDict2->dictLookupNF("Pattern", &ref1);
+  if (!ref1.isRef() || (ref1.getRefNum() < xref->getNumObjects() &&
+			!scannedObjs[ref1.getRefNum()])) {
+    if (ref1.isRef()) {
+      scannedObjs[ref1.getRefNum()] = 1;
+      ref1.fetch(xref, &obj1);
+    } else {
+      ref1.copy(&obj1);
+    }
+    if (obj1.isDict()) {
+      for (int i = 0; i < obj1.dictGetLength(); ++i) {
+	if (scanPatternForBlendMode(obj1.dictGetValNF(i, &obj2),
+				    scannedObjs, xref)) {
+	  obj2.free();
+	  obj1.free();
+	  ref1.free();
+	  return gTrue;
+	}
+	obj2.free();
+      }
+    }
+    obj1.free();
+  }
+  ref1.free();
+
+  //----- XObjects
+  resDict2->dictLookupNF("XObject", &ref1);
+  if (!ref1.isRef() || (ref1.getRefNum() < xref->getNumObjects() &&
+			!scannedObjs[ref1.getRefNum()])) {
+    if (ref1.isRef()) {
+      scannedObjs[ref1.getRefNum()] = 1;
+      ref1.fetch(xref, &obj1);
+    } else {
+      ref1.copy(&obj1);
+    }
+    if (obj1.isDict()) {
+      for (int i = 0; i < obj1.dictGetLength(); ++i) {
+	if (scanXObjectForBlendMode(obj1.dictGetValNF(i, &obj2),
+				    scannedObjs, xref)) {
+	  obj2.free();
+	  obj1.free();
+	  ref1.free();
+	  return gTrue;
+	}
+	obj2.free();
+      }
+    }
+    obj1.free();
+  }
+  ref1.free();
+
+  return gFalse;
+}
+
+GBool GfxTilingPattern::scanExtGStateForBlendMode(Object *gsObj,
+						  char *scannedObjs,
+						  XRef *xref) {
+  Object gsDict, obj1;
+
+  if (gsObj->isRef()) {
+    if (gsObj->getRefNum() >= xref->getNumObjects() ||
+	scannedObjs[gsObj->getRefNum()]) {
+      return gFalse;
+    }
+    scannedObjs[gsObj->getRefNum()] = 1;
+    gsObj->fetch(xref, &gsDict);
+  } else {
+    gsObj->copy(&gsDict);
+  }
+  if (!gsDict.isDict()) {
+    gsDict.free();
+    return gFalse;
+  }
+
+  gsDict.dictLookup("BM", &obj1);
+  if (obj1.isName() && !obj1.isName("Normal")) {
+    obj1.free();
+    gsDict.free();
+    return gTrue;
+  }
+  obj1.free();
+
+  if (!gsDict.dictLookupNF("SMask", &obj1)->isNull()) {
+    if (scanSoftMaskForBlendMode(&obj1, scannedObjs, xref)) {
+      obj1.free();
+      gsDict.free();
+      return gTrue;
+    }
+  }
+  obj1.free();
+
+  gsDict.free();
+
+  return gFalse;
+}
+
+GBool GfxTilingPattern::scanSoftMaskForBlendMode(Object *softMaskObj,
+						 char *scannedObjs,
+						 XRef *xref) {
+  Object softMaskDict, obj1;
+
+  if (softMaskObj->isRef()) {
+    if (softMaskObj->getRefNum() >= xref->getNumObjects() ||
+	scannedObjs[softMaskObj->getRefNum()]) {
+      return gFalse;
+    }
+    scannedObjs[softMaskObj->getRefNum()] = 1;
+    softMaskObj->fetch(xref, &softMaskDict);
+  } else {
+    softMaskObj->copy(&softMaskDict);
+  }
+  if (!softMaskDict.isDict()) {
+    softMaskDict.free();
+    return gFalse;
+  }
+
+  if (!softMaskDict.dictLookupNF("G", &obj1)->isNull()) {
+    if (scanXObjectForBlendMode(&obj1, scannedObjs, xref)) {
+      obj1.free();
+      softMaskDict.free();
+      return gTrue;
+    }
+  }
+  obj1.free();
+
+  softMaskDict.free();
+
+  return gFalse;
+}
+
+GBool GfxTilingPattern::scanPatternForBlendMode(Object *patternObj,
+						char *scannedObjs,
+						XRef *xref) {
+  Object patternObj2, obj1;
+  Dict *patternDict;
+
+  if (patternObj->isRef()) {
+    if (patternObj->getRefNum() >= xref->getNumObjects() ||
+	scannedObjs[patternObj->getRefNum()]) {
+      return gFalse;
+    }
+    scannedObjs[patternObj->getRefNum()] = 1;
+    patternObj->fetch(xref, &patternObj2);
+  } else {
+    patternObj->copy(&patternObj2);
+  }
+  if (patternObj2.isDict()) {
+    patternDict = patternObj2.getDict();
+  } else if (patternObj2.isStream()) {
+    patternDict = patternObj2.streamGetDict();
+  } else {
+    patternObj2.free();
+    return gFalse;
+  }
+
+  if (!patternDict->lookupNF("Resources", &obj1)->isNull()) {
+    if (scanResourcesForBlendMode(&obj1, scannedObjs, xref)) {
+      obj1.free();
+      patternObj2.free();
+      return gTrue;
+    }
+  }
+  obj1.free();
+
+  patternObj2.free();
+
+  return gFalse;
+}
+
+GBool GfxTilingPattern::scanXObjectForBlendMode(Object *xObj,
+						char *scannedObjs,
+						XRef *xref) {
+  Object xObj2, obj1;
+  Dict *dict;
+
+  if (xObj->isRef()) {
+    if (xObj->getRefNum() >= xref->getNumObjects() ||
+	scannedObjs[xObj->getRefNum()]) {
+      return gFalse;
+    }
+    scannedObjs[xObj->getRefNum()] = 1;
+    xObj->fetch(xref, &xObj2);
+  } else {
+    xObj->copy(&xObj2);
+  }
+  if (xObj2.isDict()) {
+    dict = xObj2.getDict();
+  } else if (xObj2.isStream()) {
+    dict = xObj2.streamGetDict();
+  } else {
+    xObj2.free();
+    return gFalse;
+  }
+
+  if (!dict->lookupNF("Resources", &obj1)->isNull()) {
+    if (scanResourcesForBlendMode(&obj1, scannedObjs, xref)) {
+      obj1.free();
+      xObj2.free();
+      return gTrue;
+    }
+  }
+  obj1.free();
+
+  xObj2.free();
+
+  return gFalse;
+}
+
 //------------------------------------------------------------------------
 // GfxShadingPattern
 //------------------------------------------------------------------------
@@ -2963,8 +3211,8 @@
   }
 }
 
-void GfxGouraudTriangleShading::getBBox(double *xMin, double *yMin,
-					double *xMax, double *yMax) {
+void GfxGouraudTriangleShading::getBBox(double *xMinA, double *yMinA,
+					double *xMaxA, double *yMaxA) {
   double xxMin = 0;
   double yyMin = 0;
   double xxMax = 0;
@@ -2985,10 +3233,10 @@
       yyMax = vertices[i].y;
     }
   }
-  *xMin = xxMin;
-  *yMin = yyMin;
-  *xMax = xxMax;
-  *yMax = yyMax;
+  *xMinA = xxMin;
+  *yMinA = yyMin;
+  *xMaxA = xxMax;
+  *yMaxA = yyMax;
 }
 
 void GfxGouraudTriangleShading::getColor(double *in, GfxColor *out) {
@@ -3621,8 +3869,8 @@
   return new GfxPatchMeshShading(this);
 }
 
-void GfxPatchMeshShading::getBBox(double *xMin, double *yMin,
-				  double *xMax, double *yMax) {
+void GfxPatchMeshShading::getBBox(double *xMinA, double *yMinA,
+				  double *xMaxA, double *yMaxA) {
   double xxMin = 0;
   double yyMin = 0;
   double xxMax = 0;
@@ -3647,10 +3895,10 @@
       }
     }
   }
-  *xMin = xxMin;
-  *yMin = yyMin;
-  *xMax = xxMax;
-  *yMax = yyMax;
+  *xMinA = xxMin;
+  *yMinA = yyMin;
+  *xMaxA = xxMax;
+  *yMaxA = yyMax;
 }
 
 void GfxPatchMeshShading::getColor(double *in, GfxColor *out) {
@@ -4651,35 +4899,36 @@
   // There are two cases for each point on the path:
   // (1) miter join, under miter limit => compute the miter point
   // (2) all other joins and caps => use the path point +/- 0.5 * line width
-  double xMin = 0, yMin = 0, xMax = 0, yMax = 0;
+  double uxMin = 0, uyMin = 0, uxMax = 0, uyMax = 0;
   double w = 0.5 * lineWidth;
   for (int i = 0; i < path->getNumSubpaths(); ++i) {
     GfxSubpath *subpath = path->getSubpath(i);
-    for (int j = 0; j < subpath->getNumPoints(); ++j) {
+    int nPoints;
+    if (subpath->isClosed()) {
+      nPoints = subpath->getNumPoints() - 1;
+    } else {
+      nPoints = subpath->getNumPoints();
+    }
+    for (int j = 0; j < nPoints; ++j) {
       double x1 = subpath->getX(j);
       double y1 = subpath->getY(j);
       if (i == 0 && j == 0) {
-	xMin = xMax = x1;
-	yMin = yMax = y1;
+	uxMin = uxMax = x1;
+	uyMin = uyMax = y1;
       }
       GBool useMiter = gFalse;
       if (lineJoin == 0 &&  // miter join
-	  ((j > 0 && j < subpath->getNumPoints() - 1) || subpath->isClosed())) {
+	  (subpath->isClosed() || (j > 0 && j < subpath->getNumPoints() - 1))) {
 	double x0, y0, x2, y2;
-	if (j > 0) {
+	if (j == 0) {
+	  x0 = subpath->getX(nPoints - 1);
+	  y0 = subpath->getY(nPoints - 1);
+	} else {
 	  x0 = subpath->getX(j - 1);
 	  y0 = subpath->getY(j - 1);
-	} else {
-	  x0 = subpath->getLastX();
-	  y0 = subpath->getLastY();
 	}
-	if (j < subpath->getNumPoints() - 1) {
-	  x2 = subpath->getX(j + 1);
-	  y2 = subpath->getY(j + 1);
-	} else {
-	  x2 = subpath->getX(0);
-	  y2 = subpath->getY(0);
-	}
+	x2 = subpath->getX(j + 1);
+	y2 = subpath->getY(j + 1);
 	if ((fabs(x1 - x0) > 0.0001 || fabs(y1 - y0) > 0.0001) &&
 	    (fabs(x2 - x1) > 0.0001 || fabs(y2 - y1) > 0.0001)) {
 	  double d01 = 1 / sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
@@ -4704,15 +4953,15 @@
 	      }
 	      double mx = ax + m * w * ux;
 	      double my = ay + m * w * uy;
-	      if (mx < xMin) {
-		xMin = mx;
-	      } else if (mx > xMax) {
-		xMax = mx;
+	      if (mx < uxMin) {
+		uxMin = mx;
+	      } else if (mx > uxMax) {
+		uxMax = mx;
 	      }
-	      if (my < yMin) {
-		yMin = my;
-	      } else if (my > yMax) {
-		yMax = my;
+	      if (my < uyMin) {
+		uyMin = my;
+	      } else if (my > uyMax) {
+		uyMax = my;
 	      }
 	      useMiter = gTrue;
 	    }
@@ -4720,67 +4969,72 @@
 	}
       }
       if (!useMiter) {
-	if (x1 - w < xMin) {
-	  xMin = x1 - w;
+	if (x1 - w < uxMin) {
+	  uxMin = x1 - w;
 	}
-	if (x1 + w > xMax) {
-	  xMax = x1 + w;
+	if (x1 + w > uxMax) {
+	  uxMax = x1 + w;
 	}
-	if (y1 - w < yMin) {
-	  yMin = y1 - w;
+	if (y1 - w < uyMin) {
+	  uyMin = y1 - w;
 	}
-	if (y1 + w > yMax) {
-	  yMax = y1 + w;
+	if (y1 + w > uyMax) {
+	  uyMax = y1 + w;
 	}
       }
     }
   }
 
-  double xx, yy;
-  transform(xMin, yMin, &xx, &yy);
-  if (xx < clipXMin) {
-    clipXMin = xx;
-  } else if (xx > clipXMax) {
-    clipXMax = xx;
+  double dxMin, dyMin, dxMax, dyMax, xx, yy;
+  transform(uxMin, uyMin, &xx, &yy);
+  dxMin = dxMax = xx;
+  dyMin = dyMax = yy;
+  transform(uxMin, uyMax, &xx, &yy);
+  if (xx < dxMin) {
+    dxMin = xx;
+  } else if (xx > dxMax) {
+    dxMax = xx;
   }
-  if (yy < clipYMin) {
-    clipYMin = yy;
-  } else if (yy > clipYMax) {
-    clipYMax = yy;
+  if (yy < dyMin) {
+    dyMin = yy;
+  } else if (yy > dyMax) {
+    dyMax = yy;
   }
-  transform(xMin, yMax, &xx, &yy);
-  if (xx < clipXMin) {
-    clipXMin = xx;
-  } else if (xx > clipXMax) {
-    clipXMax = xx;
+  transform(uxMax, uyMin, &xx, &yy);
+  if (xx < dxMin) {
+    dxMin = xx;
+  } else if (xx > dxMax) {
+    dxMax = xx;
   }
-  if (yy < clipYMin) {
-    clipYMin = yy;
-  } else if (yy > clipYMax) {
-    clipYMax = yy;
+  if (yy < dyMin) {
+    dyMin = yy;
+  } else if (yy > dyMax) {
+    dyMax = yy;
   }
-  transform(xMax, yMin, &xx, &yy);
-  if (xx < clipXMin) {
-    clipXMin = xx;
-  } else if (xx > clipXMax) {
-    clipXMax = xx;
+  transform(uxMax, uyMax, &xx, &yy);
+  if (xx < dxMin) {
+    dxMin = xx;
+  } else if (xx > dxMax) {
+    dxMax = xx;
   }
-  if (yy < clipYMin) {
-    clipYMin = yy;
-  } else if (yy > clipYMax) {
-    clipYMax = yy;
+  if (yy < dyMin) {
+    dyMin = yy;
+  } else if (yy > dyMax) {
+    dyMax = yy;
   }
-  transform(xMax, yMax, &xx, &yy);
-  if (xx < clipXMin) {
-    clipXMin = xx;
-  } else if (xx > clipXMax) {
-    clipXMax = xx;
+
+  if (dxMin > clipXMin) {
+    clipXMin = dxMin;
   }
-  if (yy < clipYMin) {
-    clipYMin = yy;
-  } else if (yy > clipYMax) {
-    clipYMax = yy;
+  if (dyMin > clipYMin) {
+    clipYMin = dyMin;
   }
+  if (dxMax < clipXMax) {
+    clipXMax = dxMax;
+  }
+  if (dyMax < clipYMax) {
+    clipYMax = dyMax;
+  }
 }
 
 void GfxState::clipToRect(double xMin, double yMin, double xMax, double yMax) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "Object.h"
 #include "Function.h"
@@ -663,6 +659,7 @@
     { return resDict.isDict() ? resDict.getDict() : (Dict *)NULL; }
   double *getMatrix() { return matrix; }
   Object *getContentStreamRef() { return &contentStreamRef; }
+  GBool usesBlendMode(XRef *xref);
 
 private:
 
@@ -670,6 +667,16 @@
 		   double *bboxA, double xStepA, double yStepA,
 		   Object *resDictA, double *matrixA,
 		   Object *contentStreamA);
+  GBool scanResourcesForBlendMode(Object *resDict2,
+				  char *scannedObjs, XRef *xref);
+  GBool scanExtGStateForBlendMode(Object *gsObj,
+				  char *scannedObjs, XRef *xref);
+  GBool scanSoftMaskForBlendMode(Object *softMaskObj,
+				 char *scannedObjs, XRef *xref);
+  GBool scanPatternForBlendMode(Object *patternObj,
+				char *scannedObjs, XRef *xref);
+  GBool scanXObjectForBlendMode(Object *xObj,
+				char *scannedObjs, XRef *xref);
 
   int paintType;
   int tilingType;
@@ -883,7 +890,7 @@
   void getTriangle(int i, double *x0, double *y0, double *color0,
 		   double *x1, double *y1, double *color1,
 		   double *x2, double *y2, double *color2);
-  void getBBox(double *xMin, double *yMin, double *xMax, double *yMax);
+  void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA);
   void getColor(double *in, GfxColor *out);
 
 private:
@@ -923,7 +930,7 @@
   int getNComps() { return nComps; }
   int getNPatches() { return nPatches; }
   GfxPatch *getPatch(int i) { return &patches[i]; }
-  void getBBox(double *xMin, double *yMin, double *xMax, double *yMax);
+  void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA);
   void getColor(double *in, GfxColor *out);
 
 private:

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <string.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -44,10 +40,12 @@
 #include "GlobalParams.h"
 
 #ifdef _WIN32
+#ifndef __GNUC__
 #  undef strcasecmp
 #  undef strncasecmp
 #  define strcasecmp _stricmp
 #  define strncasecmp _strnicmp
+#endif
 #else
 #  include <strings.h>
 #endif
@@ -105,14 +103,14 @@
   {NULL}
 };
 
+static const char *displayFontDirs[] = {
+#ifdef BASE14_FONT_DIR
+  BASE14_FONT_DIR,
+#endif
 #ifdef _WIN32
-static const char *displayFontDirs[] = {
   "c:/windows/fonts",
   "c:/winnt/fonts",
-  NULL
-};
-#else
-static const char *displayFontDirs[] = {
+#else // _WIN32
   "/usr/share/ghostscript/fonts",
   "/usr/local/share/ghostscript/fonts",
   "/usr/share/fonts/default/Type1",
@@ -121,9 +119,9 @@
 #if defined(__sun) && defined(__SVR4)
   "/usr/sfw/share/ghostscript/fonts",
 #endif
+#endif // _WIN32
   NULL
 };
-#endif
 
 #ifdef __APPLE__
 static const char *macSystemFontPath = "/System/Library/Fonts";
@@ -183,7 +181,7 @@
   ~SysFontInfo();
   GString *mungeName1(GString *in);
   GString *mungeName2(GString *in);
-  void mungeName3(GString *name, GBool *bold, GBool *italic);
+  void mungeName3(GString *nameA, GBool *bold, GBool *italic);
   int match(GString *nameA);
 };
 
@@ -260,24 +258,24 @@
 
 // Remove trailing bold/italic/regular/roman tags from the name.
 // (Note: the names have already been uppercased by mungeName1/2.)
-void SysFontInfo::mungeName3(GString *name, GBool *bold, GBool *italic) {
+void SysFontInfo::mungeName3(GString *nameA, GBool *bold, GBool *italic) {
   *bold = gFalse;
   *italic = gFalse;
-  int n = name->getLength();
+  int n = nameA->getLength();
   while (1) {
-    if (n >= 4 && !strcmp(name->getCString() + n - 4, "BOLD")) {
-      name->del(n - 4, 4);
+    if (n >= 4 && !strcmp(nameA->getCString() + n - 4, "BOLD")) {
+      nameA->del(n - 4, 4);
       n -= 4;
       *bold = gTrue;
-    } else if (n >= 6 && !strcmp(name->getCString() + n - 6, "ITALIC")) {
-      name->del(n - 6, 6);
+    } else if (n >= 6 && !strcmp(nameA->getCString() + n - 6, "ITALIC")) {
+      nameA->del(n - 6, 6);
       n -= 6;
       *italic = gTrue;
-    } else if (n >= 7 && !strcmp(name->getCString() + n - 7, "REGULAR")) {
-      name->del(n - 7, 7);
+    } else if (n >= 7 && !strcmp(nameA->getCString() + n - 7, "REGULAR")) {
+      nameA->del(n - 7, 7);
       n -= 7;
-    } else if (n >= 5 && !strcmp(name->getCString() + n - 5, "ROMAN")) {
-      name->del(n - 5, 5);
+    } else if (n >= 5 && !strcmp(nameA->getCString() + n - 5, "ROMAN")) {
+      nameA->del(n - 5, 5);
       n -= 5;
     } else {
       break;
@@ -659,7 +657,7 @@
   base14SysFonts = new GHash(gTrue);
   sysFonts = new SysFontList();
 #if HAVE_PAPER_H
-  char *paperName;
+  const char *paperName;
   const struct paper *paperType;
   paperinit();
   if ((paperName = systempapername())) {
@@ -715,6 +713,21 @@
   textKeepTinyChars = gTrue;
   initialZoom = new GString("125");
   defaultFitZoom = 0;
+  zoomScaleFactor = 1;
+  zoomValues = new GList();
+  zoomValues->append(new GString("25"));
+  zoomValues->append(new GString("50"));
+  zoomValues->append(new GString("75"));
+  zoomValues->append(new GString("100"));
+  zoomValues->append(new GString("110"));
+  zoomValues->append(new GString("125"));
+  zoomValues->append(new GString("150"));
+  zoomValues->append(new GString("175"));
+  zoomValues->append(new GString("200"));
+  zoomValues->append(new GString("300"));
+  zoomValues->append(new GString("400"));
+  zoomValues->append(new GString("600"));
+  zoomValues->append(new GString("800"));
   initialDisplayMode = new GString("continuous");
   initialToolbarState = gTrue;
   initialSidebarState = gTrue;
@@ -748,6 +761,7 @@
   fullScreenMatteColor = new GString("#000000");
   selectionColor = new GString("#8080ff");
   reverseVideoInvertImages = gFalse;
+  allowLinksToChangeZoom = gTrue;
   launchCommand = NULL;
   movieCommand = NULL;
   defaultPrinter = NULL;
@@ -755,10 +769,15 @@
   mapUnknownCharNames = gFalse;
   mapExtTrueTypeFontsViaUnicode = gTrue;
   useTrueTypeUnicodeMapping = gFalse;
+  ignoreWrongSizeToUnicode = gFalse;
   droppedFonts = new GHash(gTrue);
+  separateRotatedText = gFalse;
   createDefaultKeyBindings();
   popupMenuCmds = new GList();
-  tabStateFile = appendToPath(getHomeDir(), ".xpdf.tab-state");
+#ifndef PDF_PARSER_ONLY
+  initStateFilePaths();
+#endif
+  saveSessionOnQuit = gTrue;
   savePageNumbers = gTrue;
   printCommands = gFalse;
   printStatusInfo = gFalse;
@@ -1017,6 +1036,27 @@
 				     xpdfKeyContextAny, "zoomFitWidth"));
 }
 
+#ifndef PDF_PARSER_ONLY
+void GlobalParams::initStateFilePaths() {
+#ifdef _WIN32
+  char path[MAX_PATH];
+  if (SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL,
+		       SHGFP_TYPE_CURRENT, path) != S_OK) {
+    return;
+  }
+  GString *dir = appendToPath(new GString(path), "xpdf");
+  CreateDirectoryA(dir->getCString(), NULL);
+  pagesFile = appendToPath(dir->copy(), "xpdf.pages");
+  tabStateFile = appendToPath(dir->copy(), "xpdf.tab-state");
+  sessionFile = appendToPath(dir, "xpdf.session");
+#else
+  pagesFile = appendToPath(getHomeDir(), ".xpdf.pages");
+  tabStateFile = appendToPath(getHomeDir(), ".xpdf.tab-state");
+  sessionFile = appendToPath(getHomeDir(), ".xpdf.session");
+#endif
+}
+#endif
+
 void GlobalParams::parseFile(GString *fileName, FILE *f) {
   int line;
   char buf[512];
@@ -1157,6 +1197,10 @@
       parseString("initialZoom", &initialZoom, tokens, fileName, line);
     } else if (!cmd->cmp("defaultFitZoom")) {
       parseInteger("defaultFitZoom", &defaultFitZoom, tokens, fileName, line);
+    } else if (!cmd->cmp("zoomScaleFactor")) {
+      parseZoomScaleFactor(tokens, fileName, line);
+    } else if (!cmd->cmp("zoomValues")) {
+      parseZoomValues(tokens, fileName, line);
     } else if (!cmd->cmp("initialDisplayMode")) {
       parseString("initialDisplayMode", &initialDisplayMode,
 		  tokens, fileName, line);
@@ -1244,6 +1288,9 @@
     } else if (!cmd->cmp("reverseVideoInvertImages")) {
       parseYesNo("reverseVideoInvertImages", &reverseVideoInvertImages,
 		 tokens, fileName, line);
+    } else if (!cmd->cmp("allowLinksToChangeZoom")) {
+      parseYesNo("allowLinksToChangeZoom", &allowLinksToChangeZoom,
+		 tokens, fileName, line);
     } else if (!cmd->cmp("launchCommand")) {
       parseString("launchCommand", &launchCommand, tokens, fileName, line);
     } else if (!cmd->cmp("movieCommand")) {
@@ -1261,11 +1308,16 @@
 		 &mapExtTrueTypeFontsViaUnicode,
 		 tokens, fileName, line);
     } else if (!cmd->cmp("useTrueTypeUnicodeMapping")) {
-      parseYesNo("useTrueTypeUnicodeMapping",
-		 &useTrueTypeUnicodeMapping,
+      parseYesNo("useTrueTypeUnicodeMapping", &useTrueTypeUnicodeMapping,
 		 tokens, fileName, line);
+    } else if (!cmd->cmp("ignoreWrongSizeToUnicode")) {
+      parseYesNo("ignoreWrongSizeToUnicode", &ignoreWrongSizeToUnicode,
+		 tokens, fileName, line);
     } else if (!cmd->cmp("dropFont")) {
       parseDropFont(tokens, fileName, line);
+    } else if (!cmd->cmp("separateRotatedText")) {
+      parseYesNo("separateRotatedText", &separateRotatedText,
+		 tokens, fileName, line);
     } else if (!cmd->cmp("bind")) {
       parseBind(tokens, fileName, line);
     } else if (!cmd->cmp("unbind")) {
@@ -1274,6 +1326,11 @@
       parsePopupMenuCmd(tokens, fileName, line);
     } else if (!cmd->cmp("tabStateFile")) {
       parseString("tabStateFile", &tabStateFile, tokens, fileName, line);
+    } else if (!cmd->cmp("sessionFile")) {
+      parseString("sessionFile", &sessionFile, tokens, fileName, line);
+    } else if (!cmd->cmp("saveSessionOnQuit")) {
+      parseYesNo("saveSessionOnQuit", &saveSessionOnQuit,
+		 tokens, fileName, line);
     } else if (!cmd->cmp("savePageNumbers")) {
       parseYesNo("savePageNumbers", &savePageNumbers, tokens, fileName, line);
     } else if (!cmd->cmp("printCommands")) {
@@ -1973,6 +2030,59 @@
 					 cmds));
 }
 
+void GlobalParams::parseZoomScaleFactor(GList *tokens,
+					GString *fileName, int line) {
+  if (tokens->getLength() != 2) {
+    error(errConfig, -1, "Bad 'zoomScaleFactor' config file command ({0:t}:{1:d})",
+	  fileName, line);
+    return;
+  }
+  GString *tok = (GString *)tokens->get(1);
+  if (tok->getLength() == 0) {
+    error(errConfig, -1, "Bad 'zoomScaleFactor' config file command ({0:t}:{1:d})",
+	  fileName, line);
+    return;
+  }
+  if (tok->cmp("actual") == 0) {
+    zoomScaleFactor = -1;
+  } else {
+    for (int i = 0; i < tok->getLength(); ++i) {
+      if (!((tok->getChar(i) >= '0' && tok->getChar(i) <= '9') ||
+	    tok->getChar(i) == '.')) {
+	error(errConfig, -1, "Bad 'zoomScaleFactor' config file command ({0:t}:{1:d})",
+	      fileName, line);
+	return;
+      }
+    }
+    zoomScaleFactor = atof(tok->getCString());
+  }
+}
+
+void GlobalParams::parseZoomValues(GList *tokens,
+				   GString *fileName, int line) {
+  if (tokens->getLength() < 2) {
+    error(errConfig, -1, "Bad 'zoomValues' config file command ({0:t}:{1:d})",
+	  fileName, line);
+    return;
+  }
+  for (int i = 1; i < tokens->getLength(); ++i) {
+    GString *tok = (GString *)tokens->get(i);
+    for (int j = 0; j < tok->getLength(); ++j) {
+      if (tok->getChar(j) < '0' || tok->getChar(j) > '9') {
+	error(errConfig, -1, "Bad 'zoomValues' config file command ({0:t}:{1:d})",
+	      fileName, line);
+	return;
+      }
+    }
+  }
+  deleteGList(zoomValues, GString);
+  zoomValues = new GList();
+  for (int i = 1; i < tokens->getLength(); ++i) {
+    GString *tok = (GString *)tokens->get(i);
+    zoomValues->append(tok->copy());
+  }
+}
+
 void GlobalParams::parseYesNo(const char *cmdName, GBool *flag,
 			      GList *tokens, GString *fileName, int line) {
   GString *tok;
@@ -2104,6 +2214,7 @@
   deleteGList(psResidentFontsCC, PSFontParam16);
   delete textEncoding;
   delete initialZoom;
+  deleteGList(zoomValues, GString);
   delete initialDisplayMode;
   delete initialSelectMode;
   if (paperColor) {
@@ -2130,7 +2241,9 @@
   delete droppedFonts;
   deleteGList(keyBindings, KeyBinding);
   deleteGList(popupMenuCmds, PopupMenuCmd);
+  delete pagesFile;
   delete tabStateFile;
+  delete sessionFile;
   delete debugLogFile;
 
   cMapDirs->startIter(&iter);
@@ -2959,6 +3072,19 @@
   return z;
 }
 
+double GlobalParams::getZoomScaleFactor() {
+  double z;
+
+  lockGlobalParams;
+  z = zoomScaleFactor;
+  unlockGlobalParams;
+  return z;
+}
+
+GList *GlobalParams::getZoomValues() {
+  return zoomValues;
+}
+
 GString *GlobalParams::getInitialDisplayMode() {
   GString *s;
 
@@ -3250,6 +3376,15 @@
   return invert;
 }
 
+GBool GlobalParams::getAllowLinksToChangeZoom() {
+  GBool allow;
+
+  lockGlobalParams;
+  allow = allowLinksToChangeZoom;
+  unlockGlobalParams;
+  return allow;
+}
+
 GString *GlobalParams::getDefaultPrinter() {
   GString *s;
 
@@ -3295,6 +3430,15 @@
   return use;
 }
 
+GBool GlobalParams::getIgnoreWrongSizeToUnicode() {
+  GBool ignore;
+
+  lockGlobalParams;
+  ignore = ignoreWrongSizeToUnicode;
+  unlockGlobalParams;
+  return ignore;
+}
+
 GBool GlobalParams::isDroppedFont(const char *fontName) {
   GBool isDropped;
 
@@ -3304,6 +3448,15 @@
   return isDropped;
 }
 
+GBool GlobalParams::getSeparateRotatedText() {
+  GBool sep;
+
+  lockGlobalParams;
+  sep = separateRotatedText;
+  unlockGlobalParams;
+  return sep;
+}
+
 GList *GlobalParams::getKeyBinding(int code, int mods, int context) {
   KeyBinding *binding;
   GList *cmds;
@@ -3356,6 +3509,15 @@
   return cmd;
 }
 
+GString *GlobalParams::getPagesFile() {
+  GString *s;
+
+  lockGlobalParams;
+  s = pagesFile->copy();
+  unlockGlobalParams;
+  return s;
+}
+
 GString *GlobalParams::getTabStateFile() {
   GString *s;
 
@@ -3365,6 +3527,15 @@
   return s;
 }
 
+GString *GlobalParams::getSessionFile() {
+  GString *s;
+
+  lockGlobalParams;
+  s = sessionFile->copy();
+  unlockGlobalParams;
+  return s;
+}
+
 GBool GlobalParams::getSavePageNumbers() {
   GBool s;
 
@@ -3374,6 +3545,15 @@
   return s;
 }
 
+GBool GlobalParams::getSaveSessionOnQuit() {
+  GBool s;
+
+  lockGlobalParams;
+  s = saveSessionOnQuit;
+  unlockGlobalParams;
+  return s;
+}
+
 GBool GlobalParams::getPrintCommands() {
   GBool p;
 
@@ -3712,6 +3892,12 @@
   unlockGlobalParams;
 }
 
+void GlobalParams::setDefaultFitZoom(int z) {
+  lockGlobalParams;
+  defaultFitZoom = z;
+  unlockGlobalParams;
+}
+
 GBool GlobalParams::setEnableFreeType(char *s) {
   GBool ok;
 
@@ -3815,6 +4001,13 @@
   unlockGlobalParams;
 }
 
+void GlobalParams::setSessionFile(char *sessionFileA) {
+  lockGlobalParams;
+  delete sessionFile;
+  sessionFile = new GString(sessionFileA);
+  unlockGlobalParams;
+}
+
 void GlobalParams::setPrintCommands(GBool printCommandsA) {
   lockGlobalParams;
   printCommands = printCommandsA;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -14,10 +14,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <stdio.h>
 #ifdef _WIN32
 #  include <windows.h>
@@ -303,6 +299,8 @@
   GBool getTextKeepTinyChars();
   GString *getInitialZoom();
   int getDefaultFitZoom();
+  double getZoomScaleFactor();
+  GList *getZoomValues();
   GString *getInitialDisplayMode();
   GBool getInitialToolbarState();
   GBool getInitialSidebarState();
@@ -336,6 +334,7 @@
   GString *getFullScreenMatteColor();
   GString *getSelectionColor();
   GBool getReverseVideoInvertImages();
+  GBool getAllowLinksToChangeZoom();
   GString *getLaunchCommand() { return launchCommand; }
   GString *getMovieCommand() { return movieCommand; }
   GString *getDefaultPrinter();
@@ -343,12 +342,17 @@
   GBool getMapUnknownCharNames();
   GBool getMapExtTrueTypeFontsViaUnicode();
   GBool getUseTrueTypeUnicodeMapping();
+  GBool getIgnoreWrongSizeToUnicode();
   GBool isDroppedFont(const char *fontName);
+  GBool getSeparateRotatedText();
   GList *getKeyBinding(int code, int mods, int context);
   GList *getAllKeyBindings();
   int getNumPopupMenuCmds();
   PopupMenuCmd *getPopupMenuCmd(int idx);
+  GString *getPagesFile();
   GString *getTabStateFile();
+  GString *getSessionFile();
+  GBool getSaveSessionOnQuit();
   GBool getSavePageNumbers();
   GBool getPrintCommands();
   GBool getPrintStatusInfo();
@@ -390,6 +394,7 @@
   void setTextPageBreaks(GBool pageBreaks);
   void setTextKeepTinyChars(GBool keep);
   void setInitialZoom(char *s);
+  void setDefaultFitZoom(int z);
   GBool setEnableFreeType(char *s);
   GBool setAntialias(char *s);
   GBool setVectorAntialias(char *s);
@@ -405,6 +410,7 @@
   void setMapUnknownCharNames(GBool map);
   void setMapExtTrueTypeFontsViaUnicode(GBool map);
   void setTabStateFile(char *tabStateFileA);
+  void setSessionFile(char *sessionFileA);
   void setPrintCommands(GBool printCommandsA);
   void setPrintStatusInfo(GBool printStatusInfoA);
   void setErrQuiet(GBool errQuietA);
@@ -420,6 +426,9 @@
 
   void setDataDirVar();
   void createDefaultKeyBindings();
+#ifndef PDF_PARSER_ONLY
+  void initStateFilePaths();
+#endif
   void parseFile(GString *fileName, FILE *f);
   GList *parseLineTokens(char *buf, GString *fileName, int line);
   void parseNameToUnicode(GList *tokens, GString *fileName, int line);
@@ -450,6 +459,8 @@
 		 const char *cmdName,
 		 GList *tokens, GString *fileName, int line);
   void parsePopupMenuCmd(GList *tokens, GString *fileName, int line);
+  void parseZoomScaleFactor(GList *tokens, GString *fileName, int line);
+  void parseZoomValues(GList *tokens, GString *fileName, int line);
   void parseYesNo(const char *cmdName, GBool *flag,
 		  GList *tokens, GString *fileName, int line);
   GBool parseYesNo2(char *token, GBool *flag);
@@ -548,7 +559,9 @@
   GBool textKeepTinyChars;	// keep all characters in text output
   GString *initialZoom;		// initial zoom level
   int defaultFitZoom;		// default zoom factor if initialZoom is
-				//   'page' or 'width'.
+				//   'page' or 'width'
+  double zoomScaleFactor;	// displayed zoom values are scaled by this
+  GList *zoomValues;		// zoom values for the combo box
   GString *initialDisplayMode;	// initial display mode (single,
 				//   continuous, etc.)
   GBool initialToolbarState;	// initial toolbar state - open (true)
@@ -586,6 +599,7 @@
   GString *fullScreenMatteColor; // matte color in full-screen mode
   GString *selectionColor;	// selection color
   GBool reverseVideoInvertImages; // invert images in reverse video mode
+  GBool allowLinksToChangeZoom;	// allow clicking on a link to change the zoom
   GString *launchCommand;	// command executed for 'launch' links
   GString *movieCommand;	// command executed for movie annotations
   GString *defaultPrinter;	// default printer (for interactive printing
@@ -597,10 +611,16 @@
   GBool useTrueTypeUnicodeMapping;	// use the Unicode cmaps in TrueType
 					//   fonts, rather than the PDF
 					//   ToUnicode mapping
+  GBool ignoreWrongSizeToUnicode;  // ignore ToUnicode CMaps if their size
+				   //   (8-bit vs 16-bit) doesn't match the font
   GHash *droppedFonts;		// dropped fonts [int]
+  GBool separateRotatedText;	// separate text at each rotation
   GList *keyBindings;		// key & mouse button bindings [KeyBinding]
   GList *popupMenuCmds;		// popup menu commands [PopupMenuCmd]
+  GString *pagesFile;		// path for the page number save file
   GString *tabStateFile;	// path for the tab state save file
+  GString *sessionFile;		// path for the session save file
+  GBool saveSessionOnQuit;	// save session info when xpdf is quit
   GBool savePageNumbers;	// save page number when file is closed
 				//   and restore page number when opened
   GBool printCommands;		// print the drawing commands

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -21,10 +21,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <png.h>
 #include "gmem.h"
@@ -35,6 +31,7 @@
 #include "PDFDoc.h"
 #include "GfxFont.h"
 #include "AcroForm.h"
+#include "TextString.h"
 #include "TextOutputDev.h"
 #include "SplashOutputDev.h"
 #include "ErrorCodes.h"
@@ -42,9 +39,11 @@
 #include "HTMLGen.h"
 
 #ifdef _WIN32
+#ifndef __GNUC__
 #  define strcasecmp stricmp
 #  define strncasecmp strnicmp
 #endif
+#endif
 
 //------------------------------------------------------------------------
 
@@ -297,6 +296,7 @@
   convertFormFields = gFalse;
   embedBackgroundImage = gFalse;
   embedFonts = gFalse;
+  includeMetadata = gFalse;
 
   // set up the TextOutputDev
   textOutControl.mode = tableMode ? textOutTableLayout : textOutReadingOrder;
@@ -312,6 +312,10 @@
   splashOut = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor);
 
   fontDefns = NULL;
+
+  nVisibleChars = 0;
+  nInvisibleChars = 0;
+  nRemovedDupChars = 0;
 }
 
 HTMLGen::~HTMLGen() {
@@ -462,11 +466,11 @@
 	    llyI = bitmap->getHeight() - 1;
 	  }
 	  if (uryI <= llyI && llxI <= urxI) {
-	    SplashColorPtr p = bitmap->getDataPtr()
-	                         + uryI * bitmap->getRowSize() + llxI * 3;
-	    for (int y = uryI; y <= llyI; ++y) {
-	      memset(p, 0xff, (urxI - llxI + 1) * 3);
-	      p += bitmap->getRowSize();
+	    SplashColorPtr pix = bitmap->getDataPtr()
+	                           + uryI * bitmap->getRowSize() + llxI * 3;
+	    for (y = uryI; y <= llyI; ++y) {
+	      memset(pix, 0xff, (urxI - llxI + 1) * 3);
+	      pix += bitmap->getRowSize();
 	    }
 	  }
 
@@ -483,6 +487,9 @@
   pr(writeHTML, htmlStream, "<html>\n");
   pr(writeHTML, htmlStream, "<head>\n");
   pr(writeHTML, htmlStream, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
+  if (includeMetadata) {
+    genDocMetadata(writeHTML, htmlStream);
+  }
   pr(writeHTML, htmlStream, "<style type=\"text/css\">\n");
   pr(writeHTML, htmlStream, ".txt { white-space:nowrap; }\n");
   if (convertFormFields) {
@@ -571,6 +578,9 @@
   // generate the HTML text
   nextFieldID = 0;
   cols = text->makeColumns();
+  nVisibleChars = text->getNumVisibleChars();
+  nInvisibleChars = text->getNumInvisibleChars();
+  nRemovedDupChars = text->getNumRemovedDupChars();
   for (colIdx = 0; colIdx < cols->getLength(); ++colIdx) {
     col = (TextColumn *)cols->get(colIdx);
     pars = col->getParagraphs();
@@ -1118,3 +1128,47 @@
   *weight = bold ? "bold" : "normal";
   *style = italic ? "italic" : "normal";
 }
+
+void HTMLGen::genDocMetadata(int (*writeHTML)(void *stream,
+					      const char *data, int size),
+			     void *htmlStream) {
+  Object info;
+  doc->getDocInfo(&info);
+  if (info.isDict()) {
+    genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "Title");
+    genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "Subject");
+    genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "Keywords");
+    genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "Author");
+    genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "Creator");
+    genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "Producer");
+    genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "CreationDate");
+    genDocMetadataItem(writeHTML, htmlStream, info.getDict(), "ModDate");
+  }
+  info.free();
+}
+
+void HTMLGen::genDocMetadataItem(int (*writeHTML)(void *stream,
+						  const char *data, int size),
+				 void *htmlStream,
+				 Dict *infoDict, const char *key) {
+  Object val;
+  if (infoDict->lookup(key, &val)->isString()) {
+    GString *s = GString::format("<meta name=\"{0:s}\" content=\"", key);
+    TextString *ts = new TextString(val.getString());
+    Unicode *u = ts->getUnicode();
+    for (int i = 0; i < ts->getLength(); ++i) {
+      if (u[i] == '"') {
+	s->append(""");
+      } else if (u[i] == '&') {
+	s->append("&");
+      } else {
+	appendUTF8(u[i], s);
+      }
+    }
+    delete ts;
+    s->append("\">\n");
+    writeHTML(htmlStream, s->getCString(), s->getLength());
+    delete s;
+  }
+  val.free();
+}

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 class GString;
 class PDFDoc;
 class TextOutputDev;
@@ -61,6 +57,9 @@
   void setEmbedFonts(GBool embedFontsA)
     { embedFonts = embedFontsA; }
 
+  void setIncludeMetadata(GBool includeMetadataA)
+    { includeMetadata = includeMetadataA; }
+
   void startDoc(PDFDoc *docA);
   int convertPage(int pg, const char *pngURL, const char *htmlDir,
 		  int (*writeHTML)(void *stream, const char *data, int size),
@@ -68,6 +67,11 @@
 		  int (*writePNG)(void *stream, const char *data, int size),
 		  void *pngStream);
 
+  // Get the counter values.
+  int getNumVisibleChars() { return nVisibleChars; }
+  int getNumInvisibleChars() { return nInvisibleChars; }
+  int getNumRemovedDupChars() { return nRemovedDupChars; }
+
 private:
 
   int findDirSpan(GList *words, int firstWordIdx, int primaryDir,
@@ -82,6 +86,13 @@
   void getFontDetails(TextFontInfo *font, const char **family,
 		      const char **weight, const char **style,
 		      double *scale);
+  void genDocMetadata(int (*writeHTML)(void *stream,
+				       const char *data, int size),
+		      void *htmlStream);
+  void genDocMetadataItem(int (*writeHTML)(void *stream,
+					   const char *data, int size),
+			  void *htmlStream,
+			  Dict *infoDict, const char *key);
 
   double backgroundResolution;
   double zoom;
@@ -92,6 +103,7 @@
   GBool convertFormFields;
   GBool embedBackgroundImage;
   GBool embedFonts;
+  GBool includeMetadata;
 
   PDFDoc *doc;
   TextOutputDev *textOut;
@@ -107,6 +119,10 @@
   GList *formFieldInfo;		// [HTMLGenFormFieldInfo]
   int nextFieldID;
 
+  int nVisibleChars;		// number of visible chars on the page
+  int nInvisibleChars;		// number of invisible chars on the page
+  int nRemovedDupChars;		// number of duplicate chars removed
+
   GBool ok;
 };
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
@@ -22,6 +18,7 @@
 #include "config.h"
 #include "Error.h"
 #include "GfxState.h"
+#include "Gfx.h"
 #include "Object.h"
 #include "Stream.h"
 #include "ImageOutputDev.h"
@@ -52,7 +49,8 @@
 				       double *mat, double *bbox,
 				       int x0, int y0, int x1, int y1,
 				       double xStep, double yStep) {
-  // do nothing -- this avoids the potentially slow loop in Gfx.cc
+  // draw the tile once, just in case it contains image(s)
+  gfx->drawForm(strRef, resDict, mat, bbox);
 }
 
 void ImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <stdio.h>
 #include "gtypes.h"
 #include "OutputDev.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include "gmempp.h"
 #include "Object.h"
 #include "Stream.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -13,10 +13,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 
 class Stream;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <limits.h>
 #include "gmempp.h"
@@ -1798,6 +1794,11 @@
 	    break;
 	  }
 	}
+	if (refAggNum <= 0 || refAggNum > 10000) {
+	  error(errSyntaxError, getPos(),
+		"Invalid refinement/aggregation instance count in JBIG2 symbol dictionary");
+	  goto syntaxError;
+	}
 #if 0 //~ This special case was added about a year before the final draft
       //~ of the JBIG2 spec was released.  I have encountered some old
       //~ JBIG2 images that predate it.
@@ -2440,6 +2441,18 @@
 	  refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
 	  refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
 
+	  if (rdw > INT_MAX - syms[symID]->getWidth() ||
+	      rdh > INT_MAX - syms[symID]->getHeight()) {
+	    error(errSyntaxError, getPos(),
+		  "Invalid refinement size in JBIG2 text region");
+	    continue;
+	  }
+	  // sanity check
+	  if (rdw > 1000 || rdh > 1000) {
+	    error(errSyntaxError, getPos(),
+		  "Invalid refinement size in JBIG2 text region");
+	    continue;
+	  }
 	  symbolBitmap =
 	    readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
 					rdh + syms[symID]->getHeight(),
@@ -2527,7 +2540,8 @@
       !readULong(&grayMax)) {
     goto eofError;
   }
-  if (patternW == 0 || patternH == 0) {
+  if (patternW == 0 || patternH == 0 ||
+      grayMax > UINT_MAX / patternW - 1) {
     error(errSyntaxError, getPos(),
 	  "Bad size in JBIG2 pattern dictionary segment");
     return;
@@ -3948,7 +3962,9 @@
       !readUByte(&flags) || !readUWord(&striping)) {
     goto eofError;
   }
-  if (pageW == 0 || pageH == 0 || pageW > INT_MAX / pageW) {
+  if (pageW == 0 || pageH == 0 ||
+      pageW > INT_MAX || pageH > INT_MAX ||
+      pageH > INT_MAX / pageW) {
     error(errSyntaxError, getPos(), "Bad page size in JBIG2 stream");
     return;
   }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "Object.h"
 #include "Stream.h"
@@ -45,6 +41,7 @@
   virtual GString *getPSFilter(int psLevel, const char *indent,
 			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
+  virtual GBool hasStrongCompression() { return gTrue; }
 
 private:
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <limits.h>
 #include "gmem.h"
 #include "gmempp.h"
@@ -1117,6 +1113,7 @@
 	      "JPX COC marker segment before COD segment");
 	return jpxDecodeFatalError;
       }
+      comp = 0;
       if ((img.nComps > 256 && !readUWord(&comp)) ||
 	  (img.nComps <= 256 && !readUByte(&comp)) ||
 	  comp >= img.nComps ||
@@ -1269,6 +1266,7 @@
 	      "JPX QCC marker segment before QCD segment");
 	return jpxDecodeFatalError;
       }
+      comp = 0;
       if ((img.nComps > 256 && !readUWord(&comp)) ||
 	  (img.nComps <= 256 && !readUByte(&comp)) ||
 	  comp >= img.nComps ||
@@ -1641,6 +1639,7 @@
 	error(errSyntaxError, getPos(), "Extraneous JPX COC marker segment");
 	return gFalse;
       }
+      comp = 0;
       if ((img.nComps > 256 && !readUWord(&comp)) ||
 	  (img.nComps <= 256 && !readUByte(&comp)) ||
 	  comp >= img.nComps ||
@@ -1774,6 +1773,7 @@
 	error(errSyntaxError, getPos(), "Extraneous JPX QCC marker segment");
 	return gFalse;
       }
+      comp = 0;
       if ((img.nComps > 256 && !readUWord(&comp)) ||
 	  (img.nComps <= 256 && !readUByte(&comp)) ||
 	  comp >= img.nComps ||
@@ -2619,7 +2619,12 @@
 
   if (cb->arithDecoder) {
     cover(63);
-    cb->arithDecoder->restart(cb->dataLen[0]);
+    if (tileComp->codeBlockStyle & 0x04) {
+      cb->arithDecoder->setStream(bufStr, cb->dataLen[0]);
+      cb->arithDecoder->start();
+    } else {
+      cb->arithDecoder->restart(cb->dataLen[0]);
+    }
   } else {
     cover(64);
     cb->arithDecoder = new JArithmeticDecoder();
@@ -3319,7 +3324,7 @@
 // converts fixed point samples back to integers.
 GBool JPXStream::inverseMultiCompAndDC(JPXTile *tile) {
   JPXTileComp *tileComp;
-  int coeff, d0, d1, d2, t, minVal, maxVal, zeroVal;
+  int coeff, d0, d1, d2, t, minVal, maxVal, zeroVal, shift, rounding;
   int *dataPtr;
   Guint j, comp, x, y;
 
@@ -3404,12 +3409,14 @@
       maxVal = (1 << tileComp->prec) - 1;
       zeroVal = 1 << (tileComp->prec - 1);
       dataPtr = tileComp->data;
+      shift = fracBits - tileComp->prec;
+      rounding = 1 << (shift - 1);
       for (y = 0; y < tileComp->h; ++y) {
 	for (x = 0; x < tileComp->w; ++x) {
 	  coeff = *dataPtr;
 	  if (tileComp->transform == 0) {
 	    cover(112);
-	    coeff >>= fracBits - tileComp->prec;
+	    coeff = (coeff + rounding) >> shift;
 	  }
 	  coeff += zeroVal;
 	  if (coeff < 0) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "Object.h"
 #include "Stream.h"
@@ -291,6 +287,7 @@
   virtual GString *getPSFilter(int psLevel, const char *indent,
 			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
+  virtual GBool hasStrongCompression() { return gTrue; }
   virtual void getImageParams(int *bitsPerComponent,
 			      StreamColorSpaceMode *csMode);
   void reduceResolution(int reductionA) { reduction = reductionA; }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <stddef.h>
 #include <string.h>
@@ -113,7 +109,7 @@
   char *p;
   int c, c2;
   GBool comment, neg, doubleMinus, done, invalid;
-  int numParen;
+  int numParen, nErrors;
   int xi;
   double xf, scale;
   GString *s;
@@ -434,7 +430,8 @@
       m = n = 0;
       c2 = 0;
       s = NULL;
-      while (1) {
+      nErrors = 0;
+      while (nErrors < 100) {
 	c = getChar();
 	if (c == '>') {
 	  break;
@@ -443,15 +440,17 @@
 	  break;
 	} else if (specialChars[c] != 1) {
 	  c2 = c2 << 4;
-	  if (c >= '0' && c <= '9')
+	  if (c >= '0' && c <= '9') {
 	    c2 += c - '0';
-	  else if (c >= 'A' && c <= 'F')
+	  } else if (c >= 'A' && c <= 'F') {
 	    c2 += c - 'A' + 10;
-	  else if (c >= 'a' && c <= 'f')
+	  } else if (c >= 'a' && c <= 'f') {
 	    c2 += c - 'a' + 10;
-	  else
+	  } else {
 	    error(errSyntaxError, getPos(),
 		  "Illegal character <{0:02x}> in hex string", c);
+	    ++nErrors;
+	  }
 	  if (++m == 2) {
 	    if (n == tokBufSize) {
 	      if (!s)

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "Object.h"
 #include "Stream.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stddef.h>
 #include <string.h>
 #include "gmem.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Link.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Link.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Link.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "Object.h"
 
 class GString;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <string.h>
 #include "gmem.h"
 #include "gmempp.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "CharTypes.h"
 
 struct NameToCharCodeEntry;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stddef.h>
 #include "gmempp.h"
 #include "Object.h"
@@ -42,7 +38,7 @@
   "none"
 };
 
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
 #if MULTITHREADED
 GAtomicCounter Object::numAlloc[numObjTypes] =
   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -50,7 +46,7 @@
 long Object::numAlloc[numObjTypes] =
   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 #endif
-#endif // DEBUG_MEM
+#endif // DEBUG_OBJECT_MEM
 
 Object *Object::initArray(XRef *xref) {
   initObj(objArray);
@@ -101,7 +97,7 @@
   default:
     break;
   }
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
 #if MULTITHREADED
   gAtomicIncrement(&numAlloc[type]);
 #else
@@ -143,7 +139,7 @@
   default:
     break;
   }
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
 #if MULTITHREADED
   gAtomicDecrement(&numAlloc[type]);
 #else
@@ -225,7 +221,7 @@
 }
 
 void Object::memCheck(FILE *f) {
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
   int i;
   long t;
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Object.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Object.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Object.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <stdio.h>
 #include <string.h>
 #include "gtypes.h"
@@ -71,7 +67,7 @@
 // Object
 //------------------------------------------------------------------------
 
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
 #  if MULTITHREADED
 #    define initObj(t) gAtomicIncrement(&numAlloc[type = t])
 #  else
@@ -216,7 +212,7 @@
     char *cmd;			//   command
   };
 
-#ifdef DEBUG_MEM
+#ifdef DEBUG_OBJECT_MEM
 #if MULTITHREADED
   static GAtomicCounter		// number of each type of object
     numAlloc[numObjTypes];	//   currently allocated

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include "gmempp.h"
 #include "GString.h"
 #include "GList.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "Object.h"
 #include "CharTypes.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include "gmem.h"
 #include "gmempp.h"
 #include "GString.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "Object.h"
 #include "CharTypes.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stddef.h>
 #include "gmempp.h"
 #include "Object.h"
@@ -76,6 +72,15 @@
   updateFont(state);
 }
 
+void OutputDev::fillStroke(GfxState *state, GBool eo) {
+  if (eo) {
+    eoFill(state);
+  } else {
+    fill(state);
+  }
+  stroke(state);
+}
+
 GBool OutputDev::beginType3Char(GfxState *state, double x, double y,
 				double dx, double dy,
 				CharCode code, Unicode *u, int uLen) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "CharTypes.h"
 
@@ -99,6 +95,10 @@
   // End a page.
   virtual void endPage() {}
 
+  // Start/end a sub-page stream (Form XObject, annotation).
+  virtual void startStream(Ref streamRef, GfxState *state) {}
+  virtual void endStream(Ref streamRef) {}
+
   //----- coordinate conversion
 
   // Convert between device and user coordinates.
@@ -147,13 +147,12 @@
   virtual void updateHorizScaling(GfxState *state) {}
   virtual void updateTextPos(GfxState *state) {}
   virtual void updateTextShift(GfxState *state, double shift) {}
-  virtual void saveTextPos(GfxState *state) {}
-  virtual void restoreTextPos(GfxState *state) {}
 
   //----- path painting
   virtual void stroke(GfxState *state) {}
   virtual void fill(GfxState *state) {}
   virtual void eoFill(GfxState *state) {}
+  virtual void fillStroke(GfxState *state, GBool eo);
   virtual void tilingPatternFill(GfxState *state, Gfx *gfx, Object *strRef,
 				 int paintType, int tilingType, Dict *resDict,
 				 double *mat, double *bbox,
@@ -175,8 +174,17 @@
   virtual void drawChar(GfxState *state, double x, double y,
 			double dx, double dy,
 			double originX, double originY,
-			CharCode code, int nBytes, Unicode *u, int uLen) {}
-  virtual void drawString(GfxState *state, GString *s) {}
+			CharCode code, int nBytes, Unicode *u, int uLen,
+			GBool fill, GBool stroke, GBool makePath) {}
+  virtual void drawString(GfxState *state, GString *s,
+			  GBool fill, GBool stroke, GBool makePath) {}
+  virtual void fillTextPath(GfxState *state) {}
+  virtual void strokeTextPath(GfxState *state) {}
+  virtual void clipToTextPath(GfxState *state) {}
+  virtual void clipToTextStrokePath(GfxState *state) {}
+  virtual void clearTextPath(GfxState *state) {}
+  virtual void addTextPathToSavedClipPath(GfxState *state) {}
+  virtual void clipToSavedClipPath(GfxState *state) {}
   virtual GBool beginType3Char(GfxState *state, double x, double y,
 			       double dx, double dy,
 			       CharCode code, Unicode *u, int uLen);
@@ -242,6 +250,10 @@
   //----- links
   virtual void processLink(Link *link) {}
 
+  //----- structure tree
+  virtual void beginStructureItem(const char *tag, int mcid, Dict *dict) {}
+  virtual void endStructureItem() {}
+
 private:
 
   double defCTM[6];		// default coordinate transform matrix

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <math.h>
 #include "gtypes.h"
 #include "GString.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDF417Barcode.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 class GString;
 
 // Draw a PDF417 barcode:

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <math.h>
 #include "gmempp.h"
 #include "GString.h"
@@ -47,9 +43,6 @@
   linksPage = 0;
   links = NULL;
 
-  annotsPage = 0;
-  annots = NULL;
-
   textPage = 0;
   textDPI = 0;
   textRotate = 0;
@@ -116,6 +109,7 @@
   delete state;
   clearPage();
   if (doc) {
+    aboutToDeleteDoc();
     delete doc;
   }
   for (i = 0; i < pdfHistorySize; ++i) {
@@ -201,6 +195,7 @@
   // NB: do not delete doc until after DisplayState::setDoc() returns
   state->setDoc(newDoc);
   if (doc) {
+    aboutToDeleteDoc();
     delete doc;
   }
   doc = newDoc;
@@ -219,6 +214,7 @@
   // no document
   // NB: do not delete doc until after DisplayState::setDoc() returns
   state->setDoc(NULL);
+  aboutToDeleteDoc();
   delete doc;
   doc = NULL;
   clearPage();
@@ -300,6 +296,8 @@
     page = 1;
   }
 
+  GBool changeZoom = globalParams->getAllowLinksToChangeZoom();
+
   switch (dest->getKind()) {
   case destXYZ:
     cvtUserToDev(page, dest->getLeft(), dest->getTop(), &dx, &dy);
@@ -317,7 +315,9 @@
     break;
   case destFit:
   case destFitB:
-    state->setZoom(zoomPage);
+    if (changeZoom) {
+      state->setZoom(zoomPage);
+    }
     scrollX = tileMap->getPageLeftX(page);
     scrollY = tileMap->getPageTopY(page);
     startUpdate();
@@ -326,7 +326,9 @@
     break;
   case destFitH:
   case destFitBH:
-    state->setZoom(zoomWidth);
+    if (changeZoom) {
+      state->setZoom(zoomWidth);
+    }
     scrollX = tileMap->getPageLeftX(page);
     scrollY = tileMap->getPageTopY(page);
     if (dest->getChangeTop()) {
@@ -339,7 +341,9 @@
     break;
   case destFitV:
   case destFitBV:
-    state->setZoom(zoomHeight);
+    if (changeZoom) {
+      state->setZoom(zoomHeight);
+    }
     scrollX = tileMap->getPageLeftX(page);
     scrollY = tileMap->getPageTopY(page);
     if (dest->getChangeTop()) {
@@ -351,8 +355,13 @@
     finishUpdate(gTrue, gTrue);
     break;
   case destFitR:
-    zoomToRect(page, dest->getLeft(), dest->getTop(),
-	       dest->getRight(), dest->getBottom());
+    if (changeZoom) {
+      zoomToRect(page, dest->getLeft(), dest->getTop(),
+		 dest->getRight(), dest->getBottom());
+    } else {
+      scrollToCentered(page, 0.5 * (dest->getLeft() + dest->getRight()),
+		       0.5 * (dest->getTop(), dest->getBottom()));
+    }
     break;
   }
 }
@@ -426,9 +435,16 @@
   //   tileDone or tick (incremental update) to avoid "flashing" the
   //   screen (drawing a blank background, followed by the actual
   //   content slightly later)
-  getWindowBitmap(gTrue);
-  if (bitmapFinished) {
+  // - this postponement actually causes flickering in certain cases
+  //   (the Qt QML backend) -- don't do it if alwaysInvalidateOnUpdate()
+  //   returns true
+  if (alwaysInvalidateOnUpdate()) {
     invalidateWholeWindow();
+  } else {
+    getWindowBitmap(gTrue);
+    if (bitmapFinished) {
+      invalidateWholeWindow();
+    }
   }
   updateScrollbars();
 
@@ -1637,7 +1653,51 @@
   return results;
 }
 
+GList *AsyncFindAll::run(PDFDoc *doc, Unicode *u, int len, GBool caseSensitive,
+			 GBool wholeWord, int firstPage, int lastPage) {
+  GList *results = new GList();
 
+  TextOutputDev *textOut = new TextOutputDev(NULL, &core->textOutCtrl, gFalse);
+  if (!textOut->isOk()) {
+    delete textOut;
+    return results;
+  }
+
+  for (int pg = firstPage; pg <= lastPage && !canceled; ++pg) {
+    doc->displayPage(textOut, pg, 72, 72, 0, gFalse, gTrue, gFalse);
+    GBool first = gTrue;
+    while (!canceled) {
+      double xMin, yMin, xMax, yMax;
+      if (!textOut->findText(u, len, first, gTrue, !first, gFalse,
+			    caseSensitive, gFalse, wholeWord,
+			    &xMin, &yMin, &xMax, &yMax)) {
+	break;
+      }
+      double uxMin, uyMin, uxMax, uyMax, t;
+      textOut->cvtDevToUser(xMin, yMin, &uxMin, &uyMin);
+      textOut->cvtDevToUser(xMax, yMax, &uxMax, &uyMax);
+      if (uxMin > uxMax) {
+	t = uxMin;  uxMin = uxMax;  uxMax = t;
+      }
+      if (uyMin > uyMax) {
+	t = uyMin;  uyMin = uyMax;  uyMax = t;
+      }
+      results->append(new FindResult(pg, uxMin, uyMin, uxMax, uyMax));
+      first = gFalse;
+    }
+  }
+
+  delete textOut;
+
+  if (canceled) {
+    deleteGList(results, FindResult);
+    return NULL;
+  }
+
+  return results;
+}
+
+
 GBool PDFCore::cvtWindowToUser(int xw, int yw,
 			       int *pg, double *xu, double *yu) {
   return tileMap->cvtWindowToUser(xw, yw, pg, xu, yu);
@@ -1751,25 +1811,13 @@
 }
 
 Annot *PDFCore::findAnnot(int pg, double x, double y) {
-  loadAnnots(pg);
-  return annots->find(x, y);
+  return doc->getAnnots()->find(pg, x, y);
 }
 
 int PDFCore::findAnnotIdx(int pg, double x, double y) {
-  loadAnnots(pg);
-  return annots->findIdx(x, y);
+  return doc->getAnnots()->findIdx(pg, x, y);
 }
 
-Annot *PDFCore::getAnnot(int idx) {
-  if (!annots) {
-    return NULL;
-  }
-  if (idx < 0 || idx >= annots->getNumAnnots()) {
-    return NULL;
-  }
-  return annots->getAnnot(idx);
-}
-
 AcroFormField *PDFCore::findFormField(int pg, double x, double y) {
   if (!doc->getCatalog()->getForm()) {
     return NULL;
@@ -1816,7 +1864,8 @@
 
   startUpdate();
 
-  wx0 = wy0 = 0; // make gcc happy
+  page = wx0 = wy0 = 0; // make gcc happy
+  ux = uy = 0;
   doScroll = gFalse;
   if (state->getZoom() < 0 && state->displayModeIsContinuous()) {
     // save the user coordinates of the appropriate edge of the window
@@ -1879,12 +1928,6 @@
   links = NULL;
   linksPage = 0;
 
-  if (annots) {
-    delete annots;
-  }
-  annots = NULL;
-  annotsPage = 0;
-
   if (text) {
     delete text;
   }
@@ -1906,22 +1949,6 @@
   linksPage = pg;
 }
 
-// Load the annotations for <pg>.
-void PDFCore::loadAnnots(int pg) {
-  Object annotsObj;
-
-  if (annots && annotsPage == pg) {
-    return;
-  }
-  if (annots) {
-    delete annots;
-  }
-  doc->getCatalog()->getPage(pg)->getAnnots(&annotsObj);
-  annots = new Annots(doc, &annotsObj);
-  annotsObj.free();
-  annotsPage = pg;
-}
-
 // Extract text from <pg>.
 void PDFCore::loadText(int pg) {
   TextOutputDev *textOut;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,11 +11,10 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
+#include <stdlib.h>
+#ifndef PDF_PARSER_ONLY
+#include <atomic>
 #endif
-
-#include <stdlib.h>
 #include "SplashTypes.h"
 #include "CharTypes.h"
 #include "DisplayState.h"
@@ -31,7 +30,6 @@
 class LinkDest;
 class LinkAction;
 class Annot;
-class Annots;
 class AcroFormField;
 class TextPage;
 class HighlightFile;
@@ -77,6 +75,34 @@
 };
 
 //------------------------------------------------------------------------
+// AsyncFindAll
+//------------------------------------------------------------------------
+#ifndef PDF_PARSER_ONLY
+class AsyncFindAll {
+public:
+
+  AsyncFindAll(PDFCore *coreA): core(coreA), canceled(gFalse) {}
+
+  void reset() { canceled = false; }
+
+  // Run the search, returning a list of FindResults -- same as
+  // PDFCore::findAll().  This can be run on a separate thread.  If
+  // cancel() is called while the search is running, this function
+  // returns null.
+  GList *run(PDFDoc *doc, Unicode *u, int len, GBool caseSensitive,
+	     GBool wholeWord, int firstPage, int lastPage);
+
+  // Cancel a running search, causing run() to return null.
+  void cancel() { canceled = true; }
+
+private:
+
+  PDFCore *core;
+  std::atomic<bool> canceled;
+};
+#endif
+
+//------------------------------------------------------------------------
 // PDFCore
 //------------------------------------------------------------------------
 
@@ -256,7 +282,6 @@
   LinkAction *findLink(int pg, double x, double y);
   Annot *findAnnot(int pg, double x, double y);
   int findAnnotIdx(int pg, double x, double y);
-  Annot *getAnnot(int idx);
   AcroFormField *findFormField(int pg, double x, double y);
   int findFormFieldIdx(int pg, double x, double y);
   AcroFormField *getFormField(int idx);
@@ -288,6 +313,11 @@
 
   //--- callbacks to PDFCore subclass
 
+  // Subclasses can return true here to force PDFCore::finishUpdate()
+  // to always invalidate the window.  This is necessary to avoid
+  // flickering on some backends.
+  virtual GBool alwaysInvalidateOnUpdate() { return gFalse; }
+
   // Invalidate the specified rectangle (in window coordinates).
   virtual void invalidate(int x, int y, int w, int h) = 0;
 
@@ -304,6 +334,11 @@
   // This is called just after a PDF file is loaded.
   virtual void postLoad() {}
 
+  // This is called just before deleting the PDFDoc.  The PDFCore
+  // subclass must shut down any secondary threads that are using the
+  // PDFDoc pointer.
+  virtual void aboutToDeleteDoc() {}
+
   //--- internal
 
   int loadFile2(PDFDoc *newDoc);
@@ -310,7 +345,6 @@
   void addToHistory();
   void clearPage();
   void loadLinks(int pg);
-  void loadAnnots(int pg);
   void loadText(int pg);
   void getSelectionBBox(int *wxMin, int *wyMin, int *wxMax, int *wyMax);
   void getSelectRectListBBox(GList *rects, int *wxMin, int *wyMin,
@@ -318,14 +352,13 @@
   void checkInvalidate(int x, int y, int w, int h);
   void invalidateWholeWindow();
 
+  friend class AsyncFindAll;
+
   PDFDoc *doc;
 
   int linksPage;		// cached links for one page
   Links *links;
 
-  int annotsPage;		// cached annotations for one page
-  Annots *annots;
-
   int textPage;			// cached extracted text for one page
   double textDPI;
   int textRotate;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
@@ -26,6 +22,7 @@
 #include "GlobalParams.h"
 #include "Page.h"
 #include "Catalog.h"
+#include "Annot.h"
 #include "Stream.h"
 #include "XRef.h"
 #include "Link.h"
@@ -178,6 +175,7 @@
   int i, j;
 #endif
 #endif /* 0 */
+
   init(coreA);
 
   fileName = new GString(fileNameA);
@@ -204,7 +202,7 @@
     file = _wfopen(fileNameU, wfopenReadMode);
   } else {
 #endif /* 0 */
-    file = fopen(fileName->getCString(), fopenReadMode);
+  file = fopen(fileName->getCString(), fopenReadMode);
 #if 0
   }
 #endif /* 0 */
@@ -263,6 +261,7 @@
   str = NULL;
   xref = NULL;
   catalog = NULL;
+  annots = NULL;
 #ifndef DISABLE_OUTLINE
   outline = NULL;
 #endif
@@ -335,6 +334,9 @@
     return gFalse;
   }
 
+  // initialize the Annots object
+  annots = new Annots(this);
+
   return gTrue;
 }
 
@@ -347,6 +349,9 @@
     delete outline;
   }
 #endif
+  if (annots) {
+    delete annots;
+  }
   if (catalog) {
     delete catalog;
   }
@@ -485,6 +490,7 @@
 				       abortCheckCbk, abortCheckCbkData);
 }
 
+
 Links *PDFDoc::getLinks(int page) {
   return catalog->getPage(page)->getLinks();
 }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <stdio.h>
 #include "XRef.h"
 #include "Catalog.h"
@@ -23,6 +19,7 @@
 class GString;
 class BaseStream;
 class OutputDev;
+class Annots;
 class Links;
 class LinkAction;
 class LinkDest;
@@ -74,6 +71,9 @@
   // Get catalog.
   Catalog *getCatalog() { return catalog; }
 
+  // Get annotations.
+  Annots *getAnnots() { return annots; }
+
   // Get base stream.
   BaseStream *getBaseStream() { return str; }
 
@@ -121,6 +121,7 @@
 			GBool (*abortCheckCbk)(void *data) = NULL,
 			void *abortCheckCbkData = NULL);
 
+
   // Find a page, given its object ID.  Returns page number, or 0 if
   // not found.
   int findPage(int num, int gen) { return catalog->findPage(num, gen); }
@@ -195,7 +196,10 @@
 #endif
   char *getEmbeddedFileMem(int idx, int *size);
 
+  // Return true if the document uses JavaScript.
+  GBool usesJavaScript() { return catalog->usesJavaScript(); }
 
+
 private:
 
   void init(PDFCore *coreA);
@@ -216,6 +220,7 @@
   double pdfVersion;
   XRef *xref;
   Catalog *catalog;
+  Annots *annots;
 #ifndef DISABLE_OUTLINE
   Outline *outline;
 #endif

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <stddef.h>
 #include <stdarg.h>
@@ -108,7 +104,8 @@
   "/pdfOpNames [",
   "  /pdfFill /pdfStroke /pdfLastFill /pdfLastStroke",
   "  /pdfTextMat /pdfFontSize /pdfCharSpacing /pdfTextRender",
-  "  /pdfTextRise /pdfWordSpacing /pdfHorizScaling /pdfTextClipPath",
+  "  /pdfTextRise /pdfWordSpacing /pdfHorizScaling /pdfTextPath",
+  "  /pdfTextClipPath",
   "] def",
   "~123ngs",
   "/pdfStartPage {",
@@ -145,6 +142,7 @@
   "  /pdfTextRise 0 def",
   "  /pdfWordSpacing 0 def",
   "  /pdfHorizScaling 1 def",
+  "  /pdfTextPath [] def",
   "  /pdfTextClipPath [] def",
   "} def",
   "/pdfEndPage { end } def",
@@ -475,32 +473,34 @@
   "/Tj {",
   "  fCol",  // because stringwidth has to draw Type 3 chars
   "  0 pdfTextRise pdfTextMat dtransform rmoveto",
-  "  currentpoint 4 2 roll",
-  "  pdfTextRender 1 and 0 eq {",
-  "    2 copy xyshow2",
-  "  } if",
-  "  pdfTextRender 3 and dup 1 eq exch 2 eq or {",
-  "    3 index 3 index moveto",
-  "    2 copy",
-  "    currentfont /FontType get 3 eq { fCol } { sCol } ifelse",
-  "    xycp currentpoint stroke moveto",
-  "  } if",
-  "  pdfTextRender 4 and 0 ne {",
-  "    4 2 roll moveto xycp",
-  "    /pdfTextClipPath [ pdfTextClipPath aload pop",
-  "      {/moveto cvx}",
-  "      {/lineto cvx}",
-  "      {/curveto cvx}",
-  "      {/closepath cvx}",
-  "    pathforall ] def",
-  "    currentpoint newpath moveto",
-  "  } {",
-  "    pop pop pop pop",
-  "  } ifelse",
+  "  xyshow2",
   "  0 pdfTextRise neg pdfTextMat dtransform rmoveto",
   "} def",
+  "/TjS {",
+  "  fCol",  // because stringwidth has to draw Type 3 chars
+  "  0 pdfTextRise pdfTextMat dtransform rmoveto",
+  "  currentfont /FontType get 3 eq { fCol } { sCol } ifelse",
+  "  xycp currentpoint stroke moveto",
+  "  0 pdfTextRise neg pdfTextMat dtransform rmoveto",
+  "} def",
+  "/TjFS {",
+  "  2 copy currentpoint 4 2 roll Tj moveto TjS",
+  "} def",
+  "/TjSave {",
+  "  fCol",  // because stringwidth has to draw Type 3 chars
+  "  0 pdfTextRise pdfTextMat dtransform rmoveto",
+  "  xycp",
+  "  /pdfTextPath [ pdfTextPath aload pop",
+  "    {/moveto cvx}",
+  "    {/lineto cvx}",
+  "    {/curveto cvx}",
+  "    {/closepath cvx}",
+  "  pathforall ] def",
+  "  currentpoint newpath moveto",
+  "  0 pdfTextRise neg pdfTextMat dtransform rmoveto",
+  "} def",
   "/Tj3 {",
-  "  pdfTextRender 3 and 3 ne {"
+  "  pdfTextRender 3 and 3 ne {",
   "    fCol",  // because stringwidth has to draw Type 3 chars
   "    0 pdfTextRise pdfTextMat dtransform rmoveto",
   "    xyshow2",
@@ -513,8 +513,18 @@
   "       pdfTextMat dtransform rmoveto } def",
   "/TJmV { 0.001 mul pdfFontSize mul neg 0 exch",
   "        pdfTextMat dtransform rmoveto } def",
-  "/Tclip { pdfTextClipPath cvx exec clip newpath",
-  "         /pdfTextClipPath [] def } def",
+  "/Tfill { fCol pdfTextPath cvx exec fill } def",
+  "/Tstroke { sCol pdfTextPath cvx exec stroke } def",
+  "/Tclip { pdfTextPath cvx exec clip newpath } def",
+  "/Tstrokeclip { pdfTextPath cvx exec strokepath clip newpath } def",
+  "/Tclear { /pdfTextPath [] def } def",
+  "/Tsave {",
+  "  /pdfTextClipPath [ pdfTextClipPath aload pop pdfTextPath aload pop ] def",
+  "} def",
+  "/Tclip2 {",
+  "  pdfTextClipPath cvx exec clip newpath",
+  "  /pdfTextClipPath [] def",
+  "} def",
   "~1ns",
   "% Level 1 image operators",
   "~1n",
@@ -1309,7 +1319,8 @@
   paperSizes = NULL;
   embFontList = NULL;
   customColors = NULL;
-  haveTextClip = gFalse;
+  haveSavedTextPath = gFalse;
+  haveSavedClipPath = gFalse;
   t3String = NULL;
 
   // open file or pipe
@@ -1376,7 +1387,8 @@
   paperSizes = NULL;
   embFontList = NULL;
   customColors = NULL;
-  haveTextClip = gFalse;
+  haveSavedTextPath = gFalse;
+  haveSavedClipPath = gFalse;
   t3String = NULL;
 
   init(outputFuncA, outputStreamA, psGeneric,
@@ -1748,7 +1760,6 @@
 void PSOutputDev::writeDocSetup(Catalog *catalog) {
   Page *page;
   Dict *resDict;
-  Annots *annots;
   AcroForm *form;
   Object obj1, obj2, obj3;
   GString *s;
@@ -1774,6 +1785,7 @@
   } else {
     writePS("xpdf begin\n");
   }
+  Annots *annots = doc->getAnnots();
   needDefaultFont = gFalse;
   for (pg = firstPage; pg <= lastPage; ++pg) {
     if (rasterizePage[pg - firstPage]) {
@@ -1783,13 +1795,12 @@
     if ((resDict = page->getResourceDict())) {
       setupResources(resDict);
     }
-    annots = new Annots(doc, page->getAnnots(&obj1));
-    obj1.free();
-    if (annots->getNumAnnots()) {
+    int nAnnots = annots->getNumAnnots(pg);
+    if (nAnnots > 0) {
       needDefaultFont = gTrue;
     }
-    for (i = 0; i < annots->getNumAnnots(); ++i) {
-      if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) {
+    for (i = 0; i < nAnnots; ++i) {
+      if (annots->getAnnot(pg, i)->getAppearance(&obj1)->isStream()) {
 	obj1.streamGetDict()->lookup("Resources", &obj2);
 	if (obj2.isDict()) {
 	  setupResources(obj2.getDict());
@@ -1798,7 +1809,6 @@
       }
       obj1.free();
     }
-    delete annots;
   }
   if ((form = catalog->getForm())) {
     if (form->getNumFields() > 0) {
@@ -2150,6 +2160,9 @@
 	case fontType1:
 	  fi->ff = setupExternalType1Font(font, fontLoc->path);
 	  break;
+	case fontType1COT:
+	  fi->ff = setupExternalOpenTypeT1CFont(font, fontLoc->path);
+	  break;
 	case fontTrueType:
 	case fontTrueTypeOT:
 	  fi->ff = setupExternalTrueTypeFont(font, fontLoc->path,
@@ -2573,6 +2586,48 @@
   return ff;
 }
 
+PSFontFileInfo *PSOutputDev::setupExternalOpenTypeT1CFont(GfxFont *font,
+							  GString *fileName) {
+  GString *psName;
+  PSFontFileInfo *ff;
+  FoFiTrueType *ffTT;
+
+  if (font->getName()) {
+    // check if font is already embedded
+    if ((ff = (PSFontFileInfo *)fontFileInfo->lookup(font->getName()))) {
+      return ff;
+    }
+    // this assumes that the PS font name matches the PDF font name
+    psName = font->getName()->copy();
+  } else {
+    // generate name
+    psName = makePSFontName(font, font->getID());
+  }
+
+  // beginning comment
+  writePSFmt("%%BeginResource: font {0:t}\n", psName);
+  embFontList->append("%%+ font ");
+  embFontList->append(psName->getCString());
+  embFontList->append("\n");
+
+  // convert it to a Type 1 font
+  if ((ffTT = FoFiTrueType::load(fileName->getCString(), 0, gTrue))) {
+    if (ffTT->isOpenTypeCFF()) {
+      ffTT->convertToType1(psName->getCString(), NULL, gTrue,
+			   outputFunc, outputStream);
+    }
+    delete ffTT;
+  }
+
+  // ending comment
+  writePS("%%EndResource\n");
+
+  ff = new PSFontFileInfo(psName, font->getType(), psFontFileExternal);
+  ff->extFileName = fileName->copy();
+  fontFileInfo->add(ff->psName, ff);
+  return ff;
+}
+
 PSFontFileInfo *PSOutputDev::setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id) {
   GString *psName;
   PSFontFileInfo *ff;
@@ -3867,8 +3922,14 @@
     } else {
       s = str->getPSFilter(level < psLevel3 ? 2 : 3, "", gTrue);
       if (s) {
-	useLZW = useRLE = gFalse;
-	useCompressed = gTrue;
+	if (globalParams->getPSLZW() && !str->hasStrongCompression()) {
+	  useRLE = gFalse;
+	  useLZW = gTrue;
+	  useCompressed = gFalse;
+	} else {
+	  useLZW = useRLE = gFalse;
+	  useCompressed = gTrue;
+	}
 	delete s;
       } else {
 	if (globalParams->getPSLZW()) {
@@ -4541,10 +4602,21 @@
       tx -= xScale * x1;
       ty -= yScale * y1;
     }
-    // center
+    // offset or center
     if (tx0 >= 0 && ty0 >= 0) {
-      tx += (rotate == 0 || rotate == 180) ? tx0 : ty0;
-      ty += (rotate == 0 || rotate == 180) ? ty0 : -tx0;
+      if (rotate == 0) {
+	tx += tx0;
+	ty += ty0;
+      } else if (rotate == 90) {
+	tx += ty0;
+	ty += (imgWidth - yScale * height) - tx0;
+      } else if (rotate == 180) {
+	tx += (imgWidth - xScale * width) - tx0;
+	ty += (imgHeight - yScale * height) - ty0;
+      } else { // rotate == 270
+	tx += (imgHeight - xScale * width) - ty0;
+	ty += tx0;
+      }
     } else if (globalParams->getPSCenter()) {
       if (clipLLX0 < clipURX0 && clipLLY0 < clipURY0) {
 	tx += (imgWidth2 - xScale * (clipURX0 - clipLLX0)) / 2;
@@ -5103,16 +5175,6 @@
   noStateChanges = gFalse;
 }
 
-void PSOutputDev::saveTextPos(GfxState *state) {
-  writePS("currentpoint\n");
-  noStateChanges = gFalse;
-}
-
-void PSOutputDev::restoreTextPos(GfxState *state) {
-  writePS("m\n");
-  noStateChanges = gFalse;
-}
-
 void PSOutputDev::stroke(GfxState *state) {
   doPath(state->getPath());
   if (inType3Char && t3FillColorOnly) {
@@ -5766,23 +5828,10 @@
   }
 }
 
-void PSOutputDev::drawString(GfxState *state, GString *s) {
-  GfxFont *font;
-  int wMode;
-  int *codeToGID;
-  GString *s2;
-  double dx, dy, originX, originY, originX0, originY0, tOriginX0, tOriginY0;
-  char *p;
-  PSFontInfo *fi;
-  UnicodeMap *uMap;
-  CharCode code;
-  Unicode u[8];
-  char buf[8];
-  double *dxdy;
-  int dxdySize, len, nChars, uLen, n, m, i, j;
-
+void PSOutputDev::drawString(GfxState *state, GString *s,
+			     GBool fill, GBool stroke, GBool makePath) {
   // check for invisible text -- this is used by Acrobat Capture
-  if (state->getRender() == 3) {
+  if (!fill && !stroke && !makePath) {
     return;
   }
 
@@ -5792,13 +5841,14 @@
   }
 
   // get the font
-  if (!(font = state->getFont())) {
+  GfxFont *font = state->getFont();
+  if (!font) {
     return;
   }
-  wMode = font->getWMode();
+  int wMode = font->getWMode();
 
-  fi = NULL;
-  for (i = 0; i < fontInfo->getLength(); ++i) {
+  PSFontInfo *fi = NULL;
+  for (int i = 0; i < fontInfo->getLength(); ++i) {
     fi = (PSFontInfo *)fontInfo->get(i);
     if (fi->fontID.num == font->getID()->num &&
 	fi->fontID.gen == font->getID()->gen) {
@@ -5808,8 +5858,8 @@
   }
 
   // check for a subtitute 16-bit font
-  uMap = NULL;
-  codeToGID = NULL;
+  UnicodeMap *uMap = NULL;
+  int *codeToGID = NULL;
   if (font->isCIDFont()) {
     if (!(fi && fi->ff)) {
       // font substitution failed, so don't output any text
@@ -5827,17 +5877,21 @@
   }
 
   // compute the positioning (dx, dy) for each char in the string
-  nChars = 0;
-  p = s->getCString();
-  len = s->getLength();
-  s2 = new GString();
-  dxdySize = font->isCIDFont() ? 8 : s->getLength();
-  dxdy = (double *)gmallocn(2 * dxdySize, sizeof(double));
-  originX0 = originY0 = 0; // make gcc happy
+  int nChars = 0;
+  char *p = s->getCString();
+  int len = s->getLength();
+  GString *s2 = new GString();
+  int dxdySize = font->isCIDFont() ? 8 : s->getLength();
+  double *dxdy = (double *)gmallocn(2 * dxdySize, sizeof(double));
+  double originX0 = 0, originY0 = 0;
   while (len > 0) {
-    n = font->getNextChar(p, len, &code,
-			  u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
-			  &dx, &dy, &originX, &originY);
+    CharCode code;
+    Unicode u[8];
+    int uLen;
+    double dx, dy, originX, originY;
+    int n = font->getNextChar(p, len, &code,
+			      u, (int)(sizeof(u) / sizeof(Unicode)), &uLen,
+			      &dx, &dy, &originX, &originY);
     //~ this doesn't handle the case where the origin offset changes
     //~   within a string of characters -- which could be fixed by
     //~   modifying dx,dy as needed for each character
@@ -5867,9 +5921,10 @@
 	  } while (nChars + uLen > dxdySize);
 	  dxdy = (double *)greallocn(dxdy, 2 * dxdySize, sizeof(double));
 	}
-	for (i = 0; i < uLen; ++i) {
-	  m = uMap->mapUnicode(u[i], buf, (int)sizeof(buf));
-	  for (j = 0; j < m; ++j) {
+	char buf[8];
+	for (int i = 0; i < uLen; ++i) {
+	  int m = uMap->mapUnicode(u[i], buf, (int)sizeof(buf));
+	  for (int j = 0; j < m; ++j) {
 	    s2->append(buf[j]);
 	  }
 	  //~ this really needs to get the number of chars in the target
@@ -5906,6 +5961,7 @@
   }
   originX0 *= state->getFontSize();
   originY0 *= state->getFontSize();
+  double tOriginX0, tOriginY0;
   state->textTransformDelta(originX0, originY0, &tOriginX0, &tOriginY0);
 
   if (nChars > 0) {
@@ -5912,19 +5968,38 @@
     if (wMode) {
       writePSFmt("{0:.6g} {1:.6g} rmoveto\n", -tOriginX0, -tOriginY0);
     }
+
     writePSString(s2);
     writePS("\n[");
-    for (i = 0; i < 2 * nChars; ++i) {
+    for (int i = 0; i < 2 * nChars; ++i) {
       if (i > 0) {
 	writePS("\n");
       }
       writePSFmt("{0:.6g}", dxdy[i]);
     }
+    writePS("] ");
+
+    // the possible operations are:
+    //   - fill
+    //   - stroke
+    //   - fill + stroke
+    //   - makePath
+
     if (font->getType() == fontType3) {
-      writePS("] Tj3\n");
+      writePS("Tj3\n");
     } else {
-      writePS("] Tj\n");
+      if (fill && stroke) {
+	writePS("TjFS\n");
+      } else if (fill) {
+	writePS("Tj\n");
+      } else if (stroke) {
+	writePS("TjS\n");
+      } else if (makePath) {
+	writePS("TjSave\n");
+	haveSavedTextPath = gTrue;
+      }
     }
+
     if (wMode) {
       writePSFmt("{0:.6g} {1:.6g} rmoveto\n", tOriginX0, tOriginY0);
     }
@@ -5932,21 +6007,51 @@
   gfree(dxdy);
   delete s2;
 
-  if ((state->getRender() & 4) && font->getType() != fontType3) {
-    haveTextClip = gTrue;
+  noStateChanges = gFalse;
+}
+
+void PSOutputDev::fillTextPath(GfxState *state) {
+  writePS("Tfill\n");
+}
+
+void PSOutputDev::strokeTextPath(GfxState *state) {
+  writePS("Tstroke\n");
+}
+
+void PSOutputDev::clipToTextPath(GfxState *state) {
+  writePS("Tclip\n");
+}
+
+void PSOutputDev::clipToTextStrokePath(GfxState *state) {
+  writePS("Tstrokeclip\n");
+}
+
+void PSOutputDev::clearTextPath(GfxState *state) {
+  if (haveSavedTextPath) {
+    writePS("Tclear\n");
+    haveSavedTextPath = gFalse;
   }
+}
 
-  noStateChanges = gFalse;
+void PSOutputDev::addTextPathToSavedClipPath(GfxState *state) {
+  if (haveSavedTextPath) {
+    writePS("Tsave\n");
+    haveSavedTextPath = gFalse;
+    haveSavedClipPath = gTrue;
+  }
 }
 
-void PSOutputDev::endTextObject(GfxState *state) {
-  if (haveTextClip) {
-    writePS("Tclip\n");
-    haveTextClip = gFalse;
-    noStateChanges = gFalse;
+void PSOutputDev::clipToSavedClipPath(GfxState *state) {
+  if (!haveSavedClipPath) {
+    return;
   }
+  writePS("Tclip2\n");
+  haveSavedClipPath = gFalse;
 }
 
+void PSOutputDev::endTextObject(GfxState *state) {
+}
+
 void PSOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
 				int width, int height, GBool invert,
 				GBool inlineImg, GBool interpolate) {
@@ -6396,6 +6501,11 @@
       }
       useASCII = !(mode == psModeForm || inType3Char || preload);
       useCompressed = gFalse;
+    } else if (globalParams->getPSLZW() && !str->hasStrongCompression()) {
+      useRLE = gFalse;
+      useLZW = gTrue;
+      useASCII = !(mode == psModeForm || inType3Char || preload);
+      useCompressed = gFalse;
     } else {
       useLZW = useRLE = gFalse;
       useASCII = str->isBinary() &&
@@ -6869,6 +6979,11 @@
 	}
 	maskUseASCII = !(mode == psModeForm || inType3Char || preload);
 	maskUseCompressed = gFalse;
+      } else if (globalParams->getPSLZW() && !maskStr->hasStrongCompression()) {
+	maskUseRLE = gFalse;
+	maskUseLZW = gTrue;
+	maskUseASCII = !(mode == psModeForm || inType3Char || preload);
+	maskUseCompressed = gFalse;
       } else {
 	maskUseLZW = maskUseRLE = gFalse;
 	maskUseASCII = maskStr->isBinary() &&
@@ -7097,6 +7212,11 @@
       }
       useASCII = !(mode == psModeForm || inType3Char || preload);
       useCompressed = gFalse;
+    } else if (globalParams->getPSLZW() && !str->hasStrongCompression()) {
+      useRLE = gFalse;
+      useLZW = gTrue;
+      useASCII = !(mode == psModeForm || inType3Char || preload);
+      useCompressed = gFalse;
     } else {
       useLZW = useRLE = gFalse;
       useASCII = str->isBinary() &&

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <stddef.h>
 #include "config.h"
 #include "Object.h"
@@ -199,8 +195,6 @@
   virtual void updateHorizScaling(GfxState *state);
   virtual void updateTextPos(GfxState *state);
   virtual void updateTextShift(GfxState *state, double shift);
-  virtual void saveTextPos(GfxState *state);
-  virtual void restoreTextPos(GfxState *state);
 
   //----- path painting
   virtual void stroke(GfxState *state);
@@ -219,7 +213,15 @@
   virtual void clipToStrokePath(GfxState *state);
 
   //----- text drawing
-  virtual void drawString(GfxState *state, GString *s);
+  virtual void drawString(GfxState *state, GString *s,
+			  GBool fill, GBool stroke, GBool makePath);
+  virtual void fillTextPath(GfxState *state);
+  virtual void strokeTextPath(GfxState *state);
+  virtual void clipToTextPath(GfxState *state);
+  virtual void clipToTextStrokePath(GfxState *state);
+  virtual void clearTextPath(GfxState *state);
+  virtual void addTextPathToSavedClipPath(GfxState *state);
+  virtual void clipToSavedClipPath(GfxState *state);
   virtual void endTextObject(GfxState *state);
 
   //----- image drawing
@@ -295,6 +297,8 @@
   PSFontFileInfo *setupExternalType1Font(GfxFont *font, GString *fileName);
   PSFontFileInfo *setupEmbeddedType1CFont(GfxFont *font, Ref *id);
   PSFontFileInfo *setupEmbeddedOpenTypeT1CFont(GfxFont *font, Ref *id);
+  PSFontFileInfo *setupExternalOpenTypeT1CFont(GfxFont *font,
+					       GString *fileName);
   PSFontFileInfo *setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id);
   PSFontFileInfo *setupExternalTrueTypeFont(GfxFont *font, GString *fileName,
 					    int fontNum);
@@ -489,8 +493,11 @@
   PSOutCustomColor		// used custom colors
     *customColors;
 
-  GBool haveTextClip;		// set if text has been drawn with a
-				//   clipping render mode
+  GBool haveSavedTextPath;	// set if text has been drawn with the
+				//   'makePath' argument
+  GBool haveSavedClipPath;	// set if the text path has been added
+				//   to the saved clipping path (with
+				//   addTextPathToSavedClipPath)
 
   GBool inType3Char;		// inside a Type 3 CharProc
   GString *t3String;		// Type 3 content string

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include "gmempp.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 
 //------------------------------------------------------------------------

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stddef.h>
 #include "gmempp.h"
 #include "Trace.h"
@@ -381,7 +377,6 @@
   PDFRectangle box;
   Gfx *gfx;
   Object obj;
-  Annots *annotList;
   AcroForm *form;
   int i;
 
@@ -426,21 +421,20 @@
 
   // draw (non-form) annotations
   if (globalParams->getDrawAnnotations()) {
-    annotList = new Annots(doc, getAnnots(&obj));
-    obj.free();
-    annotList->generateAnnotAppearances();
-    if (annotList->getNumAnnots() > 0) {
+    Annots *annots2 = doc->getAnnots();
+    annots2->generateAnnotAppearances(num);
+    int n = annots2->getNumAnnots(num);
+    if (n > 0) {
       if (globalParams->getPrintCommands()) {
 	printf("***** Annotations\n");
       }
-      for (i = 0; i < annotList->getNumAnnots(); ++i) {
+      for (i = 0; i < n; ++i) {
 	if (abortCheckCbk && (*abortCheckCbk)(abortCheckCbkData)) {
 	  break;
 	}
-	annotList->getAnnot(i)->draw(gfx, printing);
+	annots2->getAnnot(num, i)->draw(gfx, printing);
       }
     }
-    delete annotList;
   }
 
   // draw form fields
@@ -552,3 +546,4 @@
   delete state;
 #endif
 }
+

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "Object.h"
 
 class Dict;
@@ -192,6 +188,7 @@
   void getDefaultCTM(double *ctm, double hDPI, double vDPI,
 		     int rotate, GBool useMediaBox, GBool upsideDown);
 
+
 private:
 
   PDFDoc *doc;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stddef.h>
 #include <string.h>
 #include "gmempp.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "Lexer.h"
 
 //------------------------------------------------------------------------

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <math.h>
 #include "gmempp.h"
 #include "GlobalParams.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "GfxState.h"
 #include "OutputDev.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include "gmempp.h"
 #include "GString.h"
 #include "PDFDoc.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "Object.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <math.h>
 #include "Trace.h"
 #include "GfxState.h"
@@ -70,6 +66,14 @@
   }
 }
 
+static double max4(double x0, double x1, double x2, double x3) {
+  double t = x0;
+  t = (x1 > t) ? x1 : t;
+  t = (x2 > t) ? x2 : t;
+  t = (x3 > t) ? x3 : t;
+  return t;
+}
+
 SplashBitmap *ShadingImage::generateFunctionBitmap(GfxState *state,
 						   GfxFunctionShading *shading,
 						   SplashColorMode mode,
@@ -204,7 +208,8 @@
   // compute the inverse CTM
   double *ctm = state->getCTM();
   double det = ctm[0] * ctm[3] - ctm[1] * ctm[2];
-  if (fabs(det) < 0.000001) {
+  if (fabs(det) < 1e-10 * max4(fabs(ctm[0]), fabs(ctm[1]),
+			       fabs(ctm[2]), fabs(ctm[3]))) {
     return NULL;
   }
   det = 1 / det;
@@ -468,7 +473,8 @@
   // compute the inverse CTM
   double *ctm = state->getCTM();
   double det = ctm[0] * ctm[3] - ctm[1] * ctm[2];
-  if (fabs(det) < 0.000001) {
+  if (fabs(det) < 1e-10 * max4(fabs(ctm[0]), fabs(ctm[1]),
+			       fabs(ctm[2]), fabs(ctm[3]))) {
     return NULL;
   }
   det = 1 / det;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/ShadingImage.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -13,10 +13,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "SplashTypes.h"
 
 class GfxState;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <string.h>
 #include <math.h>
 #include <limits.h>
@@ -598,6 +594,8 @@
   SplashBitmap *tBitmap;	// bitmap for transparency group
   GfxColorSpace *blendingColorSpace;
   GBool isolated;
+  GBool inSoftMask;		// true if this, or any containing
+				//   group, is a soft mask
 
   //----- modified region in tBitmap
   int modXMin, modYMin, modXMax, modYMax;
@@ -654,7 +652,8 @@
 
   font = NULL;
   needFontUpdate = gFalse;
-  textClipPath = NULL;
+  savedTextPath = NULL;
+  savedClipPath = NULL;
 
   transpGroupStack = NULL;
 
@@ -731,9 +730,12 @@
   if (bitmap) {
     delete bitmap;
   }
-  if (textClipPath) {
-    delete textClipPath;
+  if (savedTextPath) {
+    delete savedTextPath;
   }
+  if (savedClipPath) {
+    delete savedClipPath;
+  }
 }
 
 void SplashOutputDev::startDoc(XRef *xrefA) {
@@ -1074,7 +1076,10 @@
   Guint mask;
   GfxCMYK cmyk;
 
-  if (overprintFlag && globalParams->getOverprintPreview()) {
+  // Adobe ignores overprint in soft masks.
+  if (overprintFlag &&
+      !(transpGroupStack && transpGroupStack->inSoftMask) &&
+      globalParams->getOverprintPreview()) {
     mask = colorSpace->getOverprintMask();
     // The OPM (overprintMode) setting is only relevant when the color
     // space is DeviceCMYK or is "implicitly converted to DeviceCMYK".
@@ -2218,27 +2223,24 @@
 			       double dx, double dy,
 			       double originX, double originY,
 			       CharCode code, int nBytes,
-			       Unicode *u, int uLen) {
-  SplashPath *path;
-  int render;
-  GBool doFill, doStroke, doClip;
-  SplashStrokeAdjustMode strokeAdjust;
-  double m[4];
-  GBool horiz;
-
+			       Unicode *u, int uLen,
+			       GBool fill, GBool stroke, GBool makePath) {
   if (skipHorizText || skipRotatedText) {
+    double m[4];
     state->getFontTransMat(&m[0], &m[1], &m[2], &m[3]);
     // this matches the 'diagonal' test in TextPage::updateFont()
-    horiz = m[0] > 0 && fabs(m[1]) < 0.001 &&
-            fabs(m[2]) < 0.001 && m[3] < 0;
+    GBool horiz = m[0] > 0 && fabs(m[1]) < 0.001 &&
+                  fabs(m[2]) < 0.001 && m[3] < 0;
     if ((skipHorizText && horiz) || (skipRotatedText && !horiz)) {
       return;
     }
   }
 
+  fill = fill && !state->getFillColorSpace()->isNonMarking();
+  stroke = stroke && !state->getStrokeColorSpace()->isNonMarking();
+
   // check for invisible text -- this is used by Acrobat Capture
-  render = state->getRender();
-  if (render == 3) {
+  if (!fill && !stroke && !makePath) {
     return;
   }
 
@@ -2252,13 +2254,8 @@
   x -= originX;
   y -= originY;
 
-  doFill = !(render & 1) && !state->getFillColorSpace()->isNonMarking();
-  doStroke = ((render & 3) == 1 || (render & 3) == 2) &&
-             !state->getStrokeColorSpace()->isNonMarking();
-  doClip = render & 4;
-
-  path = NULL;
-  if (doStroke || doClip) {
+  SplashPath *path = NULL;
+  if (stroke || makePath) {
     if ((path = font->getGlyphPath(code))) {
       path->offset((SplashCoord)x, (SplashCoord)y);
     }
@@ -2267,14 +2264,19 @@
   // don't use stroke adjustment when stroking text -- the results
   // tend to be ugly (because characters with horizontal upper or
   // lower edges get misaligned relative to the other characters)
-  strokeAdjust = splashStrokeAdjustOff; // make gcc happy
-  if (doStroke) {
-    strokeAdjust = splash->getStrokeAdjust();
+  SplashStrokeAdjustMode savedStrokeAdjust = splashStrokeAdjustOff;
+  if (stroke) {
+    savedStrokeAdjust = splash->getStrokeAdjust();
     splash->setStrokeAdjust(splashStrokeAdjustOff);
   }
 
-  // fill and stroke
-  if (doFill && doStroke) {
+  // the possible operations are:
+  //   - fill
+  //   - stroke
+  //   - fill + stroke
+  //   - makePath
+
+  if (fill && stroke) {
     if (path) {
       setOverprintMask(state, state->getFillColorSpace(),
 		       state->getFillOverprint(), state->getOverprintMode(),
@@ -2286,15 +2288,13 @@
       splash->stroke(path);
     }
 
-  // fill
-  } else if (doFill) {
+  } else if (fill) {
     setOverprintMask(state, state->getFillColorSpace(),
 		     state->getFillOverprint(), state->getOverprintMode(),
 		     state->getFillColor());
     splash->fillChar((SplashCoord)x, (SplashCoord)y, code, font);
 
-  // stroke
-  } else if (doStroke) {
+  } else if (stroke) {
     if (path) {
       setOverprintMask(state, state->getStrokeColorSpace(),
 		       state->getStrokeOverprint(), state->getOverprintMode(),
@@ -2301,22 +2301,20 @@
 		       state->getStrokeColor());
       splash->stroke(path);
     }
-  }
 
-  // clip
-  if (doClip) {
+  } else if (makePath) {
     if (path) {
-      if (textClipPath) {
-	textClipPath->append(path);
+      if (savedTextPath) {
+	savedTextPath->append(path);
       } else {
-	textClipPath = path;
+	savedTextPath = path;
 	path = NULL;
       }
     }
   }
 
-  if (doStroke) {
-    splash->setStrokeAdjust(strokeAdjust);
+  if (stroke) {
+    splash->setStrokeAdjust(savedStrokeAdjust);
   }
 
   if (path) {
@@ -2324,6 +2322,73 @@
   }
 }
 
+void SplashOutputDev::fillTextPath(GfxState *state) {
+  if (!savedTextPath) {
+    return;
+  }
+  setOverprintMask(state, state->getFillColorSpace(),
+		   state->getFillOverprint(), state->getOverprintMode(),
+		   state->getFillColor());
+  splash->fill(savedTextPath, gFalse);
+}
+
+void SplashOutputDev::strokeTextPath(GfxState *state) {
+  if (!savedTextPath) {
+    return;
+  }
+  setOverprintMask(state, state->getStrokeColorSpace(),
+		   state->getStrokeOverprint(), state->getOverprintMode(),
+		   state->getStrokeColor());
+  splash->stroke(savedTextPath);
+}
+
+void SplashOutputDev::clipToTextPath(GfxState *state) {
+  if (!savedTextPath) {
+    return;
+  }
+  splash->clipToPath(savedTextPath, gFalse);
+}
+
+void SplashOutputDev::clipToTextStrokePath(GfxState *state) {
+  if (!savedTextPath) {
+    return;
+  }
+  SplashPath *path = splash->makeStrokePath(savedTextPath,
+					    state->getLineWidth(),
+					    state->getLineCap(),
+					    state->getLineJoin());
+  splash->clipToPath(path, gFalse);
+  delete path;
+}
+
+void SplashOutputDev::clearTextPath(GfxState *state) {
+  if (savedTextPath) {
+    delete savedTextPath;
+    savedTextPath = NULL;
+  }
+}
+
+void SplashOutputDev::addTextPathToSavedClipPath(GfxState *state) {
+  if (savedTextPath) {
+    if (savedClipPath) {
+      savedClipPath->append(savedTextPath);
+      delete savedTextPath;
+    } else {
+      savedClipPath = savedTextPath;
+    }
+    savedTextPath = NULL;
+  }
+}
+
+void SplashOutputDev::clipToSavedClipPath(GfxState *state) {
+  if (!savedClipPath) {
+    return;
+  }
+  splash->clipToPath(savedClipPath, gFalse);
+  delete savedClipPath;
+  savedClipPath = NULL;
+}
+
 GBool SplashOutputDev::beginType3Char(GfxState *state, double x, double y,
 				      double dx, double dy,
 				      CharCode code, Unicode *u, int uLen) {
@@ -2679,11 +2744,6 @@
 }
 
 void SplashOutputDev::endTextObject(GfxState *state) {
-  if (textClipPath) {
-    splash->clipToPath(textClipPath, gFalse);
-    delete textClipPath;
-    textClipPath = NULL;
-  }
 }
 
 struct SplashOutImageMaskData {
@@ -3855,7 +3915,7 @@
   SplashBitmap *backdropBitmap;
   SplashColor color;
   double xMin, yMin, xMax, yMax, x, y;
-  int bw, bh, tx, ty, w, h, i;
+  int bw, bh, tx, ty, w, h, xx, yy, i;
 
   // transform the bbox
   state->transform(bbox[0], bbox[1], &x, &y);
@@ -3928,22 +3988,24 @@
   } else if (ty >= bh) {
     ty = bh - 1;
   }
-  w = (int)ceil(xMax) - tx + 1;
-  // NB bw and tx are both non-negative, so 'bw - tx' can't overflow
-  if (bw - tx < w) {
+  xx = (int)ceil(xMax);
+  if (xx < tx) {
+    w = 1;
+  } else if (xx > bw - 1) {
+    // NB bw and tx are both non-negative, so 'bw - tx' can't overflow
     w = bw - tx;
+  } else {
+    w = xx - tx + 1;
   }
-  if (w < 1) {
-    w = 1;
-  }
-  h = (int)ceil(yMax) - ty + 1;
-  // NB bh and ty are both non-negative, so 'bh - ty' can't overflow
-  if (bh - ty < h) {
+  yy = (int)ceil(yMax);
+  if (yy < ty) {
+    h = 1;
+  } else if (yy > bh - 1) {
+    // NB bh and ty are both non-negative, so 'bh - ty' can't overflow
     h = bh - ty;
+  } else {
+    h = yy - ty + 1;
   }
-  if (h < 1) {
-    h = 1;
-  }
 
   // optimization: a non-isolated group drawn with alpha=1 and
   // Blend=Normal and backdrop alpha=0 is equivalent to drawing
@@ -3973,6 +4035,8 @@
   transpGroup->ty = ty;
   transpGroup->blendingColorSpace = blendingColorSpace;
   transpGroup->isolated = isolated;
+  transpGroup->inSoftMask = (transpGroupStack && transpGroupStack->inSoftMask)
+                            || forSoftMask;
   transpGroup->next = transpGroupStack;
   transpGroupStack = transpGroup;
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "SplashTypes.h"
 #include "config.h"
@@ -129,7 +125,15 @@
   virtual void drawChar(GfxState *state, double x, double y,
 			double dx, double dy,
 			double originX, double originY,
-			CharCode code, int nBytes, Unicode *u, int uLen);
+			CharCode code, int nBytes, Unicode *u, int uLen,
+			GBool fill, GBool stroke, GBool makePath);
+  virtual void fillTextPath(GfxState *state);
+  virtual void strokeTextPath(GfxState *state);
+  virtual void clipToTextPath(GfxState *state);
+  virtual void clipToTextStrokePath(GfxState *state);
+  virtual void clearTextPath(GfxState *state);
+  virtual void addTextPathToSavedClipPath(GfxState *state);
+  virtual void clipToSavedClipPath(GfxState *state);
   virtual GBool beginType3Char(GfxState *state, double x, double y,
 			       double dx, double dy,
 			       CharCode code, Unicode *u, int uLen);
@@ -306,7 +310,8 @@
 
   SplashFont *font;		// current font
   GBool needFontUpdate;		// set when the font needs to be updated
-  SplashPath *textClipPath;	// clipping path built with text object
+  SplashPath *savedTextPath;	// path built for text string
+  SplashPath *savedClipPath;	// clipping path built with text object
 
   SplashTransparencyGroup *	// transparency group stack
     transpGroupStack;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
@@ -2673,6 +2669,7 @@
     frameBuf[i] = NULL;
   }
   rowBuf = NULL;
+  memset(quantTables, 0, sizeof(quantTables));
   memset(dcHuffTables, 0, sizeof(dcHuffTables));
   memset(acHuffTables, 0, sizeof(acHuffTables));
 
@@ -2894,7 +2891,7 @@
     bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
     bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
     if (bufWidth <= 0 || bufHeight <= 0 ||
-	bufWidth > INT_MAX / bufWidth / (int)sizeof(int)) {
+	bufWidth > INT_MAX / bufHeight / (int)sizeof(int)) {
       error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
       y = height;
       prepared = gTrue;
@@ -2942,7 +2939,13 @@
 
     // allocate a buffer for one row of MCUs
     bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
-    rowBuf = (Guchar *)gmallocn(numComps * mcuHeight, bufWidth);
+    if (bufWidth <= 0 || bufWidth > INT_MAX / numComps / mcuHeight) {
+      error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
+      y = height;
+      prepared = gTrue;
+      return;
+    }
+    rowBuf = (Guchar *)gmallocn(bufWidth, numComps * mcuHeight);
     rowBufPtr = rowBufEnd = rowBuf;
 
     // initialize counters
@@ -3848,11 +3851,12 @@
 }
 
 GBool DCTStream::readHeader(GBool frame) {
-  GBool doScan;
+  GBool haveSOF, doScan;
   int n, i;
   int c = 0;
 
   // read headers
+  haveSOF = gFalse;
   doScan = gFalse;
   while (!doScan) {
     c = readMarker();
@@ -3867,6 +3871,7 @@
       if (!readBaselineSOF()) {
 	return gFalse;
       }
+      haveSOF = gTrue;
       break;
     case 0xc2:			// SOF2 (progressive)
       if (!frame) {
@@ -3877,6 +3882,7 @@
       if (!readProgressiveSOF()) {
 	return gFalse;
       }
+      haveSOF = gTrue;
       break;
     case 0xc4:			// DHT
       if (!readHuffmanTables()) {
@@ -3893,6 +3899,10 @@
     case 0xd9:			// EOI
       return gFalse;
     case 0xda:			// SOS
+      if (frame && !haveSOF) {
+	error(errSyntaxError, getPos(), "Missing SOF in DCT stream");
+	return gFalse;
+      }
       if (!readScanInfo()) {
 	return gFalse;
       }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <stdio.h>
 #if HAVE_JPEGLIB
 #include <jpeglib.h>
@@ -130,6 +126,10 @@
   // Does this stream type potentially contain non-printable chars?
   virtual GBool isBinary(GBool last = gTrue) = 0;
 
+  // Does this stream include a "strong" compression filter (anything
+  // other than RLE)?
+  virtual GBool hasStrongCompression() { return gFalse; }
+
   // Get the BaseStream of this stream.
   virtual BaseStream *getBaseStream() = 0;
 
@@ -490,6 +490,7 @@
   virtual GString *getPSFilter(int psLevel, const char *indent,
 			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
+  virtual GBool hasStrongCompression() { return gTrue; }
 
 private:
 
@@ -573,6 +574,7 @@
   virtual GString *getPSFilter(int psLevel, const char *indent,
 			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
+  virtual GBool hasStrongCompression() { return gTrue; }
 
 private:
 
@@ -672,6 +674,7 @@
   virtual GString *getPSFilter(int psLevel, const char *indent,
 			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
+  virtual GBool hasStrongCompression() { return gTrue; }
   Stream *getRawStream() { return str; }
 
 private:
@@ -813,6 +816,7 @@
   virtual GString *getPSFilter(int psLevel, const char *indent,
 			       GBool okToReadStream);
   virtual GBool isBinary(GBool last = gTrue);
+  virtual GBool hasStrongCompression() { return gTrue; }
 
 private:
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
@@ -65,8 +61,12 @@
 
 // A large character has a font size larger than
 // largeCharThreshold * avgFontSize.
-#define largeCharThreshold 1.5
+#define largeCharThreshold 2.0
 
+// Max ratio of large-to-total chars to prefer a large char split over
+// a line split.
+#define largeCharRatio 0.2
+
 // A block will be split vertically only if the resulting chunk widths
 // are greater than minChunkWidth * avgFontSize.  However, Blocks of
 // height less than maxSingleLineHeight * avgFontSize are not subject
@@ -83,9 +83,9 @@
 #define maxWordGapSize 2.5
 #define tableModeMaxWordGapSize 1.1
 
-// Adjacent lines can overlap by at most lineOverlapThreshold *
-// lineHeight.
-#define lineOverlapThreshold 0.33
+// Chars whose baseline is within baselineRange * avgFontSize of a
+// line's current average baseline are added to the line.
+#define baselineRange 0.5
 
 // Subscripts (superscripts) must overlap the next (previous) line by
 // minSubSuperscriptVertOverlap * fontSize.
@@ -214,6 +214,7 @@
 
   static int cmpX(const void *p1, const void *p2);
   static int cmpY(const void *p1, const void *p2);
+  static int cmpBase(const void *p1, const void *p2);
   static int cmpCharPos(const void *p1, const void *p2);
 
   Unicode c;
@@ -220,6 +221,7 @@
   int charPos;
   int charLen;
   double xMin, yMin, xMax, yMax;
+  double base;
   TextFontInfo *font;
   double fontSize;
   double colorR,
@@ -249,39 +251,51 @@
   yMin = yMinA;
   xMax = xMaxA;
   yMax = yMaxA;
-  // this can happen with vertical writing mode, or with odd values
-  // for the char/word spacing parameters
-  if (xMin > xMax) {
-    t = xMin; xMin = xMax; xMax = t;
+  switch (rotA) {
+  case 0:
+  default:  base = yMax + fontSizeA * fontA->getDescent();  break;
+  case 1:   base = xMin - fontSizeA * fontA->getDescent();  break;
+  case 2:   base = yMin - fontSizeA * fontA->getDescent();  break;
+  case 3:   base = xMax + fontSizeA * fontA->getDescent();  break;
   }
-  if (yMin > yMax) {
-    t = yMin; yMin = yMax; yMax = t;
-  }
   // TextPage::findGaps uses integer coordinates, so clip the char
   // bbox to fit in a 32-bit int (this is generally only a problem in
   // damaged PDF files)
   if (xMin < -1e8) {
     xMin = -1e8;
+  } else if (xMin > 1e8) {
+    xMin = 1e8;
   }
-  if (xMax > 1e8) {
+  if (xMax < -1e8) {
+    xMax = -1e8;
+  } else if (xMax > 1e8) {
     xMax = 1e8;
   }
   if (yMin < -1e8) {
     yMin = -1e8;
+  } else if (yMin > 1e8) {
+    yMin = 1e8;
   }
-  if (yMax > 1e8) {
+  if (yMax < -1e8) {
+    yMax = -1e8;
+  } else if (yMax > 1e8) {
     yMax = 1e8;
   }
-  // zero-width characters will cause problems in the splitting code
-  if (rotA & 1) {
-    if (yMax - yMin < 1e-6) {
-      yMax = yMin + 1e-6;
-    }
-  } else {
-    if (xMax - xMin < 1e-6) {
-      xMax = xMin + 1e-6;
-    }
+  // this can happen with vertical writing mode, or with odd values
+  // for the char/word spacing parameters
+  if (xMin > xMax) {
+    t = xMin; xMin = xMax; xMax = t;
   }
+  if (yMin > yMax) {
+    t = yMin; yMin = yMax; yMax = t;
+  }
+  // zero-width/height characters will cause problems in the splitting code
+  if (xMax - xMin < 1e-6) {
+    xMax = xMin + 1e-6;
+  }
+  if (yMax - yMin < 1e-6) {
+    yMax = yMin + 1e-6;
+  }
   rot = (Guchar)rotA;
   rotated = (char)rotatedA;
   clipped = (char)clippedA;
@@ -321,6 +335,19 @@
   }
 }
 
+int TextChar::cmpBase(const void *p1, const void *p2) {
+  const TextChar *ch1 = *(const TextChar **)p1;
+  const TextChar *ch2 = *(const TextChar **)p2;
+
+  if (ch1->base < ch2->base) {
+    return -1;
+  } else if (ch1->base > ch2->base) {
+    return 1;
+  } else {
+    return ch1->charPos - ch2->charPos;
+  }
+}
+
 int TextChar::cmpCharPos(const void *p1, const void *p2) {
   const TextChar *ch1 = *(const TextChar **)p1;
   const TextChar *ch2 = *(const TextChar **)p2;
@@ -985,7 +1012,8 @@
     }
   }
   //~ need to check for other Unicode chars used as hyphens
-  hyphenated = text[len - 1] == (Unicode)'-';
+  hyphenated = text[len - 1] == (Unicode)'-' ||
+               text[len - 1] == (Unicode)0xad;
 }
 
 TextLine::~TextLine() {
@@ -1212,6 +1240,7 @@
 
   chars = new GList();
   fonts = new GList();
+  primaryRot = 0;
 
   underlines = new GList();
   links = new GList();
@@ -1240,6 +1269,15 @@
   if (state) {
     pageWidth = state->getPageWidth();
     pageHeight = state->getPageHeight();
+    // When rotating characters, the coordinates are flipped using the
+    // page size.  See the comment in TextChar::TextChar() about
+    // integer coordinates.
+    if (pageWidth > 1e8) {
+      pageWidth = 1e8;
+    }
+    if (pageHeight > 1e8) {
+      pageHeight = 1e8;
+    }
   } else {
     pageWidth = pageHeight = 0;
   }
@@ -1266,6 +1304,9 @@
   underlines = new GList();
   deleteGList(links, TextLink);
   links = new GList();
+  nVisibleChars = 0;
+  nInvisibleChars = 0;
+  nRemovedDupChars = 0;
 
   if (findCols) {
     deleteGList(findCols, TextColumn);
@@ -1560,13 +1601,18 @@
       } else {
 	j = i;
       }
+      GBool invisible = state->getRender() == 3 || alpha < 0.001;
       chars->append(new TextChar(uBuf[j], charPos, nBytes,
 				 xMin, yMin, xMax, yMax,
-				 curRot, rotated, clipped,
-				 state->getRender() == 3 || alpha < 0.001,
+				 curRot, rotated, clipped, invisible,
 				 curFont, curFontSize,
 				 colToDbl(rgb.r), colToDbl(rgb.g),
 				 colToDbl(rgb.b)));
+      if (invisible) {
+	++nInvisibleChars;
+      } else {
+	++nVisibleChars;
+      }
     }
   }
 
@@ -1730,7 +1776,7 @@
   GList *columns;
   GBool primaryLR;
   GString *s;
-  int colIdx, parIdx, lineIdx, rot, n;
+  int colIdx, parIdx, lineIdx, n;
 
 #if 0 //~debug
   dumpChars(chars);
@@ -1740,7 +1786,7 @@
   } else {
     overlappingChars = NULL;
   }
-  rot = rotateChars(chars);
+  primaryRot = rotateChars(chars);
   primaryLR = checkPrimaryLR(chars);
   tree = splitChars(chars);
 #if 0 //~debug
@@ -1748,14 +1794,14 @@
 #endif
   if (!tree) {
     // no text
-    unrotateChars(chars, rot);
+    unrotateChars(chars, primaryRot);
     return;
   }
   columns = buildColumns(tree, primaryLR);
   delete tree;
-  unrotateChars(chars, rot);
+  unrotateChars(chars, primaryRot);
   if (control.html) {
-    rotateUnderlinesAndLinks(rot);
+    rotateUnderlinesAndLinks(primaryRot);
     generateUnderlinesAndLinks(columns);
   }
   if (overlappingChars) {
@@ -1799,10 +1845,10 @@
   GList *overlappingChars;
   GList *columns;
   GBool primaryLR;
-  int rot;
 
   if (control.mode == textOutSimple2Layout) {
     primaryLR = checkPrimaryLR(chars);
+    primaryRot = 0;
     rotateCharsToZero(chars);
     columns = buildSimple2Columns(chars);
     unrotateCharsFromZero(chars);
@@ -1813,7 +1859,7 @@
     } else {
       overlappingChars = NULL;
     }
-    rot = rotateChars(chars);
+    primaryRot = rotateChars(chars);
     primaryLR = checkPrimaryLR(chars);
     if ((tree = splitChars(chars))) {
       columns = buildColumns(tree, primaryLR);
@@ -1822,8 +1868,8 @@
       // no text
       columns = new GList();
     }
-    unrotateChars(chars, rot);
-    unrotateColumns(columns, rot);
+    unrotateChars(chars, primaryRot);
+    unrotateColumns(columns, primaryRot);
     if (control.html) {
       generateUnderlinesAndLinks(columns);
     }
@@ -1852,7 +1898,7 @@
   GList *overlappingChars;
   GList *columns;
   GBool primaryLR;
-  int ph, colIdx, parIdx, lineIdx, rot, y, i;
+  int ph, colIdx, parIdx, lineIdx, y, i;
 
 #if 0 //~debug
   dumpChars(chars);
@@ -1865,7 +1911,7 @@
   } else {
     overlappingChars = NULL;
   }
-  rot = rotateChars(chars);
+  primaryRot = rotateChars(chars);
   primaryLR = checkPrimaryLR(chars);
   tree = splitChars(chars);
 #if 0 //~debug
@@ -1873,15 +1919,15 @@
 #endif
   if (!tree) {
     // no text
-    unrotateChars(chars, rot);
+    unrotateChars(chars, primaryRot);
     return;
   }
   //~ this doesn't correctly handle the right-to-left case
   columns = buildColumns(tree, gTrue);
   delete tree;
-  unrotateChars(chars, rot);
+  unrotateChars(chars, primaryRot);
   if (control.html) {
-    rotateUnderlinesAndLinks(rot);
+    rotateUnderlinesAndLinks(primaryRot);
     generateUnderlinesAndLinks(columns);
   }
   ph = assignPhysLayoutPositions(columns);
@@ -1940,7 +1986,7 @@
 
   if (overlappingChars) {
     if (overlappingChars->getLength() > 0) {
-      TextColumn *col = buildOverlappingTextColumn(overlappingChars);
+      col = buildOverlappingTextColumn(overlappingChars);
       (*outputFunc)(outputStream, eol, eolLen);
       for (parIdx = 0; parIdx < col->paragraphs->getLength(); ++parIdx) {
 	par = (TextParagraph *)col->paragraphs->get(parIdx);
@@ -1973,12 +2019,12 @@
   GList *superLines;
   GString *out;
   GBool primaryLR;
-  int rot, x, i, j;
+  int x, i, j;
 
 #if 0 //~debug
   dumpChars(chars);
 #endif
-  rot = rotateChars(chars);
+  primaryRot = rotateChars(chars);
   primaryLR = checkPrimaryLR(chars);
   tree = splitChars(chars);
 #if 0 //~debug
@@ -1986,13 +2032,13 @@
 #endif
   if (!tree) {
     // no text
-    unrotateChars(chars, rot);
+    unrotateChars(chars, primaryRot);
     return;
   }
   superLines = new GList();
   buildSuperLines(tree, superLines);
   delete tree;
-  unrotateChars(chars, rot);
+  unrotateChars(chars, primaryRot);
   assignSimpleLayoutPositions(superLines, uMap);
 
   for (i = 0; i < superLines->getLength(); ++i) {
@@ -2036,6 +2082,7 @@
   int colIdx, parIdx, lineIdx;
 
   primaryLR = checkPrimaryLR(chars);
+  primaryRot = 0;
   rotateCharsToZero(chars);
 #if 0 //~debug
   dumpChars(chars);
@@ -2074,9 +2121,9 @@
   double pitch, lineSpacing, delta;
   double yMin0, yShift, xMin0, xShift;
   double y, x;
-  int rot, n, i, j, k;
+  int n, i, j, k;
 
-  rot = rotateChars(chars);
+  primaryRot = rotateChars(chars);
   chars->sort(&TextChar::cmpX);
   // don't call removeDuplicates here, because it expects to be
   // working on a secondary list that doesn't own the TextChar objects
@@ -2186,7 +2233,7 @@
     delete line;
   }
 
-  unrotateChars(chars, rot);
+  unrotateChars(chars, primaryRot);
 }
 
 void TextPage::writeRaw(void *outputStream,
@@ -2451,6 +2498,7 @@
       ch->xMax = xMax;
       ch->yMin = yMin;
       ch->yMax = yMax;
+      ch->base = pageWidth - ch->base;
       ch->rot = (ch->rot + 3) & 3;
     }
     t = pageWidth;
@@ -2468,6 +2516,7 @@
       ch->xMax = xMax;
       ch->yMin = yMin;
       ch->yMax = yMax;
+      ch->base = pageHeight - ch->base;
       ch->rot = (ch->rot + 2) & 3;
     }
     break;
@@ -2515,6 +2564,7 @@
       ch->xMax = xMax;
       ch->yMin = yMin;
       ch->yMax = yMax;
+      ch->base = pageWidth - ch->base;
       break;
     case 2:
       xMin = pageWidth - ch->xMax;
@@ -2525,6 +2575,7 @@
       ch->xMax = xMax;
       ch->yMin = yMin;
       ch->yMax = yMax;
+      ch->base = pageHeight - ch->base;
       break;
     case 3:
       xMin = pageHeight - ch->yMax;
@@ -2654,6 +2705,7 @@
       ch->xMax = xMax;
       ch->yMin = yMin;
       ch->yMax = yMax;
+      ch->base = pageWidth - ch->base;
       ch->rot = (ch->rot + 1) & 3;
     }
     break;
@@ -2668,6 +2720,7 @@
       ch->xMax = xMax;
       ch->yMin = yMin;
       ch->yMax = yMax;
+      ch->base = pageHeight - ch->base;
       ch->rot = (ch->rot + 2) & 3;
     }
     break;
@@ -3220,7 +3273,7 @@
 // by x for rot=0,2; by y for rot=1,3.
 void TextPage::removeDuplicates(GList *charsA, int rot) {
   TextChar *ch, *ch2;
-  double xDelta, yDelta;
+  double xDelta, yDelta, xDelta2, yDelta2;
   int i, j;
 
   if (rot & 1) {
@@ -3229,6 +3282,10 @@
       ch = (TextChar *)charsA->get(i);
       xDelta = dupMaxSecDelta * ch->fontSize;
       yDelta = dupMaxPriDelta * ch->fontSize;
+      yDelta2 = 0.5 * (ch->yMax - ch->yMin);
+      if (yDelta2 < yDelta) {
+	yDelta = yDelta2;
+      }
       j = i + 1;
       while (j < charsA->getLength()) {
 	ch2 = (TextChar *)charsA->get(j);
@@ -3241,6 +3298,7 @@
 	    fabs(ch2->yMax - ch->yMax) < yDelta) {
 	  if (ch->invisible && !ch2->invisible) {
 	    charsA->del(i);
+	    ++nRemovedDupChars;
 	    --i;
 	    break;
 	  }
@@ -3248,6 +3306,7 @@
 	    ch->spaceAfter = (char)gTrue;
 	  }
 	  charsA->del(j);
+	  ++nRemovedDupChars;
 	} else {
 	  ++j;
 	}
@@ -3259,6 +3318,10 @@
     while (i < charsA->getLength()) {
       ch = (TextChar *)charsA->get(i);
       xDelta = dupMaxPriDelta * ch->fontSize;
+      xDelta2 = 0.5 * (ch->xMax - ch->xMin);
+      if (xDelta2 < xDelta) {
+	xDelta = xDelta2;
+      }
       yDelta = dupMaxSecDelta * ch->fontSize;
       j = i + 1;
       while (j < charsA->getLength()) {
@@ -3272,6 +3335,7 @@
 	    fabs(ch2->yMax - ch->yMax) < yDelta) {
 	  if (ch->invisible && !ch2->invisible) {
 	    charsA->del(i);
+	    ++nRemovedDupChars;
 	    --i;
 	    break;
 	  }
@@ -3279,6 +3343,7 @@
 	    ch->spaceAfter = (char)gTrue;
 	  }
 	  charsA->del(j);
+	  ++nRemovedDupChars;
 	} else {
 	  ++j;
 	}
@@ -3559,7 +3624,7 @@
 	}
       }
       if (chars2->getLength() > 0) {
-	tree[rot] = split(chars2, rot, gFalse);
+	tree[rot] = split(chars2, rot);
       }
     }
     delete chars2;
@@ -3590,9 +3655,11 @@
   }
 
   // merge non-primary-rotation text into the primary-rotation tree
+  GBool doReorder = control.mode == textOutReadingOrder &&
+                    globalParams->getSeparateRotatedText();
   for (rot = 1; rot < 4; ++rot) {
     if (tree[rot]) {
-      insertIntoTree(tree[rot], tree[0]);
+      insertIntoTree(tree[rot], tree[0], doReorder);
       tree[rot] = NULL;
     }
   }
@@ -3610,7 +3677,7 @@
 }
 
 // Generate a tree of TextBlocks, marked as columns, lines, and words.
-TextBlock *TextPage::split(GList *charsA, int rot, GBool vertOnly) {
+TextBlock *TextPage::split(GList *charsA, int rot) {
   TextBlock *blk;
   GList *chars2, *chars3;
   GList *splitLines;
@@ -3762,18 +3829,13 @@
   doHorizSplit = doVertSplit = doLineSplit = doLargeCharSplit = gFalse;
   smallSplit = gFalse;
   if (rot & 1) {
-    if (vertOnly) {
-      if (nHorizGaps > 0 && horizGapSize > minGapSize * minFontSize) {
-	doHorizSplit = gTrue;
-	smallSplit = horizGapSize < smallSplitThreshold;
-      }
-    } else if (control.mode == textOutSimpleLayout) {
+    if (control.mode == textOutSimpleLayout) {
       if (nVertGaps > 0) {
 	doVertSplit = gTrue;
       } else if (nHorizGaps > 0 && horizGapSize > minGapSize * minFontSize) {
 	doHorizSplit = gTrue;
 	smallSplit = horizGapSize < smallSplitThreshold;
-      } else if (!vertOnly && splitLines->getLength() > 1) {
+      } else if (splitLines->getLength() > 1) {
 	doLineSplit = gTrue;
       }
     } else if (nHorizGaps > 0 &&
@@ -3786,19 +3848,15 @@
       smallSplit = horizGapSize < smallSplitThreshold;
     } else if (nVertGaps > 0) {
       doVertSplit = gTrue;
-    } else if (nLargeChars > 0) {
+    } else if (nLargeChars > 0 &&
+	       ((nLargeChars < largeCharRatio * charsA->getLength()) ||
+		splitLines->getLength() <= 1)) {
       doLargeCharSplit = gTrue;
     } else if (splitLines->getLength() > 1) {
       doLineSplit = gTrue;
     }
   } else {
-    if (vertOnly) {
-      if (nVertGaps > 0 &&
-	  vertGapSize > minGapSize * minFontSize) {
-	doVertSplit = gTrue;
-	smallSplit = vertGapSize < smallSplitThreshold;
-      }
-    } else if (control.mode == textOutSimpleLayout) {
+    if (control.mode == textOutSimpleLayout) {
       if (nHorizGaps > 0) {
 	doHorizSplit = gTrue;
       } else if (nVertGaps > 0 && vertGapSize > minGapSize * minFontSize) {
@@ -3817,7 +3875,9 @@
       smallSplit = vertGapSize < smallSplitThreshold;
     } else if (nHorizGaps > 0) {
       doHorizSplit = gTrue;
-    } else if (nLargeChars > 0) {
+    } else if (nLargeChars > 0 &&
+	       ((nLargeChars < largeCharRatio * charsA->getLength()) ||
+		splitLines->getLength() <= 1)) {
       doLargeCharSplit = gTrue;
     } else if (splitLines->getLength() > 1) {
       doLineSplit = gTrue;
@@ -3847,13 +3907,13 @@
       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, vertOnly));
+	blk->addChild(split(chars2, rot));
 	delete chars2;
 	x0 = x1;
       }
     }
     chars2 = getChars(charsA, x0, yMin - 1, xMax + 1, yMax + 1);
-    blk->addChild(split(chars2, rot, vertOnly));
+    blk->addChild(split(chars2, rot));
     delete chars2;
 
   // split horizontally
@@ -3874,13 +3934,13 @@
       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, gFalse));
+	blk->addChild(split(chars2, rot));
 	delete chars2;
 	y0 = y1;
       }
     }
     chars2 = getChars(charsA, xMin - 1, y0, xMax + 1, yMax + 1);
-    blk->addChild(split(chars2, rot, gFalse));
+    blk->addChild(split(chars2, rot));
     delete chars2;
 
   // split into larger and smaller chars
@@ -3899,7 +3959,7 @@
 	chars3->append(ch);
       }
     }
-    blk = split(chars3, rot, gFalse);
+    blk = split(chars3, rot);
     chars2->sort((rot & 1) ? &TextChar::cmpY : &TextChar::cmpX);
     insertLargeChars(chars2, blk);
     delete chars2;
@@ -3925,12 +3985,21 @@
       for (i = 0; i < splitLine->chars->getLength(); ++i) {
 	blk->addChild((TextChar *)splitLine->chars->get(i), gTrue);
       }
+#if 0 //~debug
+      printf("line-leaf xMin=%g yMin=%g xMax=%g yMax=%g\n",
+	     xMin, pageHeight - yMax, xMax, pageHeight - yMin);
+      printf("    ");
+      for (i = 0; i < splitLine->chars->getLength(); ++i) {
+	printf("%c", ((TextChar *)splitLine->chars->get(i))->c);
+      }
+      printf("\n");
+#endif
     } else {
       blk = new TextBlock((rot & 1) ? blkVertSplit : blkHorizSplit, rot);
       blk->smallSplit = gFalse;
       for (i = 0; i < splitLines->getLength(); ++i) {
 	SplitLine *splitLine = (SplitLine *)splitLines->get(i);
-	blk->addChild(split(splitLine->chars, rot, singleLine));
+	blk->addChild(split(splitLine->chars, rot));
       }
     }
 
@@ -4058,54 +4127,146 @@
     }
   }
 
-  //----- partition into lines and find horizontal gaps
+  //----- find horizontal gaps
 
   if (rot & 1) {
     charsA->sort(&TextChar::cmpX);
-    SplitLine *splitLine = NULL;
-    double xxMin = 0, xxMax = 0;
+    double xxMax = 0;
     for (int i = 0; i < charsA->getLength(); ++i) {
       TextChar *ch = (TextChar *)charsA->get(i);
-      if (i == 0 ||
-	  ch->xMin > xxMax - lineOverlapThreshold * (xxMax - xxMin)) {
-	if (i > 0 && ch->xMin > xxMax) {
-	  vertGaps->addGap(0.5 * (ch->xMin + xxMax), ch->xMin - xxMax);
-	}
-	xxMin = ch->xMin;
+      if (i == 0) {
 	xxMax = ch->xMax;
-	splitLine = new SplitLine(i, i, xxMin, xxMax);
-	splitLines->append(splitLine);
-      } else {
-	splitLine->lastCharIdx = i;
+      } else if (ch->xMin <= xxMax) {
 	if (ch->xMax > xxMax) {
 	  xxMax = ch->xMax;
-	  splitLine->yMax = xxMax;
 	}
+      } else {
+	vertGaps->addGap(0.5 * (ch->xMin + xxMax), ch->xMin - xxMax);
+	xxMax = ch->xMax;
       }
     }
   } else {
     charsA->sort(&TextChar::cmpY);
-    SplitLine *splitLine = NULL;
-    double yyMin = 0, yyMax = 0;
+    double yyMax = 0;
     for (int i = 0; i < charsA->getLength(); ++i) {
       TextChar *ch = (TextChar *)charsA->get(i);
-      if (i == 0 ||
-	  ch->yMin > yyMax - lineOverlapThreshold * (yyMax - yyMin)) {
-	if (i > 0 && ch->yMin > yyMax) {
-	  horizGaps->addGap(0.5 * (ch->yMin + yyMax), ch->yMin - yyMax);
+      if (i == 0) {
+	yyMax = ch->yMax;
+      } else if (ch->yMin <= yyMax) {
+	if (ch->yMax > yyMax) {
+	  yyMax = ch->yMax;
 	}
-	yyMin = ch->yMin;
+      } else {
+	horizGaps->addGap(0.5 * (ch->yMin + yyMax), ch->yMin - yyMax);
 	yyMax = ch->yMax;
-	splitLine = new SplitLine(i, i, yyMin, yyMax);
-	splitLines->append(splitLine);
-      } else {
-	splitLine->lastCharIdx = i;
+      }
+    }
+  }
+
+  //----- split into lines
+
+  double baseDelta = baselineRange * avgFontSize;
+
+  if (rot & 1) {
+
+    // split into non-overlapping chunks
+    int firstChar = 0;
+    while (firstChar < charsA->getLength()) {
+      TextChar *ch = (TextChar *)charsA->get(firstChar);
+      double xxMax = ch->xMax;
+      int nextChar = firstChar + 1;
+      while (nextChar < charsA->getLength()) {
+	ch = (TextChar *)charsA->get(nextChar);
+	if (ch->xMin > xxMax) {
+	  break;
+	}
+	if (ch->xMax > xxMax) {
+	  xxMax = ch->xMax;
+	}
+	++nextChar;
+      }
+
+      // split the chunk [firstChar, nextChar) into lines
+      charsA->sort(firstChar, nextChar - firstChar, &TextChar::cmpBase);
+      int i0 = firstChar;
+      while (i0 < nextChar) {
+	ch = (TextChar *)charsA->get(i0);
+	double baseTotal = ch->base;
+	double baseAvg = baseTotal;
+	double xxMin = ch->xMin;
+	xxMax = ch->xMax;
+	int i1 = i0 + 1;
+	while (i1 < nextChar) {
+	  ch = (TextChar *)charsA->get(i1);
+	  if (ch->base > baseAvg + baseDelta) {
+	    break;
+	  }
+	  baseTotal += ch->base;
+	  if (ch->xMin < xxMin) {
+	    xxMin = ch->xMin;
+	  }
+	  if (ch->xMax > xxMax) {
+	    xxMax = ch->xMax;
+	  }
+	  ++i1;
+	  baseAvg = baseTotal / (i1 - i0);
+	}
+	splitLines->append(new SplitLine(i0, i1 - 1, xxMin, xxMax));
+	i0 = i1;
+      }
+      firstChar = nextChar;
+    }
+
+  } else {
+
+    // split into non-overlapping chunks
+    int firstChar = 0;
+    while (firstChar < charsA->getLength()) {
+      TextChar *ch = (TextChar *)charsA->get(firstChar);
+      double yyMax = ch->yMax;
+      int nextChar = firstChar + 1;
+      while (nextChar < charsA->getLength()) {
+	ch = (TextChar *)charsA->get(nextChar);
+	if (ch->yMin > yyMax) {
+	  break;
+	}
 	if (ch->yMax > yyMax) {
 	  yyMax = ch->yMax;
-	  splitLine->yMax = yyMax;
 	}
+	++nextChar;
       }
+
+      // split the chunk [firstChar, nextChar) into lines
+      charsA->sort(firstChar, nextChar - firstChar, &TextChar::cmpBase);
+      int i0 = firstChar;
+      while (i0 < nextChar) {
+	ch = (TextChar *)charsA->get(i0);
+	double baseTotal = ch->base;
+	double baseAvg = baseTotal;
+	double yyMin = ch->yMin;
+	yyMax = ch->yMax;
+	int i1 = i0 + 1;
+	while (i1 < nextChar) {
+	  ch = (TextChar *)charsA->get(i1);
+	  if (ch->base > baseAvg + baseDelta) {
+	    break;
+	  }
+	  baseTotal += ch->base;
+	  if (ch->yMin < yyMin) {
+	    yyMin = ch->yMin;
+	  }
+	  if (ch->yMax > yyMax) {
+	    yyMax = ch->yMax;
+	  }
+	  ++i1;
+	  baseAvg = baseTotal / (i1 - i0);
+	}
+	splitLines->append(new SplitLine(i0, i1 - 1, yyMin, yyMax));
+	i0 = i1;
+      }
+      firstChar = nextChar;
     }
+
   }
 }
 
@@ -4197,10 +4358,19 @@
 
       // merge sub/superscripts into correct lines
       if (allSubSuper) {
+	idxAbove = 0;
+	idxBelow = 0;
 	for (int idx = 0; idx < splitLine->chars->getLength(); ++idx) {
 	  TextChar *ch = (TextChar *)splitLine->chars->get(idx);
 	  if (maybeSub && ch->xMin < prevLine->yMax) {
-	    prevLine->chars->append(ch);
+	    while (idxAbove < prevLine->chars->getLength()) {
+	      TextChar *ch2 = (TextChar *)prevLine->chars->get(idxAbove);
+	      if (ch2->yMin > ch->yMin && ch2->xMin < ch->xMax && ch2->xMax > ch->xMin) {
+		break;
+	      }
+	      ++idxAbove;
+	    }
+	    prevLine->chars->insert(idxAbove, ch);
 	    if (ch->xMin < prevLine->yMin) {
 	      prevLine->yMin = ch->xMin;
 	    }
@@ -4208,7 +4378,14 @@
 	      prevLine->yMax = ch->xMax;
 	    }
 	  } else {
-	    nextLine->chars->append(ch);
+	    while (idxBelow < nextLine->chars->getLength()) {
+	      TextChar *ch2 = (TextChar *)nextLine->chars->get(idxBelow);
+	      if (ch2->yMin > ch->yMin && ch2->xMin < ch->xMax && ch2->xMax > ch->xMin) {
+		break;
+	      }
+	      ++idxBelow;
+	    }
+	    nextLine->chars->insert(idxBelow, ch);
 	    if (ch->xMin < nextLine->yMin) {
 	      nextLine->yMin = ch->xMin;
 	    }
@@ -4217,12 +4394,6 @@
 	    }
 	  }
 	}
-	if (maybeSub) {
-	  prevLine->chars->sort(&TextChar::cmpY);
-	}
-	if (maybeSuper) {
-	  nextLine->chars->sort(&TextChar::cmpY);
-	}
 	delete splitLine;
 	splitLines->del(i);
       }
@@ -4252,7 +4423,7 @@
 	prevLine = (SplitLine *)splitLines->get(i-1);
 	double minOverlap = minSubSuperscriptVertOverlap
 	                    * (prevLine->yMax - prevLine->yMin);
-	maybeSub = prevLine->yMax - splitLine->yMin  > minOverlap;
+	maybeSub = prevLine->yMax - splitLine->yMin > minOverlap;
       }
       GBool maybeSuper = gFalse;
       if (i < splitLines->getLength() - 1) {
@@ -4259,7 +4430,7 @@
 	nextLine = (SplitLine *)splitLines->get(i+1);
 	double minOverlap = minSubSuperscriptVertOverlap
 	                    * (nextLine->yMax - nextLine->yMin);
-	maybeSuper = splitLine->yMax - nextLine->yMin  > minOverlap;
+	maybeSuper = splitLine->yMax - nextLine->yMin > minOverlap;
       }
       if (!maybeSub && !maybeSuper) {
 	continue;
@@ -4315,10 +4486,19 @@
 
       // merge sub/superscripts into correct lines
       if (allSubSuper) {
+	idxAbove = 0;
+	idxBelow = 0;
 	for (int idx = 0; idx < splitLine->chars->getLength(); ++idx) {
 	  TextChar *ch = (TextChar *)splitLine->chars->get(idx);
 	  if (maybeSub && ch->yMin < prevLine->yMax) {
-	    prevLine->chars->append(ch);
+	    while (idxAbove < prevLine->chars->getLength()) {
+	      TextChar *ch2 = (TextChar *)prevLine->chars->get(idxAbove);
+	      if (ch2->xMin > ch->xMin && ch2->yMin < ch->yMax && ch2->yMax > ch->yMin) {
+		break;
+	      }
+	      ++idxAbove;
+	    }
+	    prevLine->chars->insert(idxAbove, ch);
 	    if (ch->yMin < prevLine->yMin) {
 	      prevLine->yMin = ch->yMin;
 	    }
@@ -4326,7 +4506,14 @@
 	      prevLine->yMax = ch->yMax;
 	    }
 	  } else {
-	    nextLine->chars->append(ch);
+	    while (idxBelow < nextLine->chars->getLength()) {
+	      TextChar *ch2 = (TextChar *)nextLine->chars->get(idxBelow);
+	      if (ch2->xMin > ch->xMin && ch2->yMin < ch->yMax && ch2->yMax > ch->yMin) {
+		break;
+	      }
+	      ++idxBelow;
+	    }
+	    nextLine->chars->insert(idxBelow, ch);
 	    if (ch->yMin < nextLine->yMin) {
 	      nextLine->yMin = ch->yMin;
 	    }
@@ -4335,12 +4522,6 @@
 	    }
 	  }
 	}
-	if (maybeSub) {
-	  prevLine->chars->sort(&TextChar::cmpX);
-	}
-	if (maybeSuper) {
-	  nextLine->chars->sort(&TextChar::cmpX);
-	}
 	delete splitLine;
 	splitLines->del(i);
       }
@@ -4517,23 +4698,51 @@
 }
 
 // Merge blk (rot != 0) into primaryTree (rot == 0).
-void TextPage::insertIntoTree(TextBlock *blk, TextBlock *primaryTree) {
-  TextBlock *child;
+void TextPage::insertIntoTree(TextBlock *blk, TextBlock *primaryTree,
+			      GBool doReorder) {
+  // if we're separating each rotation (only supported in reading
+  // order mode), reorder the block's children as appropriate and then
+  // append the block
+  if (doReorder) {
+    reorderBlocks(blk);
+    primaryTree->children->append(blk);
 
-  // we insert a whole column at a time - so call insertIntoTree
-  // recursively until we get to a column (or line)
+  // otherwise, insert blocks into the primary tree in the appropriate
+  // locations
+  } else {
 
-  if (blk->tag == blkTagMulticolumn) {
-    while (blk->children->getLength()) {
-      child = (TextBlock *)blk->children->del(0);
-      insertIntoTree(child, primaryTree);
+    // we insert a whole column at a time - so call insertIntoTree
+    // recursively until we get to a column (or line)
+    if (blk->tag == blkTagMulticolumn) {
+      while (blk->children->getLength()) {
+	TextBlock *child = (TextBlock *)blk->children->del(0);
+	insertIntoTree(child, primaryTree, doReorder);
+      }
+      delete blk;
+
+    } else {
+      insertColumnIntoTree(blk, primaryTree);
     }
-    delete blk;
-  } else {
-    insertColumnIntoTree(blk, primaryTree);
   }
 }
 
+// Reorder non-primary-rotation blocks as appropriate (for reading
+// order mode only).
+void TextPage::reorderBlocks(TextBlock *blk) {
+  if (blk->tag  != blkTagMulticolumn) {
+    return;
+  }
+  for (int i = 0; i < blk->children->getLength(); ++i) {
+    reorderBlocks((TextBlock *)blk->children->get(i));
+  }
+  //~ check/test these conditions
+  if ((blk->rot == 1 && blk->type == blkVertSplit) ||
+      blk->rot == 2 ||
+      (blk->rot == 3 && blk->type == blkHorizSplit)) {
+    blk->children->reverse();
+  }
+}
+
 // Insert a column (as an atomic subtree) into tree.
 // Requirement: tree is not a leaf node.
 void TextPage::insertColumnIntoTree(TextBlock *column, TextBlock *tree) {
@@ -5095,11 +5304,13 @@
   TextWord *word;
   double wordSp, lineFontSize, sp;
   int dir, dir2;
-  GBool rotated, spaceAfter, spaceBefore;
+  GBool rotated2, spaceAfter, spaceBefore;
   int i, j;
 
   wordSp = computeWordSpacingThreshold(charsA, rot);
 
+  adjustCombiningChars(charsA, rot);
+
   words = new GList();
   lineFontSize = 0;
   spaceBefore = gFalse;
@@ -5113,7 +5324,7 @@
 			             : (TextChar *)NULL,
 	      (i < charsA->getLength() - 1) ? (TextChar *)charsA->get(i+1)
 	                                    : (TextChar *)NULL);
-    rotated = ((TextChar *)charsA->get(i))->rotated;
+    rotated2 = ((TextChar *)charsA->get(i))->rotated;
     for (j = i+1; j < charsA->getLength(); ++j) {
       ch = (TextChar *)charsA->get(j-1);
       ch2 = (TextChar *)charsA->get(j);
@@ -5134,7 +5345,7 @@
 		                               : (TextChar *)NULL);
       if (ch->font != ch2->font ||
 	  fabs(ch->fontSize - ch2->fontSize) > 0.01 ||
-	  (control.splitRotatedWords && ch2->rotated != rotated) ||
+	  (control.splitRotatedWords && ch2->rotated != rotated2) ||
 	  (dir && dir2 && dir2 != dir) ||
 	  (control.mode == textOutRawOrder &&
 	   ch2->charPos != ch->charPos + ch->charLen)) {
@@ -5145,7 +5356,7 @@
       }
       sp = wordSp - 1;
     }
-    word = new TextWord(charsA, i, j - i, rot, rotated, dir,
+    word = new TextWord(charsA, i, j - i, rot, rotated2, dir,
 			(rot >= 2) ? spaceBefore : spaceAfter);
     spaceBefore = spaceAfter;
     i = j;
@@ -5277,6 +5488,89 @@
   }
 }
 
+// Move Unicode combining characters around so that they come
+// immediately after the correct base characters.
+//~ this currently won't work for RtL scripts
+void TextPage::adjustCombiningChars(GList *charsA, int rot) {
+  int i = 1;
+  while (i < charsA->getLength()) {
+    TextChar *ch = (TextChar *)charsA->get(i);
+
+    // look for a zero-width combining char
+    if (!(unicodeTypeCombiningMark(ch->c) &&
+	  fabs((rot & 1) ? ch->yMax - ch->yMin             // width ~= zero 
+	                 : ch->xMax - ch->xMin) < 0.01)) {
+      ++i;
+      continue;
+    }
+
+    // look for a sequence of zero-width combining chars at the same
+    // position (NB: slight negative char spacing can reorder things
+    // so that diacritics for different base chars appear next to each
+    // other)
+    int j;
+    for (j = i + 1; j < charsA->getLength(); ++j) {
+      TextChar *ch2 = (TextChar *)charsA->get(j);
+      if (!(unicodeTypeCombiningMark(ch2->c) &&
+	    fabs((rot & 1) ? ch2->yMin - ch->yMax
+		           : ch2->xMin - ch->xMax) < 0.01 * ch->fontSize &&
+	    fabs((rot & 1) ? ch->yMax - ch->yMin             // width ~= zero 
+	                   : ch->xMax - ch->xMin) < 0.01)) {
+	break;
+      }
+    }
+
+    // identify the two previous chars
+    TextChar *prev1 = (i >= 2) ? (TextChar *)charsA->get(i - 2) : NULL;
+    TextChar *prev2 = (TextChar *)charsA->get(i - 1);
+
+    //~ this code currently makes things worse for RtL scripts, so
+    //~   skip any RtL text
+    if (unicodeTypeR(prev2->c)) {
+      ++i;
+      continue;
+    }
+
+    // if the combining chars are placed in the left 3/4 of prev2,
+    // assume the base char is prev1, not prev2, and reorder the chars
+    // accordingly
+    TextChar *base;
+    if (prev1 &&
+	((rot & 1) ? (ch->yMin < 0.25 * prev2->yMin + 0.75 * prev2->yMax)
+                   : (ch->xMin < 0.25 * prev2->xMin + 0.75 * prev2->xMax))) {
+      for (int k = i; k < j; ++k) {
+	charsA->put(k - 1, charsA->get(k));
+      }
+      charsA->put(j - 1, prev2);
+      --i;
+      --j;
+      base = prev1;
+    } else {
+      base = prev2;
+    }
+
+    // sort the diacritics into content stream order
+    // (slight negative char spacing, used for kerning, will push
+    // zero-width diacritics out of order)
+    if (j - i > 1) {
+      charsA->sort(i, j - i, &TextChar::cmpCharPos);
+    }
+
+    // set the diacritics' positions immediately to the right of the
+    // base char
+    for (int k = i; k < j; ++k) {
+      TextChar *ch2 = (TextChar *)charsA->get(k);
+      if (rot & 1) {
+	ch2->yMin = ch2->yMax = base->yMax;
+      } else {
+	ch2->xMin = ch2->xMax = base->xMax;
+      }
+    }
+
+    i = j;
+  }
+}
+
 // Check the character's direction: returns 1 for L or Num; -1 for R; 0
 // for others.
 int TextPage::getCharDirection(TextChar *ch) {
@@ -6624,7 +6918,8 @@
 void TextOutputDev::drawChar(GfxState *state, double x, double y,
 			     double dx, double dy,
 			     double originX, double originY,
-			     CharCode c, int nBytes, Unicode *u, int uLen) {
+			     CharCode c, int nBytes, Unicode *u, int uLen,
+			     GBool fill, GBool stroke, GBool makePath) {
   text->addChar(state, x, y, dx, dy, c, nBytes, u, uLen);
 }
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include <stdio.h>
 #include "gtypes.h"
 #include "GfxFont.h"
@@ -122,6 +118,9 @@
   // Get the width of the 'm' character, if available.
   double getMWidth() { return mWidth; }
 
+  double getAscent() { return ascent; }
+  double getDescent() { return descent; }
+
   Ref getFontID() { return fontID; }
 
 private:
@@ -474,10 +473,18 @@
   TextWordList *makeWordListForRect(double xMin, double yMin,
 				    double xMax, double yMax);
 
+  // Get the primary rotation of text on the page.
+  int getPrimaryRotation() { return primaryRot; }
+
   // Returns true if the primary character direction is left-to-right,
   // false if it is right-to-left.
   GBool primaryDirectionIsLR();
 
+  // Get the counter values.
+  int getNumVisibleChars() { return nVisibleChars; }
+  int getNumInvisibleChars() { return nInvisibleChars; }
+  int getNumRemovedDupChars() { return nRemovedDupChars; }
+
   // Returns true if any of the fonts used on this page are likely to
   // be problematic when converting text to Unicode.
   GBool problematicForUnicode() { return problematic; }
@@ -557,7 +564,7 @@
   GList *separateOverlappingText(GList *charsA);
   TextColumn *buildOverlappingTextColumn(GList *overlappingChars);
   TextBlock *splitChars(GList *charsA);
-  TextBlock *split(GList *charsA, int rot, GBool vertOnly);
+  TextBlock *split(GList *charsA, int rot);
   GList *getChars(GList *charsA, double xMin, double yMin,
 		  double xMax, double yMax);
   void findGaps(GList *charsA, int rot,
@@ -571,7 +578,9 @@
   void insertLargeChars(GList *largeChars, TextBlock *blk);
   void insertLargeCharsInFirstLeaf(GList *largeChars, TextBlock *blk);
   void insertLargeCharInLeaf(TextChar *ch, TextBlock *blk);
-  void insertIntoTree(TextBlock *subtree, TextBlock *primaryTree);
+  void insertIntoTree(TextBlock *subtree, TextBlock *primaryTree,
+		      GBool doReorder);
+  void reorderBlocks(TextBlock *blk);
   void insertColumnIntoTree(TextBlock *column, TextBlock *tree);
   void insertClippedChars(GList *clippedChars, TextBlock *tree);
   TextBlock *findClippedCharLeaf(TextChar *ch, TextBlock *tree);
@@ -589,6 +598,7 @@
 		      double xMin, double yMin, double xMax, double yMax);
   void getLineChars(TextBlock *blk, GList *charsA);
   double computeWordSpacingThreshold(GList *charsA, int rot);
+  void adjustCombiningChars(GList *charsA, int rot);
   int getCharDirection(TextChar *ch);
   int getCharDirection(TextChar *ch, TextChar *left, TextChar *right);
   int assignPhysLayoutPositions(GList *columns);
@@ -640,10 +650,15 @@
   GList *chars;			// [TextChar]
   GList *fonts;			// all font info objects used on this
 				//   page [TextFontInfo]
+  int primaryRot;		// primary rotation
 
   GList *underlines;		// [TextUnderline]
   GList *links;			// [TextLink]
 
+  int nVisibleChars;		// number of visible chars on the page
+  int nInvisibleChars;		// number of invisible chars on the page
+  int nRemovedDupChars;		// number of duplicate chars removed
+
   GList *findCols;		// text used by the findText**/findPoint**
 				//   functions [TextColumn]
   double lastFindXMin,		// coordinates of the last "find" result
@@ -725,7 +740,8 @@
   virtual void drawChar(GfxState *state, double x, double y,
 			double dx, double dy,
 			double originX, double originY,
-			CharCode c, int nBytes, Unicode *u, int uLen);
+			CharCode c, int nBytes, Unicode *u, int uLen,
+			GBool fill, GBool stroke, GBool makePath);
   virtual void incCharCount(int nChars);
   virtual void beginActualText(GfxState *state, Unicode *u, int uLen);
   virtual void endActualText(GfxState *state);
@@ -784,6 +800,11 @@
   // Turn extra processing for HTML conversion on or off.
   void enableHTMLExtras(GBool html) { control.html = html; }
 
+  // Get the counter values.
+  int getNumVisibleChars() { return text->nVisibleChars; }
+  int getNumInvisibleChars() { return text->nInvisibleChars; }
+  int getNumRemovedDupChars() { return text->nRemovedDupChars; }
+
 private:
 
   void generateBOM();

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <string.h>
 #include "gmem.h"
 #include "gmempp.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -15,10 +15,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "CharTypes.h"
 
 class GString;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include "gmem.h"
 #include "gmempp.h"
 #include "GList.h"
@@ -237,7 +233,7 @@
 }
 
 void TileCacheThreadPool::worker() {
-  CachedTileDesc *ct;
+  CachedTileDesc *ct = NULL;
 
   while (1) {
     gLockMutex(&mutex);

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "SplashTypes.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <string.h>
 #include <math.h>
 #include "gmempp.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "SplashTypes.h"
 
 class GList;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include "gmem.h"
 #include "gmempp.h"
 #include "GList.h"
@@ -903,7 +899,7 @@
 
 void TileMap::getWindowPageRange(int x, int y, int w, int h,
 				 int *firstPage, int *lastPage) {
-  GList *tiles;
+  GList *tiles2;
   PlacedTileDesc *tile;
   int i;
 
@@ -913,9 +909,9 @@
   }
   *firstPage = state->getDoc()->getNumPages();
   *lastPage = 0;
-  tiles = getTileList();
-  for (i = 0; i < tiles->getLength(); ++i) {
-    tile = (PlacedTileDesc *)tiles->get(i);
+  tiles2 = getTileList();
+  for (i = 0; i < tiles2->getLength(); ++i) {
+    tile = (PlacedTileDesc *)tiles2->get(i);
     if (tile->px < x + w &&
 	tile->px + tile->tw > x &&
 	tile->py < y + h &&
@@ -1352,7 +1348,7 @@
       // rotate the page boxes
       if (page & 1) {
 	otherPage = page + 1;
-	if (otherPage >= state->getDoc()->getNumPages()) {
+	if (otherPage > state->getDoc()->getNumPages()) {
 	  otherPage = page;
 	}
       } else {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 
 class GList;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <string.h>
 #include "gmem.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -13,10 +13,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "CharTypes.h"
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdio.h>
 #include <string.h>
 #include "gmem.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -13,10 +13,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "CharTypes.h"
 
 struct UnicodeRemappingString;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -25,36 +25,36 @@
   { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN...NNNNN.....##########.NNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN.N....NNNNLNNNNN..##NLNNN#LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL", 'X' },
   { NULL, 'L' },
   { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLNNNNNNNNNNNNNNLLNNNNNNNNNNNNNNLLLLLNNNNNNNNNLNNNNNNNNNNNNNNNNN", 'X' },
-  { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLNNLLLLLLLLNLNNNNNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLL", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNN.NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNRNRNNRNNRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR###########", 'X' },
-  { "######NNR..R.RNNNNNNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNNNNNNNNN##########.##RRRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNN#NNNNNNNRRNNNNNNNRR##########RRRRRR", 'X' },
-  { "RRRRRRRRRRRRRRRRRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNNNNNNNNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNRRNNNNRNNNRR", 'X' },
-  { "RRRRRRRRRRRRRRRRRRRRRRNNNNRNNNNNNNNNRNNNRNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNNNNNNNNNNNNNN#NNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
-  { "NNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNLLLLNNNNNNNNLLLLNLLLNNNNNNNLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNLLLLLLLLNLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLL..LLLLLLL.LLNN", 'X' },
-  { "NNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLNLNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNLLLLNLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLL.LLLLLLLLNNNNNN", 'X' },
-  { "NNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLNLNNNNLLLLLLLLNNNNNNNNNNLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNN.NNNNNN", 'X' },
-  { "NLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNNNNNNNNNNNLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLNNNNNNNLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLNNNNNNNNNNNNN", 'X' },
-  { "NNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLNNNNLLLLLLLLNLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNNNNNNN.....LLLLLLLNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNNNNNNNNNLLLLLLLLLLNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNLNNNNNLNNLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLNNNNNNLNNLLNNLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLNNNLLLLLLLLLLLLLLLLNNNNLLLLLLLLLLLLLNLLNNLLLLLLNLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+  { "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLLLLNNLLLLLLLLNLNNNNNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLL", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNN.MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMRMRMMRMMRMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR###########", 'X' },
+  { "######NNR..R.RNNMMMMMMMMMMMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMMMMMMMMMMMMMMMMMMM##########.##RRRMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMMMMM#NMMMMMMRRMMNMMMMRR##########RRRRRR", 'X' },
+  { "RRRRRRRRRRRRRRRRRMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMMMMMMMMMMMMMMMMMMMMMMMMMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMMMMMMMMMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMMMMMMMRRNNNNRMMMRR", 'X' },
+  { "RRRRRRRRRRRRRRRRRRRRRRMMMMRMMMMMMMMMRMMMRMMMMMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR###MMMMMMMMMMMMMMRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRMMMMMMMMMMMMMMMMMMMMMMMM#MMMMMMMMMMMMMMMMMMMMMMMMMMMMM", 'X' },
+  { "MMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMLLLLMMMMMMMMLLLLMLLLMMMMMMMLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLLLLMMMMLLLLLLLLMLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLL..LLLLLLL.LLMM", 'X' },
+  { "MMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLLLLMMMMMMMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLMLMMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLLLLMMMMMMMMLLLLMLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLL.LLLLLLLLMMMMMM", 'X' },
+  { "MMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLLMLMMMMLLLLLLLLMMMMMMMMMMLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNN.NMMMMM", 'X' },
+  { "MLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLMMMLLLLMMMMMMMMMMMMMMMMMMLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLNNNNNNNLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLMMMMMMMMMMMM", 'X' },
+  { "MMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLMMMMLLLLLLLLMLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMLLLLLLLMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLMMMMMMM.....LLLLLLLMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLMMMMMMMMMLLLLLLLLLLMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMLMNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMLMMMMMLMMLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMLMMMMMMLMMLLMMLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLMMMLLLLLLLLLLLLLLLLMMMMLLLLLLLLLLLLLMLLMMLLLLLLMLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
   { NULL, 'L' },
   { NULL, 'L' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNN", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNN", 'X' },
   { "NLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
   { NULL, 'L' },
   { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
-  { "LLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLNNNNNNNLLLLLLLLNLLNNNNNNNNNNNLLLLLLL.LNLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNN", 'X' },
-  { "NNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLNNLLLLLLLLLNLLLLLLNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLNNLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNNNNNNNLNLLNNNNNNNNLLLLLLNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
-  { "NNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNNNLNLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNLLLLLLLLLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLNNLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNLLLNLNNNLLLLLLLLLLLLLL", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNLNNNNNNNNNNNNNLNNNNNNNLLLLNLLLLLLNLLLNNLLLLLL", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+  { "LLLLLLLLLLLLLLLLLLMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLMMMMMMMLLLLLLLLMLLMMMMMMMMMMMLLLLLLL.LMLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+  { "NNNNNNNNNNNMMMNMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMLLLLMMLLLLLLLLLMLLLLLLMMMNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLMMLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMMMMMMMMMLMLLMMMMMMMMLLLLLLMMMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", 'X' },
+  { "MMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMMMMMLMLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMLLLLLLLLLLLMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMLLMMLMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMMLLLMLMMMLLLLLLLLLLLLLL", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMLMMMMMMMMMMMMMLMMMMMMMLLLLMLLLLLLMLLLMMLLLLLL", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", 'X' },
   { NULL, 'L' },
   { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNLLLLLLLLLLLNNNLLLLLLLLLLLLNNNNLLLLLLLLLLLLLNNNLLLLLLLLLLLLLNNN", 'X' },
-  { "NNNNNNNNNNNNNNLRNNNNNNNNNNNNNNNNNNNNNNNNNNLRNLR......NNNNNNNNNNNNNNN.NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLRNNNNNNNN#L########..NNNL##########..NNNLLLLLLLLLLLLLL...................................NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+  { "NNNNNNNNNNNNNNLRNNNNNNNNNNNNNNNNNNNNNNNNNNLRNLR......NNNNNNNNNNNNNNN.NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLRNNNNNNNN#L########..NNNL##########..NNNLLLLLLLLLLLLLL....................................MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNN", 'X' },
   { "NNLNNNNLNNLLLLLLLLLLNLNNNLLLLLNNNNNNLNLNLNLLLL.LLLLLLLLLLLNNLLLLNNNNNLLLLLNNNNLLNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
   { "NNNNNNNNNNNNNNNNNN..NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
   { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
@@ -66,12 +66,12 @@
   { NULL, 'N' },
   { NULL, 'N' },
   { NULL, 'N' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLNNNLLNNNNNNNNNNNN", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLMMMLLNNNNNNNNNNNN", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", 'X' },
   { NULL, 'N' },
   { NULL, 'N' },
-  { "NNNNNLLLNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLNNNNLLNLLLLLNNLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLL", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+  { "NNNNNLLLNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLMMMMLLNLLLLLNNLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMNNLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLL", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLL", 'X' },
   { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
   { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN", 'X' },
   { NULL, 'L' },
@@ -188,12 +188,12 @@
   { NULL, 'L' },
   { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
   { NULL, 'L' },
-  { "LLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLNNNNNNNN", 'X' },
+  { "LLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMNMMMMMMMMMMNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLNNNNNNNN", 'X' },
   { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
-  { "LLNLLLNLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLNNLNNNNNLLLLLLLLLLL..LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLN", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNNNNLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLNNLLNNLLLLLLLLLLLLNLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNLLNNLLLLLNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLNLLLLLLLLL", 'X' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNLLLLNLLLLLLLLLLLLLLLLLL", 'X' },
+  { "LLMLLLMLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLMMLNNNNMLLLLLLLLLLL..LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMLLLLLLLLLLLLLM", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLMMMMLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMLLMMLLMMLLLLLLLLLLLLMLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLMMMLLMMLLLLLMMLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLLLLLLMLLLLLLLLL", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLMLLLLMLLLLLLLLLLLLLLLLLL", 'X' },
   { NULL, 'L' },
   { NULL, 'L' },
   { NULL, 'L' },
@@ -273,10 +273,10 @@
   { NULL, 'L' },
   { NULL, 'L' },
   { NULL, 'L' },
-  { "LLLLLLLLLLLLLLLLLLLLLLLLRRRRRRNRRRRRRRRRR.RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR", 'X' },
+  { "LLLLLLLLLLLLLLLLLLLLLLLLRRRRRRMRRRRRRRRRR.RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR", 'X' },
   { NULL, 'R' },
-  { "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNN", 'X' },
-  { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN.N.NN.NNNNNNNNN.NN..NNNNN..NRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNN", 'X' },
+  { "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNN", 'X' },
+  { "MMMMMMMMMMMMMMMMNNNNNNNNNNMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN.N.NN.NNNNNNNNN.NN..NNNNN..NRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNN", 'X' },
   { "NNN...NNNNN.....##########.NNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.....NNN..NNNNNNNNNNNNNNNNNNNNNNNLL", 'X' }
 };
 
@@ -647,9 +647,9 @@
   0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x1fb3, 0x1fbd, 0x03b9, 0x1fbf,
   0x1fc0, 0x1fc1, 0x1fc2, 0x1fc3, 0x1fc4, 0x1fc5, 0x1fc6, 0x1fc7,
   0x1f72, 0x1f73, 0x1f74, 0x1f75, 0x1fc3, 0x1fcd, 0x1fce, 0x1fcf,
-  0x1fd0, 0x1fd1, 0x1fd2, 0x1fd3, 0x1fd4, 0x1fd5, 0x1fd6, 0x1fd7,
+  0x1fd0, 0x1fd1, 0x1fd2, 0x0390, 0x1fd4, 0x1fd5, 0x1fd6, 0x1fd7,
   0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0x1fdc, 0x1fdd, 0x1fde, 0x1fdf,
-  0x1fe0, 0x1fe1, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe5, 0x1fe6, 0x1fe7,
+  0x1fe0, 0x1fe1, 0x1fe2, 0x03b0, 0x1fe4, 0x1fe5, 0x1fe6, 0x1fe7,
   0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0x1fed, 0x1fee, 0x1fef,
   0x1ff0, 0x1ff1, 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7,
   0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x1ff3, 0x1ffd, 0x1ffe, 0x1fff
@@ -728,7 +728,7 @@
   0x2c40, 0x2c41, 0x2c42, 0x2c43, 0x2c44, 0x2c45, 0x2c46, 0x2c47,
   0x2c48, 0x2c49, 0x2c4a, 0x2c4b, 0x2c4c, 0x2c4d, 0x2c4e, 0x2c4f,
   0x2c50, 0x2c51, 0x2c52, 0x2c53, 0x2c54, 0x2c55, 0x2c56, 0x2c57,
-  0x2c58, 0x2c59, 0x2c5a, 0x2c5b, 0x2c5c, 0x2c5d, 0x2c5e, 0x2c2f,
+  0x2c58, 0x2c59, 0x2c5a, 0x2c5b, 0x2c5c, 0x2c5d, 0x2c5e, 0x2c5f,
   0x2c30, 0x2c31, 0x2c32, 0x2c33, 0x2c34, 0x2c35, 0x2c36, 0x2c37,
   0x2c38, 0x2c39, 0x2c3a, 0x2c3b, 0x2c3c, 0x2c3d, 0x2c3e, 0x2c3f,
   0x2c40, 0x2c41, 0x2c42, 0x2c43, 0x2c44, 0x2c45, 0x2c46, 0x2c47,
@@ -815,10 +815,10 @@
   0xa7a9, 0xa7a9, 0x0266, 0x025c, 0x0261, 0x026c, 0x026a, 0xa7af,
   0x029e, 0x0287, 0x029d, 0xab53, 0xa7b5, 0xa7b5, 0xa7b7, 0xa7b7,
   0xa7b9, 0xa7b9, 0xa7bb, 0xa7bb, 0xa7bd, 0xa7bd, 0xa7bf, 0xa7bf,
-  0xa7c0, 0xa7c1, 0xa7c3, 0xa7c3, 0xa794, 0x0282, 0x1d8e, 0xa7c8,
+  0xa7c1, 0xa7c1, 0xa7c3, 0xa7c3, 0xa794, 0x0282, 0x1d8e, 0xa7c8,
   0xa7c8, 0xa7ca, 0xa7ca, 0xa7cb, 0xa7cc, 0xa7cd, 0xa7ce, 0xa7cf,
-  0xa7d0, 0xa7d1, 0xa7d2, 0xa7d3, 0xa7d4, 0xa7d5, 0xa7d6, 0xa7d7,
-  0xa7d8, 0xa7d9, 0xa7da, 0xa7db, 0xa7dc, 0xa7dd, 0xa7de, 0xa7df,
+  0xa7d1, 0xa7d1, 0xa7d2, 0xa7d3, 0xa7d4, 0xa7d5, 0xa7d7, 0xa7d7,
+  0xa7d9, 0xa7d9, 0xa7da, 0xa7db, 0xa7dc, 0xa7dd, 0xa7de, 0xa7df,
   0xa7e0, 0xa7e1, 0xa7e2, 0xa7e3, 0xa7e4, 0xa7e5, 0xa7e6, 0xa7e7,
   0xa7e8, 0xa7e9, 0xa7ea, 0xa7eb, 0xa7ec, 0xa7ed, 0xa7ee, 0xa7ef,
   0xa7f0, 0xa7f1, 0xa7f2, 0xa7f3, 0xa7f4, 0xa7f6, 0xa7f6, 0xa7f7,
@@ -858,6 +858,40 @@
   0xabf0, 0xabf1, 0xabf2, 0xabf3, 0xabf4, 0xabf5, 0xabf6, 0xabf7,
   0xabf8, 0xabf9, 0xabfa, 0xabfb, 0xabfc, 0xabfd, 0xabfe, 0xabff
 }};
+static UnicodeCaseTableVector caseTablefb = {{
+  0xfb00, 0xfb01, 0xfb02, 0xfb03, 0xfb04, 0xfb06, 0xfb06, 0xfb07,
+  0xfb08, 0xfb09, 0xfb0a, 0xfb0b, 0xfb0c, 0xfb0d, 0xfb0e, 0xfb0f,
+  0xfb10, 0xfb11, 0xfb12, 0xfb13, 0xfb14, 0xfb15, 0xfb16, 0xfb17,
+  0xfb18, 0xfb19, 0xfb1a, 0xfb1b, 0xfb1c, 0xfb1d, 0xfb1e, 0xfb1f,
+  0xfb20, 0xfb21, 0xfb22, 0xfb23, 0xfb24, 0xfb25, 0xfb26, 0xfb27,
+  0xfb28, 0xfb29, 0xfb2a, 0xfb2b, 0xfb2c, 0xfb2d, 0xfb2e, 0xfb2f,
+  0xfb30, 0xfb31, 0xfb32, 0xfb33, 0xfb34, 0xfb35, 0xfb36, 0xfb37,
+  0xfb38, 0xfb39, 0xfb3a, 0xfb3b, 0xfb3c, 0xfb3d, 0xfb3e, 0xfb3f,
+  0xfb40, 0xfb41, 0xfb42, 0xfb43, 0xfb44, 0xfb45, 0xfb46, 0xfb47,
+  0xfb48, 0xfb49, 0xfb4a, 0xfb4b, 0xfb4c, 0xfb4d, 0xfb4e, 0xfb4f,
+  0xfb50, 0xfb51, 0xfb52, 0xfb53, 0xfb54, 0xfb55, 0xfb56, 0xfb57,
+  0xfb58, 0xfb59, 0xfb5a, 0xfb5b, 0xfb5c, 0xfb5d, 0xfb5e, 0xfb5f,
+  0xfb60, 0xfb61, 0xfb62, 0xfb63, 0xfb64, 0xfb65, 0xfb66, 0xfb67,
+  0xfb68, 0xfb69, 0xfb6a, 0xfb6b, 0xfb6c, 0xfb6d, 0xfb6e, 0xfb6f,
+  0xfb70, 0xfb71, 0xfb72, 0xfb73, 0xfb74, 0xfb75, 0xfb76, 0xfb77,
+  0xfb78, 0xfb79, 0xfb7a, 0xfb7b, 0xfb7c, 0xfb7d, 0xfb7e, 0xfb7f,
+  0xfb80, 0xfb81, 0xfb82, 0xfb83, 0xfb84, 0xfb85, 0xfb86, 0xfb87,
+  0xfb88, 0xfb89, 0xfb8a, 0xfb8b, 0xfb8c, 0xfb8d, 0xfb8e, 0xfb8f,
+  0xfb90, 0xfb91, 0xfb92, 0xfb93, 0xfb94, 0xfb95, 0xfb96, 0xfb97,
+  0xfb98, 0xfb99, 0xfb9a, 0xfb9b, 0xfb9c, 0xfb9d, 0xfb9e, 0xfb9f,
+  0xfba0, 0xfba1, 0xfba2, 0xfba3, 0xfba4, 0xfba5, 0xfba6, 0xfba7,
+  0xfba8, 0xfba9, 0xfbaa, 0xfbab, 0xfbac, 0xfbad, 0xfbae, 0xfbaf,
+  0xfbb0, 0xfbb1, 0xfbb2, 0xfbb3, 0xfbb4, 0xfbb5, 0xfbb6, 0xfbb7,
+  0xfbb8, 0xfbb9, 0xfbba, 0xfbbb, 0xfbbc, 0xfbbd, 0xfbbe, 0xfbbf,
+  0xfbc0, 0xfbc1, 0xfbc2, 0xfbc3, 0xfbc4, 0xfbc5, 0xfbc6, 0xfbc7,
+  0xfbc8, 0xfbc9, 0xfbca, 0xfbcb, 0xfbcc, 0xfbcd, 0xfbce, 0xfbcf,
+  0xfbd0, 0xfbd1, 0xfbd2, 0xfbd3, 0xfbd4, 0xfbd5, 0xfbd6, 0xfbd7,
+  0xfbd8, 0xfbd9, 0xfbda, 0xfbdb, 0xfbdc, 0xfbdd, 0xfbde, 0xfbdf,
+  0xfbe0, 0xfbe1, 0xfbe2, 0xfbe3, 0xfbe4, 0xfbe5, 0xfbe6, 0xfbe7,
+  0xfbe8, 0xfbe9, 0xfbea, 0xfbeb, 0xfbec, 0xfbed, 0xfbee, 0xfbef,
+  0xfbf0, 0xfbf1, 0xfbf2, 0xfbf3, 0xfbf4, 0xfbf5, 0xfbf6, 0xfbf7,
+  0xfbf8, 0xfbf9, 0xfbfa, 0xfbfb, 0xfbfc, 0xfbfd, 0xfbfe, 0xfbff
+}};
 static UnicodeCaseTableVector caseTableff = {{
   0xff00, 0xff01, 0xff02, 0xff03, 0xff04, 0xff05, 0xff06, 0xff07,
   0xff08, 0xff09, 0xff0a, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f,
@@ -1144,10 +1178,10 @@
   NULL,
   NULL,
   NULL,
+  &caseTablefb,
   NULL,
   NULL,
   NULL,
-  NULL,
   &caseTableff
 };
 
@@ -1400,6 +1434,8 @@
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0x80002e56, 0x2e55, 0x80002e58,
+  0x2e57, 0x80002e5a, 0x2e59, 0x80002e5c, 0x2e5b, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
@@ -1419,8 +1455,6 @@
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0
 };
 static Unicode bracketTable30[256] = {
@@ -1807,6 +1841,10 @@
   return getType(c) == 'R';
 }
 
+GBool unicodeTypeCombiningMark(Unicode c) {
+  return getType(c) == 'M';
+}
+
 GBool unicodeTypeDigit(Unicode c) {
   return getType(c) == '#';
 }
@@ -1833,7 +1871,7 @@
   char t;
 
   t = getType(c);
-  return t == 'L' || t == 'R' || t == '#';
+  return t == 'L' || t == 'R' || t == '#' || t == 'M';
 }
 
 Unicode unicodeToLower(Unicode c) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -15,6 +15,8 @@
 
 extern GBool unicodeTypeR(Unicode c);
 
+extern GBool unicodeTypeCombiningMark(Unicode c);
+
 extern GBool unicodeTypeDigit(Unicode c);
 
 extern GBool unicodeTypeNumSep(Unicode c);

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include "gmem.h"
 #include "gmempp.h"
 #include "GHash.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -13,10 +13,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "FoFiBase.h"
 #include "GfxFont.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include "GString.h"
 #include "GHash.h"
 #include "Object.h"

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 class GHash;
 class ZxElement;
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -8,10 +8,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <stddef.h>
 #include <string.h>
@@ -133,7 +129,7 @@
 
   // Create an object stream, using object number <objStrNum>,
   // generation 0.
-  ObjectStream(XRef *xref, int objStrNumA);
+  ObjectStream(XRef *xref, int objStrNumA, int recursion);
 
   GBool isOk() { return ok; }
 
@@ -155,7 +151,7 @@
   GBool ok;
 };
 
-ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
+ObjectStream::ObjectStream(XRef *xref, int objStrNumA, int recursion) {
   Stream *str;
   Lexer *lexer;
   Parser *parser;
@@ -169,7 +165,7 @@
   objNums = NULL;
   ok = gFalse;
 
-  if (!xref->fetch(objStrNum, 0, &objStr)->isStream()) {
+  if (!xref->fetch(objStrNum, 0, &objStr, recursion)->isStream()) {
     goto err1;
   }
 
@@ -234,11 +230,10 @@
   lexer->skipToEOF();
   delete parser;
 
-  // skip to the first object - this shouldn't be necessary because
-  // the First key is supposed to be equal to offsets[0], but just in
-  // case...
-  if (first < offsets[0]) {
-    objStr.getStream()->discardChars(offsets[0] - first);
+  // skip to the first object - this generally shouldn't be needed,
+  // because offsets[0] is normally 0, but just in case...
+  if (offsets[0] > 0) {
+    objStr.getStream()->discardChars(offsets[0]);
   }
 
   // parse the objects
@@ -880,6 +875,7 @@
   char *p = buf;
   char *end = buf;
   GBool startOfLine = gTrue;
+  GBool space = gTrue;
   GBool eof = gFalse;
   while (1) {
     if (end - p < 256 && !eof) {
@@ -900,6 +896,7 @@
       constructTrailerDict((GFileOffset)(bufPos + (p + 7 - buf)));
       p += 7;
       startOfLine = gFalse;
+      space = gFalse;
     } else if (startOfLine && !strncmp(p, "endstream", 9)) {
       if (streamEndsLen == streamEndsSize) {
 	streamEndsSize += 64;
@@ -909,13 +906,16 @@
       streamEnds[streamEndsLen++] = (GFileOffset)(bufPos + (p - buf));
       p += 9;
       startOfLine = gFalse;
-    } else if (startOfLine && *p >= '0' && *p <= '9') {
+      space = gFalse;
+    } else if (space && *p >= '0' && *p <= '9') {
       p = constructObjectEntry(p, (GFileOffset)(bufPos + (p - buf)),
 			       &lastObjNum);
       startOfLine = gFalse;
+      space = gFalse;
     } else if (p[0] == '>' && p[1] == '>') {
       p += 2;
       startOfLine = gFalse;
+      space = gFalse;
       // skip any PDF whitespace except for '\0'
       while (*p == '\t' || *p == '\n' || *p == '\x0c' ||
 	     *p == '\r' || *p == ' ') {
@@ -922,6 +922,7 @@
 	if (*p == '\n' || *p == '\r') {
 	  startOfLine = gTrue;
 	}
+	space = gTrue;
 	++p;
       }
       if (!strncmp(p, "stream", 6)) {
@@ -935,12 +936,17 @@
 	}
 	p += 6;
 	startOfLine = gFalse;
+	space = gFalse;
       }
     } else {
       if (*p == '\n' || *p == '\r') {
 	startOfLine = gTrue;
-      } else if (!Lexer::isSpace(*p & 0xff)) {
+	space = gTrue;
+      } else if (Lexer::isSpace(*p & 0xff)) {
+	space = gTrue;
+      } else {
 	startOfLine = gFalse;
+	space = gFalse;
       }
       ++p;
     }
@@ -1263,7 +1269,7 @@
       error(errSyntaxError, -1, "Invalid object stream");
       goto err;
     }
-    if (!getObjectStreamObject((int)e->offset, e->gen, num, obj)) {
+    if (!getObjectStreamObject((int)e->offset, e->gen, num, obj, recursion)) {
       goto err;
     }
     break;
@@ -1297,21 +1303,38 @@
 }
 
 GBool XRef::getObjectStreamObject(int objStrNum, int objIdx,
-				  int objNum, Object *obj) {
-  ObjectStream *objStr;
-
+				  int objNum, Object *obj, int recursion) {
+  // check for a cached ObjectStream
 #if MULTITHREADED
   gLockMutex(&objStrsMutex);
 #endif
-  if (!(objStr = getObjectStream(objStrNum))) {
+  ObjectStream *objStr = getObjectStreamFromCache(objStrNum);
+  GBool found = gFalse;
+  if (objStr) {
+    objStr->getObject(objIdx, objNum, obj);
+    cleanObjectStreamCache();
+    found = gTrue;
+  }
 #if MULTITHREADED
-    gUnlockMutex(&objStrsMutex);
+  gUnlockMutex(&objStrsMutex);
 #endif
+  if (found) {
+    return gTrue;
+  }
+
+  // load a new ObjectStream
+  objStr = new ObjectStream(this, objStrNum, recursion);
+  if (!objStr->isOk()) {
+    delete objStr;
     return gFalse;
   }
-  cleanObjectStreamCache();
   objStr->getObject(objIdx, objNum, obj);
 #if MULTITHREADED
+  gLockMutex(&objStrsMutex);
+#endif
+  addObjectStreamToCache(objStr);
+  cleanObjectStreamCache();
+#if MULTITHREADED
   gUnlockMutex(&objStrsMutex);
 #endif
   return gTrue;
@@ -1318,22 +1341,19 @@
 }
 
 // NB: objStrsMutex must be locked when calling this function.
-ObjectStream *XRef::getObjectStream(int objStrNum) {
-  ObjectStream *objStr;
-  int i, j;
-
+ObjectStream *XRef::getObjectStreamFromCache(int objStrNum) {
   // check the MRU entry in the cache
   if (objStrs[0] && objStrs[0]->getObjStrNum() == objStrNum) {
-    objStr = objStrs[0];
+    ObjectStream *objStr = objStrs[0];
     objStrLastUse[0] = objStrTime++;
     return objStr;
   }
 
   // check the rest of the cache
-  for (i = 1; i < objStrCacheLength; ++i) {
+  for (int i = 1; i < objStrCacheLength; ++i) {
     if (objStrs[i] && objStrs[i]->getObjStrNum() == objStrNum) {
-      objStr = objStrs[i];
-      for (j = i; j > 0; --j) {
+      ObjectStream *objStr = objStrs[i];
+      for (int j = i; j > 0; --j) {
 	objStrs[j] = objStrs[j - 1];
 	objStrLastUse[j] = objStrLastUse[j - 1];
       }
@@ -1343,19 +1363,17 @@
     }
   }
 
-  // load a new ObjectStream
-  objStr = new ObjectStream(this, objStrNum);
-  if (!objStr->isOk()) {
-    delete objStr;
-    return NULL;
-  }
+  return NULL;
+}
 
+// NB: objStrsMutex must be locked when calling this function.
+void XRef::addObjectStreamToCache(ObjectStream *objStr) {
   // add to the cache
   if (objStrCacheLength == objStrCacheSize) {
     delete objStrs[objStrCacheSize - 1];
     --objStrCacheLength;
   }
-  for (j = objStrCacheLength; j > 0; --j) {
+  for (int j = objStrCacheLength; j > 0; --j) {
     objStrs[j] = objStrs[j - 1];
     objStrLastUse[j] = objStrLastUse[j - 1];
   }
@@ -1362,8 +1380,6 @@
   ++objStrCacheLength;
   objStrs[0] = objStr;
   objStrLastUse[0] = objStrTime++;
-
-  return objStr;
 }
 
 // If the oldest (least recently used) entry in the object stream
@@ -1370,6 +1386,7 @@
 // cache is more than objStrCacheTimeout accesses old (hasn't been
 // used in the last objStrCacheTimeout accesses), eject it from the
 // cache.
+// NB: objStrsMutex must be locked when calling this function.
 void XRef::cleanObjectStreamCache() {
   // NB: objStrTime and objStrLastUse[] are unsigned ints, so the
   // mod-2^32 arithmetic makes the subtraction work out, even if the

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -11,10 +11,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 #include "gfile.h"
 #include "Object.h"
@@ -183,8 +179,9 @@
   GBool constructXRefEntry(int num, int gen, GFileOffset pos,
 			   XRefEntryType type);
   GBool getObjectStreamObject(int objStrNum, int objIdx,
-			      int objNum, Object *obj);
-  ObjectStream *getObjectStream(int objStrNum);
+			      int objNum, Object *obj, int recursion);
+  ObjectStream *getObjectStreamFromCache(int objStrNum);
+  void addObjectStreamToCache(ObjectStream *objStr);
   void cleanObjectStreamCache();
   GFileOffset strToFileOffset(char *s);
 };

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -6,10 +6,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -279,6 +275,8 @@
   parseEnd = data + dataLen;
   
   parseSpace();
+  parseBOM();
+  parseSpace();
   parseXMLDecl(this);
   parseMisc(this);
   parseDocTypeDecl(this);
@@ -783,6 +781,12 @@
   return s;
 }
 
+void ZxDoc::parseBOM() {
+  if (match("\xef\xbb\xbf")) {
+    parsePtr += 3;
+  }
+}
+
 void ZxDoc::parseSpace() {
   while (parsePtr < parseEnd && (*parsePtr == '\x20' ||
 				 *parsePtr == '\x09' ||

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -9,10 +9,6 @@
 
 #include <aconf.h>
 
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
 #include "gtypes.h"
 
 class GString;
@@ -110,6 +106,7 @@
   void parsePI(ZxNode *par);
   GString *parseName();
   GString *parseQuotedString();
+  void parseBOM();
   void parseSpace();
   bool match(const char *s);
 

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/config.h	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/config.h	2024-02-10 06:55:23 UTC (rev 69765)
@@ -2,7 +2,7 @@
 //
 // config.h
 //
-// Copyright 1996-2022 Glyph & Cog, LLC
+// Copyright 1996-2024 Glyph & Cog, LLC
 //
 //========================================================================
 
@@ -14,13 +14,13 @@
 //------------------------------------------------------------------------
 
 // xpdf version
-#define xpdfVersion          "4.04"
-#define xpdfVersionNum       4.04
+#define xpdfVersion          "4.05"
+#define xpdfVersionNum       4.05
 #define xpdfMajorVersion     4
-#define xpdfMinorVersion     4
+#define xpdfMinorVersion     5
 #define xpdfUpdateVersion    0
 #define xpdfMajorVersionStr  "4"
-#define xpdfMinorVersionStr  "4"
+#define xpdfMinorVersionStr  "5"
 #define xpdfUpdateVersionStr "0"
 
 // supported PDF version
@@ -28,11 +28,11 @@
 #define supportedPDFVersionNum 2.0
 
 // copyright notice
-#define xpdfCopyright "Copyright 1996-2022 Glyph & Cog, LLC"
+#define xpdfCopyright "Copyright 1996-2024 Glyph & Cog, LLC"
 
 // Windows resource file stuff
-#define winxpdfVersion "WinXpdf 4.04"
-#define xpdfCopyrightAmp "Copyright 1996-2022 Glyph && Cog, LLC"
+#define winxpdfVersion "WinXpdf 4.05"
+#define xpdfCopyrightAmp "Copyright 1996-2024 Glyph && Cog, LLC"
 
 //------------------------------------------------------------------------
 // paper size

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -62,6 +62,10 @@
 };
 
 int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+  try {
+#endif
+
   char *fileName;
   UnicodeMap *uMap;
   GString *ownerPW, *userPW;
@@ -213,4 +217,11 @@
   gMemReport(stderr);
 
   return exitCode;
+
+#if USE_EXCEPTIONS
+  } catch (GMemException e) {
+    fprintf(stderr, "Out of memory\n");
+    return 98;
+  }
+#endif
 }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -96,6 +96,10 @@
 static int numObjects;
 
 int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+  try {
+#endif
+
   char *fileName;
   GString *ownerPW, *userPW;
   GBool ok;
@@ -174,15 +178,15 @@
   numObjects = doc->getXRef()->getNumObjects();
   seenObjs = (char *)gmalloc(numObjects);
   memset(seenObjs, 0, numObjects);
+  annots = doc->getAnnots();
   for (pg = firstPage; pg <= lastPage; ++pg) {
     page = doc->getCatalog()->getPage(pg);
     if ((resDict = page->getResourceDict())) {
       scanFonts(resDict, doc);
     }
-    annots = new Annots(doc, page->getAnnots(&obj1));
-    obj1.free();
-    for (i = 0; i < annots->getNumAnnots(); ++i) {
-      if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) {
+    int nAnnots = annots->getNumAnnots(pg);
+    for (i = 0; i < nAnnots; ++i) {
+      if (annots->getAnnot(pg, i)->getAppearance(&obj1)->isStream()) {
 	obj1.streamGetDict()->lookupNF("Resources", &obj2);
 	scanFonts(&obj2, doc);
 	obj2.free();
@@ -189,7 +193,6 @@
       }
       obj1.free();
     }
-    delete annots;
   }
   if ((form = doc->getCatalog()->getForm())) {
     for (i = 0; i < form->getNumFields(); ++i) {
@@ -222,6 +225,13 @@
   gMemReport(stderr);
 
   return exitCode;
+
+#if USE_EXCEPTIONS
+  } catch (GMemException e) {
+    fprintf(stderr, "Out of memory\n");
+    return 98;
+  }
+#endif
 }
 
 static void scanFonts(Object *obj, PDFDoc *doc) {

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -76,6 +76,10 @@
 };
 
 int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+  try {
+#endif
+
   PDFDoc *doc;
   char *fileName;
   char *imgRoot;
@@ -171,4 +175,11 @@
   gMemReport(stderr);
 
   return exitCode;
+
+#if USE_EXCEPTIONS
+  } catch (GMemException e) {
+    fprintf(stderr, "Out of memory\n");
+    return 98;
+  }
+#endif
 }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -41,6 +41,7 @@
 			    const char *xmpKey2,
 			    const char *text, GBool parseDate,
 			    UnicodeMap *uMap);
+static void printCustomInfo(Object *infoDict, UnicodeMap *uMap);
 static GString *parseInfoDate(GString *s);
 static GString *parseXMPDate(GString *s);
 static void printBox(const char *text, PDFRectangle *box);
@@ -50,6 +51,7 @@
 static GBool printBoxes = gFalse;
 static GBool printMetadata = gFalse;
 static GBool rawDates = gFalse;
+static GBool printCustom = gFalse;
 static char textEncName[128] = "";
 static char ownerPassword[33] = "\001";
 static char userPassword[33] = "\001";
@@ -68,6 +70,8 @@
    "print the document metadata (XML)"},
   {"-rawdates", argFlag,   &rawDates,         0,
    "print the undecoded date strings directly from the PDF file"},
+  {"-custom", argFlag,     &printCustom,      0,
+   "print the custom info dictionary fields"},
   {"-enc",    argString,   textEncName,    sizeof(textEncName),
    "output text encoding name"},
   {"-opw",    argString,   ownerPassword,  sizeof(ownerPassword),
@@ -90,6 +94,10 @@
 };
 
 int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+  try {
+#endif
+
   PDFDoc *doc;
   char *fileName;
   GString *ownerPW, *userPW;
@@ -193,6 +201,9 @@
   printInfoString(&info, "Producer",     xmp, "pdf:Producer",    NULL,              "Producer:       ", gFalse,    uMap);
   printInfoString(&info, "CreationDate", xmp, "xap:CreateDate",  "xmp:CreateDate",  "CreationDate:   ", !rawDates, uMap);
   printInfoString(&info, "ModDate",      xmp, "xap:ModifyDate",  "xmp:ModifyDate",  "ModDate:        ", !rawDates, uMap);
+  if (printCustom) {
+    printCustomInfo(&info, uMap);
+  }
   info.free();
   if (xmp) {
     delete xmp;
@@ -304,6 +315,9 @@
   // print linearization info
   printf("Optimized:      %s\n", doc->isLinearized() ? "yes" : "no");
 
+  // print JavaScript info
+  printf("JavaScript:     %s\n", doc->usesJavaScript() ? "yes" : "no");
+
   // print PDF version
   printf("PDF version:    %.1f\n", doc->getPDFVersion());
 
@@ -333,6 +347,13 @@
   gMemReport(stderr);
 
   return exitCode;
+
+#if USE_EXCEPTIONS
+  } catch (GMemException e) {
+    fprintf(stderr, "Out of memory\n");
+    return 98;
+  }
+#endif
 }
 
 static void printInfoString(Object *infoDict, const char *infoKey,
@@ -397,7 +418,7 @@
 	      if (!parseDate ||
 		  !(value = parseXMPDate(((ZxCharData *)node2)->getData()))) {
 		tmp = ((ZxCharData *)node2)->getData();
-		int i = 0;
+		i = 0;
 		value = new GString();
 		while (getUTF8(tmp, &i, &uu)) {
 		  n = uMap->mapUnicode(uu, buf, sizeof(buf));
@@ -414,12 +435,48 @@
 
   if (value) {
     fputs(text, stdout);
-    fwrite(value->getCString(), 1, value->getLength(), stdout);
+   fwrite(value->getCString(), 1, value->getLength(), stdout);
     fputc('\n', stdout);
     delete value;
   }
 }
 
+static void printCustomInfo(Object *infoDict, UnicodeMap *uMap) {
+  if (!infoDict->isDict()) {
+    return;
+  }
+  for (int i = 0; i < infoDict->dictGetLength(); ++i) {
+    char *key = infoDict->dictGetKey(i);
+    Object obj;
+    infoDict->dictGetVal(i, &obj);
+    if (obj.isString() &&
+	strcmp(key, "Title") &&
+	strcmp(key, "Subject") &&
+	strcmp(key, "Keywords") &&
+	strcmp(key, "Author") &&
+	strcmp(key, "Creator") &&
+	strcmp(key, "Producer") &&
+	strcmp(key, "CreationDate") &&
+	strcmp(key, "ModDate")) {
+      printf("%s: ", key);
+      int n = 14 - (int)strlen(key);
+      if (n > 0) {
+	printf("%*s", n, "");
+      }
+      TextString *s = new TextString(obj.getString());
+      Unicode *u = s->getUnicode();
+      char buf[8];
+      for (int j = 0; j < s->getLength(); ++j) {
+	n = uMap->mapUnicode(u[j], buf, sizeof(buf));
+	fwrite(buf, 1, n, stdout);
+      }
+      delete s;
+      printf("\n");
+    }
+    obj.free();
+  }
+}
+
 static GString *parseInfoDate(GString *s) {
   int year, mon, day, hour, min, sec, n;
   struct tm tmStruct;

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -38,7 +38,9 @@
 static GBool skipInvisible = gFalse;
 static GBool allInvisible = gFalse;
 static GBool formFields = gFalse;
+static GBool includeMetadata = gFalse;
 static GBool tableMode = gFalse;
+static GBool overwrite = gFalse;
 static char ownerPassword[33] = "\001";
 static char userPassword[33] = "\001";
 static GBool verbose = gFalse;
@@ -70,8 +72,12 @@
    "treat all text as invisible"},
   {"-formfields",       argFlag,   &formFields,      0,
    "convert form fields to HTML"},
+  {"-meta",             argFlag,   &includeMetadata, 0,
+   "include document metadata in the HTML output"},
   {"-table",            argFlag,   &tableMode,       0,
    "use table mode for text extraction"},
+  {"-overwrite",        argFlag,   &overwrite,       0,
+   "overwrite files in an existing output directory"},
   {"-opw",              argString, ownerPassword,    sizeof(ownerPassword),
    "owner password (for encrypted files)"},
   {"-upw",              argString, userPassword,     sizeof(userPassword),
@@ -102,6 +108,10 @@
 }
 
 int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+  try {
+#endif
+
   PDFDoc *doc;
   char *fileName;
   char *htmlDir;
@@ -184,10 +194,19 @@
 
   // create HTML directory
   if (makeDir(htmlDir, 0755)) {
-    error(errIO, -1, "Couldn't create HTML output directory '{0:s}'",
-	  htmlDir);
-    exitCode = 2;
-    goto err1;
+    if (pathIsDir(htmlDir)) {
+      if (!overwrite) {
+	error(errIO, -1, "HTML output directory '{0:s}' already exists (use '-overwrite' to overwrite it)",
+	      htmlDir);
+	exitCode = 2;
+	goto err1;
+      }
+    } else {
+      error(errIO, -1, "Couldn't create HTML output directory '{0:s}'",
+	    htmlDir);
+      exitCode = 2;
+      goto err1;
+    }
   }
 
   // set up the HTMLGen object
@@ -204,6 +223,7 @@
   htmlGen->setExtractFontFiles(!noFonts);
   htmlGen->setEmbedFonts(embedFonts);
   htmlGen->setConvertFormFields(formFields);
+  htmlGen->setIncludeMetadata(includeMetadata);
   htmlGen->startDoc(doc);
 
   // convert the pages
@@ -271,6 +291,13 @@
   gMemReport(stderr);
 
   return exitCode;
+
+#if USE_EXCEPTIONS
+  } catch (GMemException e) {
+    fprintf(stderr, "Out of memory\n");
+    return 98;
+  }
+#endif
 }
 
 static GBool createIndex(char *htmlDir) {
@@ -280,11 +307,12 @@
 
   htmlFileName = GString::format("{0:s}/index.html", htmlDir);
   html = openFile(htmlFileName->getCString(), "w");
-  delete htmlFileName;
   if (!html) {
     error(errIO, -1, "Couldn't open HTML file '{0:t}'", htmlFileName);
+    delete htmlFileName;
     return gFalse;
   }
+  delete htmlFileName;
 
   fprintf(html, "<html>\n");
   fprintf(html, "<body>\n");

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -99,6 +99,10 @@
 static void finishPNG(png_structp *png, png_infop *pngInfo);
 
 int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+  try {
+#endif
+
   PDFDoc *doc;
   char *fileName;
   char *pngRoot;
@@ -296,6 +300,13 @@
   gMemReport(stderr);
 
   return exitCode;
+
+#if USE_EXCEPTIONS
+  } catch (GMemException e) {
+    fprintf(stderr, "Out of memory\n");
+    return 98;
+  }
+#endif
 }
 
 static void setupPNG(png_structp *png, png_infop *pngInfo, FILE *f,

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -98,6 +98,10 @@
 };
 
 int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+  try {
+#endif
+
   PDFDoc *doc;
   char *fileName;
   char *ppmRoot;
@@ -277,4 +281,11 @@
   gMemReport(stderr);
 
   return exitCode;
+
+#if USE_EXCEPTIONS
+  } catch (GMemException e) {
+    fprintf(stderr, "Out of memory\n");
+    return 98;
+  }
+#endif
 }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -153,6 +153,10 @@
 };
 
 int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+  try {
+#endif
+
   PDFDoc *doc;
   char *fileName;
   GString *psFileName;
@@ -396,4 +400,11 @@
   gMemReport(stderr);
 
   return exitCode;
+
+#if USE_EXCEPTIONS
+  } catch (GMemException e) {
+    fprintf(stderr, "Out of memory\n");
+    return 98;
+  }
+#endif
 }

Modified: trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
===================================================================
--- trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc	2024-02-10 03:25:28 UTC (rev 69764)
+++ trunk/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc	2024-02-10 06:55:23 UTC (rev 69765)
@@ -132,6 +132,10 @@
 };
 
 int main(int argc, char *argv[]) {
+#if USE_EXCEPTIONS
+  try {
+#endif
+
   PDFDoc *doc;
   char *fileName;
   GString *textFileName;
@@ -329,4 +333,11 @@
   gMemReport(stderr);
 
   return exitCode;
+
+#if USE_EXCEPTIONS
+  } catch (GMemException e) {
+    fprintf(stderr, "Out of memory\n");
+    return 98;
+  }
+#endif
 }



More information about the tex-live-commits mailing list.