summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Build/source/libs/README2
-rw-r--r--Build/source/libs/xpdf/ChangeLog5
-rw-r--r--Build/source/libs/xpdf/TLpatches/ChangeLog4
-rw-r--r--Build/source/libs/xpdf/TLpatches/TL-Changes2
-rw-r--r--Build/source/libs/xpdf/TLpatches/patch-bunched196
-rwxr-xr-xBuild/source/libs/xpdf/configure20
-rw-r--r--Build/source/libs/xpdf/version.ac2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/ANNOUNCE4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/CHANGES70
-rw-r--r--Build/source/libs/xpdf/xpdf-src/CMakeLists.txt8
-rw-r--r--Build/source/libs/xpdf/xpdf-src/INSTALL8
-rw-r--r--Build/source/libs/xpdf/xpdf-src/README7
-rw-r--r--Build/source/libs/xpdf/xpdf-src/cmake-config.txt97
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.113
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat12
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdffonts.113
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat12
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfimages.117
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat18
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.112
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat12
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.141
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat53
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftopng.117
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat18
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.117
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat18
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftops.116
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat18
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftotext.120
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat24
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/xpdf.152
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat45
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.549
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat201
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/CMakeLists.txt2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc16
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/CMakeLists.txt2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/gfile.cc48
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/gfile.h17
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/Splash.cc407
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/Splash.h11
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc74
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashState.h19
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc13
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt21
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc40
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc126
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc206
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h11
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc308
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc82
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc622
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h23
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc93
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc232
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h8
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc33
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc42
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc12
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h3
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc62
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Page.h2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc143
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc11
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h8
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc19
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc151
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h8
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc180
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h15
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc881
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h25
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc22
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMapTables.h6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc33
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc1026
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h8
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc73
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h11
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc41
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/config.h16
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc10
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc88
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc28
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc24
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc13
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc19
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/winLongPath.exe.manifest15
105 files changed, 5031 insertions, 1570 deletions
diff --git a/Build/source/libs/README b/Build/source/libs/README
index 4f4ef10fccb..5b46bf55f05 100644
--- a/Build/source/libs/README
+++ b/Build/source/libs/README
@@ -58,7 +58,7 @@ pplib 2.05.0 - checked 21apr20
teckit 2.5.11 - checked 09nov21
https://github.com/silnrsi/teckit/archive/2.5.11.tar.gz
-xpdf 4.03 - checked 01feb21
+xpdf 4.04 - checked 24apr22
http://www.xpdfreader.com/download.html
with modifications for pdftex
diff --git a/Build/source/libs/xpdf/ChangeLog b/Build/source/libs/xpdf/ChangeLog
index 981ef4a53cf..ad36056044e 100644
--- a/Build/source/libs/xpdf/ChangeLog
+++ b/Build/source/libs/xpdf/ChangeLog
@@ -1,3 +1,8 @@
+2022-04-24 Akira Kakuto <kakuto@jcom.zaq.ne.jp>
+
+ * Import xpdf-4.04.
+ * version.ac: Adjust.
+
2021-05-10 Karl Berry <karl@freefriends.org>
* xpdf-src/xpdf/Error.cc (error): label error messages
diff --git a/Build/source/libs/xpdf/TLpatches/ChangeLog b/Build/source/libs/xpdf/TLpatches/ChangeLog
index c0fed972499..1b2e8497313 100644
--- a/Build/source/libs/xpdf/TLpatches/ChangeLog
+++ b/Build/source/libs/xpdf/TLpatches/ChangeLog
@@ -1,3 +1,7 @@
+2022-04-24 Akira Kakuto <kakuto@jcom.zaq.ne.jp>
+
+ * patch-bunched: Adjust.
+
2021-02-01 Akira Kakuto <kakuto@w32tex.org>
* patch-bunched: Adjust.
diff --git a/Build/source/libs/xpdf/TLpatches/TL-Changes b/Build/source/libs/xpdf/TLpatches/TL-Changes
index c0b5e4aeb54..aab26569f98 100644
--- a/Build/source/libs/xpdf/TLpatches/TL-Changes
+++ b/Build/source/libs/xpdf/TLpatches/TL-Changes
@@ -1,4 +1,4 @@
-Changes applied to the xpdf-4.03/ tree as obtained from:
+Changes applied to the xpdf-4.04/ tree as obtained from:
http://www.xpdfreader.com/download.html
Removed:
diff --git a/Build/source/libs/xpdf/TLpatches/patch-bunched b/Build/source/libs/xpdf/TLpatches/patch-bunched
index 07b3f05a983..bb36d99d8f7 100644
--- a/Build/source/libs/xpdf/TLpatches/patch-bunched
+++ b/Build/source/libs/xpdf/TLpatches/patch-bunched
@@ -1,6 +1,6 @@
-diff -ur xpdf-4.03/goo/gfile.cc xpdf-src/goo/gfile.cc
---- xpdf-4.03/goo/gfile.cc Thu Jan 28 07:23:51 2021
-+++ xpdf-src/goo/gfile.cc Mon Feb 01 13:13:50 2021
+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
@@ -7,6 +7,9 @@
// Copyright 1996-2003 Glyph & Cog, LLC
//
@@ -11,19 +11,7 @@ diff -ur xpdf-4.03/goo/gfile.cc xpdf-src/goo/gfile.cc
#include <aconf.h>
-@@ -56,7 +59,11 @@
- char *s;
- GString *ret;
-
-+#ifdef _WIN32
-+ if ((s = getenv("USERPROFILE")))
-+#else
- if ((s = getenv("HOME")))
-+#endif
- ret = new GString(s);
- else
- ret = new GString(".");
-@@ -405,6 +412,7 @@
+@@ -429,6 +432,7 @@
#endif
}
@@ -31,7 +19,7 @@ diff -ur xpdf-4.03/goo/gfile.cc xpdf-src/goo/gfile.cc
GBool openTempFile(GString **name, FILE **f,
const char *mode, const char *ext) {
#if defined(_WIN32)
-@@ -519,10 +527,11 @@
+@@ -543,6 +547,7 @@
return gTrue;
#endif
}
@@ -39,29 +27,24 @@ diff -ur xpdf-4.03/goo/gfile.cc xpdf-src/goo/gfile.cc
GBool createDir(char *path, int mode) {
#ifdef _WIN32
-- return !mkdir(path);
-+ return !_mkdir(path);
- #else
- return !mkdir(path, mode);
- #endif
-@@ -602,6 +611,8 @@
+@@ -626,6 +631,8 @@
FILE *openFile(const char *path, const char *mode) {
#if defined(_WIN32)
+ return fopen(path, mode);
+#if 0
- wchar_t wPath[_MAX_PATH + 1];
+ wchar_t wPath[winMaxLongPath + 1];
wchar_t wMode[8];
int i;
-@@ -613,6 +624,7 @@
+@@ -637,6 +644,7 @@
wMode[i] = (wchar_t)0;
- readWindowsShortcut(wPath, _MAX_PATH + 1);
+ readWindowsShortcut(wPath, winMaxLongPath + 1);
return _wfopen(wPath, wMode);
+#endif /* 0 */
#elif defined(VMS)
return fopen(path, mode, "ctx=stm");
#else
-@@ -620,6 +632,7 @@
+@@ -644,6 +652,7 @@
#endif
}
@@ -69,7 +52,7 @@ diff -ur xpdf-4.03/goo/gfile.cc xpdf-src/goo/gfile.cc
#ifdef _WIN32
void readWindowsShortcut(wchar_t *wPath, size_t wPathSize) {
size_t n = wcslen(wPath);
-@@ -665,11 +678,11 @@
+@@ -689,11 +698,15 @@
wcscpy(wPath, target);
}
#endif
@@ -77,13 +60,15 @@ diff -ur xpdf-4.03/goo/gfile.cc xpdf-src/goo/gfile.cc
int makeDir(const char *path, int mode) {
#ifdef _WIN32
-- wchar_t wPath[_MAX_PATH + 1];
-- return _wmkdir(fileNameToUCS2(path, wPath, sizeof(wPath) / sizeof(wchar_t)));
++ /*
+ wchar_t wPath[winMaxLongPath + 1];
+ return _wmkdir(fileNameToUCS2(path, wPath, winMaxLongPath + 1));
++ */
+ return _mkdir(path);
#else
return mkdir(path, (mode_t)mode);
#endif
-@@ -728,6 +741,7 @@
+@@ -752,6 +765,7 @@
#endif
}
@@ -91,28 +76,29 @@ diff -ur xpdf-4.03/goo/gfile.cc xpdf-src/goo/gfile.cc
void fixCommandLine(int *argc, char **argv[]) {
#ifdef _WIN32
int argcw;
-@@ -753,3 +767,4 @@
+@@ -777,3 +791,4 @@
LocalFree(argvw);
#endif
}
+#endif /* !PDF_PARSER_ONLY */
-diff -ur xpdf-4.03/goo/gfile.h xpdf-src/goo/gfile.h
---- xpdf-4.03/goo/gfile.h Thu Jan 28 07:23:51 2021
-+++ xpdf-src/goo/gfile.h Mon Feb 01 13:14:50 2021
-@@ -91,12 +91,6 @@
+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 @@
// UCS-2 and calls _wfopen(). On other OSes, this simply calls fopen().
extern FILE *openFile(const char *path, const char *mode);
--#ifdef _WIN32
--// If [wPath] is a Windows shortcut (.lnk file), read the target path
--// and store it back into [wPath].
--extern void readWindowsShortcut(wchar_t *wPath, size_t wPathSize);
--#endif
--
++#if 0
+ #ifdef _WIN32
+ // If [wPath] is a Windows shortcut (.lnk file), read the target path
+ // and store it back into [wPath].
+ extern void readWindowsShortcut(wchar_t *wPath, size_t wPathSize);
+ #endif
++#endif /* 0 */
+
// Create a directory. On Windows, this converts the path from UTF-8
// to UCS-2 and calls _wmkdir(), ignoring the mode argument. On other
- // OSes, this simply calls mkdir().
-@@ -130,6 +124,8 @@
+@@ -139,6 +141,8 @@
// On Windows, this gets the Unicode command line and converts it to
// UTF-8. On other systems, this is a nop.
@@ -121,20 +107,30 @@ diff -ur xpdf-4.03/goo/gfile.h xpdf-src/goo/gfile.h
+#endif /* !PDF_PARSER_ONLY */
#endif
-diff -ur xpdf-4.03/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
---- xpdf-4.03/xpdf/GlobalParams.cc Thu Jan 28 07:23:51 2021
-+++ xpdf-src/xpdf/GlobalParams.cc Mon Feb 01 12:20:24 2021
-@@ -5,6 +5,9 @@
- // Copyright 2001-2003 Glyph & Cog, LLC
- //
- //========================================================================
-+// Modified for TeX Live by Peter Breitenlohner <tex-live@tug.org>
-+// See top-level ChangeLog for a list of all modifications
-+//========================================================================
-
- #include <aconf.h>
-
-@@ -44,8 +47,12 @@
+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 @@
+ (*errorCbk)(errorCbkData, category, (int)pos, sanitized->getCString());
+ } else {
+ fflush(stdout);
++ /* Label the error messages for pdftex's use as libxpdf.
++ It would be cleaner to use the callback feature, but seems
++ like too much trouble at this late date. */
+ if (pos >= 0) {
+- fprintf(stderr, "%s (%d): %s\n",
++ fprintf(stderr, "\nlibxpdf: %s (%d): %s\n",
+ errorCategoryNames[category], (int)pos, sanitized->getCString());
+ } else {
+- fprintf(stderr, "%s: %s\n",
++ fprintf(stderr, "\nlibxpdf: %s: %s\n",
+ 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"
#ifdef _WIN32
@@ -149,7 +145,7 @@ diff -ur xpdf-4.03/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
#endif
#if MULTITHREADED
-@@ -787,6 +794,7 @@
+@@ -794,6 +798,7 @@
f = NULL;
fileName = NULL;
if (cfgFileName && cfgFileName[0]) {
@@ -157,7 +153,7 @@ diff -ur xpdf-4.03/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
fileName = new GString(cfgFileName);
if (!(f = fopen(fileName->getCString(), "r"))) {
delete fileName;
-@@ -819,6 +827,7 @@
+@@ -826,6 +831,7 @@
parseFile(fileName, f);
delete fileName;
fclose(f);
@@ -165,7 +161,7 @@ diff -ur xpdf-4.03/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
}
}
-@@ -2358,8 +2367,11 @@
+@@ -2378,8 +2384,11 @@
base14->fontNum,
displayFontTab[i].obliqueFactor));
} else {
@@ -177,9 +173,9 @@ diff -ur xpdf-4.03/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
}
}
}
-diff -ur xpdf-4.03/xpdf/GlobalParams.h xpdf-src/xpdf/GlobalParams.h
---- xpdf-4.03/xpdf/GlobalParams.h Thu Jan 28 07:23:51 2021
-+++ xpdf-src/xpdf/GlobalParams.h Mon Feb 01 12:23:07 2021
+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
@@ -5,6 +5,9 @@
// Copyright 2001-2003 Glyph & Cog, LLC
//
@@ -199,9 +195,9 @@ diff -ur xpdf-4.03/xpdf/GlobalParams.h xpdf-src/xpdf/GlobalParams.h
~GlobalParams();
-diff -ur xpdf-4.03/xpdf/PDFDoc.cc xpdf-src/xpdf/PDFDoc.cc
---- xpdf-4.03/xpdf/PDFDoc.cc Thu Jan 28 07:23:51 2021
-+++ xpdf-src/xpdf/PDFDoc.cc Mon Feb 01 13:01:20 2021
+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 @@
ok = setup(ownerPassword, userPassword);
}
@@ -210,7 +206,7 @@ diff -ur xpdf-4.03/xpdf/PDFDoc.cc xpdf-src/xpdf/PDFDoc.cc
#ifdef _WIN32
PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GString *ownerPassword,
GString *userPassword, PDFCore *coreA) {
-@@ -161,23 +162,29 @@
+@@ -161,23 +162,28 @@
ok = setup(ownerPassword, userPassword);
}
#endif
@@ -218,29 +214,29 @@ diff -ur xpdf-4.03/xpdf/PDFDoc.cc xpdf-src/xpdf/PDFDoc.cc
PDFDoc::PDFDoc(char *fileNameA, GString *ownerPassword,
GString *userPassword, PDFCore *coreA) {
-+/*
++#if 0
#ifdef _WIN32
OSVERSIONINFO version;
#endif
-+*/
++#endif /* 0 */
Object obj;
-+/*
++#if 0
#ifdef _WIN32
Unicode u;
int i, j;
#endif
-+*/
-
+-
++#endif /* 0 */
init(coreA);
fileName = new GString(fileNameA);
#if defined(_WIN32)
+#if 0
- wchar_t wPath[MAX_PATH + 1];
+ wchar_t wPath[winMaxLongPath + 1];
i = 0;
j = 0;
-@@ -197,8 +204,11 @@
+@@ -197,8 +203,11 @@
if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
file = _wfopen(fileNameU, wfopenReadMode);
} else {
@@ -252,34 +248,34 @@ diff -ur xpdf-4.03/xpdf/PDFDoc.cc xpdf-src/xpdf/PDFDoc.cc
#elif defined(VMS)
file = fopen(fileName->getCString(), fopenReadMode, "ctx=stm");
#else
-@@ -603,6 +613,7 @@
+@@ -608,6 +617,7 @@
GBool ret;
// NB: _wfopen is only available in NT
-+/*
++#if 0
version.dwOSVersionInfoSize = sizeof(version);
GetVersionEx(&version);
if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-@@ -612,12 +623,15 @@
+@@ -617,12 +627,15 @@
path2w[i] = 0;
f = _wfopen(path2w, L"wb");
} else {
-+*/
- for (i = 0; i < pathLen && i < _MAX_PATH; ++i) {
++#endif /* 0 */
+ for (i = 0; i < pathLen && i < MAX_PATH; ++i) {
path2c[i] = (char)path[i];
}
path2c[i] = 0;
f = fopen(path2c, "wb");
-+/*
++#if 0
}
-+*/
++#endif /* 0 */
if (!f) {
return gFalse;
}
-diff -ur xpdf-4.03/xpdf/Page.cc xpdf-src/xpdf/Page.cc
---- xpdf-4.03/xpdf/Page.cc Thu Jan 28 07:23:51 2021
-+++ xpdf-src/xpdf/Page.cc Mon Feb 01 12:31:27 2021
-@@ -485,9 +485,9 @@
+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 @@
delete links;
}
@@ -290,16 +286,16 @@ diff -ur xpdf-4.03/xpdf/Page.cc xpdf-src/xpdf/Page.cc
GfxState *state;
int i;
-@@ -504,5 +504,5 @@
+@@ -550,5 +550,5 @@
ctm[i] = state->getCTM()[i];
}
delete state;
-}
#endif
+}
-diff -ur xpdf-4.03/xpdf/config.h xpdf-src/xpdf/config.h
---- xpdf-4.03/xpdf/config.h Thu Jan 28 07:23:52 2021
-+++ xpdf-src/xpdf/config.h Mon Feb 01 12:34:28 2021
+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
@@ -80,11 +80,6 @@
// popen
//------------------------------------------------------------------------
@@ -312,23 +308,3 @@ diff -ur xpdf-4.03/xpdf/config.h xpdf-src/xpdf/config.h
#if defined(VMS) || defined(VMCMS) || defined(DOS) || defined(OS2) || defined(__EMX__) || defined(_WIN32) || defined(__DJGPP__)
#define POPEN_READ_MODE "rb"
#else
-diff -ur xpdf-4.03/xpdf/Error.cc xpdf-src/xpdf/Error.cc
---- xpdf-4.03/xpdf/Error.cc Thu Jan 28 07:23:52 2021
-+++ xpdf-src/xpdf/Error.cc Mon Feb 01 12:34:28 2021
-@@ -77,11 +77,14 @@
- (*errorCbk)(errorCbkData, category, (int)pos, sanitized->getCString());
- } else {
- fflush(stdout);
-+ /* Label the error messages for pdftex's use as libxpdf.
-+ It would be cleaner to use the callback feature, but seems
-+ like too much trouble at this late date. */
- if (pos >= 0) {
-- fprintf(stderr, "%s (%d): %s\n",
-+ fprintf(stderr, "\nlibxpdf: %s (%d): %s\n",
- errorCategoryNames[category], (int)pos, sanitized->getCString());
- } else {
-- fprintf(stderr, "%s: %s\n",
-+ fprintf(stderr, "\nlibxpdf: %s: %s\n",
- errorCategoryNames[category], sanitized->getCString());
- }
- fflush(stderr);
diff --git a/Build/source/libs/xpdf/configure b/Build/source/libs/xpdf/configure
index fe781453b03..2a2d1b60d43 100755
--- a/Build/source/libs/xpdf/configure
+++ b/Build/source/libs/xpdf/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for xpdf (TeX Live) 4.03.
+# Generated by GNU Autoconf 2.71 for xpdf (TeX Live) 4.04.
#
# Report bugs to <tex-k@tug.org>.
#
@@ -610,8 +610,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='xpdf (TeX Live)'
PACKAGE_TARNAME='xpdf--tex-live-'
-PACKAGE_VERSION='4.03'
-PACKAGE_STRING='xpdf (TeX Live) 4.03'
+PACKAGE_VERSION='4.04'
+PACKAGE_STRING='xpdf (TeX Live) 4.04'
PACKAGE_BUGREPORT='tex-k@tug.org'
PACKAGE_URL=''
@@ -1324,7 +1324,7 @@ if test "$ac_init_help" = "long"; then
# 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.03 to adapt to many kinds of systems.
+\`configure' configures xpdf (TeX Live) 4.04 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1391,7 +1391,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of xpdf (TeX Live) 4.03:";;
+ short | recursive ) echo "Configuration of xpdf (TeX Live) 4.04:";;
esac
cat <<\_ACEOF
@@ -1495,7 +1495,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-xpdf (TeX Live) configure 4.03
+xpdf (TeX Live) configure 4.04
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@@ -1752,7 +1752,7 @@ cat >config.log <<_ACEOF
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.03, which was
+It was created by xpdf (TeX Live) $as_me 4.04, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -4511,7 +4511,7 @@ fi
# Define the identity of the package.
PACKAGE='xpdf--tex-live-'
- VERSION='4.03'
+ VERSION='4.04'
# Some tools Automake needs.
@@ -7419,7 +7419,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# 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.03, which was
+This file was extended by xpdf (TeX Live) $as_me 4.04, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -7491,7 +7491,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
-xpdf (TeX Live) config.status 4.03
+xpdf (TeX Live) config.status 4.04
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
diff --git a/Build/source/libs/xpdf/version.ac b/Build/source/libs/xpdf/version.ac
index 64e2f3e635e..9e02a92b491 100644
--- a/Build/source/libs/xpdf/version.ac
+++ b/Build/source/libs/xpdf/version.ac
@@ -8,4 +8,4 @@ dnl
dnl --------------------------------------------------------
dnl
dnl m4-include this file to define the current xpdf version
-m4_define([xpdf_version], [4.03])
+m4_define([xpdf_version], [4.04])
diff --git a/Build/source/libs/xpdf/xpdf-src/ANNOUNCE b/Build/source/libs/xpdf/xpdf-src/ANNOUNCE
index e070ad95d5b..c20dcaf47ae 100644
--- a/Build/source/libs/xpdf/xpdf-src/ANNOUNCE
+++ b/Build/source/libs/xpdf/xpdf-src/ANNOUNCE
@@ -1,4 +1,4 @@
-Subject: ANNOUNCE: Xpdf 4.03 - a PDF viewer and related tools
+Subject: ANNOUNCE: Xpdf 4.04 - 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,7 +10,7 @@ non-graphical components (pdftops, pdftotext, etc.) run on Linux,
Unix, Windows, MacOSX, and pretty much any other system with a decent
C++ compiler.
-4.03 is primarily a bug fix release. There are some new features:
+4.04 is primarily a bug fix release. There are some new features:
* XpdfReader improvements:
- Implemented selection extension via shift-click, and word/line
diff --git a/Build/source/libs/xpdf/xpdf-src/CHANGES b/Build/source/libs/xpdf/xpdf-src/CHANGES
index f2dccc095fd..564aff32b4f 100644
--- a/Build/source/libs/xpdf/xpdf-src/CHANGES
+++ b/Build/source/libs/xpdf/xpdf-src/CHANGES
@@ -2740,3 +2740,73 @@ Check for invalid AcroForm ListBox field top index. [Thanks to
Chengbin for the bug report.]
Check for invalid mesh shading parameters. [Thanks to Chengbin for
the bug report.]
+
+4.04 (2022-apr-18)
+------------------
+When closing a file, save the current page number in ~/.xpdf.pages,
+ and restore it next time the file is opened. This can be disabled
+ with "savePageNumbers no" in your xpdfrc file.
+Allow the tab list to be reordered, using drag-and-drop.
+Added a document information dialog, with metadata and fonts, to xpdf.
+Pdftohtml now generates HTML links for URI links anchored on text.
+Added the useTrueTypeUnicodeMapping xpdfrc setting.
+Added the 'enableXFA' xpdfrc setting back: if set to 'no', xpdf will
+ not read an XFA form, meaning all form info comes from the AcroForm.
+Add support for long paths on Windows 10.
+Added the "-formfields" option to pdftohtml.
+Added the "-embedbackground" and "-embedfonts" options to pdftohtml.
+Added the "-vstretch" option to pdftohtml.
+Added the "-verbose" flag to pdfimages, pdftohtml, pdftopng, pdftoppm,
+ pdftops, and pdftotext.
+Added the showAttachmentsPane, showLayersPane, and showOutlinePane
+ commands.
+Added the 'openFile2' command to xpdf.
+Added the showMenuBar, hideMenuBar, and toggleMenuBar commands to
+ xpdf.
+Rearrange file names in the tab list to "foo.pdf [/full/path/]", to
+ improve the usability of the (narrow) tab list.
+Added the 'imageMaskAntialias' xpdfrc setting.
+Added the '-table' switch to pdftohtml.
+Fixed a couple of progression order bugs in the JPEG 2000 decoder.
+ [Thanks to shellway for the bug reports.]
+Fixed a problem with subsampled pixel index computations in the JPEG
+ 2000 decoder. [Thanks to shellway for the bug report.]
+Fixed a couple of memory leaks triggered by fuzzed PDF files. [Thanks
+ to shellway for the bug report.]
+Changed pdftohtml to generate spans with 'class=' instead of 'id=', so
+ there aren't duplicate ids. Also removed the unused id in the
+ background img element.
+Optimized SplashOutputDev::drawTilingPattern for the case where the
+ tile is much larger than the area being drawn (i.e., the clipping
+ bbox). In this case, we can render just the needed portion of the
+ tile.
+Added a missing zero check for precinct size in the JPEG 2000 decoder.
+ [Thanks to shellway for the bug report.]
+Added a missing null check in the XFA form scanner. [Thanks to Taolaw
+ for the bug report.]
+Deal with xref streams that include a free entry with gen=0xffffffff.
+Fixed a problematic corner case in looking up XObject resources.
+ [Thanks to shellway for the bug report.]
+The unicodeRemapping config command wasn't correctly handling unsorted
+ remapping files.
+Improved handling of RTL text in the text extractor.
+Extended the saveTabState/loadTabState commands to save/restore
+ display mode, zoom, rotation, and scroll position for each tab.
+Added support for Qt6.
+Added a missing bounds check on stream DecodeParms arrays. [Thanks to
+ minipython for the bug report.]
+Fixed an integer overflow check in XRef::readXRefTable. [Thanks to
+ yangshufan for the bug report.]
+The builtin Latin1 encoding was mapping 'endash' instead of
+ 'softhyphen' to 0xad. [Thanks to Jach Fong for the bug report.]
+Fixed a bug in PSOutputDev::checkPageSlice() when built without
+ SPLASH_CMYK. [Thanks to irfanariq for the bug report.]
+Added missing array length and type checks in Gfx::doForm(). [Thanks
+ to shaohua for the bug report.]
+Fixed an integer overflow security hole in the JBIG2 decoder.
+Substitute Helvetica for undefined fonts and bad font objects.
+Added an integer overflow check in JPXStream. (JPXStream issue)
+ [Thanks to Shin Ando @ Ricera Security for the bug report.]
+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.]
diff --git a/Build/source/libs/xpdf/xpdf-src/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/CMakeLists.txt
index a99cd253231..90cefe33dac 100644
--- a/Build/source/libs/xpdf/xpdf-src/CMakeLists.txt
+++ b/Build/source/libs/xpdf/xpdf-src/CMakeLists.txt
@@ -4,11 +4,11 @@
#
# CMake script for the Xpdf package.
#
-# Copyright 2015 Glyph & Cog, LLC
+# Copyright 2021 Glyph & Cog, LLC
#
#========================================================================
-cmake_minimum_required(VERSION 2.8.8)
+cmake_minimum_required(VERSION 2.8.12)
project(xpdf)
@@ -28,8 +28,8 @@ if (NOT PNG_FOUND)
message(WARNING "Couldn't find libpng -- will not build pdftopng or pdftohtml.")
endif ()
-if (NOT QT4_FOUND AND NOT Qt5Widgets_FOUND)
- message(WARNING "Couldn't find Qt4 or Qt5 -- will not build xpdf.")
+if (NOT QT4_FOUND AND NOT Qt5Widgets_FOUND AND NOT Qt6Widgets_FOUND)
+ message(WARNING "Couldn't find Qt4/5/6 -- will not build xpdf.")
endif ()
if (NOT MULTITHREADED)
diff --git a/Build/source/libs/xpdf/xpdf-src/INSTALL b/Build/source/libs/xpdf/xpdf-src/INSTALL
index 5a7eb6423f4..57ff61f2156 100644
--- a/Build/source/libs/xpdf/xpdf-src/INSTALL
+++ b/Build/source/libs/xpdf/xpdf-src/INSTALL
@@ -1,11 +1,11 @@
Xpdf
====
-version 4.03
-2021-jan-28
+version 4.04
+2022-apr-18
The Xpdf software and documentation are
-copyright 1996-2021 Glyph & Cog, LLC.
+copyright 1996-2022 Glyph & Cog, LLC.
Email: xpdf@xpdfreader.com
WWW: http://www.xpdfreader.com/
@@ -33,7 +33,7 @@ different systems.
- CMake 2.8.8 or newer
- FreeType 2.0.5 or newer
- - Qt 4.8.x or 5.x (for xpdf only)
+ - Qt 5.x or 6.x (for xpdf only)
- libpng (for pdftoppm and pdftohtml)
- zlib (for pdftoppm and pdftohtml)
diff --git a/Build/source/libs/xpdf/xpdf-src/README b/Build/source/libs/xpdf/xpdf-src/README
index e5a114262f0..026460dd24b 100644
--- a/Build/source/libs/xpdf/xpdf-src/README
+++ b/Build/source/libs/xpdf/xpdf-src/README
@@ -1,11 +1,11 @@
Xpdf
====
-version 4.03
-2021-jan-28
+version 4.04
+2022-apr-18
The Xpdf software and documentation are
-copyright 1996-2021 Glyph & Cog, LLC.
+copyright 1996-2022 Glyph & Cog, LLC.
Email: xpdf@xpdfreader.com
WWW: http://www.xpdfreader.com/
@@ -154,6 +154,7 @@ Xpdf uses the following libraries:
* libpng [http://www.libpng.com/pub/png/libpng.html] (used by pdftohtml
and pdftopng)
* zlib [http://zlib.net/] (used by pdftohtml)
+* Qt [https://www.qt.io/]
Acknowledgments
diff --git a/Build/source/libs/xpdf/xpdf-src/cmake-config.txt b/Build/source/libs/xpdf/xpdf-src/cmake-config.txt
index e4b3650fcb3..f9339b9fc81 100644
--- a/Build/source/libs/xpdf/xpdf-src/cmake-config.txt
+++ b/Build/source/libs/xpdf/xpdf-src/cmake-config.txt
@@ -4,7 +4,7 @@
#
# CMake script to do misc cmake config and platform-specific config.
#
-# Copyright 2015 Glyph & Cog, LLC
+# Copyright 2021 Glyph & Cog, LLC
#
#========================================================================
@@ -25,38 +25,32 @@ include(GNUInstallDirs)
enable_language(CXX)
-#--- set default C/C++ compiler flags for Unix
-# and add a 'Profiling' build mode
+#--- add a 'Profiling' build mode
if (CMAKE_GENERATOR STREQUAL "Unix Makefiles")
- if (CYGWIN)
- set(PIC_FLAG "")
- elseif (CMAKE_HOST_SYSTEM_NAME MATCHES "AIX")
- set(PIC_FLAG "-qPIC")
- else ()
- set(PIC_FLAG "-fPIC")
- endif ()
- set(CMAKE_C_FLAGS_DEBUG "-g -O -Wall ${PIC_FLAG}")
- set(CMAKE_CXX_FLAGS_DEBUG "-g -O -Wall ${PIC_FLAG}")
- set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-g -O -Wall ${PIC_FLAG}")
- set(CMAKE_C_FLAGS_RELEASE "-O3 -Wall ${PIC_FLAG}")
- set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wall ${PIC_FLAG}")
- set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-O2 -Wall ${PIC_FLAG}")
- set(CMAKE_C_FLAGS_PROFILING "-g -pg -O -Wall ${PIC_FLAG}"
- CACHE STRING "C compiler flags for profiling mode")
- set(CMAKE_CXX_FLAGS_PROFILING "-g -pg -O -Wall ${PIC_FLAG}"
- CACHE STRING "C++ compiler flags for profiling mode")
- set(CMAKE_EXE_LINKER_FLAGS_PROFILING "-g -pg -O -Wall ${PIC_FLAG}"
- CACHE STRING "linker flags for profiling mode")
+ set(CMAKE_C_FLAGS_PROFILING "-g -pg -O -Wall"
+ CACHE STRING "C compiler flags for profiling mode"
+ FORCE)
+ set(CMAKE_CXX_FLAGS_PROFILING "-g -pg -O -Wall"
+ CACHE STRING "C++ compiler flags for profiling mode"
+ FORCE)
+ set(CMAKE_EXE_LINKER_FLAGS_PROFILING "-g -pg -O -Wall"
+ CACHE STRING "linker flags for profiling mode"
+ FORCE)
+ set(CMAKE_SHARED_LINKER_FLAGS_PROFILING "-g -pg -O -Wall"
+ CACHE STRING "shared linker flags for profiling mode"
+ FORCE)
mark_as_advanced(
CMAKE_C_FLAGS_PROFILING
CMAKE_CXX_FLAGS_PROFILING
- CMAKE_EXE_LINKER_FLAGS_PROFILING)
+ CMAKE_EXE_LINKER_FLAGS_PROFILING
+ CMAKE_SHARED_LINKER_FLAGS_PROFILING)
set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
- "Choose build mode - options are: None Debug Release RelWithDebInfo MinSizeRel Profiling")
+ "Choose build mode - options are: None Debug Release RelWithDebInfo MinSizeRel Profiling"
+ FORCE)
endif ()
#--- set default C/C++ compiler flags for Windows
-if (WIN32)
+if (MSVC)
option(USE_MT_IN_DEBUG "use /MT instead of /MTd in debug builds" OFF)
foreach (var CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE
@@ -108,7 +102,7 @@ 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 SYSTEM_XPDFRC */")
+ set(XPDFRC_DATADIR_DEFINE "/* #undef XPDFRC_DATADIR */")
endif ()
if (WIN32)
option(XPDFWIDGET_PRINTING "include printing support in XpdfWidget" OFF)
@@ -211,14 +205,20 @@ find_package(PNG)
#--- look for Qt
-find_package(Qt5Widgets QUIET)
-if (Qt5Widgets_FOUND)
- find_package(Qt5Network)
- find_package(Qt5PrintSupport)
+find_package(Qt6Widgets QUIET)
+if (Qt6Widgets_FOUND)
+ find_package(Qt6Network)
+ find_package(Qt6PrintSupport)
else ()
- find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork)
+ find_package(Qt5Widgets QUIET)
+ if (Qt5Widgets_FOUND)
+ find_package(Qt5Network)
+ find_package(Qt5PrintSupport)
+ else ()
+ find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork)
+ endif ()
endif ()
-if(Qt5Widgets_FOUND)
+if (Qt5Widgets_FOUND)
message(STATUS "Qt5 found")
if (XPDFWIDGET_PRINTING)
set(QT_INCLUDES "${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5PrintSupport_INCLUDE_DIRS}")
@@ -245,7 +245,34 @@ if(Qt5Widgets_FOUND)
endif ()
# remove "-fPIE" here because we added "-fPIC" above
string(REPLACE "-fPIE" "" QT_CFLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
-elseif(QT4_FOUND)
+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)
+ else ()
+ set(QT_INCLUDES "${Qt6Widgets_INCLUDE_DIRS} ${Qt6Network_INCLUDE_DIRS}")
+ set(QT_DEFINITIONS "${Qt6Widgets_DEFINITIONS} ${Qt6Network_DEFINITIONS}")
+ set(QT_LIBRARIES Qt6::Widgets Qt6::Network)
+ endif ()
+ if (XPDFWIDGET_PRINTING)
+ if (APPLE)
+ set(EXTRA_QT_LIBRARIES "-framework ApplicationServices")
+ elseif (UNIX)
+ find_package(Cups)
+ if (CUPS_FOUND)
+ set(EXTRA_QT_LIBRARIES ${CUPS_LIBRARIES})
+ else ()
+ set (XPDFWIDGET_PRINTING OFF)
+ endif ()
+ else ()
+ set(EXTRA_QT_LIBRARIES "")
+ endif ()
+ endif ()
+ # remove "-fPIE" here because we added "-fPIC" above
+ string(REPLACE "-fPIE" "" QT_CFLAGS "${Qt6Widgets_EXECUTABLE_COMPILE_FLAGS}")
+elseif (QT4_FOUND)
message(STATUS "Qt4 found")
if (XPDFWIDGET_PRINTING)
if (APPLE)
@@ -261,9 +288,9 @@ elseif(QT4_FOUND)
set(EXTRA_QT_LIBRARIES "")
endif ()
endif ()
-else()
+else ()
message(STATUS "No Qt library found")
-endif()
+endif ()
#--- look for libpaper
find_library(PAPER_LIBRARY
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1 b/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1
index 7fd3b8a5231..4d00f3722d6 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1
@@ -1,8 +1,8 @@
-.\" Copyright 2013-2021 Glyph & Cog, LLC
-.TH pdfdetach 1 "28 Jan 2021"
+.\" Copyright 2013-2022 Glyph & Cog, LLC
+.TH pdfdetach 1 "18 Apr 2022"
.SH NAME
pdfdetach \- Portable Document Format (PDF) document embedded file
-extractor (version 4.03)
+extractor (version 4.04)
.SH SYNOPSIS
.B pdfdetach
[options]
@@ -14,9 +14,8 @@ Document Format (PDF) file.
.SH CONFIGURATION FILE
Pdfdetach 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
-/usr/local/etc/xpdfrc (but this location can be changed when pdfinfo
-is built). See the
+exist, it looks for a system-wide config file, typically /etc/xpdfrc
+(but this location can be changed when pdfinfo is built). See the
.BR xpdfrc (5)
man page for details.
.SH OPTIONS
@@ -90,7 +89,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdfinfo software and documentation are copyright 1996-2021 Glyph &
+The pdfinfo software and documentation are copyright 1996-2022 Glyph &
Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat
index 000eb66e5ae..220bb752467 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat
@@ -4,7 +4,7 @@ pdfdetach(1) General Commands Manual pdfdetach(1)
NAME
pdfdetach - Portable Document Format (PDF) document embedded file
- extractor (version 4.03)
+ extractor (version 4.04)
SYNOPSIS
pdfdetach [options] [PDF-file]
@@ -16,9 +16,9 @@ DESCRIPTION
CONFIGURATION FILE
Pdfdetach 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 /usr/local/etc/xpdfrc
- (but this location can be changed when pdfinfo is built). See the
- xpdfrc(5) man page for details.
+ it looks for a system-wide config file, typically /etc/xpdfrc (but this
+ location can be changed when pdfinfo is built). See the xpdfrc(5) man
+ page for details.
OPTIONS
Some of the following options can be set with configuration file com-
@@ -79,7 +79,7 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdfinfo software and documentation are copyright 1996-2021 Glyph &
+ The pdfinfo software and documentation are copyright 1996-2022 Glyph &
Cog, LLC.
SEE ALSO
@@ -89,4 +89,4 @@ SEE ALSO
- 28 Jan 2021 pdfdetach(1)
+ 18 Apr 2022 pdfdetach(1)
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.1 b/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.1
index 0192bd3247e..6ee0226e677 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.1
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.1
@@ -1,8 +1,8 @@
-.\" Copyright 1999-2021 Glyph & Cog, LLC
-.TH pdffonts 1 "28 Jan 2021"
+.\" Copyright 1999-2022 Glyph & Cog, LLC
+.TH pdffonts 1 "18 Apr 2022"
.SH NAME
pdffonts \- Portable Document Format (PDF) font analyzer (version
-4.03)
+4.04)
.SH SYNOPSIS
.B pdffonts
[options]
@@ -84,9 +84,8 @@ CID TrueType (OT) -- OpenType with CID TrueType data
.SH CONFIGURATION FILE
Pdffonts 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
-/usr/local/etc/xpdfrc (but this location can be changed when pdffonts
-is built). See the
+exist, it looks for a system-wide config file, typically /etc/xpdfrc
+(but this location can be changed when pdffonts is built). See the
.BR xpdfrc (5)
man page for details.
.SH OPTIONS
@@ -147,7 +146,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdffonts software and documentation are copyright 1996-2021 Glyph
+The pdffonts software and documentation are copyright 1996-2022 Glyph
& Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat
index 59f4dd90ca9..77fef55fd64 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat
@@ -3,7 +3,7 @@ pdffonts(1) General Commands Manual pdffonts(1)
NAME
- pdffonts - Portable Document Format (PDF) font analyzer (version 4.03)
+ pdffonts - Portable Document Format (PDF) font analyzer (version 4.04)
SYNOPSIS
pdffonts [options] [PDF-file]
@@ -53,9 +53,9 @@ DESCRIPTION
CONFIGURATION FILE
Pdffonts 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 /usr/local/etc/xpdfrc
- (but this location can be changed when pdffonts is built). See the
- xpdfrc(5) man page for details.
+ looks for a system-wide config file, typically /etc/xpdfrc (but this
+ location can be changed when pdffonts is built). See the xpdfrc(5) man
+ page for details.
OPTIONS
Many of the following options can be set with configuration file com-
@@ -105,7 +105,7 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdffonts software and documentation are copyright 1996-2021 Glyph &
+ The pdffonts software and documentation are copyright 1996-2022 Glyph &
Cog, LLC.
SEE ALSO
@@ -115,4 +115,4 @@ SEE ALSO
- 28 Jan 2021 pdffonts(1)
+ 18 Apr 2022 pdffonts(1)
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.1 b/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.1
index 2d95ac79b66..06a9c1fc85c 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.1
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.1
@@ -1,8 +1,8 @@
-.\" Copyright 1998-2021 Glyph & Cog, LLC
-.TH pdfimages 1 "28 Jan 2021"
+.\" Copyright 1998-2022 Glyph & Cog, LLC
+.TH pdfimages 1 "18 Apr 2022"
.SH NAME
pdfimages \- Portable Document Format (PDF) image extractor
-(version 4.03)
+(version 4.04)
.SH SYNOPSIS
.B pdfimages
[options]
@@ -29,9 +29,8 @@ color inversion, etc. done by the PDF content stream is ignored.
.SH CONFIGURATION FILE
Pdfimages 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
-/usr/local/etc/xpdfrc (but this location can be changed when pdfimages
-is built). See the
+exist, it looks for a system-wide config file, typically /etc/xpdfrc
+(but this location can be changed when pdfimages is built). See the
.BR xpdfrc (5)
man page for details.
.SH OPTIONS
@@ -71,6 +70,10 @@ bypass all security restrictions.
.BI \-upw " password"
Specify the user password for the PDF file.
.TP
+.B \-verbose
+Print a status message (to stdout) before processing each page.
+.RB "[config file: " printStatusInfo ]
+.TP
.B \-q
Don't print any messages or errors.
.RB "[config file: " errQuiet ]
@@ -102,7 +105,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdfimages software and documentation are copyright 1998-2021 Glyph
+The pdfimages software and documentation are copyright 1998-2022 Glyph
& Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat
index 97a0371573b..7361a3bb11c 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat
@@ -4,7 +4,7 @@ pdfimages(1) General Commands Manual pdfimages(1)
NAME
pdfimages - Portable Document Format (PDF) image extractor (version
- 4.03)
+ 4.04)
SYNOPSIS
pdfimages [options] PDF-file image-root
@@ -26,9 +26,9 @@ DESCRIPTION
CONFIGURATION FILE
Pdfimages 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 /usr/local/etc/xpdfrc
- (but this location can be changed when pdfimages is built). See the
- xpdfrc(5) man page for details.
+ it looks for a system-wide config file, typically /etc/xpdfrc (but this
+ location can be changed when pdfimages is built). See the xpdfrc(5)
+ man page for details.
OPTIONS
Many of the following options can be set with configuration file com-
@@ -65,6 +65,10 @@ OPTIONS
-upw password
Specify the user password for the PDF file.
+ -verbose
+ Print a status message (to stdout) before processing each page.
+ [config file: printStatusInfo]
+
-q Don't print any messages or errors. [config file: errQuiet]
-v Print copyright and version information.
@@ -85,14 +89,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdfimages software and documentation are copyright 1998-2021 Glyph
+ The pdfimages software and documentation are copyright 1998-2022 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/
- 28 Jan 2021 pdfimages(1)
+ 18 Apr 2022 pdfimages(1)
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.1 b/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.1
index f84badc9814..66f3e70bf3a 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.1
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.1
@@ -1,8 +1,8 @@
-.\" Copyright 1999-2021 Glyph & Cog, LLC
-.TH pdfinfo 1 "28 Jan 2021"
+.\" Copyright 1999-2022 Glyph & Cog, LLC
+.TH pdfinfo 1 "18 Apr 2022"
.SH NAME
pdfinfo \- Portable Document Format (PDF) document information
-extractor (version 4.03)
+extractor (version 4.04)
.SH SYNOPSIS
.B pdfinfo
[options]
@@ -74,8 +74,8 @@ metadata (only if requested)
.SH CONFIGURATION FILE
Pdfinfo 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 /usr/local/etc/xpdfrc
-(but this location can be changed when pdfinfo is built). See the
+looks for a system-wide config file, typically /etc/xpdfrc (but this
+location can be changed when pdfinfo is built). See the
.BR xpdfrc (5)
man page for details.
.SH OPTIONS
@@ -150,7 +150,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdfinfo software and documentation are copyright 1996-2021 Glyph &
+The pdfinfo software and documentation are copyright 1996-2022 Glyph &
Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat
index 0478db677c4..05dbc38f18b 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat
@@ -4,7 +4,7 @@ pdfinfo(1) General Commands Manual pdfinfo(1)
NAME
pdfinfo - Portable Document Format (PDF) document information extractor
- (version 4.03)
+ (version 4.04)
SYNOPSIS
pdfinfo [options] [PDF-file]
@@ -40,9 +40,9 @@ DESCRIPTION
CONFIGURATION FILE
Pdfinfo 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 /usr/local/etc/xpdfrc
- (but this location can be changed when pdfinfo is built). See the
- xpdfrc(5) man page for details.
+ looks for a system-wide config file, typically /etc/xpdfrc (but this
+ location can be changed when pdfinfo is built). See the xpdfrc(5) man
+ page for details.
OPTIONS
Many of the following options can be set with configuration file com-
@@ -104,7 +104,7 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdfinfo software and documentation are copyright 1996-2021 Glyph &
+ The pdfinfo software and documentation are copyright 1996-2022 Glyph &
Cog, LLC.
SEE ALSO
@@ -114,4 +114,4 @@ SEE ALSO
- 28 Jan 2021 pdfinfo(1)
+ 18 Apr 2022 pdfinfo(1)
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.1 b/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.1
index 4618a7a77a9..5129f0dd4b9 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.1
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.1
@@ -1,8 +1,8 @@
-.\" Copyright 1997-2021 Glyph & Cog, LLC
-.TH pdftohtml 1 "28 Jan 2021"
+.\" Copyright 1997-2022 Glyph & Cog, LLC
+.TH pdftohtml 1 "18 Apr 2022"
.SH NAME
pdftohtml \- Portable Document Format (PDF) to HTML converter
-(version 4.03)
+(version 4.04)
.SH SYNOPSIS
.B pdftohtml
[options]
@@ -22,9 +22,8 @@ will report an error.
.SH CONFIGURATION FILE
Pdftohtml 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
-/usr/local/etc/xpdfrc (but this location can be changed when pdftohtml
-is built). See the
+exist, it looks for a system-wide config file, typically /etc/xpdfrc
+(but this location can be changed when pdftohtml is built). See the
.BR xpdfrc (5)
man page for details.
.SH OPTIONS
@@ -50,11 +49,24 @@ zoom level is controlled by the \'-z' option. Specifying a larger
\'-r' value will allow the viewer to zoom in farther without upscaling
artifacts in the background.
.TP
+.BI \-vstretch " number"
+Specifies a vertical stretch factor. Setting this to a value greater
+than 1.0 will stretch each page vertically, spreading out the lines.
+This also stretches the background image to match.
+.TP
+.B \-embedbackground
+Embeds the background image as base64-encoded data directly in the
+HTML file, rather than storing it as a separate file.
+.TP
.B \-nofonts
Disable extraction of embedded fonts. By default, pdftohtml extracts
TrueType and OpenType fonts. Disabling extraction can work around
problems with buggy fonts.
.TP
+.B \-embedfonts
+Embeds any extracted fonts as base64-encoded data directly in the HTML
+file, rather than storing them as separate files.
+.TP
.B \-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.
@@ -67,6 +79,17 @@ on top of the image. This option tells pdftohtml to include the
regular text in the background image, and then draw it as transparent
(alpha=0) HTML text.
.TP
+.B \-formfields
+Convert AcroForm text and checkbox fields to HTML input elements.
+This also removes text (e.g., underscore characters) and erases
+background image content (e.g., lines or boxes) in the field areas.
+.TP
+.B \-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.
+.TP
.BI \-opw " password"
Specify the owner password for the PDF file. Providing this will
bypass all security restrictions.
@@ -74,6 +97,10 @@ bypass all security restrictions.
.BI \-upw " password"
Specify the user password for the PDF file.
.TP
+.B \-verbose
+Print a status message (to stdout) before processing each page.
+.RB "[config file: " printStatusInfo ]
+.TP
.B \-q
Don't print any messages or errors.
.RB "[config file: " errQuiet ]
@@ -114,7 +141,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdftohtml software and documentation are copyright 1996-2021 Glyph
+The pdftohtml software and documentation are copyright 1996-2022 Glyph
& Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat
index 3eea2e32ec1..5ddbfa0c9fb 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat
@@ -4,7 +4,7 @@ pdftohtml(1) General Commands Manual pdftohtml(1)
NAME
pdftohtml - Portable Document Format (PDF) to HTML converter (version
- 4.03)
+ 4.04)
SYNOPSIS
pdftohtml [options] PDF-file HTML-dir
@@ -20,9 +20,9 @@ DESCRIPTION
CONFIGURATION FILE
Pdftohtml 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 /usr/local/etc/xpdfrc
- (but this location can be changed when pdftohtml is built). See the
- xpdfrc(5) man page for details.
+ it looks for a system-wide config file, typically /etc/xpdfrc (but this
+ location can be changed when pdftohtml is built). See the xpdfrc(5)
+ man page for details.
OPTIONS
Many of the following options can be set with configuration file com-
@@ -48,31 +48,60 @@ OPTIONS
larger '-r' value will allow the viewer to zoom in farther with-
out upscaling artifacts in the background.
+ -vstretch number
+ Specifies a vertical stretch factor. Setting this to a value
+ greater than 1.0 will stretch each page vertically, spreading
+ out the lines. This also stretches the background image to
+ match.
+
+ -embedbackground
+ Embeds the background image as base64-encoded data directly in
+ 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
work around problems with buggy fonts.
+ -embedfonts
+ Embeds any extracted fonts as base64-encoded data directly in
+ the HTML file, rather than storing them as separate files.
+
-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
+ text. This option tells pdftohtml to discard invisible text
entirely.
-allinvisible
- Treat all text as invisible. By default, regular (non-invisi-
- ble) text is not drawn in the background image, and is instead
- drawn with HTML on top of the image. This option tells pdfto-
- html to include the regular text in the background image, and
+ Treat all text as invisible. By default, regular (non-invisi-
+ ble) text is not drawn in the background image, and is instead
+ drawn with HTML on top of the image. This option tells pdfto-
+ html to include the regular text in the background image, and
then draw it as transparent (alpha=0) HTML text.
+ -formfields
+ Convert AcroForm text and checkbox fields to HTML input ele-
+ ments. This also removes text (e.g., underscore characters) and
+ 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;
+ it just changes the way text is split up.
+
-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
Specify the user password for the PDF file.
+ -verbose
+ Print a status message (to stdout) before processing each page.
+ [config file: printStatusInfo]
+
-q Don't print any messages or errors. [config file: errQuiet]
-cfg config-file
@@ -102,7 +131,7 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdftohtml software and documentation are copyright 1996-2021 Glyph
+ The pdftohtml software and documentation are copyright 1996-2022 Glyph
& Cog, LLC.
SEE ALSO
@@ -112,4 +141,4 @@ SEE ALSO
- 28 Jan 2021 pdftohtml(1)
+ 18 Apr 2022 pdftohtml(1)
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.1 b/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.1
index bd8f517358f..1193120a54d 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.1
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.1
@@ -1,8 +1,8 @@
-.\" Copyright 2017-2021 Glyph & Cog, LLC
-.TH pdftopng 1 "28 Jan 2021"
+.\" Copyright 2017-2022 Glyph & Cog, LLC
+.TH pdftopng 1 "18 Apr 2022"
.SH NAME
pdftopng \- Portable Document Format (PDF) to Portable Network Graphics
-(PNG) converter (version 4.03)
+(PNG) converter (version 4.04)
.SH SYNOPSIS
.B pdftopng
[options]
@@ -26,9 +26,8 @@ when converting a single page).
.SH CONFIGURATION FILE
Pdftopng 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
-/usr/local/etc/xpdfrc (but this location can be changed when pdftopng
-is built). See the
+exist, it looks for a system-wide config file, typically /etc/xpdfrc
+(but this location can be changed when pdftopng is built). See the
.BR xpdfrc (5)
man page for details.
.SH OPTIONS
@@ -79,6 +78,10 @@ bypass all security restrictions.
.BI \-upw " password"
Specify the user password for the PDF file.
.TP
+.B \-verbose
+Print a status message (to stdout) before processing each page.
+.RB "[config file: " printStatusInfo ]
+.TP
.B \-q
Don't print any messages or errors.
.RB "[config file: " errQuiet ]
@@ -110,7 +113,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdftopng software and documentation are copyright 1996-2021 Glyph
+The pdftopng software and documentation are copyright 1996-2022 Glyph
& Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat
index 7e17c504b4b..10a4408496f 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat
@@ -4,7 +4,7 @@ pdftopng(1) General Commands Manual pdftopng(1)
NAME
pdftopng - Portable Document Format (PDF) to Portable Network Graphics
- (PNG) converter (version 4.03)
+ (PNG) converter (version 4.04)
SYNOPSIS
pdftopng [options] PDF-file PNG-root
@@ -22,9 +22,9 @@ DESCRIPTION
CONFIGURATION FILE
Pdftopng 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 /usr/local/etc/xpdfrc
- (but this location can be changed when pdftopng is built). See the
- xpdfrc(5) man page for details.
+ looks for a system-wide config file, typically /etc/xpdfrc (but this
+ location can be changed when pdftopng is built). See the xpdfrc(5) man
+ page for details.
OPTIONS
Many of the following options can be set with configuration file com-
@@ -70,6 +70,10 @@ OPTIONS
-upw password
Specify the user password for the PDF file.
+ -verbose
+ Print a status message (to stdout) before processing each page.
+ [config file: printStatusInfo]
+
-q Don't print any messages or errors. [config file: errQuiet]
-v Print copyright and version information.
@@ -90,14 +94,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdftopng software and documentation are copyright 1996-2021 Glyph &
+ The pdftopng software and documentation are copyright 1996-2022 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/
- 28 Jan 2021 pdftopng(1)
+ 18 Apr 2022 pdftopng(1)
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.1 b/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.1
index 23b5b06980c..d485b2bc48f 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.1
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.1
@@ -1,8 +1,8 @@
-.\" Copyright 2005-2021 Glyph & Cog, LLC
-.TH pdftoppm 1 "28 Jan 2021"
+.\" Copyright 2005-2022 Glyph & Cog, LLC
+.TH pdftoppm 1 "18 Apr 2022"
.SH NAME
pdftoppm \- Portable Document Format (PDF) to Portable Pixmap (PPM)
-converter (version 4.03)
+converter (version 4.04)
.SH SYNOPSIS
.B pdftoppm
[options]
@@ -28,9 +28,8 @@ when converting a single page).
.SH CONFIGURATION FILE
Pdftoppm 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
-/usr/local/etc/xpdfrc (but this location can be changed when pdftoppm
-is built). See the
+exist, it looks for a system-wide config file, typically /etc/xpdfrc
+(but this location can be changed when pdftoppm is built). See the
.BR xpdfrc (5)
man page for details.
.SH OPTIONS
@@ -79,6 +78,10 @@ bypass all security restrictions.
.BI \-upw " password"
Specify the user password for the PDF file.
.TP
+.B \-verbose
+Print a status message (to stdout) before processing each page.
+.RB "[config file: " printStatusInfo ]
+.TP
.B \-q
Don't print any messages or errors.
.RB "[config file: " errQuiet ]
@@ -110,7 +113,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdftoppm software and documentation are copyright 1996-2021 Glyph
+The pdftoppm software and documentation are copyright 1996-2022 Glyph
& Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat
index 9621be3c3b0..30d012df246 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat
@@ -4,7 +4,7 @@ pdftoppm(1) General Commands Manual pdftoppm(1)
NAME
pdftoppm - Portable Document Format (PDF) to Portable Pixmap (PPM) con-
- verter (version 4.03)
+ verter (version 4.04)
SYNOPSIS
pdftoppm [options] PDF-file PPM-root
@@ -23,9 +23,9 @@ DESCRIPTION
CONFIGURATION FILE
Pdftoppm 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 /usr/local/etc/xpdfrc
- (but this location can be changed when pdftoppm is built). See the
- xpdfrc(5) man page for details.
+ looks for a system-wide config file, typically /etc/xpdfrc (but this
+ location can be changed when pdftoppm is built). See the xpdfrc(5) man
+ page for details.
OPTIONS
Many of the following options can be set with configuration file com-
@@ -69,6 +69,10 @@ OPTIONS
-upw password
Specify the user password for the PDF file.
+ -verbose
+ Print a status message (to stdout) before processing each page.
+ [config file: printStatusInfo]
+
-q Don't print any messages or errors. [config file: errQuiet]
-v Print copyright and version information.
@@ -89,14 +93,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdftoppm software and documentation are copyright 1996-2021 Glyph &
+ The pdftoppm software and documentation are copyright 1996-2022 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/
- 28 Jan 2021 pdftoppm(1)
+ 18 Apr 2022 pdftoppm(1)
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftops.1 b/Build/source/libs/xpdf/xpdf-src/doc/pdftops.1
index e23425d5bad..028e983aec9 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftops.1
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftops.1
@@ -1,8 +1,8 @@
-.\" Copyright 1996-2021 Glyph & Cog, LLC
-.TH pdftops 1 "28 Jan 2021"
+.\" Copyright 1996-2022 Glyph & Cog, LLC
+.TH pdftops 1 "18 Apr 2022"
.SH NAME
pdftops \- Portable Document Format (PDF) to PostScript converter
-(version 4.03)
+(version 4.04)
.SH SYNOPSIS
.B pdftops
[options]
@@ -31,8 +31,8 @@ is \'-', the PostScript is sent to stdout.
.SH CONFIGURATION FILE
Pdftops 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 /usr/local/etc/xpdfrc
-(but this location can be changed when pdftops is built). See the
+looks for a system-wide config file, typically /etc/xpdfrc (but this
+location can be changed when pdftops is built). See the
.BR xpdfrc (5)
man page for details.
.SH OPTIONS
@@ -200,6 +200,10 @@ bypass all security restrictions.
.BI \-upw " password"
Specify the user password for the PDF file.
.TP
+.B \-verbose
+Print a status message (to stdout) before processing each page.
+.RB "[config file: " printStatusInfo ]
+.TP
.B \-q
Don't print any messages or errors.
.RB "[config file: " errQuiet ]
@@ -236,7 +240,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdftops software and documentation are copyright 1996-2021 Glyph &
+The pdftops software and documentation are copyright 1996-2022 Glyph &
Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat
index c985d686fea..ed1c8b718cc 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat
@@ -4,7 +4,7 @@ pdftops(1) General Commands Manual pdftops(1)
NAME
pdftops - Portable Document Format (PDF) to PostScript converter (ver-
- sion 4.03)
+ sion 4.04)
SYNOPSIS
pdftops [options] [PDF-file [PS-file]]
@@ -21,9 +21,9 @@ DESCRIPTION
CONFIGURATION FILE
Pdftops 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 /usr/local/etc/xpdfrc
- (but this location can be changed when pdftops is built). See the
- xpdfrc(5) man page for details.
+ looks for a system-wide config file, typically /etc/xpdfrc (but this
+ location can be changed when pdftops is built). See the xpdfrc(5) man
+ page for details.
OPTIONS
Many of the following options can be set with configuration file com-
@@ -177,6 +177,10 @@ OPTIONS
-upw password
Specify the user password for the PDF file.
+ -verbose
+ Print a status message (to stdout) before processing each page.
+ [config file: printStatusInfo]
+
-q Don't print any messages or errors. [config file: errQuiet]
-cfg config-file
@@ -201,14 +205,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdftops software and documentation are copyright 1996-2021 Glyph &
+ The pdftops software and documentation are copyright 1996-2022 Glyph &
Cog, LLC.
SEE ALSO
- xpdf(1), pdftotext(1), pdftohtml(1), pdfinfo(1), pdffonts(1), pdfde-
+ xpdf(1), pdftotext(1), pdftohtml(1), pdfinfo(1), pdffonts(1), pdfde-
tach(1), pdftoppm(1), pdftopng(1), pdfimages(1), xpdfrc(5)
http://www.xpdfreader.com/
- 28 Jan 2021 pdftops(1)
+ 18 Apr 2022 pdftops(1)
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.1 b/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.1
index d1e81d01f25..e5e7d655bda 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.1
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.1
@@ -1,8 +1,8 @@
-.\" Copyright 1997-2021 Glyph & Cog, LLC
-.TH pdftotext 1 "28 Jan 2021"
+.\" Copyright 1997-2022 Glyph & Cog, LLC
+.TH pdftotext 1 "18 Apr 2022"
.SH NAME
pdftotext \- Portable Document Format (PDF) to text converter
-(version 4.03)
+(version 4.04)
.SH SYNOPSIS
.B pdftotext
[options]
@@ -28,9 +28,8 @@ is \'-', the text is sent to stdout.
.SH CONFIGURATION FILE
Pdftotext 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
-/usr/local/etc/xpdfrc (but this location can be changed when pdftotext
-is built). See the
+exist, it looks for a system-wide config file, typically /etc/xpdfrc
+(but this location can be changed when pdftotext is built). See the
.BR xpdfrc (5)
man page for details.
.SH OPTIONS
@@ -124,7 +123,8 @@ Sets the end-of-line convention to use for text output.
.RB "[config file: " textEOL ]
.TP
.B \-nopgbrk
-Don't insert page breaks (form feed characters) between pages.
+Don't insert a page breaks (form feed character) at the end of each
+page.
.RB "[config file: " textPageBreaks ]
.TP
.B \-bom
@@ -158,6 +158,10 @@ bypass all security restrictions.
.BI \-upw " password"
Specify the user password for the PDF file.
.TP
+.B \-verbose
+Print a status message (to stdout) before processing each page.
+.RB "[config file: " printStatusInfo ]
+.TP
.B \-q
Don't print any messages or errors.
.RB "[config file: " errQuiet ]
@@ -201,7 +205,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdftotext software and documentation are copyright 1996-2021 Glyph
+The pdftotext software and documentation are copyright 1996-2022 Glyph
& Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat
index d4a001d7c63..face2575a3f 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat
@@ -4,7 +4,7 @@ pdftotext(1) General Commands Manual pdftotext(1)
NAME
pdftotext - Portable Document Format (PDF) to text converter (version
- 4.03)
+ 4.04)
SYNOPSIS
pdftotext [options] [PDF-file [text-file]]
@@ -19,9 +19,9 @@ DESCRIPTION
CONFIGURATION FILE
Pdftotext 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 /usr/local/etc/xpdfrc
- (but this location can be changed when pdftotext is built). See the
- xpdfrc(5) man page for details.
+ it looks for a system-wide config file, typically /etc/xpdfrc (but this
+ location can be changed when pdftotext is built). See the xpdfrc(5)
+ man page for details.
OPTIONS
Many of the following options can be set with configuration file com-
@@ -101,8 +101,8 @@ OPTIONS
file: textEOL]
-nopgbrk
- Don't insert page breaks (form feed characters) between pages.
- [config file: textPageBreaks]
+ Don't insert a page breaks (form feed character) at the end of
+ each page. [config file: textPageBreaks]
-bom Insert a Unicode byte order marker (BOM) at the start of the
text output.
@@ -134,6 +134,10 @@ OPTIONS
-upw password
Specify the user password for the PDF file.
+ -verbose
+ Print a status message (to stdout) before processing each page.
+ [config file: printStatusInfo]
+
-q Don't print any messages or errors. [config file: errQuiet]
-cfg config-file
@@ -145,11 +149,11 @@ OPTIONS
-v Print copyright and version information, then exit.
- -h Print usage information, then exit. (-help and --help are
+ -h Print usage information, then exit. (-help and --help are
equivalent.)
BUGS
- Some PDF files contain fonts whose encodings have been mangled beyond
+ Some PDF files contain fonts whose encodings have been mangled beyond
recognition. There is no way (short of OCR) to extract text from these
files.
@@ -167,7 +171,7 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdftotext software and documentation are copyright 1996-2021 Glyph
+ The pdftotext software and documentation are copyright 1996-2022 Glyph
& Cog, LLC.
SEE ALSO
@@ -177,4 +181,4 @@ SEE ALSO
- 28 Jan 2021 pdftotext(1)
+ 18 Apr 2022 pdftotext(1)
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1 b/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1
index 7cf06315f88..2eaa95af69b 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1
+++ b/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1
@@ -1,7 +1,7 @@
-.\" Copyright 1996-2021 Glyph & Cog, LLC
-.TH xpdf 1 "28 Jan 2021"
+.\" Copyright 1996-2022 Glyph & Cog, LLC
+.TH xpdf 1 "18 Apr 2022"
.SH NAME
-xpdf \- Portable Document Format (PDF) file viewer (version 4.03)
+xpdf \- Portable Document Format (PDF) file viewer (version 4.04)
.SH SYNOPSIS
.B xpdf
[options]
@@ -61,8 +61,8 @@ xpdf
.SH CONFIGURATION FILE
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 /usr/local/etc/xpdfrc
-(but this location can be changed when xpdf is built). See the
+looks for a system-wide config file, typically /etc/xpdfrc (but this
+location can be changed when xpdf is built). See the
.BR xpdfrc (5)
man page for details.
.SH OPTIONS
@@ -551,6 +551,9 @@ Go to the specified page.
.BI help
Open the help URL.
.TP
+.B hideMenuBar
+Hide the menu bar.
+.TP
.B hideToolbar
Hide the toolbar.
.TP
@@ -591,6 +594,25 @@ Open the error window.
.BI openFile( file )
Open the specified file in the current tab.
.TP
+.BI openFile2( file, page, dest, passwd, location )
+Open the specified file. If
+.I dest
+is not empty, go to the specified named destination. Else, if
+.I page
+is not empty, go to the specified page number. If
+.I password
+is not empty, it is used as the PDF password. If
+.I 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
+.IR file ,
+can be empty strings. For example:
+.nf
+openFile2(test.pdf,7,,,tab)
+.fi
+.TP
.BI openFileAtDest( file, dest )
Open the specified file in the current tab at the specified named
destination.
@@ -787,9 +809,24 @@ Set the selection to the word at the current mouse position.
.BI setSelection( pg , ulx , uly , lrx , lry )
Set the selection to the specified coordinates on the specified page.
.TP
+.B showAttachmentsPane
+Shows the attachments in the outline/layers/attachments pane.
+.TP
+.B showDocumentInfo
+Open the document information dialog.
+.TP
.B showKeyBindings
Open the key bindings dialog.
.TP
+.B showLayersPane
+Shows the layers in the outline/layers/attachments pane.
+.TP
+.B showMenuBar
+Show the menu bar.
+.TP
+.B showOutlinePane
+Shows the outline in the outline/layers/attachments pane.
+.TP
.B showToolbar
Show the toolbar.
.TP
@@ -826,6 +863,9 @@ Toggle between continuous and single page view modes.
.B toggleFullScreenMode
Toggle between full-screen and window modes.
.TP
+.B toggleMenuBar
+Toggle the menu bar between shown and hidden.
+.TP
.B toggleSelectMode
Toggle between block and linear selection mode.
.TP
@@ -908,7 +948,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The xpdf software and documentation are copyright 1996-2021 Glyph &
+The xpdf software and documentation are copyright 1996-2022 Glyph &
Cog, LLC.
.SH "SEE ALSO"
.BR pdftops (1),
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat b/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat
index 3b71667f055..ba20911962d 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat
@@ -3,7 +3,7 @@ xpdf(1) General Commands Manual xpdf(1)
NAME
- xpdf - Portable Document Format (PDF) file viewer (version 4.03)
+ xpdf - Portable Document Format (PDF) file viewer (version 4.04)
SYNOPSIS
xpdf [options] [PDF-file [:page | +dest]] ...
@@ -44,9 +44,9 @@ DESCRIPTION
CONFIGURATION FILE
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 /usr/local/etc/xpdfrc (but
- this location can be changed when xpdf is built). See the xpdfrc(5)
- man page for details.
+ 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.
OPTIONS
The following command line options are available. All command line
@@ -500,6 +500,9 @@ COMMANDS
help Open the help URL.
+ hideMenuBar
+ Hide the menu bar.
+
hideToolbar
Hide the toolbar.
@@ -538,6 +541,18 @@ COMMANDS
openFile(file)
Open the specified file in the current tab.
+ 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
+ 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
named destination.
@@ -711,9 +726,24 @@ COMMANDS
Set the selection to the specified coordinates on the specified
page.
+ showAttachmentsPane
+ Shows the attachments in the outline/layers/attachments pane.
+
+ showDocumentInfo
+ Open the document information dialog.
+
showKeyBindings
Open the key bindings dialog.
+ showLayersPane
+ Shows the layers in the outline/layers/attachments pane.
+
+ showMenuBar
+ Show the menu bar.
+
+ showOutlinePane
+ Shows the outline in the outline/layers/attachments pane.
+
showToolbar
Show the toolbar.
@@ -748,6 +778,9 @@ COMMANDS
toggleFullScreenMode
Toggle between full-screen and window modes.
+ toggleMenuBar
+ Toggle the menu bar between shown and hidden.
+
toggleSelectMode
Toggle between block and linear selection mode.
@@ -825,7 +858,7 @@ EXIT CODES
99 Other error.
AUTHOR
- The xpdf software and documentation are copyright 1996-2021 Glyph &
+ The xpdf software and documentation are copyright 1996-2022 Glyph &
Cog, LLC.
SEE ALSO
@@ -835,4 +868,4 @@ SEE ALSO
- 28 Jan 2021 xpdf(1)
+ 18 Apr 2022 xpdf(1)
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5 b/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5
index 07639316ec7..1c47e2ebb29 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5
+++ b/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5
@@ -1,17 +1,22 @@
-.\" Copyright 2002-2021 Glyph & Cog, LLC
-.TH xpdfrc 5 "28 Jan 2021"
+.\" Copyright 2002-2022 Glyph & Cog, LLC
+.TH xpdfrc 5 "18 Apr 202"
.SH NAME
-xpdfrc \- configuration file for Xpdf tools (version 4.03)
+xpdfrc \- configuration file for Xpdf tools (version 4.04)
.SH DESCRIPTION
-All of the Xpdf tools read a single configuration file. If you have a
+All of the Xpdf tools read a single configuration file.
+.PP
+On Linux/Unix/MacOS: if you have a
.I .xpdfrc
file in your home directory, it will be read. Otherwise, a
system-wide configuration file will be read from
-.IR /usr/local/etc/xpdfrc ,
+.IR /etc/xpdfrc ,
if it exists. (This is its default location; depending on build
-options, it may be placed elsewhere.) On Win32 systems, the
+options, it may be placed elsewhere.)
+.PP
+On Windows: the file must be named
.I xpdfrc
-file should be placed in the same directory as the executables.
+(no leading dot, no extension), and must be placed in the same
+directory as the executable (pdftotext.exe, xpdf.exe, etc.)
.PP
The xpdfrc file consists of a series of configuration options, one
per line. Blank lines and lines starting with a \'#' (comments) are
@@ -437,6 +442,12 @@ mapExtTrueTypeFontsViaUnicode is set to "no", Xpdf will assume the
character codes are GIDs (i.e., use an identity mapping). This
defaults to "yes".
.TP
+.BI useTrueTypeUnicodeMapping " yes | no"
+If set to "yes", the Xpdf tools will use the Unicode encoding
+information in TrueType fonts (16-bit only), if avaiable, to override
+the PDF ToUnicode maps. Otherwise, the ToUnicode maps are always used
+when present. This defaults to "no".
+.TP
.BI dropFont " font-name"
Drop all text drawn in the specified font. To drop text drawn in
unnamed fonts, use:
@@ -468,6 +479,10 @@ anti-aliasing control provided by the old "t1libControl" and
Enables or disables anti-aliasing of vector graphics in the PDF
rasterizer. This defaults to "yes".
.TP
+.BR imageMaskAntialias " yes | no"
+Enables or disables anti-aliasing of image masks (when downsampling or
+upsampling) in the PDF rasterizer. This defaults to "yes".
+.TP
.BR antialiasPrinting " yes | no"
If this is "yes", bitmaps sent to the printer will be antialiased
(according to the "antialias" and "vectorAntialias" settings). If
@@ -736,10 +751,26 @@ value is "yes".
If set to "no", form fields will not be drawn or printed. The default
value is "yes".
.TP
+.BI enableXFA " yes | no"
+If an XFA form is present, and this option is set to "yes", Xpdf will
+parse the XFA form and use certain XFA information to override
+AcroForm information. If set to "no", the XFA form will not be read.
+The default value is "yes".
+.TP
+.BI savePageNumbers " yes | no"
+If set to "yes", xpdf will save the current page numbers of all open
+files in ~/.xpdf.pages when the files are closed (or when quitting
+xpdf). Next time the file is opened, the last-viewed page number will
+be restored. The default value is "yes".
+.TP
.BI printCommands " yes | no"
If set to "yes", drawing commands are printed as they're executed
(useful for debugging). This defaults to "no".
.TP
+.BI printStatusInfo
+If set to "yes", print a status message (to stdout) before each page
+is processed. This defaults to "no".
+.TP
.BI errQuiet " yes | no"
If set to "yes", this suppresses all error and warning messages from
all of the Xpdf tools. This defaults to "no".
@@ -798,7 +829,7 @@ launchCommand viewer-script
.fi
.SH FILES
.TP
-.B /usr/local/etc/xpdfrc
+.B /etc/xpdfrc
This is the default location for the system-wide configuration file.
Depending on build options, it may be placed elsewhere.
.TP
@@ -806,7 +837,7 @@ Depending on build options, it may be placed elsewhere.
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-2021 Glyph &
+The Xpdf software and documentation are copyright 1996-2022 Glyph &
Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat b/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat
index c43e8005e2b..c38791eaa28 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat
@@ -3,15 +3,19 @@ xpdfrc(5) File Formats Manual xpdfrc(5)
NAME
- xpdfrc - configuration file for Xpdf tools (version 4.03)
+ xpdfrc - configuration file for Xpdf tools (version 4.04)
DESCRIPTION
- All of the Xpdf tools read a single configuration file. If you have a
- .xpdfrc file in your home directory, it will be read. Otherwise, a
- system-wide configuration file will be read from /usr/local/etc/xpdfrc,
- if it exists. (This is its default location; depending on build
- options, it may be placed elsewhere.) On Win32 systems, the xpdfrc
- file should be placed in the same directory as the executables.
+ All of the Xpdf tools read a single configuration file.
+
+ On Linux/Unix/MacOS: if you have a .xpdfrc file in your home directory,
+ it will be read. Otherwise, a system-wide configuration file will be
+ read from /etc/xpdfrc, if it exists. (This is its default location;
+ depending on build options, it may be placed elsewhere.)
+
+ On Windows: the file must be named xpdfrc (no leading dot, no exten-
+ sion), and must be placed in the same directory as the executable
+ (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
@@ -385,8 +389,14 @@ TEXT CONTROL AND CHARACTER MAPPING
character codes are GIDs (i.e., use an identity mapping). This
defaults to "yes".
+ useTrueTypeUnicodeMapping yes | no
+ If set to "yes", the Xpdf tools will use the Unicode encoding
+ information in TrueType fonts (16-bit only), if avaiable, to
+ override the PDF ToUnicode maps. Otherwise, the ToUnicode maps
+ are always used when present. This defaults to "no".
+
dropFont font-name
- Drop all text drawn in the specified font. To drop text drawn
+ Drop all text drawn in the specified font. To drop text drawn
in unnamed fonts, use:
dropFont ""
@@ -395,114 +405,119 @@ TEXT CONTROL AND CHARACTER MAPPING
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
+ "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
+ 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".
strokeAdjust yes | no | cad
- Sets the stroke adjustment mode. If set to "no", no stroke
+ 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
+ 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
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.
initialDisplayMode single | continuous | sideBySideSingle | sideBySide-
@@ -515,23 +530,23 @@ VIEWER SETTINGS
"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
@@ -540,7 +555,7 @@ VIEWER SETTINGS
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
@@ -548,14 +563,14 @@ VIEWER SETTINGS
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
+ If set to "no", xpdf's reverse-video mode inverts text and vec-
+ tor graphic content, but not images. If set to "yes", xpdf
inverts images as well. The default is "no".
popupMenuCmd title command ...
- Add a command to the popup menu. Title is the text to be dis-
- played in the menu. Command is an Xpdf command (see the COM-
- 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
@@ -563,11 +578,11 @@ VIEWER SETTINGS
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
@@ -575,16 +590,16 @@ VIEWER SETTINGS
izing pages. This defaults to 1.
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 file type and runs the appropriate viewer.
- The command line will consist of the file to be launched, fol-
- lowed by any parameters specified with the link. Do not use
- "%s" in "command". By default, this is unset, and Xpdf will
+ 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 file type and runs the appropriate viewer.
+ The command line will consist of the file to be launched, fol-
+ lowed by any parameters specified with the link. Do not use
+ "%s" in "command". By default, this is unset, and Xpdf will
simply try to execute the file (after prompting the user).
movieCommand command
- Sets the command executed when you click on a movie annotation.
+ Sets the command executed when you click on a movie annotation.
The string "%s" will be replaced with the movie file name. This
has no default value.
@@ -592,7 +607,7 @@ VIEWER SETTINGS
Sets the default printer used in the viewer's print dialog.
bind modifiers-key context command ...
- Add a key or mouse button binding. Modifiers can be zero or
+ Add a key or mouse button binding. Modifiers can be zero or
more of:
shift-
@@ -628,14 +643,14 @@ VIEWER SETTINGS
overLink / offLink (mouse over link or not)
scrLockOn / scrLockOff (scroll lock on/off)
- The context string can include only one of each pair in the
+ The context string can include only one of each pair in the
above list.
- Command is an Xpdf command (see the COMMANDS section of the
- xpdf(1) man page for details). Multiple commands are separated
+ Command is an Xpdf command (see the COMMANDS section of the
+ xpdf(1) man page for details). Multiple commands are separated
by whitespace.
- The bind command replaces any existing binding, but only if it
+ The bind command replaces any existing binding, but only if it
was defined for the exact same modifiers, key, and context. All
tokens (modifiers, key, context, commands) are case-sensitive.
@@ -653,10 +668,10 @@ VIEWER SETTINGS
See the xpdf(1) man page for more examples.
unbind modifiers-key context
- Removes a key binding established with the bind command. This
- is most useful to remove default key bindings before establish-
- ing new ones (e.g., if the default key binding is given for
- "any" context, and you want to create new key bindings for mul-
+ Removes a key binding established with the bind command. This
+ is most useful to remove default key bindings before establish-
+ ing new ones (e.g., if the default key binding is given for
+ "any" context, and you want to create new key bindings for mul-
tiple contexts).
tabStateFile path
@@ -665,17 +680,33 @@ VIEWER SETTINGS
MISCELLANEOUS SETTINGS
drawAnnotations yes | no
- If set to "no", annotations will not be drawn or printed. The
+ If set to "no", annotations will not be drawn or printed. The
default value is "yes".
drawFormFields yes | no
- If set to "no", form fields will not be drawn or printed. The
+ If set to "no", form fields will not be drawn or printed. The
default value is "yes".
+ enableXFA yes | no
+ If an XFA form is present, and this option is set to "yes", Xpdf
+ will parse the XFA form and use certain XFA information to over-
+ ride AcroForm information. If set to "no", the XFA form will
+ not be read. The default value is "yes".
+
+ savePageNumbers yes | no
+ If set to "yes", xpdf will save the current page numbers of all
+ open files in ~/.xpdf.pages when the files are closed (or when
+ quitting xpdf). Next time the file is opened, the last-viewed
+ page number will be restored. The default value is "yes".
+
printCommands yes | no
- If set to "yes", drawing commands are printed as they're exe-
+ If set to "yes", drawing commands are printed as they're exe-
cuted (useful for debugging). This defaults to "no".
+ printStatusInfo
+ If set to "yes", print a status message (to stdout) before each
+ page is processed. This defaults to "no".
+
errQuiet yes | no
If set to "yes", this suppresses all error and warning messages
from all of the Xpdf tools. This defaults to "no".
@@ -733,7 +764,7 @@ EXAMPLES
FILES
- /usr/local/etc/xpdfrc
+ /etc/xpdfrc
This is the default location for the system-wide configuration
file. Depending on build options, it may be placed elsewhere.
@@ -742,7 +773,7 @@ FILES
read in place of the system-wide file.
AUTHOR
- The Xpdf software and documentation are copyright 1996-2021 Glyph &
+ The Xpdf software and documentation are copyright 1996-2022 Glyph &
Cog, LLC.
SEE ALSO
@@ -752,4 +783,4 @@ SEE ALSO
- 28 Jan 2021 xpdfrc(5)
+ 18 Apr 202 xpdfrc(5)
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/fofi/CMakeLists.txt
index 076cfafb247..fd61b25903c 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/CMakeLists.txt
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/CMakeLists.txt
@@ -20,6 +20,8 @@ add_library(fofi_objs OBJECT
FoFiType1.cc
FoFiType1C.cc
)
+set_property(TARGET fofi_objs
+ PROPERTY POSITION_INDEPENDENT_CODE True)
add_library(fofi
$<TARGET_OBJECTS:fofi_objs>
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc
index b4f0a061be9..b6a13390b40 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc
@@ -405,7 +405,9 @@ void FoFiType1C::convertToType1(char *psName, const char **newEncoding,
eexecWrite(&eb, "/password 5839 def\n");
if (privateDicts[0].nBlueValues) {
eexecWrite(&eb, "/BlueValues [");
- for (i = 0; i < privateDicts[0].nBlueValues; ++i) {
+ // number of entries must be even
+ int n = privateDicts[0].nBlueValues & ~1;
+ for (i = 0; i < n; ++i) {
buf = GString::format("{0:s}{1:d}",
i > 0 ? " " : "", privateDicts[0].blueValues[i]);
eexecWrite(&eb, buf->getCString());
@@ -415,7 +417,9 @@ void FoFiType1C::convertToType1(char *psName, const char **newEncoding,
}
if (privateDicts[0].nOtherBlues) {
eexecWrite(&eb, "/OtherBlues [");
- for (i = 0; i < privateDicts[0].nOtherBlues; ++i) {
+ // number of entries must be even
+ int n = privateDicts[0].nOtherBlues & ~1;
+ for (i = 0; i < n; ++i) {
buf = GString::format("{0:s}{1:d}",
i > 0 ? " " : "", privateDicts[0].otherBlues[i]);
eexecWrite(&eb, buf->getCString());
@@ -425,7 +429,9 @@ void FoFiType1C::convertToType1(char *psName, const char **newEncoding,
}
if (privateDicts[0].nFamilyBlues) {
eexecWrite(&eb, "/FamilyBlues [");
- for (i = 0; i < privateDicts[0].nFamilyBlues; ++i) {
+ // number of entries must be even
+ int n = privateDicts[0].nFamilyBlues & ~1;
+ for (i = 0; i < n; ++i) {
buf = GString::format("{0:s}{1:d}",
i > 0 ? " " : "", privateDicts[0].familyBlues[i]);
eexecWrite(&eb, buf->getCString());
@@ -435,7 +441,9 @@ void FoFiType1C::convertToType1(char *psName, const char **newEncoding,
}
if (privateDicts[0].nFamilyOtherBlues) {
eexecWrite(&eb, "/FamilyOtherBlues [");
- for (i = 0; i < privateDicts[0].nFamilyOtherBlues; ++i) {
+ // number of entries must be even
+ int n = privateDicts[0].nFamilyOtherBlues & ~1;
+ for (i = 0; i < n; ++i) {
buf = GString::format("{0:s}{1:d}", i > 0 ? " " : "",
privateDicts[0].familyOtherBlues[i]);
eexecWrite(&eb, buf->getCString());
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/goo/CMakeLists.txt
index 0a1c56b0ebd..f3f6932eaed 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/CMakeLists.txt
+++ b/Build/source/libs/xpdf/xpdf-src/goo/CMakeLists.txt
@@ -22,6 +22,8 @@ add_library(goo_objs OBJECT
parseargs.c
Trace.cc
)
+set_property(TARGET goo_objs
+ PROPERTY POSITION_INDEPENDENT_CODE True)
add_library(goo
$<TARGET_OBJECTS:goo_objs>
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc b/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc
index 570f4e7ab13..c2e7512e188 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc
+++ b/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc
@@ -54,16 +54,23 @@ GString *getHomeDir() {
//---------- VMS ----------
return new GString("SYS$LOGIN:");
-#elif defined(__EMX__) || defined(_WIN32)
- //---------- OS/2+EMX and Win32 ----------
+#elif defined(_WIN32)
+ //---------- Win32 ----------
char *s;
GString *ret;
-#ifdef _WIN32
if ((s = getenv("USERPROFILE")))
-#else
+ ret = new GString(s);
+ else
+ ret = new GString(".");
+ return ret;
+
+#elif defined(__EMX__)
+ //---------- OS/2+EMX ----------
+ char *s;
+ GString *ret;
+
if ((s = getenv("HOME")))
-#endif
ret = new GString(s);
else
ret = new GString(".");
@@ -335,11 +342,11 @@ GString *makePathAbsolute(GString *path) {
#elif defined(_WIN32)
//---------- Win32 ----------
- char buf[_MAX_PATH];
+ char buf[MAX_PATH];
char *fp;
buf[0] = '\0';
- if (!GetFullPathNameA(path->getCString(), _MAX_PATH, buf, &fp)) {
+ if (!GetFullPathNameA(path->getCString(), MAX_PATH, buf, &fp)) {
path->clear();
return path;
}
@@ -398,6 +405,19 @@ GString *makePathAbsolute(GString *path) {
#endif
}
+GBool pathIsFile(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 | FILE_ATTRIBUTE_DEVICE));
+#else
+ struct stat statBuf;
+ return stat(path, &statBuf) == 0 && S_ISREG(statBuf.st_mode);
+#endif
+}
+
time_t getModTime(char *fileName) {
#ifdef _WIN32
//~ should implement this, but it's (currently) only used in xpdf
@@ -613,16 +633,16 @@ FILE *openFile(const char *path, const char *mode) {
#if defined(_WIN32)
return fopen(path, mode);
#if 0
- wchar_t wPath[_MAX_PATH + 1];
+ wchar_t wPath[winMaxLongPath + 1];
wchar_t wMode[8];
int i;
- fileNameToUCS2(path, wPath, sizeof(wPath) / sizeof(wchar_t));
+ fileNameToUCS2(path, wPath, winMaxLongPath + 1);
for (i = 0; mode[i] && i < sizeof(wMode)/sizeof(wchar_t) - 1; ++i) {
wMode[i] = (wchar_t)(mode[i] & 0xff);
}
wMode[i] = (wchar_t)0;
- readWindowsShortcut(wPath, _MAX_PATH + 1);
+ readWindowsShortcut(wPath, winMaxLongPath + 1);
return _wfopen(wPath, wMode);
#endif /* 0 */
#elif defined(VMS)
@@ -663,8 +683,8 @@ void readWindowsShortcut(wchar_t *wPath, size_t wPathSize) {
fprintf(stderr, "IPersistFile.Load failed: 0x%08x\n", hres);
exit(1);
}
- wchar_t target[_MAX_PATH + 1];
- hres = shellLink->GetPath(target, _MAX_PATH + 1, NULL, 0);
+ wchar_t target[winMaxLongPath + 1];
+ hres = shellLink->GetPath(target, winMaxLongPath + 1, NULL, 0);
if (FAILED(hres)) {
return;
}
@@ -682,6 +702,10 @@ void readWindowsShortcut(wchar_t *wPath, size_t wPathSize) {
int makeDir(const char *path, int mode) {
#ifdef _WIN32
+ /*
+ wchar_t wPath[winMaxLongPath + 1];
+ return _wmkdir(fileNameToUCS2(path, wPath, winMaxLongPath + 1));
+ */
return _mkdir(path);
#else
return mkdir(path, (mode_t)mode);
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/gfile.h b/Build/source/libs/xpdf/xpdf-src/goo/gfile.h
index 2075d731a6c..d0d2ad6f9e1 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/gfile.h
+++ b/Build/source/libs/xpdf/xpdf-src/goo/gfile.h
@@ -30,6 +30,12 @@
#endif
#include "gtypes.h"
+// Windows 10 supports long paths - with a registry setting, and only
+// with Unicode (...W) functions.
+#ifdef _WIN32
+# define winMaxLongPath 32767
+#endif
+
class GString;
//------------------------------------------------------------------------
@@ -55,6 +61,9 @@ extern GBool isAbsolutePath(char *path);
// relative) or prepending user's directory (if path starts with '~').
extern GString *makePathAbsolute(GString *path);
+// Returns true if [path] exists and is a regular file.
+extern GBool pathIsFile(const char *path);
+
// Get the modification time for <fileName>. Returns 0 if there is an
// error.
extern time_t getModTime(char *fileName);
@@ -91,6 +100,14 @@ extern wchar_t *fileNameToUCS2(const char *path, wchar_t *out, size_t outSize);
// UCS-2 and calls _wfopen(). On other OSes, this simply calls fopen().
extern FILE *openFile(const char *path, const char *mode);
+#if 0
+#ifdef _WIN32
+// If [wPath] is a Windows shortcut (.lnk file), read the target path
+// and store it back into [wPath].
+extern void readWindowsShortcut(wchar_t *wPath, size_t wPathSize);
+#endif
+#endif /* 0 */
+
// Create a directory. On Windows, this converts the path from UTF-8
// to UCS-2 and calls _wmkdir(), ignoring the mode argument. On other
// OSes, this simply calls mkdir().
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt
index f84968cfb2a..4ac14edc459 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt
+++ b/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt
@@ -40,6 +40,8 @@ if (HAVE_SPLASH)
SplashXPathScanner.cc
${DTYPE_SRCS}
)
+ set_property(TARGET splash_objs
+ PROPERTY POSITION_INDEPENDENT_CODE True)
add_library(splash
$<TARGET_OBJECTS:splash_objs>
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
index 343db796fb2..4afe21b4a25 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
@@ -469,6 +469,12 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
if (pipe->noTransparency && !state->blendFunc) {
+ //----- handle overprint
+
+ if (overprintMaskPtr) {
+ *overprintMaskPtr++ = 0xffffffff;
+ }
+
//----- result color
switch (bitmap->mode) {
@@ -650,7 +656,19 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
// This path is only used when Splash::composite() is called to
// composite a non-isolated group onto the backdrop. In this
// case, shape is the source (group) alpha.
- t = (aDest * 255) / shape - aDest;
+ //
+ // In a nested non-isolated group, i.e., if the destination is
+ // also a non-isolated group (state->inNonIsolatedGroup), we
+ // need to compute the corrected alpha, because the
+ // destination is is storing group alpha (same computation as
+ // blitCorrectedAlpha).
+ if (alpha0Ptr) {
+ t = *alpha0Ptr;
+ t = (Guchar)(aDest + t - div255(aDest * t));
+ } else {
+ t = aDest;
+ }
+ t = (t * 255) / shape - t;
switch (bitmap->mode) {
#if SPLASH_CMYK
case splashModeCMYK8:
@@ -3916,10 +3934,13 @@ class ImageMaskScaler {
public:
// Set up a MaskScaler to scale from [srcWidth]x[srcHeight] to
- // [scaledWidth]x[scaledHeight].
+ // [scaledWidth]x[scaledHeight]. The [interpolate] flag controls
+ // filtering on upsampling, and the [antialias] flag controls
+ // filtering on downsampling.
ImageMaskScaler(SplashImageMaskSource aSrc, void *aSrcData,
int aSrcWidth, int aSrcHeight,
- int aScaledWidth, int aScaledHeight, GBool aInterpolate);
+ int aScaledWidth, int aScaledHeight,
+ GBool aInterpolate, GBool aAntialias);
~ImageMaskScaler();
@@ -3934,10 +3955,13 @@ public:
private:
void vertDownscaleHorizDownscale();
+ void vertDownscaleHorizDownscaleThresh();
void vertDownscaleHorizUpscaleNoInterp();
void vertDownscaleHorizUpscaleInterp();
+ void vertDownscaleHorizUpscaleThresh();
void vertUpscaleHorizDownscaleNoInterp();
void vertUpscaleHorizDownscaleInterp();
+ void vertUpscaleHorizDownscaleThresh();
void vertUpscaleHorizUpscaleNoInterp();
void vertUpscaleHorizUpscaleInterp();
@@ -3979,7 +4003,7 @@ private:
ImageMaskScaler::ImageMaskScaler(SplashImageMaskSource aSrc, void *aSrcData,
int aSrcWidth, int aSrcHeight,
int aScaledWidth, int aScaledHeight,
- GBool aInterpolate) {
+ GBool aInterpolate, GBool aAntialias) {
tmpBuf0 = NULL;
tmpBuf1 = NULL;
tmpBuf2 = NULL;
@@ -4002,9 +4026,15 @@ ImageMaskScaler::ImageMaskScaler(SplashImageMaskSource aSrc, void *aSrcData,
tmpBuf0 = (Guchar *)gmalloc(srcWidth);
accBuf = (Guint *)gmallocn(srcWidth, sizeof(Guint));
if (scaledWidth <= srcWidth) {
- scalingFunc = &ImageMaskScaler::vertDownscaleHorizDownscale;
+ if (!aAntialias) {
+ scalingFunc = &ImageMaskScaler::vertDownscaleHorizDownscaleThresh;
+ } else {
+ scalingFunc = &ImageMaskScaler::vertDownscaleHorizDownscale;
+ }
} else {
- if (aInterpolate) {
+ if (!aAntialias) {
+ scalingFunc = &ImageMaskScaler::vertDownscaleHorizUpscaleThresh;
+ } else if (aInterpolate) {
scalingFunc = &ImageMaskScaler::vertDownscaleHorizUpscaleInterp;
} else {
scalingFunc = &ImageMaskScaler::vertDownscaleHorizUpscaleNoInterp;
@@ -4016,7 +4046,14 @@ ImageMaskScaler::ImageMaskScaler(SplashImageMaskSource aSrc, void *aSrcData,
yq = scaledHeight % srcHeight;
yt = 0;
yn = 0;
- if (aInterpolate) {
+ if (!aAntialias) {
+ tmpBuf0 = (Guchar *)gmalloc(srcWidth);
+ if (scaledWidth <= srcWidth) {
+ scalingFunc = &ImageMaskScaler::vertUpscaleHorizDownscaleThresh;
+ } else {
+ scalingFunc = &ImageMaskScaler::vertUpscaleHorizUpscaleNoInterp;
+ }
+ } else if (aInterpolate) {
yInvScale = (SplashCoord)srcHeight / (SplashCoord)scaledHeight;
tmpBuf0 = (Guchar *)gmalloc(srcWidth);
tmpBuf1 = (Guchar *)gmalloc(srcWidth);
@@ -4099,6 +4136,43 @@ void ImageMaskScaler::vertDownscaleHorizDownscale() {
}
}
+void ImageMaskScaler::vertDownscaleHorizDownscaleThresh() {
+ //--- vert downscale
+ int yStep = yp;
+ yt += yq;
+ if (yt >= scaledHeight) {
+ yt -= scaledHeight;
+ ++yStep;
+ }
+ memset(accBuf, 0, srcWidth * sizeof(Guint));
+ for (int i = 0; i < yStep; ++i) {
+ (*src)(srcData, tmpBuf0);
+ for (int j = 0; j < srcWidth; ++j) {
+ accBuf[j] += tmpBuf0[j];
+ }
+ }
+
+ //--- horiz downscale
+ int acc;
+ int xt = 0;
+ int unscaledIdx = 0;
+ for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) {
+ int xStep = xp;
+ xt += xq;
+ if (xt >= scaledWidth) {
+ xt -= scaledWidth;
+ ++xStep;
+ }
+
+ acc = 0;
+ for (int i = 0; i < xStep; ++i) {
+ acc += accBuf[unscaledIdx];
+ ++unscaledIdx;
+ }
+ line[scaledIdx] = acc > ((xStep * yStep) >> 1) ? (Guchar)255 : (Guchar)0;
+ }
+}
+
void ImageMaskScaler::vertDownscaleHorizUpscaleNoInterp() {
//--- vert downscale
int yStep = yp;
@@ -4169,6 +4243,40 @@ void ImageMaskScaler::vertDownscaleHorizUpscaleInterp() {
}
}
+void ImageMaskScaler::vertDownscaleHorizUpscaleThresh() {
+ //--- vert downscale
+ int yStep = yp;
+ yt += yq;
+ if (yt >= scaledHeight) {
+ yt -= scaledHeight;
+ ++yStep;
+ }
+ memset(accBuf, 0, srcWidth * sizeof(Guint));
+ for (int i = 0; i < yStep; ++i) {
+ (*src)(srcData, tmpBuf0);
+ for (int j = 0; j < srcWidth; ++j) {
+ accBuf[j] += tmpBuf0[j];
+ }
+ }
+
+ //--- horiz upscale
+ int xt = 0;
+ int scaledIdx = 0;
+ for (int srcIdx = 0; srcIdx < srcWidth; ++srcIdx) {
+ int xStep = xp;
+ xt += xq;
+ if (xt >= srcWidth) {
+ xt -= srcWidth;
+ ++xStep;
+ }
+ Guchar buf = accBuf[srcIdx] > (Guint)(yStep >> 1) ? (Guchar)255 : (Guchar)0;
+ for (int i = 0; i < xStep; ++i) {
+ line[scaledIdx] = buf;
+ ++scaledIdx;
+ }
+ }
+}
+
void ImageMaskScaler::vertUpscaleHorizDownscaleNoInterp() {
//--- vert upscale
if (yn == 0) {
@@ -4256,6 +4364,40 @@ void ImageMaskScaler::vertUpscaleHorizDownscaleInterp() {
}
}
+void ImageMaskScaler::vertUpscaleHorizDownscaleThresh() {
+ //--- vert upscale
+ if (yn == 0) {
+ yn = yp;
+ yt += yq;
+ if (yt >= srcHeight) {
+ yt -= srcHeight;
+ ++yn;
+ }
+ (*src)(srcData, tmpBuf0);
+ }
+ --yn;
+
+ //--- horiz downscale
+ int acc;
+ int xt = 0;
+ int unscaledIdx = 0;
+ for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) {
+ int xStep = xp;
+ xt += xq;
+ if (xt >= scaledWidth) {
+ xt -= scaledWidth;
+ ++xStep;
+ }
+
+ acc = 0;
+ for (int i = 0; i < xStep; ++i) {
+ acc += tmpBuf0[unscaledIdx];
+ ++unscaledIdx;
+ }
+ line[scaledIdx] = acc > (xStep >> 1) ? (Guchar)255 : (Guchar)0;
+ }
+}
+
void ImageMaskScaler::vertUpscaleHorizUpscaleNoInterp() {
//--- vert upscale
if (yn == 0) {
@@ -4585,8 +4727,8 @@ SplashError Splash::clipToPath(SplashPath *path, GBool eo) {
return state->clipToPath(path, eo);
}
-void Splash::setSoftMask(SplashBitmap *softMask) {
- state->setSoftMask(softMask);
+void Splash::setSoftMask(SplashBitmap *softMask, GBool deleteBitmap) {
+ state->setSoftMask(softMask, deleteBitmap);
}
void Splash::setInTransparencyGroup(SplashBitmap *groupBackBitmapA,
@@ -4608,6 +4750,41 @@ void Splash::forceDeferredInit(int y, int h) {
useDestRow(y + h - 1);
}
+// Check that alpha is 0 in the specified rectangle.
+// NB: This doesn't work correctly in a non-isolated group, because
+// the rasterizer temporarily stores alpha_g instead of alpha.
+GBool Splash::checkTransparentRect(int x, int y, int w, int h) {
+ if (state->inNonIsolatedGroup) {
+ return gFalse;
+ }
+
+
+ if (!bitmap->alpha) {
+ return gFalse;
+ }
+ int yy0, yy1;
+ if (groupDestInitMode == splashGroupDestPreInit) {
+ yy0 = y;
+ yy1 = y + h - 1;
+ } else {
+ // both splashGroupDestInitZero and splashGroupDestInitCopy set
+ // alpha to zero, so anything outside of groupDestInit[YMin,YMax]
+ // will have alpha=0
+ yy0 = (y > groupDestInitYMin) ? y : groupDestInitYMin;
+ yy1 = (y + h - 1 < groupDestInitYMax) ? y + h - 1 : groupDestInitYMax;
+ }
+ Guchar *alphaP = &bitmap->alpha[yy0 * bitmap->alphaRowSize + x];
+ for (int yy = yy0; yy <= yy1; ++yy) {
+ for (int xx = 0; xx < w; ++xx) {
+ if (alphaP[xx] != 0) {
+ return gFalse;
+ }
+ }
+ alphaP += bitmap->getAlphaRowSize();
+ }
+ return gTrue;
+}
+
void Splash::setTransfer(Guchar *red, Guchar *green, Guchar *blue,
Guchar *gray) {
state->setTransfer(red, green, blue, gray);
@@ -5749,7 +5926,8 @@ struct SplashDrawImageMaskRowData {
SplashError Splash::fillImageMask(GString *imageTag,
SplashImageMaskSource src, void *srcData,
int w, int h, SplashCoord *mat,
- GBool glyphMode, GBool interpolate) {
+ GBool glyphMode, GBool interpolate,
+ GBool antialias) {
if (debugMode) {
printf("fillImageMask: w=%d h=%d mat=[%.2f %.2f %.2f %.2f %.2f %.2f]\n",
w, h, (double)mat[0], (double)mat[1], (double)mat[2],
@@ -5763,28 +5941,35 @@ SplashError Splash::fillImageMask(GString *imageTag,
//--- compute image bbox, check clipping
GBool flipsOnly = splashAbs(mat[1]) <= 0.0001 && splashAbs(mat[2]) <= 0.0001;
+ GBool rot90Only = splashAbs(mat[0]) <= 0.0001 && splashAbs(mat[3]) <= 0.0001;
GBool horizFlip = gFalse;
GBool vertFlip = gFalse;
int xMin, yMin, xMax, yMax;
if (flipsOnly) {
horizFlip = mat[0] < 0;
vertFlip = mat[3] < 0;
+ if (horizFlip) {
+ getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax);
+ } else {
+ getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax);
+ }
if (vertFlip) {
- if (horizFlip) { // bottom-up, mirrored
- getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax);
- getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax);
- } else { // bottom-up
- getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax);
- getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax);
- }
+ getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax);
} else {
- if (horizFlip) { // top-down, mirrored
- getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax);
- getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax);
- } else { // top-down
- getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax);
- getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax);
- }
+ getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax);
+ }
+ } else if (rot90Only) {
+ horizFlip = mat[2] < 0;
+ vertFlip = mat[1] < 0;
+ if (horizFlip) {
+ getImageBounds(mat[2] + mat[4], mat[4], &xMin, &xMax);
+ } else {
+ getImageBounds(mat[4], mat[2] + mat[4], &xMin, &xMax);
+ }
+ if (vertFlip) {
+ getImageBounds(mat[1] + mat[5], mat[5], &yMin, &yMax);
+ } else {
+ getImageBounds(mat[5], mat[1] + mat[5], &yMin, &yMax);
}
} else {
int xx = splashRound(mat[4]); // (0,0)
@@ -5860,7 +6045,7 @@ SplashError Splash::fillImageMask(GString *imageTag,
if (clipRes == splashClipAllInside) {
drawRowFunc = &Splash::drawImageMaskRowNoClip;
} else {
- if (vectorAntialias) {
+ if (antialias) {
drawRowFunc = &Splash::drawImageMaskRowClipAA;
} else {
drawRowFunc = &Splash::drawImageMaskRowClipNoAA;
@@ -5873,7 +6058,7 @@ SplashError Splash::fillImageMask(GString *imageTag,
int scaledWidth = xMax - xMin;
int scaledHeight = yMax - yMin;
ImageMaskScaler scaler(src, srcData, w, h,
- scaledWidth, scaledHeight, interpolate);
+ scaledWidth, scaledHeight, interpolate, antialias);
Guchar *tmpLine = NULL;
if (horizFlip) {
tmpLine = (Guchar *)gmalloc(scaledWidth);
@@ -5912,6 +6097,50 @@ SplashError Splash::fillImageMask(GString *imageTag,
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;
+ }
+
+ // 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;
+ }
+ } 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);
+ }
+
//--- arbitrary transform
} else {
// estimate of size of scaled image
@@ -5963,7 +6192,7 @@ SplashError Splash::fillImageMask(GString *imageTag,
Guchar *scaledMask = (Guchar *)gmallocn(scaledHeight, scaledWidth);
if (downscaling) {
ImageMaskScaler scaler(src, srcData, w, h,
- scaledWidth, scaledHeight, interpolate);
+ scaledWidth, scaledHeight, interpolate, antialias);
Guchar *ptr = scaledMask;
for (int y = 0; y < scaledHeight; ++y) {
scaler.nextLine();
@@ -5982,7 +6211,7 @@ SplashError Splash::fillImageMask(GString *imageTag,
}
// draw it
- if (interpolate) {
+ if (interpolate && antialias) {
drawImageMaskArbitraryInterp(scaledMask,
&dd, drawRowFunc, invMat,
scaledWidth, scaledHeight,
@@ -6259,28 +6488,35 @@ SplashError Splash::drawImage(GString *imageTag,
//--- compute image bbox, check clipping
GBool flipsOnly = splashAbs(mat[1]) <= 0.0001 && splashAbs(mat[2]) <= 0.0001;
+ GBool rot90Only = splashAbs(mat[0]) <= 0.0001 && splashAbs(mat[3]) <= 0.0001;
GBool horizFlip = gFalse;
GBool vertFlip = gFalse;
int xMin, yMin, xMax, yMax;
if (flipsOnly) {
horizFlip = mat[0] < 0;
vertFlip = mat[3] < 0;
+ if (horizFlip) {
+ getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax);
+ } else {
+ getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax);
+ }
if (vertFlip) {
- if (horizFlip) { // bottom-up, mirrored
- getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax);
- getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax);
- } else { // bottom-up
- getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax);
- getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax);
- }
+ getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax);
} else {
- if (horizFlip) { // top-down, mirrored
- getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax);
- getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax);
- } else { // top-down
- getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax);
- getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax);
- }
+ getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax);
+ }
+ } else if (rot90Only) {
+ horizFlip = mat[2] < 0;
+ vertFlip = mat[1] < 0;
+ if (horizFlip) {
+ getImageBounds(mat[2] + mat[4], mat[4], &xMin, &xMax);
+ } else {
+ getImageBounds(mat[4], mat[2] + mat[4], &xMin, &xMax);
+ }
+ if (vertFlip) {
+ getImageBounds(mat[1] + mat[5], mat[5], &yMin, &yMax);
+ } else {
+ getImageBounds(mat[5], mat[1] + mat[5], &yMin, &yMax);
}
} else {
int xx = splashRound(mat[4]); // (0,0)
@@ -6435,6 +6671,83 @@ SplashError Splash::drawImage(GString *imageTag,
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);
+
+ // 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, *alphaPtr;
+ if (vertFlip) {
+ ptr = scaledColor + (scaledWidth - 1 - y) * nComps;
+ if (srcAlpha) {
+ alphaPtr = scaledAlpha + (scaledWidth - 1 - y);
+ }
+ } else {
+ ptr = scaledColor + y * nComps;
+ if (srcAlpha) {
+ alphaPtr = scaledAlpha + y;
+ }
+ }
+ if (horizFlip) {
+ ptr += (scaledHeight - 1) * scaledWidth * nComps;
+ Guchar *q = tmpLine;
+ for (int x = 0; x < scaledHeight; ++x) {
+ for (int i = 0; i < nComps; ++i) {
+ *q++ = ptr[i];
+ }
+ ptr -= scaledWidth * nComps;
+ }
+ 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];
+ }
+ ptr += scaledWidth * nComps;
+ }
+ if (srcAlpha) {
+ q = tmpAlphaLine;
+ for (int x = 0; x < scaledHeight; ++x) {
+ *q++ = *alphaPtr;
+ alphaPtr += scaledWidth;
+ }
+ }
+ }
+ (this->*drawRowFunc)(&dd, tmpLine, tmpAlphaLine,
+ xMin, yMin + y, scaledHeight);
+ }
+
+ gfree(tmpLine);
+ gfree(tmpAlphaLine);
+ if (freeScaledImage) {
+ gfree(scaledColor);
+ gfree(scaledAlpha);
+ }
+ }
+
//--- arbitrary transform
} else {
// estimate of size of scaled image
@@ -6518,14 +6831,13 @@ ImageScaler *Splash::getImageScaler(GString *imageTag,
GBool srcAlpha, GBool interpolate) {
// Notes:
//
- // * If the scaled image width or height is greater than 2000, we
- // don't cache it.
+ // * If the scaled image is more than 8 Mpixels, we don't cache it.
//
// * Caching is done on the third consecutive use (second
// consecutive reuse) of an image; this avoids overhead on the
// common case of single-use images.
- if (scaledWidth < 2000 && scaledHeight < 2000 &&
+ if (scaledWidth < 8000000 / scaledHeight &&
imageCache->match(imageTag, scaledWidth, scaledHeight,
srcMode, srcAlpha, interpolate)) {
if (imageCache->colorData) {
@@ -6570,13 +6882,12 @@ void Splash::getScaledImage(GString *imageTag,
GBool *freeScaledImage) {
// Notes:
//
- // * If the scaled image width or height is greater than 2000, we
- // don't cache it.
+ // * If the scaled image is more than 8 Mpixels, we don't cache it.
//
// * This buffers the whole image anyway, so there's no reason to
// skip caching on the first reuse.
- if (scaledWidth >= 2000 || scaledHeight >= 2000) {
+ if (scaledWidth >= 8000000 / scaledHeight) {
int lineSize;
if (scaledWidth < INT_MAX / nComps) {
lineSize = scaledWidth * nComps;
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.h b/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
index d6cc33a5fad..9622b07fc27 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
@@ -182,12 +182,13 @@ public:
SplashCoord x1, SplashCoord y1);
// NB: uses untransformed coordinates.
SplashError clipToPath(SplashPath *path, GBool eo);
- void setSoftMask(SplashBitmap *softMask);
+ void setSoftMask(SplashBitmap *softMask, GBool deleteBitmap = gTrue);
void setInTransparencyGroup(SplashBitmap *groupBackBitmapA,
int groupBackXA, int groupBackYA,
SplashGroupDestInitMode groupDestInitModeA,
GBool nonIsolated, GBool knockout);
void forceDeferredInit(int y, int h);
+ GBool checkTransparentRect(int x, int y, int w, int h);
void setTransfer(Guchar *red, Guchar *green, Guchar *blue, Guchar *gray);
void setOverprintMask(Guint overprintMask);
void setEnablePathSimplification(GBool en);
@@ -228,11 +229,15 @@ public:
// [x' y' 1] = [x y 1] * mat
// Note that the Splash y axis points downward, and the image source
// is assumed to produce pixels in raster order, starting from the
- // top line.
+ // top line. If [interpolate] is false, no filtering is done when
+ // upsampling. If [antialias] is false, no filtering is done when
+ // upsampling (overriding the [interpolate] flag), and threshold
+ // filtering is done when downsampling.
SplashError fillImageMask(GString *imageTag,
SplashImageMaskSource src, void *srcData,
int w, int h, SplashCoord *mat,
- GBool glyphMode, GBool interpolate);
+ GBool glyphMode, GBool interpolate,
+ GBool antialias);
// Draw an image. This will read <h> lines of <w> pixels from
// <src>, starting with the top line. These pixels are assumed to
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc
index 74421c48a4a..7fc510439b1 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc
@@ -63,6 +63,21 @@ SplashState::SplashState(int width, int height, GBool vectorAntialias,
deleteSoftMask = gFalse;
inNonIsolatedGroup = gFalse;
inKnockoutGroup = gFalse;
+#if SPLASH_CMYK
+ rgbTransferR = (Guchar *)gmalloc(8 * 256);
+ rgbTransferG = rgbTransferR + 256;
+ rgbTransferB = rgbTransferG + 256;
+ grayTransfer = rgbTransferB + 256;
+ cmykTransferC = grayTransfer + 256;
+ cmykTransferM = cmykTransferC + 256;
+ cmykTransferY = cmykTransferM + 256;
+ cmykTransferK = cmykTransferY + 256;
+#else
+ rgbTransferR = (Guchar *)gmalloc(4 * 256);
+ rgbTransferG = rgbTransferR + 256;
+ rgbTransferB = rgbTransferG + 256;
+ grayTransfer = rgbTransferB + 256;
+#endif
for (i = 0; i < 256; ++i) {
rgbTransferR[i] = (Guchar)i;
rgbTransferG[i] = (Guchar)i;
@@ -75,6 +90,7 @@ SplashState::SplashState(int width, int height, GBool vectorAntialias,
cmykTransferK[i] = (Guchar)i;
#endif
}
+ transferIsShared = gFalse;
overprintMask = 0xffffffff;
enablePathSimplification = gFalse;
next = NULL;
@@ -110,6 +126,21 @@ SplashState::SplashState(int width, int height, GBool vectorAntialias,
deleteSoftMask = gFalse;
inNonIsolatedGroup = gFalse;
inKnockoutGroup = gFalse;
+#if SPLASH_CMYK
+ rgbTransferR = (Guchar *)gmalloc(8 * 256);
+ rgbTransferG = rgbTransferR + 256;
+ rgbTransferB = rgbTransferG + 256;
+ grayTransfer = rgbTransferB + 256;
+ cmykTransferC = grayTransfer + 256;
+ cmykTransferM = cmykTransferC + 256;
+ cmykTransferY = cmykTransferM + 256;
+ cmykTransferK = cmykTransferY + 256;
+#else
+ rgbTransferR = (Guchar *)gmalloc(4 * 256);
+ rgbTransferG = rgbTransferR + 256;
+ rgbTransferB = rgbTransferG + 256;
+ grayTransfer = rgbTransferB + 256;
+#endif
for (i = 0; i < 256; ++i) {
rgbTransferR[i] = (Guchar)i;
rgbTransferG[i] = (Guchar)i;
@@ -122,6 +153,7 @@ SplashState::SplashState(int width, int height, GBool vectorAntialias,
cmykTransferK[i] = (Guchar)i;
#endif
}
+ transferIsShared = gFalse;
overprintMask = 0xffffffff;
enablePathSimplification = gFalse;
next = NULL;
@@ -156,16 +188,17 @@ SplashState::SplashState(SplashState *state) {
deleteSoftMask = gFalse;
inNonIsolatedGroup = state->inNonIsolatedGroup;
inKnockoutGroup = state->inKnockoutGroup;
- memcpy(rgbTransferR, state->rgbTransferR, 256);
- memcpy(rgbTransferG, state->rgbTransferG, 256);
- memcpy(rgbTransferB, state->rgbTransferB, 256);
- memcpy(grayTransfer, state->grayTransfer, 256);
+ rgbTransferR = state->rgbTransferR;
+ rgbTransferG = state->rgbTransferG;
+ rgbTransferB = state->rgbTransferB;
+ grayTransfer = state->grayTransfer;
#if SPLASH_CMYK
- memcpy(cmykTransferC, state->cmykTransferC, 256);
- memcpy(cmykTransferM, state->cmykTransferM, 256);
- memcpy(cmykTransferY, state->cmykTransferY, 256);
- memcpy(cmykTransferK, state->cmykTransferK, 256);
+ cmykTransferC = state->cmykTransferC;
+ cmykTransferM = state->cmykTransferM;
+ cmykTransferY = state->cmykTransferY;
+ cmykTransferK = state->cmykTransferK;
#endif
+ transferIsShared = gTrue;
overprintMask = state->overprintMask;
enablePathSimplification = state->enablePathSimplification;
next = NULL;
@@ -179,6 +212,9 @@ SplashState::~SplashState() {
if (!clipIsShared) {
delete clip;
}
+ if (!transferIsShared) {
+ gfree(rgbTransferR);
+ }
if (deleteSoftMask && softMask) {
delete softMask;
}
@@ -265,12 +301,12 @@ SplashError SplashState::clipToPath(SplashPath *path, GBool eo) {
enablePathSimplification, strokeAdjust);
}
-void SplashState::setSoftMask(SplashBitmap *softMaskA) {
+void SplashState::setSoftMask(SplashBitmap *softMaskA, GBool deleteBitmap) {
if (deleteSoftMask) {
delete softMask;
}
softMask = softMaskA;
- deleteSoftMask = gTrue;
+ deleteSoftMask = deleteBitmap;
}
void SplashState::setTransfer(Guchar *red, Guchar *green, Guchar *blue,
@@ -279,6 +315,24 @@ void SplashState::setTransfer(Guchar *red, Guchar *green, Guchar *blue,
int i;
#endif
+ if (transferIsShared) {
+#if SPLASH_CMYK
+ rgbTransferR = (Guchar *)gmalloc(8 * 256);
+ rgbTransferG = rgbTransferR + 256;
+ rgbTransferB = rgbTransferG + 256;
+ grayTransfer = rgbTransferB + 256;
+ cmykTransferC = grayTransfer + 256;
+ cmykTransferM = cmykTransferC + 256;
+ cmykTransferY = cmykTransferM + 256;
+ cmykTransferK = cmykTransferY + 256;
+#else
+ rgbTransferR = (Guchar *)gmalloc(4 * 256);
+ rgbTransferG = rgbTransferR + 256;
+ rgbTransferB = rgbTransferG + 256;
+ grayTransfer = rgbTransferB + 256;
+#endif
+ transferIsShared = gFalse;
+ }
memcpy(rgbTransferR, red, 256);
memcpy(rgbTransferG, green, 256);
memcpy(rgbTransferB, blue, 256);
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h
index 38cb1188e94..be64b472333 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h
@@ -81,7 +81,7 @@ public:
SplashError clipToPath(SplashPath *path, GBool eo);
// Set the soft mask bitmap.
- void setSoftMask(SplashBitmap *softMaskA);
+ void setSoftMask(SplashBitmap *softMaskA, GBool deleteBitmap = gTrue);
// Set the transfer function.
void setTransfer(Guchar *red, Guchar *green, Guchar *blue, Guchar *gray);
@@ -113,16 +113,17 @@ private:
GBool deleteSoftMask;
GBool inNonIsolatedGroup;
GBool inKnockoutGroup;
- Guchar rgbTransferR[256],
- rgbTransferG[256],
- rgbTransferB[256];
- Guchar grayTransfer[256];
+ Guchar *rgbTransferR;
+ Guchar *rgbTransferG;
+ Guchar *rgbTransferB;
+ Guchar *grayTransfer;
#if SPLASH_CMYK
- Guchar cmykTransferC[256],
- cmykTransferM[256],
- cmykTransferY[256],
- cmykTransferK[256];
+ Guchar *cmykTransferC;
+ Guchar *cmykTransferM;
+ Guchar *cmykTransferY;
+ Guchar *cmykTransferK;
#endif
+ GBool transferIsShared;
Guint overprintMask;
GBool enablePathSimplification;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
index b98ca2f0189..7b2b9855669 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
@@ -18,6 +18,7 @@
#include "gmempp.h"
#include "GString.h"
#include "GList.h"
+#include "GlobalParams.h"
#include "Error.h"
#include "Object.h"
#include "PDFDoc.h"
@@ -348,13 +349,15 @@ AcroForm *AcroForm::load(PDFDoc *docA, Catalog *catalog, Object *acroFormObjA) {
if (acroFormObjA->isDict()) {
acroForm = new AcroForm(docA, acroFormObjA);
- if (!acroFormObjA->dictLookup("XFA", &xfaObj)->isNull()) {
- acroForm->xfaScanner = XFAScanner::load(&xfaObj);
- if (!catalog->getNeedsRendering()) {
- acroForm->isStaticXFA = gTrue;
+ if (globalParams->getEnableXFA()) {
+ if (!acroFormObjA->dictLookup("XFA", &xfaObj)->isNull()) {
+ acroForm->xfaScanner = XFAScanner::load(&xfaObj);
+ if (!catalog->getNeedsRendering()) {
+ acroForm->isStaticXFA = gTrue;
+ }
}
+ xfaObj.free();
}
- xfaObj.free();
if (acroFormObjA->dictLookup("NeedAppearances", &obj1)->isBool()) {
acroForm->needAppearances = obj1.getBool();
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
index d7229a2fe86..82ef600be73 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
@@ -224,6 +224,11 @@ Annot::Annot(PDFDoc *docA, Dict *dict, Ref *refA) {
}
}
obj1.free();
+ // Acrobat ignores borders with unreasonable widths
+ if (borderWidth > 1 && (borderWidth > xMax - xMin ||
+ borderWidth > yMax - yMin)) {
+ borderWidth = 0;
+ }
if (dict->lookup("C", &obj1)->isArray() &&
(obj1.arrayGetLength() == 1 ||
obj1.arrayGetLength() == 3 ||
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt
index 7b515d1d036..63a8dec2875 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt
@@ -23,6 +23,11 @@ if (HAVE_LCMS)
else ()
set(COLOR_MANAGER_SOURCE "")
endif ()
+if (WIN32)
+ set(MANIFEST "winLongPath.exe.manifest")
+else ()
+ set(MANIFEST "")
+endif ()
add_library(xpdf_objs OBJECT
AcroForm.cc
@@ -70,10 +75,12 @@ add_library(xpdf_objs OBJECT
XRef.cc
Zoox.cc
)
+set_property(TARGET xpdf_objs
+ PROPERTY POSITION_INDEPENDENT_CODE True)
#--- object files needed by XpdfWidget
-if ((QT4_FOUND OR Qt5Widgets_FOUND)
+if ((QT4_FOUND OR Qt5Widgets_FOUND OR Qt6Widgets_FOUND)
AND HAVE_SPLASH AND MULTITHREADED AND USE_EXCEPTIONS)
if (HIGHLIGHTED_REGIONS)
@@ -95,6 +102,8 @@ if ((QT4_FOUND OR Qt5Widgets_FOUND)
TileMap.cc
${HIGHLIGHT_SRC}
)
+ set_property(TARGET xpdf_widget_objs
+ PROPERTY POSITION_INDEPENDENT_CODE True)
endif ()
#--- pdftops
@@ -107,6 +116,7 @@ if (HAVE_SPLASH)
ShadingImage.cc
SplashOutputDev.cc
pdftops.cc
+ ${MANIFEST}
)
target_link_libraries(pdftops goo fofi splash
${PAPER_LIBRARY}
@@ -121,6 +131,7 @@ else ()
PreScanOutputDev.cc
PSOutputDev.cc
pdftops.cc
+ ${MANIFEST}
)
target_link_libraries(pdftops goo fofi
${PAPER_LIBRARY}
@@ -137,6 +148,7 @@ add_executable(pdftotext
$<TARGET_OBJECTS:xpdf_objs>
TextOutputDev.cc
pdftotext.cc
+ ${MANIFEST}
)
target_link_libraries(pdftotext goo fofi
${PAPER_LIBRARY}
@@ -157,6 +169,7 @@ if (HAVE_SPLASH AND PNG_FOUND)
TextOutputDev.cc
WebFont.cc
pdftohtml.cc
+ ${MANIFEST}
)
target_link_libraries(pdftohtml goo fofi splash
${PAPER_LIBRARY}
@@ -175,6 +188,7 @@ endif ()
add_executable(pdfinfo
$<TARGET_OBJECTS:xpdf_objs>
pdfinfo.cc
+ ${MANIFEST}
)
target_link_libraries(pdfinfo goo fofi
${PAPER_LIBRARY}
@@ -189,6 +203,7 @@ install(FILES ${PROJECT_SOURCE_DIR}/doc/pdfinfo.1 DESTINATION ${CMAKE_INSTALL_MA
add_executable(pdffonts
$<TARGET_OBJECTS:xpdf_objs>
pdffonts.cc
+ ${MANIFEST}
)
target_link_libraries(pdffonts goo fofi
${PAPER_LIBRARY}
@@ -203,6 +218,7 @@ install(FILES ${PROJECT_SOURCE_DIR}/doc/pdffonts.1 DESTINATION ${CMAKE_INSTALL_M
add_executable(pdfdetach
$<TARGET_OBJECTS:xpdf_objs>
pdfdetach.cc
+ ${MANIFEST}
)
target_link_libraries(pdfdetach goo fofi
${PAPER_LIBRARY}
@@ -220,6 +236,7 @@ if (HAVE_SPLASH)
ShadingImage.cc
SplashOutputDev.cc
pdftoppm.cc
+ ${MANIFEST}
)
target_link_libraries(pdftoppm goo fofi splash
${PAPER_LIBRARY}
@@ -240,6 +257,7 @@ if (HAVE_SPLASH AND PNG_FOUND)
ShadingImage.cc
SplashOutputDev.cc
pdftopng.cc
+ ${MANIFEST}
)
target_link_libraries(pdftopng goo fofi splash
${PAPER_LIBRARY}
@@ -259,6 +277,7 @@ add_executable(pdfimages
$<TARGET_OBJECTS:xpdf_objs>
ImageOutputDev.cc
pdfimages.cc
+ ${MANIFEST}
)
target_link_libraries(pdfimages goo fofi
${PAPER_LIBRARY}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
index 6ea8fa89ff4..ddcbad55f07 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
@@ -623,7 +623,7 @@ void Catalog::loadPage2(int pg, int relPg, PageTreeNode *node) {
// merge the PageAttrs
attrs = new PageAttrs(node->parent ? node->parent->attrs
: (PageAttrs *)NULL,
- pageObj.getDict());
+ pageObj.getDict(), xref);
// if "Kids" exists, it's an internal node
if (pageObj.dictLookup("Kids", &kidsObj)->isArray()) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
index 5eec7a9fc6c..0a2100fde9b 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
@@ -232,6 +232,10 @@ CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) {
return new CharCodeToUnicode(NULL, toUnicode, 256, gTrue, NULL, 0, 0);
}
+CharCodeToUnicode *CharCodeToUnicode::make16BitToUnicode(Unicode *toUnicode) {
+ return new CharCodeToUnicode(NULL, toUnicode, 65536, gTrue, NULL, 0, 0);
+}
+
CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) {
CharCodeToUnicode *ctu;
GStringIndex idx;
@@ -470,24 +474,17 @@ GBool CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n,
int offset) {
CharCode oldLen, i;
-#if 1 //~utf16
Unicode u[maxUnicodeString];
int uLen, j;
-#else
- Unicode u;
- int j;
-#endif
if (code > 0xffffff) {
// This is an arbitrary limit to avoid integer overflow issues.
// (I've seen CMaps with mappings for <ffffffff>.)
return;
}
-#if 1 //~utf16
if ((uLen = parseUTF16String(uStr, n, u)) == 0) {
return;
}
-#endif
if (code >= mapLen) {
oldLen = mapLen;
mapLen = mapLen ? 2 * mapLen : 256;
@@ -499,7 +496,6 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n,
map[i] = 0;
}
}
-#if 1 //~utf16
if (uLen == 1) {
map[code] = u[0] + offset;
} else {
@@ -517,34 +513,6 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n,
sMap[sMapLen].len = uLen;
++sMapLen;
}
-#else //~utf16
- if (n <= 4) {
- if (!parseHex(uStr, n, &u)) {
- error(errSyntaxWarning, -1, "Illegal entry in ToUnicode CMap");
- return;
- }
- map[code] = u + offset;
- } else {
- if (sMapLen >= sMapSize) {
- sMapSize = sMapSize + 16;
- sMap = (CharCodeToUnicodeString *)
- greallocn(sMap, sMapSize, sizeof(CharCodeToUnicodeString));
- }
- map[code] = 0;
- sMap[sMapLen].c = code;
- if ((sMap[sMapLen].len = n / 4) > maxUnicodeString) {
- sMap[sMapLen].len = maxUnicodeString;
- }
- for (j = 0; j < sMap[sMapLen].len; ++j) {
- if (!parseHex(uStr + j*4, 4, &sMap[sMapLen].u[j])) {
- error(errSyntaxWarning, -1, "Illegal entry in ToUnicode CMap");
- return;
- }
- }
- sMap[sMapLen].u[sMap[sMapLen].len - 1] += offset;
- ++sMapLen;
- }
-#endif //~utf16
}
// Convert a UTF-16BE hex string into a sequence of up to
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h
index c390a8c5c50..be9025107aa 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h
@@ -49,6 +49,11 @@ public:
// reference count to 1.
static CharCodeToUnicode *make8BitToUnicode(Unicode *toUnicode);
+ // Create the CharCode-to-Unicode mapping for a 16-bit font.
+ // <toUnicode> is an array of 65536 Unicode indexes. Sets the
+ // initial reference count to 1.
+ static CharCodeToUnicode *make16BitToUnicode(Unicode *toUnicode);
+
// Parse a ToUnicode CMap for an 8- or 16-bit font.
static CharCodeToUnicode *parseCMap(GString *buf, int nBits);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
index ed98d9d165f..1539b8404bc 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
@@ -527,6 +527,7 @@ Gfx::Gfx(PDFDoc *docA, OutputDev *outA, int pageNum, Dict *resDict,
xref = doc->getXRef();
subPage = gFalse;
printCommands = globalParams->getPrintCommands();
+ defaultFont = NULL;
// start the resource stack
res = new GfxResources(xref, resDict, NULL);
@@ -574,6 +575,7 @@ Gfx::Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict,
xref = doc->getXRef();
subPage = gTrue;
printCommands = globalParams->getPrintCommands();
+ defaultFont = NULL;
// start the resource stack
res = new GfxResources(xref, resDict, NULL);
@@ -609,6 +611,9 @@ Gfx::Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict,
}
Gfx::~Gfx() {
+ if (defaultFont) {
+ delete defaultFont;
+ }
if (!subPage) {
out->endPage();
}
@@ -2080,12 +2085,19 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
// Adobe's behavior
state->setFillPattern(NULL);
state->setStrokePattern(NULL);
+ state->setFillOverprint(gFalse);
+ state->setStrokeOverprint(gFalse);
+ state->setOverprintMode(0);
if (tPat->getPaintType() == 2 && (cs = patCS->getUnder())) {
state->setFillColorSpace(cs->copy());
out->updateFillColorSpace(state);
state->setStrokeColorSpace(cs->copy());
out->updateStrokeColorSpace(state);
- state->setStrokeColor(state->getFillColor());
+ if (stroke) {
+ state->setFillColor(state->getStrokeColor());
+ } else {
+ state->setStrokeColor(state->getFillColor());
+ }
out->updateFillColor(state);
out->updateStrokeColor(state);
state->setIgnoreColorOps(gTrue);
@@ -3564,8 +3576,10 @@ void Gfx::opSetFont(Object args[], int numArgs) {
void Gfx::doSetFont(GfxFont *font, double size) {
if (!font) {
- state->setFont(NULL, 0);
- return;
+ if (!defaultFont) {
+ defaultFont = GfxFont::makeDefaultFont(xref);
+ }
+ font = defaultFont;
}
if (printCommands) {
printf(" font: tag=%s name='%s' %g\n",
@@ -3847,7 +3861,7 @@ void Gfx::doShowText(GString *s) {
newCTM[2] *= state->getFontSize();
newCTM[3] *= state->getFontSize();
newCTM[0] *= state->getHorizScaling();
- newCTM[2] *= state->getHorizScaling();
+ newCTM[1] *= state->getHorizScaling();
curX = state->getCurX();
curY = state->getCurY();
oldParser = parser;
@@ -4035,7 +4049,7 @@ void Gfx::doIncCharCount(GString *s) {
void Gfx::opXObject(Object args[], int numArgs) {
char *name;
- Object obj1, obj2, obj3, refObj;
+ Object xObj, refObj, obj2, obj3;
GBool ocSaved, oc;
#if OPI_SUPPORT
Object opiDict;
@@ -4045,18 +4059,31 @@ void Gfx::opXObject(Object args[], int numArgs) {
return;
}
name = args[0].getName();
- if (!res->lookupXObject(name, &obj1)) {
+ // NB: we get both the reference and the object here, to make sure
+ // they refer to the same object. There's a problematic corner
+ // case: if the resource dict contains an entry for [name] with a
+ // reference to a nonexistent object ("/name 99999 0 R", where
+ // object 99999 doesn't exist), and a parent resource dict contains
+ // a valid entry with the same name, then lookupXObjectNF() will
+ // return "99999 0 R", but lookupXObject() will return the valid
+ // entry. This causes problems for doImage() and doForm().
+ if (!res->lookupXObjectNF(name, &refObj)) {
+ return;
+ }
+ if (!refObj.fetch(xref, &xObj)) {
+ refObj.free();
return;
}
- if (!obj1.isStream()) {
+ if (!xObj.isStream()) {
error(errSyntaxError, getPos(), "XObject '{0:s}' is wrong type", name);
- obj1.free();
+ xObj.free();
+ refObj.free();
return;
}
// check for optional content key
ocSaved = ocState;
- obj1.streamGetDict()->lookupNF("OC", &obj2);
+ xObj.streamGetDict()->lookupNF("OC", &obj2);
if (doc->getOptionalContent()->evalOCObject(&obj2, &oc)) {
ocState &= oc;
}
@@ -4066,32 +4093,28 @@ void Gfx::opXObject(Object args[], int numArgs) {
try {
#endif
#if OPI_SUPPORT
- obj1.streamGetDict()->lookup("OPI", &opiDict);
+ xObj.streamGetDict()->lookup("OPI", &opiDict);
if (opiDict.isDict()) {
out->opiBegin(state, opiDict.getDict());
}
#endif
- obj1.streamGetDict()->lookup("Subtype", &obj2);
+ xObj.streamGetDict()->lookup("Subtype", &obj2);
if (obj2.isName("Image")) {
if (out->needNonText()) {
- res->lookupXObjectNF(name, &refObj);
- doImage(&refObj, obj1.getStream(), gFalse);
- refObj.free();
+ doImage(&refObj, xObj.getStream(), gFalse);
}
} else if (obj2.isName("Form")) {
- res->lookupXObjectNF(name, &refObj);
if (out->useDrawForm() && refObj.isRef()) {
if (ocState) {
out->drawForm(refObj.getRef());
}
} else {
- doForm(&refObj, &obj1);
+ doForm(&refObj, &xObj);
}
- refObj.free();
} else if (obj2.isName("PS")) {
if (ocState) {
- obj1.streamGetDict()->lookup("Level1", &obj3);
- out->psXObject(obj1.getStream(),
+ xObj.streamGetDict()->lookup("Level1", &obj3);
+ out->psXObject(xObj.getStream(),
obj3.isStream() ? obj3.getStream() : (Stream *)NULL);
}
} else if (obj2.isName()) {
@@ -4110,13 +4133,16 @@ void Gfx::opXObject(Object args[], int numArgs) {
#endif
#if USE_EXCEPTIONS
} catch (GMemException e) {
- obj1.free();
+ xObj.free();
+ refObj.free();
throw;
}
#endif
- obj1.free();
ocState = ocSaved;
+
+ xObj.free();
+ refObj.free();
}
GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
@@ -4144,6 +4170,10 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
return gTrue;
}
+ // images can have arbitrarily high compression ratios, but the
+ // data size is inherently limited
+ str->disableDecompressionBombChecking();
+
// get info from the stream
bits = 0;
csMode = streamCSNone;
@@ -4248,6 +4278,7 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
// if drawing is disabled, skip over inline image data
if (!ocState) {
+ str->disableDecompressionBombChecking();
str->reset();
n = height * ((width + 7) / 8);
for (i = 0; i < n; ++i) {
@@ -4339,6 +4370,7 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
goto err1;
}
maskStr = smaskObj.getStream();
+ maskStr->disableDecompressionBombChecking();
maskDict = smaskObj.streamGetDict();
maskDict->lookup("Width", &obj1);
if (obj1.isNull()) {
@@ -4487,6 +4519,7 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
goto err1;
}
maskStr = maskObj.getStream();
+ maskStr->disableDecompressionBombChecking();
maskDict = maskObj.streamGetDict();
maskDict->lookup("Width", &obj1);
if (obj1.isNull()) {
@@ -4559,6 +4592,7 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
" in uncolored Type 3 char or tiling pattern");
}
if (inlineImg) {
+ str->disableDecompressionBombChecking();
str->reset();
n = height * ((width * colorMap->getNumPixelComps() *
colorMap->getBits() + 7) / 8);
@@ -4569,7 +4603,7 @@ GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
// draw it
} else {
if (haveSoftMask) {
- dict->lookupNF("Mask", &maskRef);
+ dict->lookupNF("SMask", &maskRef);
out->drawSoftMaskedImage(state, ref, str, width, height, colorMap,
&maskRef, maskStr, maskWidth, maskHeight,
maskColorMap,
@@ -4654,13 +4688,18 @@ void Gfx::doForm(Object *strRef, Object *str) {
// get bounding box
dict->lookup("BBox", &bboxObj);
- if (!bboxObj.isArray()) {
+ if (!(bboxObj.isArray() && bboxObj.arrayGetLength() == 4)) {
bboxObj.free();
error(errSyntaxError, getPos(), "Bad form bounding box");
return;
}
for (i = 0; i < 4; ++i) {
bboxObj.arrayGet(i, &obj1);
+ if (!obj1.isNum()) {
+ bboxObj.free();
+ error(errSyntaxError, getPos(), "Bad form bounding box");
+ return;
+ }
bbox[i] = obj1.getNum();
obj1.free();
}
@@ -4668,10 +4707,14 @@ void Gfx::doForm(Object *strRef, Object *str) {
// get matrix
dict->lookup("Matrix", &matrixObj);
- if (matrixObj.isArray()) {
+ if (matrixObj.isArray() && matrixObj.arrayGetLength() == 6) {
for (i = 0; i < 6; ++i) {
matrixObj.arrayGet(i, &obj1);
- m[i] = obj1.getNum();
+ if (obj1.isNum()) {
+ m[i] = obj1.getNum();
+ } else {
+ m[i] = 0;
+ }
obj1.free();
}
} else {
@@ -4769,22 +4812,27 @@ void Gfx::drawForm(Object *strRef, Dict *resDict,
groupAttrsObj.free();
strObj.free();
- traceBegin(oldBaseMatrix, softMask ? "begin soft mask" : "begin t-group");
- if (state->getBlendMode() != gfxBlendNormal) {
- state->setBlendMode(gfxBlendNormal);
- out->updateBlendMode(state);
- }
- if (state->getFillOpacity() != 1) {
- state->setFillOpacity(1);
- out->updateFillOpacity(state);
+ if (!out->beginTransparencyGroup(state, bbox, blendingColorSpace,
+ isolated, knockout, softMask)) {
+ transpGroup = gFalse;
}
- if (state->getStrokeOpacity() != 1) {
- state->setStrokeOpacity(1);
- out->updateStrokeOpacity(state);
+
+ if (softMask || transpGroup) {
+ traceBegin(oldBaseMatrix, softMask ? "begin soft mask" : "begin t-group");
+ if (state->getBlendMode() != gfxBlendNormal) {
+ state->setBlendMode(gfxBlendNormal);
+ out->updateBlendMode(state);
+ }
+ if (state->getFillOpacity() != 1) {
+ state->setFillOpacity(1);
+ out->updateFillOpacity(state);
+ }
+ if (state->getStrokeOpacity() != 1) {
+ state->setStrokeOpacity(1);
+ out->updateStrokeOpacity(state);
+ }
+ out->clearSoftMask(state);
}
- out->clearSoftMask(state);
- out->beginTransparencyGroup(state, bbox, blendingColorSpace,
- isolated, knockout, softMask);
}
// set new base matrix
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
index 4625ac289d0..14d7a608438 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
@@ -188,6 +188,7 @@ private:
GBool subPage; // is this a sub-page object?
GBool printCommands; // print the drawing commands (for debugging)
GfxResources *res; // resource stack
+ GfxFont *defaultFont; // font substituted for undefined fonts
int opCounter; // operation counter (used to decide when
// to check for an abort)
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
index f224ff75b5f..30e8bd1c79c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
@@ -198,6 +198,27 @@ GfxFont *GfxFont::makeFont(XRef *xref, const char *tagA,
return font;
}
+GfxFont *GfxFont::makeDefaultFont(XRef *xref) {
+ Object type, subtype, baseFont;
+ type.initName("Font");
+ subtype.initName("Type1");
+ baseFont.initName("Helvetica");
+ Object fontDict;
+ fontDict.initDict(xref);
+ fontDict.dictAdd(copyString("Type"), &type);
+ fontDict.dictAdd(copyString("Subtype"), &subtype);
+ fontDict.dictAdd(copyString("BaseFont"), &baseFont);
+
+ Ref r;
+ r.gen = 100000;
+ r.num = GfxFontDict::hashFontObject(&fontDict);
+
+ GfxFont *font = makeFont(xref, "undef", r, fontDict.getDict());
+ fontDict.free();
+
+ return font;
+}
+
GfxFont::GfxFont(const char *tagA, Ref idA, GString *nameA,
GfxFontType typeA, Ref embFontIDA) {
ok = gFalse;
@@ -1701,9 +1722,59 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
obj2.free();
obj1.free();
+ // encoding (i.e., CMap)
+ if (fontDict->lookup("Encoding", &obj1)->isNull()) {
+ error(errSyntaxError, -1, "Missing Encoding entry in Type 0 font");
+ goto err2;
+ }
+ if (!(cMap = CMap::parse(NULL, collection, &obj1))) {
+ goto err2;
+ }
+
+ // check for fonts that use the Identity-H encoding (cmap), and the
+ // Adobe-Identity character collection
+ identityEnc = obj1.isName("Identity-H") &&
+ !collection->cmp("Adobe-Identity");
+
+ obj1.free();
+
+ // CIDToGIDMap
+ // (the PDF 1.7 spec only allows these for TrueType fonts, but
+ // Acrobat apparently also allows them for OpenType CFF fonts -- and
+ // the PDF 2.0 spec has removed the prohibition)
+ hasIdentityCIDToGID = gFalse;
+ desFontDict->lookup("CIDToGIDMap", &obj1);
+ if (obj1.isStream()) {
+ cidToGIDLen = 0;
+ i = 64;
+ cidToGID = (int *)gmallocn(i, sizeof(int));
+ obj1.streamReset();
+ while ((c1 = obj1.streamGetChar()) != EOF &&
+ (c2 = obj1.streamGetChar()) != EOF) {
+ if (cidToGIDLen == i) {
+ i *= 2;
+ cidToGID = (int *)greallocn(cidToGID, i, sizeof(int));
+ }
+ cidToGID[cidToGIDLen++] = (c1 << 8) + c2;
+ }
+ obj1.streamClose();
+ identityEnc = gFalse;
+ } else if (obj1.isName("Identity")) {
+ hasIdentityCIDToGID = gTrue;
+ } else if (!obj1.isNull()) {
+ error(errSyntaxError, -1, "Invalid CIDToGIDMap entry in CID font");
+ }
+ obj1.free();
+
// look for a ToUnicode CMap
hasKnownCollection = gFalse;
- if (!(ctu = readToUnicodeCMap(fontDict, 16, NULL))) {
+ if (globalParams->getUseTrueTypeUnicodeMapping()) {
+ readTrueTypeUnicodeMapping(xref);
+ }
+ if (!ctu) {
+ ctu = readToUnicodeCMap(fontDict, 16, NULL);
+ }
+ if (!ctu) {
ctuUsesCharCode = gFalse;
// use an identity mapping for the "Adobe-Identity" and
@@ -1748,55 +1819,11 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
}
}
- // encoding (i.e., CMap)
- if (fontDict->lookup("Encoding", &obj1)->isNull()) {
- error(errSyntaxError, -1, "Missing Encoding entry in Type 0 font");
- goto err2;
- }
- if (!(cMap = CMap::parse(NULL, collection, &obj1))) {
- goto err2;
- }
-
- // check for fonts that use the Identity-H encoding (cmap), and the
- // Adobe-Identity character collection
- identityEnc = obj1.isName("Identity-H") &&
- !collection->cmp("Adobe-Identity");
-
- obj1.free();
-
- // CIDToGIDMap
- // (the PDF 1.7 spec only allows these for TrueType fonts, but
- // Acrobat apparently also allows them for OpenType CFF fonts -- and
- // the PDF 2.0 spec has removed the prohibition)
- hasIdentityCIDToGID = gFalse;
- desFontDict->lookup("CIDToGIDMap", &obj1);
- if (obj1.isStream()) {
- cidToGIDLen = 0;
- i = 64;
- cidToGID = (int *)gmallocn(i, sizeof(int));
- obj1.streamReset();
- while ((c1 = obj1.streamGetChar()) != EOF &&
- (c2 = obj1.streamGetChar()) != EOF) {
- if (cidToGIDLen == i) {
- i *= 2;
- cidToGID = (int *)greallocn(cidToGID, i, sizeof(int));
- }
- cidToGID[cidToGIDLen++] = (c1 << 8) + c2;
- }
- obj1.streamClose();
- identityEnc = gFalse;
- } else if (obj1.isName("Identity")) {
- hasIdentityCIDToGID = gTrue;
- } else if (!obj1.isNull()) {
- error(errSyntaxError, -1, "Invalid CIDToGIDMap entry in CID font");
- }
- obj1.free();
-
//----- character metrics -----
// default char width
- if (desFontDict->lookup("DW", &obj1)->isInt()) {
- widths.defWidth = obj1.getInt() * 0.001;
+ if (desFontDict->lookup("DW", &obj1)->isNum()) {
+ widths.defWidth = obj1.getNum() * 0.001;
}
obj1.free();
@@ -1968,6 +1995,91 @@ GfxCIDFont::~GfxCIDFont() {
}
}
+// Construct a code-to-Unicode mapping, based on the TrueType Unicode
+// cmap (if present). Constructs ctu if succesful; leaves ctu = null
+// otherwise. Always leaves ctu = null for non-TrueType fonts.
+void GfxCIDFont::readTrueTypeUnicodeMapping(XRef *xref) {
+ char *buf;
+ FoFiTrueType *ff;
+ Unicode *gidToUnicode, *codeToUnicode;
+ Unicode u;
+ int bufLen, cmapPlatform, cmapEncoding, unicodeCmap;
+ int nGlyphs, nMappings, gid, i;
+
+ // must be an embedded TrueType font, with an unknown char collection
+ if ((type != fontCIDType2 && type == fontCIDType2OT) ||
+ embFontID.num < 0 ||
+ hasKnownCollection) {
+ goto err0;
+ }
+
+ // read the embedded font and construct a FoFiTrueType
+ if (!(buf = readEmbFontFile(xref, &bufLen))) {
+ goto err0;
+ }
+ if (!(ff = FoFiTrueType::make(buf, bufLen, 0))) {
+ goto err1;
+ }
+
+ // find the TrueType Unicode cmap
+ unicodeCmap = -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)) {
+ unicodeCmap = i;
+ break;
+ }
+ }
+ if (unicodeCmap < 0) {
+ goto err2;
+ }
+
+ // construct reverse GID-to-Unicode map
+ nGlyphs = ff->getNumGlyphs();
+ gidToUnicode = (Unicode *)gmallocn(nGlyphs, sizeof(Unicode));
+ memset(gidToUnicode, 0, nGlyphs * sizeof(Unicode));
+ nMappings = 0;
+ for (u = 1; u <= 0xffff; ++u) {
+ gid = ff->mapCodeToGID(unicodeCmap, (int)u);
+ if (gid > 0 && gid < nGlyphs) {
+ gidToUnicode[gid] = u;
+ ++nMappings;
+ }
+ }
+ // bail out if the Unicode cmap was completely empty
+ if (nMappings == 0) {
+ goto err3;
+ }
+
+ // construct code-to-Unicode map
+ codeToUnicode = (Unicode *)gmallocn(65536, sizeof(Unicode));
+ memset(codeToUnicode, 0, 65536 * sizeof(Unicode));
+ for (i = 0; i <= 0xffff; ++i) {
+ // we've already checked for an identity encoding, so CID = i
+ if (cidToGID && i < cidToGIDLen) {
+ gid = cidToGID[i];
+ } else {
+ gid = i;
+ }
+ if (gid < nGlyphs && gidToUnicode[gid] > 0) {
+ codeToUnicode[i] = gidToUnicode[gid];
+ }
+ }
+ ctu = CharCodeToUnicode::make16BitToUnicode(codeToUnicode);
+
+ gfree(codeToUnicode);
+ err3:
+ gfree(gidToUnicode);
+ err2:
+ delete ff;
+ err1:
+ gfree(buf);
+ err0:
+ return;
+}
+
int GfxCIDFont::getNextChar(char *s, int len, CharCode *code,
Unicode *u, int uSize, int *uLen,
double *dx, double *dy, double *ox, double *oy) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
index ded34bc1ee7..e752ded62f8 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
@@ -135,6 +135,10 @@ public:
static GfxFont *makeFont(XRef *xref, const char *tagA,
Ref idA, Dict *fontDict);
+ // Create a simple default font, to substitute for an undefined font
+ // object.
+ static GfxFont *makeDefaultFont(XRef *xref);
+
GfxFont(const char *tagA, Ref idA, GString *nameA,
GfxFontType typeA, Ref embFontIDA);
@@ -357,6 +361,7 @@ public:
private:
+ void readTrueTypeUnicodeMapping(XRef *xref);
void getHorizontalMetrics(CID cid, double *w);
void getVerticalMetrics(CID cid, double *h,
double *vx, double *vy);
@@ -398,8 +403,10 @@ public:
private:
- int hashFontObject(Object *obj);
- void hashFontObject1(Object *obj, FNVHash *h);
+ friend class GfxFont;
+
+ 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
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
index 5e9991e1b97..43503aaedb8 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
@@ -2071,6 +2071,7 @@ GfxFunctionShading *GfxFunctionShading::parse(Dict *dict
Function *funcsA[gfxColorMaxComps];
int nFuncsA;
Object obj1, obj2;
+ GBool ok;
int i;
x0A = y0A = 0;
@@ -2139,14 +2140,21 @@ GfxFunctionShading *GfxFunctionShading::parse(Dict *dict
return NULL;
}
- for (i = 0; i < shading->nFuncs; ++i) {
- if (shading->funcs[i]->getOutputSize()
- != shading->getColorSpace()->getNComps()) {
- error(errSyntaxError, -1, "Invalid function in shading dictionary");
- delete shading;
- return NULL;
+ ok = gFalse;
+ if (shading->nFuncs == 1) {
+ ok = shading->funcs[0]->getOutputSize()
+ == shading->getColorSpace()->getNComps();
+ } else if (shading->nFuncs == shading->getColorSpace()->getNComps()) {
+ ok = gTrue;
+ for (i = 0; i < shading->nFuncs; ++i) {
+ ok = ok && shading->funcs[i]->getOutputSize() == 1;
}
}
+ if (!ok) {
+ error(errSyntaxError, -1, "Invalid function in shading dictionary");
+ delete shading;
+ return NULL;
+ }
return shading;
@@ -2241,7 +2249,7 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict
double t0A, t1A;
Function *funcsA[gfxColorMaxComps];
int nFuncsA;
- GBool extend0A, extend1A;
+ GBool extend0A, extend1A, ok;
Object obj1, obj2;
int i;
@@ -2319,14 +2327,21 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict
return NULL;
}
- for (i = 0; i < shading->nFuncs; ++i) {
- if (shading->funcs[i]->getOutputSize()
- != shading->getColorSpace()->getNComps()) {
- error(errSyntaxError, -1, "Invalid function in shading dictionary");
- delete shading;
- return NULL;
+ ok = gFalse;
+ if (shading->nFuncs == 1) {
+ ok = shading->funcs[0]->getOutputSize()
+ == shading->getColorSpace()->getNComps();
+ } else if (shading->nFuncs == shading->getColorSpace()->getNComps()) {
+ ok = gTrue;
+ for (i = 0; i < shading->nFuncs; ++i) {
+ ok = ok && shading->funcs[i]->getOutputSize() == 1;
}
}
+ if (!ok) {
+ error(errSyntaxError, -1, "Invalid function in shading dictionary");
+ delete shading;
+ return NULL;
+ }
return shading;
@@ -2420,7 +2435,7 @@ GfxRadialShading *GfxRadialShading::parse(Dict *dict
double t0A, t1A;
Function *funcsA[gfxColorMaxComps];
int nFuncsA;
- GBool extend0A, extend1A;
+ GBool extend0A, extend1A, ok;
Object obj1, obj2;
int i;
@@ -2501,14 +2516,21 @@ GfxRadialShading *GfxRadialShading::parse(Dict *dict
return NULL;
}
- for (i = 0; i < shading->nFuncs; ++i) {
- if (shading->funcs[i]->getOutputSize()
- != shading->getColorSpace()->getNComps()) {
- error(errSyntaxError, -1, "Invalid function in shading dictionary");
- delete shading;
- return NULL;
+ ok = gFalse;
+ if (shading->nFuncs == 1) {
+ ok = shading->funcs[0]->getOutputSize()
+ == shading->getColorSpace()->getNComps();
+ } else if (shading->nFuncs == shading->getColorSpace()->getNComps()) {
+ ok = gTrue;
+ for (i = 0; i < shading->nFuncs; ++i) {
+ ok = ok && shading->funcs[i]->getOutputSize() == 1;
}
}
+ if (!ok) {
+ error(errSyntaxError, -1, "Invalid function in shading dictionary");
+ delete shading;
+ return NULL;
+ }
return shading;
@@ -2675,6 +2697,7 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(
Guint c[gfxColorMaxComps];
GfxShadingBitBuf *bitBuf;
Object obj1, obj2;
+ GBool ok;
int i, j, k, state;
if (dict->lookup("BitsPerCoordinate", &obj1)->isInt()) {
@@ -2883,14 +2906,23 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(
return NULL;
}
- for (i = 0; i < shading->nFuncs; ++i) {
- if (shading->funcs[i]->getOutputSize()
- != shading->getColorSpace()->getNComps()) {
- error(errSyntaxError, -1, "Invalid function in shading dictionary");
- delete shading;
- return NULL;
+ ok = gFalse;
+ if (shading->nFuncs == 0) {
+ ok = shading->nComps == shading->getColorSpace()->getNComps();
+ } else if (shading->nFuncs == 1) {
+ ok = shading->funcs[0]->getOutputSize()
+ == shading->getColorSpace()->getNComps();
+ } else if (shading->nFuncs == shading->getColorSpace()->getNComps()) {
+ ok = gTrue;
+ for (i = 0; i < shading->nFuncs; ++i) {
+ ok = ok && shading->funcs[i]->getOutputSize() == 1;
}
}
+ if (!ok) {
+ error(errSyntaxError, -1, "Invalid function in shading dictionary");
+ delete shading;
+ return NULL;
+ }
return shading;
@@ -3042,6 +3074,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict,
Guint ci;
GfxShadingBitBuf *bitBuf;
Object obj1, obj2;
+ GBool ok;
int i, j;
nPatchesA = 0;
@@ -3555,14 +3588,23 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict,
return NULL;
}
- for (i = 0; i < shading->nFuncs; ++i) {
- if (shading->funcs[i]->getOutputSize()
- != shading->getColorSpace()->getNComps()) {
- error(errSyntaxError, -1, "Invalid function in shading dictionary");
- delete shading;
- return NULL;
+ ok = gFalse;
+ if (shading->nFuncs == 0) {
+ ok = shading->nComps == shading->getColorSpace()->getNComps();
+ } else if (shading->nFuncs == 1) {
+ ok = shading->funcs[0]->getOutputSize()
+ == shading->getColorSpace()->getNComps();
+ } else if (shading->nFuncs == shading->getColorSpace()->getNComps()) {
+ ok = gTrue;
+ for (i = 0; i < shading->nFuncs; ++i) {
+ ok = ok && shading->funcs[i]->getOutputSize() == 1;
}
}
+ if (!ok) {
+ error(errSyntaxError, -1, "Invalid function in shading dictionary");
+ delete shading;
+ return NULL;
+ }
return shading;
@@ -4091,6 +4133,26 @@ GfxPath::GfxPath(GBool justMoved1, double firstX1, double firstY1,
subpaths[i] = subpaths1[i]->copy();
}
+double GfxPath::getCurX() {
+ if (justMoved) {
+ return firstX;
+ } else if (n > 0) {
+ return subpaths[n-1]->getLastX();
+ } else {
+ return 0;
+ }
+}
+
+double GfxPath::getCurY() {
+ if (justMoved) {
+ return firstY;
+ } else if (n > 0) {
+ return subpaths[n-1]->getLastY();
+ } else {
+ return 0;
+ }
+}
+
void GfxPath::moveTo(double x, double y) {
justMoved = gTrue;
firstX = x;
@@ -4581,65 +4643,143 @@ void GfxState::clip() {
}
void GfxState::clipToStrokePath() {
- double xMin, yMin, xMax, yMax, x, y, t0, t1;
- GfxSubpath *subpath;
- int i, j;
-
- xMin = xMax = yMin = yMax = 0; // make gcc happy
- for (i = 0; i < path->getNumSubpaths(); ++i) {
- subpath = path->getSubpath(i);
- for (j = 0; j < subpath->getNumPoints(); ++j) {
- transform(subpath->getX(j), subpath->getY(j), &x, &y);
+ // We compute the stroke path bbox in user space (line width and
+ // miter limt are handled in user space), and then transform the
+ // bbox to device space. This can result in a larger-than-needed
+ // bbox if the matrix isn't "square", but that's ok.
+ //
+ // 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 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) {
+ double x1 = subpath->getX(j);
+ double y1 = subpath->getY(j);
if (i == 0 && j == 0) {
- xMin = xMax = x;
- yMin = yMax = y;
- } else {
- if (x < xMin) {
- xMin = x;
- } else if (x > xMax) {
- xMax = x;
+ xMin = xMax = x1;
+ yMin = yMax = y1;
+ }
+ GBool useMiter = gFalse;
+ if (lineJoin == 0 && // miter join
+ ((j > 0 && j < subpath->getNumPoints() - 1) || subpath->isClosed())) {
+ double x0, y0, x2, y2;
+ if (j > 0) {
+ x0 = subpath->getX(j - 1);
+ y0 = subpath->getY(j - 1);
+ } else {
+ x0 = subpath->getLastX();
+ y0 = subpath->getLastY();
}
- if (y < yMin) {
- yMin = y;
- } else if (y > yMax) {
- yMax = y;
+ if (j < subpath->getNumPoints() - 1) {
+ x2 = subpath->getX(j + 1);
+ y2 = subpath->getY(j + 1);
+ } else {
+ x2 = subpath->getX(0);
+ y2 = subpath->getY(0);
+ }
+ 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));
+ double ux = (x1 - x0) * d01;
+ double uy = (y1 - y0) * d01;
+ double d12 = 1 / sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
+ double vx = (x2 - x1) * d12;
+ double vy = (y2 - y1) * d12;
+ double dot = -ux * vx - uy * vy;
+ if (dot < 0.9999) {
+ double miter = sqrt(2 / (1 - dot));
+ if (miter <= miterLimit) {
+ double cross = ux * vy - uy * vx;
+ double m = sqrt(2 / (1 - dot) - 1);
+ double ax, ay;
+ if (cross >= 0) {
+ ax = x1 + w * uy;
+ ay = y1 - w * ux;
+ } else {
+ ax = x1 - w * uy;
+ ay = y1 + w * ux;
+ }
+ double mx = ax + m * w * ux;
+ double my = ay + m * w * uy;
+ if (mx < xMin) {
+ xMin = mx;
+ } else if (mx > xMax) {
+ xMax = mx;
+ }
+ if (my < yMin) {
+ yMin = my;
+ } else if (my > yMax) {
+ yMax = my;
+ }
+ useMiter = gTrue;
+ }
+ }
+ }
+ }
+ if (!useMiter) {
+ if (x1 - w < xMin) {
+ xMin = x1 - w;
+ }
+ if (x1 + w > xMax) {
+ xMax = x1 + w;
+ }
+ if (y1 - w < yMin) {
+ yMin = y1 - w;
+ }
+ if (y1 + w > yMax) {
+ yMax = y1 + w;
}
}
}
}
- // allow for the line width
- //~ miter joins can extend farther than this
- t0 = fabs(ctm[0]);
- t1 = fabs(ctm[2]);
- if (t0 > t1) {
- xMin -= 0.5 * lineWidth * t0;
- xMax += 0.5 * lineWidth * t0;
- } else {
- xMin -= 0.5 * lineWidth * t1;
- xMax += 0.5 * lineWidth * t1;
- }
- t0 = fabs(ctm[0]);
- t1 = fabs(ctm[3]);
- if (t0 > t1) {
- yMin -= 0.5 * lineWidth * t0;
- yMax += 0.5 * lineWidth * t0;
- } else {
- yMin -= 0.5 * lineWidth * t1;
- yMax += 0.5 * lineWidth * t1;
- }
-
- if (xMin > clipXMin) {
- clipXMin = xMin;
- }
- if (yMin > clipYMin) {
- clipYMin = yMin;
- }
- if (xMax < clipXMax) {
- clipXMax = xMax;
- }
- if (yMax < clipYMax) {
- clipYMax = yMax;
+ double xx, yy;
+ transform(xMin, yMin, &xx, &yy);
+ if (xx < clipXMin) {
+ clipXMin = xx;
+ } else if (xx > clipXMax) {
+ clipXMax = xx;
+ }
+ if (yy < clipYMin) {
+ clipYMin = yy;
+ } else if (yy > clipYMax) {
+ clipYMax = yy;
+ }
+ transform(xMin, yMax, &xx, &yy);
+ if (xx < clipXMin) {
+ clipXMin = xx;
+ } else if (xx > clipXMax) {
+ clipXMax = xx;
+ }
+ if (yy < clipYMin) {
+ clipYMin = yy;
+ } else if (yy > clipYMax) {
+ clipYMax = yy;
+ }
+ transform(xMax, yMin, &xx, &yy);
+ if (xx < clipXMin) {
+ clipXMin = xx;
+ } else if (xx > clipXMax) {
+ clipXMax = xx;
+ }
+ if (yy < clipYMin) {
+ clipYMin = yy;
+ } else if (yy > clipYMax) {
+ clipYMax = yy;
+ }
+ transform(xMax, yMax, &xx, &yy);
+ if (xx < clipXMin) {
+ clipXMin = xx;
+ } else if (xx > clipXMax) {
+ clipXMax = xx;
+ }
+ if (yy < clipYMin) {
+ clipYMin = yy;
+ } else if (yy > clipYMax) {
+ clipYMax = yy;
}
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
index f9c0cfcad6e..60d48527c29 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
@@ -1076,6 +1076,10 @@ public:
double getLastX() { return subpaths[n-1]->getLastX(); }
double getLastY() { return subpaths[n-1]->getLastY(); }
+ // Get the current point
+ double getCurX();
+ double getCurY();
+
// Move the current point.
void moveTo(double x, double y);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
index 5ff932479d1..e7cc594b12d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
@@ -5,9 +5,6 @@
// Copyright 2001-2003 Glyph & Cog, LLC
//
//========================================================================
-// Modified for TeX Live by Peter Breitenlohner <tex-live@tug.org>
-// See top-level ChangeLog for a list of all modifications
-//========================================================================
#include <aconf.h>
@@ -219,7 +216,7 @@ GString *SysFontInfo::mungeName1(GString *in) {
return out;
}
-// Remove trailing "Identity-H"/"Identity-V" from the name.
+// Remove trailing encoding tags from the name.
// Split the name into tokens at space/comma/dash/underscore.
// Remove trailing "MT" or "BT" from tokens.
// Remove trailing "PS" and "WGL4" from tokens.
@@ -229,7 +226,9 @@ GString *SysFontInfo::mungeName2(GString *in) {
GString *out = new GString();
char *p0 = in->getCString();
while (*p0) {
- if (!strcmp(p0, "Identity-H") || !strcmp(p0, "Identity-V")) {
+ if (!strcmp(p0, "Identity-H") || !strcmp(p0, "Identity-V") ||
+ !strcmp(p0, "GB2312") ||
+ !strcmp(p0, "UniGB-UCS2-H") || !strcmp(p0, "UniGB-UCS2-V")) {
break;
}
char *p1;
@@ -729,6 +728,7 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
disableFreeTypeHinting = gFalse;
antialias = gTrue;
vectorAntialias = gTrue;
+ imageMaskAntialias = gTrue;
antialiasPrinting = gFalse;
strokeAdjust = strokeAdjustNormal;
screenType = screenUnset;
@@ -741,6 +741,7 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
enablePathSimplification = gFalse;
drawAnnotations = gTrue;
drawFormFields = gTrue;
+ enableXFA = gTrue;
overprintPreview = gFalse;
paperColor = new GString("#ffffff");
matteColor = new GString("#808080");
@@ -753,11 +754,14 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
mapNumericCharNames = gTrue;
mapUnknownCharNames = gFalse;
mapExtTrueTypeFontsViaUnicode = gTrue;
+ useTrueTypeUnicodeMapping = gFalse;
droppedFonts = new GHash(gTrue);
createDefaultKeyBindings();
popupMenuCmds = new GList();
tabStateFile = appendToPath(getHomeDir(), ".xpdf.tab-state");
+ savePageNumbers = gTrue;
printCommands = gFalse;
+ printStatusInfo = gFalse;
errQuiet = gFalse;
debugLogFile = NULL;
@@ -1186,6 +1190,9 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
} else if (!cmd->cmp("vectorAntialias")) {
parseYesNo("vectorAntialias", &vectorAntialias,
tokens, fileName, line);
+ } else if (!cmd->cmp("imageMaskAntialias")) {
+ parseYesNo("imageMaskAntialias", &imageMaskAntialias,
+ tokens, fileName, line);
} else if (!cmd->cmp("antialiasPrinting")) {
parseYesNo("antialiasPrinting", &antialiasPrinting,
tokens, fileName, line);
@@ -1219,6 +1226,9 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
} else if (!cmd->cmp("drawFormFields")) {
parseYesNo("drawFormFields", &drawFormFields,
tokens, fileName, line);
+ } else if (!cmd->cmp("enableXFA")) {
+ parseYesNo("enableXFA", &enableXFA,
+ tokens, fileName, line);
} else if (!cmd->cmp("overprintPreview")) {
parseYesNo("overprintPreview", &overprintPreview,
tokens, fileName, line);
@@ -1250,6 +1260,10 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
parseYesNo("mapExtTrueTypeFontsViaUnicode",
&mapExtTrueTypeFontsViaUnicode,
tokens, fileName, line);
+ } else if (!cmd->cmp("useTrueTypeUnicodeMapping")) {
+ parseYesNo("useTrueTypeUnicodeMapping",
+ &useTrueTypeUnicodeMapping,
+ tokens, fileName, line);
} else if (!cmd->cmp("dropFont")) {
parseDropFont(tokens, fileName, line);
} else if (!cmd->cmp("bind")) {
@@ -1260,8 +1274,12 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
parsePopupMenuCmd(tokens, fileName, line);
} else if (!cmd->cmp("tabStateFile")) {
parseString("tabStateFile", &tabStateFile, tokens, fileName, line);
+ } else if (!cmd->cmp("savePageNumbers")) {
+ parseYesNo("savePageNumbers", &savePageNumbers, tokens, fileName, line);
} else if (!cmd->cmp("printCommands")) {
parseYesNo("printCommands", &printCommands, tokens, fileName, line);
+ } else if (!cmd->cmp("printStatusInfo")) {
+ parseYesNo("printStatusInfo", &printStatusInfo, tokens, fileName, line);
} else if (!cmd->cmp("errQuiet")) {
parseYesNo("errQuiet", &errQuiet, tokens, fileName, line);
} else if (!cmd->cmp("debugLogFile")) {
@@ -1281,8 +1299,6 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
} else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) {
error(errConfig, -1,
"The config file format has changed since Xpdf 0.9x");
- } else if (!cmd->cmp("enableXFA")) {
- error(errConfig, -1, "The enableXFA option is no longer used");
}
}
}
@@ -2115,6 +2131,7 @@ GlobalParams::~GlobalParams() {
deleteGList(keyBindings, KeyBinding);
deleteGList(popupMenuCmds, PopupMenuCmd);
delete tabStateFile;
+ delete debugLogFile;
cMapDirs->startIter(&iter);
while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
@@ -3060,6 +3077,15 @@ GBool GlobalParams::getVectorAntialias() {
return f;
}
+GBool GlobalParams::getImageMaskAntialias() {
+ GBool f;
+
+ lockGlobalParams;
+ f = imageMaskAntialias;
+ unlockGlobalParams;
+ return f;
+}
+
GBool GlobalParams::getAntialiasPrinting() {
GBool f;
@@ -3168,6 +3194,15 @@ GBool GlobalParams::getDrawFormFields() {
return draw;
}
+GBool GlobalParams::getEnableXFA() {
+ GBool xfa;
+
+ lockGlobalParams;
+ xfa = enableXFA;
+ unlockGlobalParams;
+ return xfa;
+}
+
GString *GlobalParams::getPaperColor() {
@@ -3251,6 +3286,15 @@ GBool GlobalParams::getMapExtTrueTypeFontsViaUnicode() {
return map;
}
+GBool GlobalParams::getUseTrueTypeUnicodeMapping() {
+ GBool use;
+
+ lockGlobalParams;
+ use = useTrueTypeUnicodeMapping;
+ unlockGlobalParams;
+ return use;
+}
+
GBool GlobalParams::isDroppedFont(const char *fontName) {
GBool isDropped;
@@ -3321,6 +3365,15 @@ GString *GlobalParams::getTabStateFile() {
return s;
}
+GBool GlobalParams::getSavePageNumbers() {
+ GBool s;
+
+ lockGlobalParams;
+ s = savePageNumbers;
+ unlockGlobalParams;
+ return s;
+}
+
GBool GlobalParams::getPrintCommands() {
GBool p;
@@ -3330,6 +3383,15 @@ GBool GlobalParams::getPrintCommands() {
return p;
}
+GBool GlobalParams::getPrintStatusInfo() {
+ GBool p;
+
+ lockGlobalParams;
+ p = printStatusInfo;
+ unlockGlobalParams;
+ return p;
+}
+
GBool GlobalParams::getErrQuiet() {
// no locking -- this function may get called from inside a locked
// section
@@ -3759,6 +3821,12 @@ void GlobalParams::setPrintCommands(GBool printCommandsA) {
unlockGlobalParams;
}
+void GlobalParams::setPrintStatusInfo(GBool printStatusInfoA) {
+ lockGlobalParams;
+ printStatusInfo = printStatusInfoA;
+ unlockGlobalParams;
+}
+
void GlobalParams::setErrQuiet(GBool errQuietA) {
lockGlobalParams;
errQuiet = errQuietA;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
index 2823ea59421..d72473f2a46 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
@@ -316,6 +316,7 @@ public:
GBool getDisableFreeTypeHinting();
GBool getAntialias();
GBool getVectorAntialias();
+ GBool getImageMaskAntialias();
GBool getAntialiasPrinting();
StrokeAdjustMode getStrokeAdjust();
ScreenType getScreenType();
@@ -328,6 +329,7 @@ public:
GBool getEnablePathSimplification();
GBool getDrawAnnotations();
GBool getDrawFormFields();
+ GBool getEnableXFA();
GBool getOverprintPreview() { return overprintPreview; }
GString *getPaperColor();
GString *getMatteColor();
@@ -340,13 +342,16 @@ public:
GBool getMapNumericCharNames();
GBool getMapUnknownCharNames();
GBool getMapExtTrueTypeFontsViaUnicode();
+ GBool getUseTrueTypeUnicodeMapping();
GBool isDroppedFont(const char *fontName);
GList *getKeyBinding(int code, int mods, int context);
GList *getAllKeyBindings();
int getNumPopupMenuCmds();
PopupMenuCmd *getPopupMenuCmd(int idx);
GString *getTabStateFile();
+ GBool getSavePageNumbers();
GBool getPrintCommands();
+ GBool getPrintStatusInfo();
GBool getErrQuiet();
GString *getDebugLogFile();
void debugLogPrintf(const char *fmt, ...);
@@ -401,6 +406,7 @@ public:
void setMapExtTrueTypeFontsViaUnicode(GBool map);
void setTabStateFile(char *tabStateFileA);
void setPrintCommands(GBool printCommandsA);
+ void setPrintStatusInfo(GBool printStatusInfoA);
void setErrQuiet(GBool errQuietA);
#ifdef _WIN32
@@ -559,6 +565,7 @@ private:
GBool disableFreeTypeHinting; // FreeType hinting disable flag
GBool antialias; // font anti-aliasing enable flag
GBool vectorAntialias; // vector anti-aliasing enable flag
+ GBool imageMaskAntialias; // image mask anti-aliasing enable flag
GBool antialiasPrinting; // allow anti-aliasing when printing
StrokeAdjustMode strokeAdjust; // stroke adjustment mode
ScreenType screenType; // halftone screen type
@@ -572,6 +579,7 @@ private:
enablePathSimplification;
GBool drawAnnotations; // draw annotations or not
GBool drawFormFields; // draw form fields or not
+ GBool enableXFA; // enable XFA form parsing
GBool overprintPreview; // enable overprint preview
GString *paperColor; // paper (page background) color
GString *matteColor; // matte (background outside of page) color
@@ -586,11 +594,17 @@ private:
GBool mapUnknownCharNames; // map unknown char names?
GBool mapExtTrueTypeFontsViaUnicode; // map char codes to GID via Unicode
// for external TrueType fonts?
+ GBool useTrueTypeUnicodeMapping; // use the Unicode cmaps in TrueType
+ // fonts, rather than the PDF
+ // ToUnicode mapping
GHash *droppedFonts; // dropped fonts [int]
GList *keyBindings; // key & mouse button bindings [KeyBinding]
GList *popupMenuCmds; // popup menu commands [PopupMenuCmd]
GString *tabStateFile; // path for the tab state save file
+ GBool savePageNumbers; // save page number when file is closed
+ // and restore page number when opened
GBool printCommands; // print the drawing commands
+ GBool printStatusInfo; // print status info for each page
GBool errQuiet; // suppress error messages?
GString *debugLogFile; // path for debug log file
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
index 6f51ad85190..a077655ef43 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
@@ -2,7 +2,7 @@
//
// HTMLGen.cc
//
-// Copyright 2010 Glyph & Cog, LLC
+// Copyright 2010-2021 Glyph & Cog, LLC
//
//========================================================================
@@ -13,9 +13,8 @@
//~ generic serif/sans-serif/monospace name)
//~ - check that htmlDir exists and is a directory
//~ - links:
-//~ - links to pages
-//~ - links to named destinations
-//~ - links to URLs
+//~ - internal links (to pages, to named destinations)
+//~ - links from non-text content
//~ - rotated text should go in the background image
//~ - metadata
//~ - PDF outline
@@ -35,6 +34,7 @@
#include "SplashBitmap.h"
#include "PDFDoc.h"
#include "GfxFont.h"
+#include "AcroForm.h"
#include "TextOutputDev.h"
#include "SplashOutputDev.h"
#include "ErrorCodes.h"
@@ -196,10 +196,93 @@ public:
//------------------------------------------------------------------------
+class HTMLGenFormFieldInfo {
+public:
+
+ HTMLGenFormFieldInfo(AcroFormField *acroFormFieldA)
+ : acroFormField(acroFormFieldA) {}
+
+ AcroFormField *acroFormField;
+};
+
+//------------------------------------------------------------------------
+
+class Base64Encoder {
+public:
+
+ Base64Encoder(int (*writeFuncA)(void *stream, const char *data, int size),
+ void *streamA);
+ void encode(const unsigned char *data, size_t size);
+ void flush();
+
+private:
+
+ int (*writeFunc)(void *stream, const char *data, int size);
+ void *stream;
+ unsigned char buf[3];
+ int bufLen;
+};
+
+static char base64Chars[65] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+Base64Encoder::Base64Encoder(int (*writeFuncA)(void *stream, const char *data,
+ int size),
+ void *streamA) {
+ writeFunc = writeFuncA;
+ stream = streamA;
+ bufLen = 0;
+}
+
+void Base64Encoder::encode(const unsigned char *data, size_t size) {
+ size_t i = 0;
+ while (1) {
+ while (bufLen < 3) {
+ if (i >= size) {
+ return;
+ }
+ buf[bufLen++] = data[i++];
+ }
+ char out[4];
+ out[0] = base64Chars[(buf[0] >> 2) & 0x3f];
+ out[1] = base64Chars[((buf[0] << 4) | (buf[1] >> 4)) & 0x3f];
+ out[2] = base64Chars[((buf[1] << 2) | (buf[2] >> 6)) & 0x3f];
+ out[3] = base64Chars[buf[2] & 0x3f];
+ writeFunc(stream, out, 4);
+ bufLen = 0;
+ }
+}
+
+void Base64Encoder::flush() {
+ // if bufLen == 0, this does nothing
+ // bufLen should never be 3 here
+ char out[4];
+ if (bufLen == 1) {
+ out[0] = base64Chars[(buf[0] >> 2) & 0x3f];
+ out[1] = base64Chars[(buf[0] << 4) & 0x3f];
+ out[2] = '=';
+ out[3] = '=';
+ writeFunc(stream, out, 4);
+ } else if (bufLen == 2) {
+ out[0] = base64Chars[(buf[0] >> 2) & 0x3f];
+ out[1] = base64Chars[((buf[0] << 4) | (buf[1] >> 4)) & 0x3f];
+ out[2] = base64Chars[(buf[1] << 2) & 0x3f];
+ out[3] = '=';
+ writeFunc(stream, out, 4);
+ }
+}
+
+static int writeToString(void *stream, const char *data, int size) {
+ ((GString *)stream)->append(data, size);
+ return size;
+}
+
+//------------------------------------------------------------------------
+
//------------------------------------------------------------------------
-HTMLGen::HTMLGen(double backgroundResolutionA) {
+HTMLGen::HTMLGen(double backgroundResolutionA, GBool tableMode) {
TextOutputControl textOutControl;
SplashColor paperColor;
@@ -207,12 +290,16 @@ HTMLGen::HTMLGen(double backgroundResolutionA) {
backgroundResolution = backgroundResolutionA;
zoom = 1.0;
+ vStretch = 1.0;
drawInvisibleText = gTrue;
allTextInvisible = gFalse;
extractFontFiles = gFalse;
+ convertFormFields = gFalse;
+ embedBackgroundImage = gFalse;
+ embedFonts = gFalse;
// set up the TextOutputDev
- textOutControl.mode = textOutReadingOrder;
+ textOutControl.mode = tableMode ? textOutTableLayout : textOutReadingOrder;
textOutControl.html = gTrue;
textOutControl.splitRotatedWords = gTrue;
textOut = new TextOutputDev(NULL, &textOutControl, gFalse);
@@ -266,15 +353,18 @@ static int pf(int (*writeFunc)(void *stream, const char *data, int size),
}
struct PNGWriteInfo {
+ Base64Encoder *base64;
int (*writePNG)(void *stream, const char *data, int size);
void *pngStream;
};
static void pngWriteFunc(png_structp png, png_bytep data, png_size_t size) {
- PNGWriteInfo *info;
-
- info = (PNGWriteInfo *)png_get_progressive_ptr(png);
- info->writePNG(info->pngStream, (char *)data, (int)size);
+ PNGWriteInfo *info = (PNGWriteInfo *)png_get_progressive_ptr(png);
+ if (info->base64) {
+ info->base64->encode(data, size);
+ } else {
+ info->writePNG(info->pngStream, (char *)data, (int)size);
+ }
}
int HTMLGen::convertPage(
@@ -304,31 +394,10 @@ int HTMLGen::convertPage(
// generate the background bitmap
splashOut->setSkipText(!allTextInvisible, gFalse);
- doc->displayPage(splashOut, pg, backgroundResolution, backgroundResolution,
+ doc->displayPage(splashOut, pg,
+ backgroundResolution, backgroundResolution * vStretch,
0, gFalse, gTrue, gFalse);
bitmap = splashOut->getBitmap();
- if (!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
- NULL, NULL, NULL)) ||
- !(pngInfo = png_create_info_struct(png))) {
- return errFileIO;
- }
- if (setjmp(png_jmpbuf(png))) {
- return errFileIO;
- }
- writeInfo.writePNG = writePNG;
- writeInfo.pngStream = pngStream;
- png_set_write_fn(png, &writeInfo, pngWriteFunc, NULL);
- png_set_IHDR(png, pngInfo, bitmap->getWidth(), bitmap->getHeight(),
- 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
- png_write_info(png, pngInfo);
- p = bitmap->getDataPtr();
- for (y = 0; y < bitmap->getHeight(); ++y) {
- png_write_row(png, (png_bytep)p);
- p += bitmap->getRowSize();
- }
- png_write_end(png, pngInfo);
- png_destroy_write_struct(&png, &pngInfo);
// page size
if (doc->getPageRotate(pg) == 90 || doc->getPageRotate(pg) == 270) {
@@ -345,12 +414,86 @@ int HTMLGen::convertPage(
text = textOut->takeText();
primaryDir = text->primaryDirectionIsLR() ? 1 : -1;
+ // insert a special character for each form field;
+ // remove existing characters inside field bboxes;
+ // erase background content inside field bboxes
+ formFieldFont = NULL;
+ formFieldInfo = NULL;
+ if (convertFormFields) {
+ AcroForm *form = doc->getCatalog()->getForm();
+ if (form) {
+ formFieldInfo = new GList();
+ formFieldFont = new TextFontInfo();
+ double yTop = doc->getCatalog()->getPage(pg)->getMediaBox()->y2;
+ for (i = 0; i < form->getNumFields(); ++i) {
+ AcroFormField *field = form->getField(i);
+ AcroFormFieldType fieldType = field->getAcroFormFieldType();
+ if (field->getPageNum() == pg &&
+ (fieldType == acroFormFieldText ||
+ fieldType == acroFormFieldCheckbox)) {
+ double llx, lly, urx, ury;
+ field->getBBox(&llx, &lly, &urx, &ury);
+ lly = yTop - lly;
+ ury = yTop - ury;
+
+ // add the field info
+ int fieldIdx = formFieldInfo->getLength();
+ formFieldInfo->append(new HTMLGenFormFieldInfo(field));
+
+ // remove exsting chars
+ text->removeChars(llx, ury, urx, lly, 0.75, 0.5);
+
+ // erase background content
+ int llxI = (int)(llx * backgroundResolution / 72 + 0.5);
+ int llyI = (int)(lly * backgroundResolution * vStretch / 72 + 0.5);
+ int urxI = (int)(urx * backgroundResolution / 72 + 0.5);
+ int uryI = (int)(ury * backgroundResolution * vStretch / 72 + 0.5);
+ llyI += (int)(backgroundResolution * vStretch / 20);
+ if (llxI < 0) {
+ llxI = 0;
+ }
+ if (urxI >= bitmap->getWidth()) {
+ urxI = bitmap->getWidth() - 1;
+ }
+ if (uryI < 0) {
+ uryI = 0;
+ }
+ if (llyI > bitmap->getHeight()) {
+ 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();
+ }
+ }
+
+ // add a special char
+ // (the font size is unused -- 10 is an arbitrary value)
+ text->addSpecialChar(llx, ury, urx, lly,
+ 0, formFieldFont, 10, 0x80000000 + fieldIdx);
+ }
+ }
+ }
+ }
+
// HTML header
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");
pr(writeHTML, htmlStream, "<style type=\"text/css\">\n");
pr(writeHTML, htmlStream, ".txt { white-space:nowrap; }\n");
+ if (convertFormFields) {
+ pr(writeHTML, htmlStream, ".textfield {\n");
+ pr(writeHTML, htmlStream, " border: 0;\n");
+ pr(writeHTML, htmlStream, " padding: 0;\n");
+ pr(writeHTML, htmlStream, " background: #ccccff;\n");
+ pr(writeHTML, htmlStream, "}\n");
+ pr(writeHTML, htmlStream, ".checkbox {\n");
+ pr(writeHTML, htmlStream, "}\n");
+ }
fonts = text->getFonts();
fontScales = (double *)gmallocn(fonts->getLength(), sizeof(double));
for (i = 0; i < fontDefns->getLength(); ++i) {
@@ -363,7 +506,7 @@ int HTMLGen::convertPage(
if (!fontDefn->used && fontDefn->fontFace) {
pr(writeHTML, htmlStream, fontDefn->fontFace->getCString());
}
- pf(writeHTML, htmlStream, "#f{0:d} {{ {1:t} }}\n", i, fontDefn->fontSpec);
+ pf(writeHTML, htmlStream, ".f{0:d} {{ {1:t} }}\n", i, fontDefn->fontSpec);
fontScales[i] = fontDefn->scale;
fontDefn->used = gTrue;
}
@@ -374,15 +517,59 @@ int HTMLGen::convertPage(
} else {
pr(writeHTML, htmlStream, "<body dir=\"rtl\">\n");
}
+
+ // background image element (part 1)
if (primaryDir >= 0) {
- pf(writeHTML, htmlStream, "<img id=\"background\" style=\"position:absolute; left:0px; top:0px;\" width=\"{0:d}\" height=\"{1:d}\" src=\"{2:s}\">\n",
- (int)(pageW * zoom), (int)(pageH * zoom), pngURL);
+ pf(writeHTML, htmlStream, "<img style=\"position:absolute; left:0px; top:0px;\" width=\"{0:d}\" height=\"{1:d}\" ",
+ (int)(pageW * zoom), (int)(pageH * zoom * vStretch));
+ } else {
+ pf(writeHTML, htmlStream, "<img style=\"position:absolute; right:0px; top:0px;\" width=\"{0:d}\" height=\"{1:d}\" ",
+ (int)(pageW * zoom), (int)(pageH * zoom * vStretch));
+ }
+ if (embedBackgroundImage) {
+ pr(writeHTML, htmlStream, "src=\"data:image/png;base64,\n");
+ writeInfo.base64 = new Base64Encoder(writeHTML, htmlStream);
+ writeInfo.writePNG = NULL;
+ writeInfo.pngStream = NULL;
} else {
- pf(writeHTML, htmlStream, "<img id=\"background\" style=\"position:absolute; right:0px; top:0px;\" width=\"{0:d}\" height=\"{1:d}\" src=\"{2:s}\">\n",
- (int)(pageW * zoom), (int)(pageH * zoom), pngURL);
+ pf(writeHTML, htmlStream, "src=\"{0:s}\"", pngURL);
+ writeInfo.base64 = NULL;
+ writeInfo.writePNG = writePNG;
+ writeInfo.pngStream = pngStream;
}
+ // background image data - writing to a separate file, or embedding
+ // with base64 encoding
+ if (!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
+ NULL, NULL, NULL)) ||
+ !(pngInfo = png_create_info_struct(png))) {
+ return errFileIO;
+ }
+ if (setjmp(png_jmpbuf(png))) {
+ return errFileIO;
+ }
+ png_set_write_fn(png, &writeInfo, pngWriteFunc, NULL);
+ png_set_IHDR(png, pngInfo, bitmap->getWidth(), bitmap->getHeight(),
+ 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+ png_write_info(png, pngInfo);
+ p = bitmap->getDataPtr();
+ for (y = 0; y < bitmap->getHeight(); ++y) {
+ png_write_row(png, (png_bytep)p);
+ p += bitmap->getRowSize();
+ }
+ png_write_end(png, pngInfo);
+ png_destroy_write_struct(&png, &pngInfo);
+ if (embedBackgroundImage) {
+ writeInfo.base64->flush();
+ delete writeInfo.base64;
+ }
+
+ // background image element (part 2)
+ pr(writeHTML, htmlStream, "\">\n");
+
// generate the HTML text
+ nextFieldID = 0;
cols = text->makeColumns();
for (colIdx = 0; colIdx < cols->getLength(); ++colIdx) {
col = (TextColumn *)cols->get(colIdx);
@@ -416,11 +603,11 @@ int HTMLGen::convertPage(
if (primaryDir >= 0) {
pf(writeHTML, htmlStream, "<div class=\"txt\" style=\"position:absolute; left:{0:d}px; top:{1:d}px;\">{2:t}</div>\n",
(int)(line->getXMin() * zoom),
- (int)(line->getYMin() * zoom), s);
+ (int)(line->getYMin() * zoom * vStretch), s);
} else {
pf(writeHTML, htmlStream, "<div class=\"txt\" style=\"position:absolute; right:{0:d}px; top:{1:d}px;\">{2:t}</div>\n",
(int)((pageW - line->getXMax()) * zoom),
- (int)(line->getYMin() * zoom), s);
+ (int)(line->getYMin() * zoom * vStretch), s);
}
delete s;
}
@@ -429,6 +616,14 @@ int HTMLGen::convertPage(
gfree(fontScales);
delete text;
deleteGList(cols, TextColumn);
+ if (formFieldFont) {
+ delete formFieldFont;
+ formFieldFont = NULL;
+ }
+ if (formFieldInfo) {
+ deleteGList(formFieldInfo, HTMLGenFormFieldInfo);
+ formFieldInfo = NULL;
+ }
// HTML trailer
pr(writeHTML, htmlStream, "</body>\n");
@@ -471,134 +666,200 @@ int HTMLGen::findDirSpan(GList *words, int firstWordIdx, int primaryDir,
void HTMLGen::appendSpans(GList *words, int firstWordIdx, int lastWordIdx,
int primaryDir, int spanDir,
double base, GBool dropCapLine, GString *s) {
- TextWord *word0, *word1;
- VerticalAlignment vertAlign0, vertAlign1;
- const char *dirTag;
- Unicode u;
- GBool invisible, sp;
- double r0, g0, b0, r1, g1, b1;
- double base1;
- int wordIdx, t, i;
+ if (allTextInvisible && !drawInvisibleText) {
+ return;
+ }
if (spanDir != primaryDir) {
- t = firstWordIdx;
+ int t = firstWordIdx;
firstWordIdx = lastWordIdx;
lastWordIdx = t;
}
- word0 = NULL;
- vertAlign0 = vertAlignBaseline; // make gcc happy
- r0 = g0 = b0 = 0; // make gcc happy
- for (wordIdx = firstWordIdx;
- (spanDir >= 0) ? wordIdx <= lastWordIdx : wordIdx >= lastWordIdx;
- wordIdx += spanDir) {
- word1 = (TextWord *)words->get(wordIdx);
- invisible = allTextInvisible || word1->isInvisible() || word1->isRotated();
- if (!drawInvisibleText && invisible) {
- continue;
- }
- word1->getColor(&r1, &g1, &b1);
- base1 = word1->getBaseline();
- if (dropCapLine) {
- //~ this will fail if there are subscripts or superscripts in
- //~ the first line of a paragraph with a drop cap
- vertAlign1 = vertAlignTop;
- } else if (base1 - base < -1) {
- vertAlign1 = vertAlignSuper;
- } else if (base1 - base > 1) {
- vertAlign1 = vertAlignSub;
- } else {
- vertAlign1 = vertAlignBaseline;
- }
- if (!word0 ||
- word1->getFontInfo() != word0->getFontInfo() ||
- word1->getFontSize() != word0->getFontSize() ||
- word1->isInvisible() != word0->isInvisible() ||
- word1->isRotated() != word0->isRotated() ||
- vertAlign1 != vertAlign0 ||
- r1 != r0 || g1 != g0 || b1 != b0) {
- if (word0) {
- s->append("</span>");
- }
- for (i = 0; i < fonts->getLength(); ++i) {
- if (word1->getFontInfo() == (TextFontInfo *)fonts->get(i)) {
- break;
+ int wordIdx = firstWordIdx;
+ while ((spanDir >= 0) ? wordIdx <= lastWordIdx
+ : wordIdx >= lastWordIdx) {
+ TextWord *word0 = (TextWord *)words->get(wordIdx);
+
+ // form field(s): generate <input> element(s)
+ if (convertFormFields && word0->getFontInfo() == formFieldFont) {
+ for (int i = (spanDir >= 0) ? 0 : word0->getLength() - 1;
+ (spanDir >= 0) ? i < word0->getLength() : i >= 0;
+ i += spanDir) {
+ int fieldIdx = word0->getChar(0) - 0x80000000;
+ if (fieldIdx >= 0 && fieldIdx < formFieldInfo->getLength()) {
+ HTMLGenFormFieldInfo *ffi =
+ (HTMLGenFormFieldInfo *)formFieldInfo->get(fieldIdx);
+ AcroFormField *field = ffi->acroFormField;
+ AcroFormFieldType fieldType = field->getAcroFormFieldType();
+ double llx, lly, urx, ury;
+ field->getBBox(&llx, &lly, &urx, &ury);
+ int width = (int)(urx - llx);
+ Ref fontID;
+ double fontSize;
+ field->getFont(&fontID, &fontSize);
+ if (fontSize == 0) {
+ fontSize = 12;
+ }
+ if (fieldType == acroFormFieldText) {
+ s->appendf("<input type=\"text\" class=\"textfield\" id=\"textfield{0:d}\" style=\"width:{1:d}px; font-size:{2:d}px;\">", nextFieldID, width, (int)(fontSize + 0.5));
+ ++nextFieldID;
+ } else if (fieldType == acroFormFieldCheckbox) {
+ s->appendf("<input type=\"checkbox\" class=\"checkbox\" id=\"checkbox{0:d}\" style=\"width:{1:d}px; font-size:{2:d}px;\">", nextFieldID, width, (int)(fontSize + 0.5));
+ ++nextFieldID;
+ }
}
}
- // we force spans to be LTR or RTL; this is a kludge, but it's
- // far easier than implementing the full Unicode bidi algorithm
- if (spanDir == primaryDir) {
- dirTag = "";
- } else if (spanDir < 0) {
- dirTag = " dir=\"rtl\"";
- } else {
- dirTag = " dir=\"ltr\"";
+
+ if (word0->getSpaceAfter()) {
+ s->append(' ');
}
- s->appendf("<span id=\"f{0:d}\"{1:s} style=\"font-size:{2:d}px;vertical-align:{3:s};{4:s}color:rgba({5:d},{6:d},{7:d},{8:d});\">",
- i,
- dirTag,
- (int)(fontScales[i] * word1->getFontSize() * zoom),
- vertAlignNames[vertAlign1],
- (dropCapLine && wordIdx == 0) ? "line-height:75%;" : "",
- (int)(r1 * 255), (int)(g1 * 255), (int)(b1 * 255),
- invisible ? 0 : 1);
- }
- // add a space before the word, if needed
- // -- this only happens with the first word in a reverse section
- if (spanDir != primaryDir && wordIdx == firstWordIdx) {
- if (spanDir >= 0) {
- if (wordIdx > 0) {
- sp = ((TextWord *)words->get(wordIdx - 1))->getSpaceAfter();
+ wordIdx += spanDir;
+
+ // skip invisible words
+ } else if (!drawInvisibleText &&
+ (word0->isInvisible() || word0->isRotated())) {
+ wordIdx += spanDir;
+
+ // generate a <span> containing one or more words
+ } else {
+
+ double r0 = 0, g0 = 0, b0 = 0; // make gcc happy
+ VerticalAlignment vertAlign0 = vertAlignBaseline; // make gcc happy
+ GString *linkURI0 = NULL;
+
+ GBool invisible = word0->isInvisible() || word0->isRotated();
+
+ do {
+ TextWord *word1 = (TextWord *)words->get(wordIdx);
+
+ // get word parameters
+ double r1, g1, b1;
+ word0->getColor(&r1, &g1, &b1);
+ double base1 = word1->getBaseline();
+ VerticalAlignment vertAlign1;
+ if (dropCapLine) {
+ //~ this will fail if there are subscripts or superscripts in
+ //~ the first line of a paragraph with a drop cap
+ vertAlign1 = vertAlignTop;
+ } else if (base1 - base < -1) {
+ vertAlign1 = vertAlignSuper;
+ } else if (base1 - base > 1) {
+ vertAlign1 = vertAlignSub;
} else {
+ vertAlign1 = vertAlignBaseline;
+ }
+ GString *linkURI1 = word1->getLinkURI();
+
+ // start of span
+ if (word1 == word0) {
+ r0 = r1;
+ g0 = g1;
+ b0 = b1;
+ vertAlign0 = vertAlign1;
+ linkURI0 = linkURI1;
+
+ int i;
+ for (i = 0; i < fonts->getLength(); ++i) {
+ if (word1->getFontInfo() == (TextFontInfo *)fonts->get(i)) {
+ break;
+ }
+ }
+ if (linkURI1) {
+ s->appendf("<a href=\"{0:t}\">", linkURI0);
+ }
+ // we force spans to be LTR or RTL; this is a kludge, but it's
+ // far easier than implementing the full Unicode bidi algorithm
+ const char *dirTag;
+ if (spanDir == primaryDir) {
+ dirTag = "";
+ } else if (spanDir < 0) {
+ dirTag = " dir=\"rtl\"";
+ } else {
+ dirTag = " dir=\"ltr\"";
+ }
+ s->appendf("<span class=\"f{0:d}\"{1:s} style=\"font-size:{2:d}px;vertical-align:{3:s};{4:s}color:rgba({5:d},{6:d},{7:d},{8:d});\">",
+ i,
+ dirTag,
+ (int)(fontScales[i] * word1->getFontSize() * zoom),
+ vertAlignNames[vertAlign1],
+ (dropCapLine && wordIdx == 0) ? "line-height:75%;" : "",
+ (int)(r0 * 255), (int)(g0 * 255), (int)(b0 * 255),
+ invisible ? 0 : 1);
+
+ // end of span
+ } else if (word1->getFontInfo() != word0->getFontInfo() ||
+ word1->getFontSize() != word0->getFontSize() ||
+ word1->isInvisible() != word0->isInvisible() ||
+ word1->isRotated() != word0->isRotated() ||
+ vertAlign1 != vertAlign0 ||
+ r1 != r0 || g1 != g0 || b1 != b0 ||
+ linkURI1 != linkURI0) {
+ break;
+ }
+
+ // add a space before the word, if needed
+ // -- this only happens with the first word in a reverse section
+ if (spanDir != primaryDir && wordIdx == firstWordIdx) {
+ GBool sp;
+ if (spanDir >= 0) {
+ if (wordIdx > 0) {
+ sp = ((TextWord *)words->get(wordIdx - 1))->getSpaceAfter();
+ } else {
+ sp = gFalse;
+ }
+ } else {
+ sp = word1->getSpaceAfter();
+ }
+ if (sp) {
+ s->append(' ');
+ }
+ }
+
+ // generate the word text
+ for (int i = (spanDir >= 0) ? 0 : word1->getLength() - 1;
+ (spanDir >= 0) ? i < word1->getLength() : i >= 0;
+ i += spanDir) {
+ Unicode u = word1->getChar(i);
+ if (u >= privateUnicodeMapStart &&
+ u <= privateUnicodeMapEnd &&
+ privateUnicodeMap[u - privateUnicodeMapStart]) {
+ u = privateUnicodeMap[u - privateUnicodeMapStart];
+ }
+ appendUTF8(u, s);
+ }
+
+ // add a space after the word, if needed
+ // -- there is never a space after the last word in a reverse
+ // section (this will be handled as a space after the last
+ // word in the previous primary-direction section)
+ GBool sp;
+ if (spanDir != primaryDir && wordIdx == lastWordIdx) {
sp = gFalse;
+ } else if (spanDir >= 0) {
+ sp = word1->getSpaceAfter();
+ } else {
+ if (wordIdx > 0) {
+ sp = ((TextWord *)words->get(wordIdx - 1))->getSpaceAfter();
+ } else {
+ sp = gFalse;
+ }
+ }
+ if (sp) {
+ s->append(' ');
}
- } else {
- sp = word1->getSpaceAfter();
- }
- if (sp) {
- s->append(' ');
- }
- }
- for (i = (spanDir >= 0) ? 0 : word1->getLength() - 1;
- (spanDir >= 0) ? i < word1->getLength() : i >= 0;
- i += spanDir) {
- u = word1->getChar(i);
- if (u >= privateUnicodeMapStart &&
- u <= privateUnicodeMapEnd &&
- privateUnicodeMap[u - privateUnicodeMapStart]) {
- u = privateUnicodeMap[u - privateUnicodeMapStart];
- }
- appendUTF8(u, s);
- }
+ wordIdx += spanDir;
+ } while ((spanDir >= 0) ? wordIdx <= lastWordIdx
+ : wordIdx >= lastWordIdx);
- // add a space after the word, if needed
- // -- there is never a space after the last word in a reverse
- // section (this will be handled as a space after the last word
- // in the previous primary-direction section)
- if (spanDir != primaryDir && wordIdx == lastWordIdx) {
- sp = gFalse;
- } else if (spanDir >= 0) {
- sp = word1->getSpaceAfter();
- } else {
- if (wordIdx > 0) {
- sp = ((TextWord *)words->get(wordIdx - 1))->getSpaceAfter();
- } else {
- sp = gFalse;
+ s->append("</span>");
+ if (linkURI0) {
+ s->append("</a>");
}
}
- if (sp) {
- s->append(' ');
- }
-
- word0 = word1;
- vertAlign0 = vertAlign1;
- r0 = r1;
- g0 = g1;
- b0 = b1;
}
- s->append("</span>");
}
void HTMLGen::appendUTF8(Unicode u, GString *s) {
@@ -694,36 +955,69 @@ HTMLGenFontDefn *HTMLGen::getFontFile(TextFontInfo *font,
gfxFont = GfxFont::makeFont(doc->getXRef(), "F", id, fontObj.getDict());
webFont = new WebFont(gfxFont, doc->getXRef());
fontDefn = NULL;
+ fontFace = NULL;
if (webFont->canWriteTTF()) {
- fontFile = GString::format("{0:d}.ttf", nextFontFaceIdx);
- fontPath = GString::format("{0:s}/{1:t}", htmlDir, fontFile);
- if (webFont->writeTTF(fontPath->getCString())) {
- fontFace = GString::format("@font-face {{ font-family: ff{0:d}; src: url(\"{1:t}\"); }}\n",
- nextFontFaceIdx, fontFile);
+ if (embedFonts) {
+ GString *ttfData = webFont->getTTFData();
+ if (ttfData) {
+ fontFace = GString::format("@font-face {{ font-family: ff{0:d}; src: url(\"data:font/ttf;base64,",
+ nextFontFaceIdx);
+ Base64Encoder enc(writeToString, fontFace);
+ enc.encode((unsigned char *)ttfData->getCString(),
+ (size_t)ttfData->getLength());
+ enc.flush();
+ fontFace->append("\"); }\n");
+ delete ttfData;
+ }
+ } else {
+ fontFile = GString::format("{0:d}.ttf", nextFontFaceIdx);
+ fontPath = GString::format("{0:s}/{1:t}", htmlDir, fontFile);
+ if (webFont->writeTTF(fontPath->getCString())) {
+ fontFace = GString::format("@font-face {{ font-family: ff{0:d}; src: url(\"{1:t}\"); }}\n",
+ nextFontFaceIdx, fontFile);
+ }
+ delete fontPath;
+ delete fontFile;
+ }
+ if (fontFace) {
getFontDetails(font, &family, &weight, &style, &scale);
fontSpec = GString::format("font-family:ff{0:d},{1:s}; font-weight:{2:s}; font-style:{3:s};",
nextFontFaceIdx, family, weight, style);
++nextFontFaceIdx;
fontDefn = new HTMLGenFontDefn(id, fontFace, fontSpec, 1.0);
}
- delete fontPath;
- delete fontFile;
} else if (webFont->canWriteOTF()) {
- fontFile = GString::format("{0:d}.otf", nextFontFaceIdx);
- fontPath = GString::format("{0:s}/{1:t}", htmlDir, fontFile);
- if (webFont->writeOTF(fontPath->getCString())) {
- fontFace = GString::format("@font-face {{ font-family: ff{0:d}; src: url(\"{1:t}\"); }}\n",
- nextFontFaceIdx, fontFile);
+ if (embedFonts) {
+ GString *otfData = webFont->getOTFData();
+ if (otfData) {
+ fontFace = GString::format("@font-face {{ font-family: ff{0:d}; src: url(\"data:font/otf;base64,",
+ nextFontFaceIdx);
+ Base64Encoder enc(writeToString, fontFace);
+ enc.encode((unsigned char *)otfData->getCString(),
+ (size_t)otfData->getLength());
+ enc.flush();
+ fontFace->append("\"); }\n");
+ delete otfData;
+ }
+ } else {
+ fontFile = GString::format("{0:d}.otf", nextFontFaceIdx);
+ fontPath = GString::format("{0:s}/{1:t}", htmlDir, fontFile);
+ if (webFont->writeOTF(fontPath->getCString())) {
+ fontFace = GString::format("@font-face {{ font-family: ff{0:d}; src: url(\"{1:t}\"); }}\n",
+ nextFontFaceIdx, fontFile);
+ }
+ delete fontPath;
+ delete fontFile;
+ }
+ if (fontFace) {
getFontDetails(font, &family, &weight, &style, &scale);
fontSpec = GString::format("font-family:ff{0:d},{1:s}; font-weight:{2:s}; font-style:{3:s};",
nextFontFaceIdx, family, weight, style);
++nextFontFaceIdx;
fontDefn = new HTMLGenFontDefn(id, fontFace, fontSpec, 1.0);
}
- delete fontPath;
- delete fontFile;
}
delete webFont;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
index d09eea3f266..66ee2d27406 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
@@ -2,7 +2,7 @@
//
// HTMLGen.h
//
-// Copyright 2010 Glyph & Cog, LLC
+// Copyright 2010-2021 Glyph & Cog, LLC
//
//========================================================================
@@ -27,7 +27,7 @@ class HTMLGenFontDefn;
class HTMLGen {
public:
- HTMLGen(double backgroundResolutionA);
+ HTMLGen(double backgroundResolutionA, GBool tableMode);
~HTMLGen();
GBool isOk() { return ok; }
@@ -39,6 +39,8 @@ public:
double getZoom() { return zoom; }
void setZoom(double zoomA) { zoom = zoomA; }
+ void setVStretch(double vStretchA) { vStretch = vStretchA; }
+
GBool getDrawInvisibleText() { return drawInvisibleText; }
void setDrawInvisibleText(GBool drawInvisibleTextA)
{ drawInvisibleText = drawInvisibleTextA; }
@@ -50,6 +52,15 @@ public:
void setExtractFontFiles(GBool extractFontFilesA)
{ extractFontFiles = extractFontFilesA; }
+ void setConvertFormFields(GBool convertFormFieldsA)
+ { convertFormFields = convertFormFieldsA; }
+
+ void setEmbedBackgroundImage(GBool embedBackgroundImageA)
+ { embedBackgroundImage = embedBackgroundImageA; }
+
+ void setEmbedFonts(GBool embedFontsA)
+ { embedFonts = embedFontsA; }
+
void startDoc(PDFDoc *docA);
int convertPage(int pg, const char *pngURL, const char *htmlDir,
int (*writeHTML)(void *stream, const char *data, int size),
@@ -74,9 +85,13 @@ private:
double backgroundResolution;
double zoom;
+ double vStretch;
GBool drawInvisibleText;
GBool allTextInvisible;
GBool extractFontFiles;
+ GBool convertFormFields;
+ GBool embedBackgroundImage;
+ GBool embedFonts;
PDFDoc *doc;
TextOutputDev *textOut;
@@ -88,6 +103,10 @@ private:
GList *fontDefns; // [HTMLGenFontDefn]
int nextFontFaceIdx;
+ TextFontInfo *formFieldFont;
+ GList *formFieldInfo; // [HTMLGenFormFieldInfo]
+ int nextFieldID;
+
GBool ok;
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
index 4c4e5183026..02450b4f816 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
@@ -1147,6 +1147,7 @@ JBIG2CodeTable::~JBIG2CodeTable() {
JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStreamA):
FilterStream(strA)
{
+ decoded = gFalse;
pageBitmap = NULL;
arithDecoder = new JArithmeticDecoder();
@@ -1205,40 +1206,9 @@ Stream *JBIG2Stream::copy() {
}
void JBIG2Stream::reset() {
- GList *t;
-
segments = new GList();
globalSegments = new GList();
-
- // read the globals stream
- if (globalsStream.isStream()) {
- curStr = globalsStream.getStream();
- curStr->reset();
- arithDecoder->setStream(curStr);
- huffDecoder->setStream(curStr);
- mmrDecoder->setStream(curStr);
- readSegments();
- curStr->close();
- // swap the newly read segments list into globalSegments
- t = segments;
- segments = globalSegments;
- globalSegments = t;
- }
-
- // read the main stream
- curStr = str;
- curStr->reset();
- arithDecoder->setStream(curStr);
- huffDecoder->setStream(curStr);
- mmrDecoder->setStream(curStr);
- readSegments();
-
- if (pageBitmap) {
- dataPtr = pageBitmap->getDataPtr();
- dataEnd = dataPtr + pageBitmap->getDataSize();
- } else {
- dataPtr = dataEnd = NULL;
- }
+ decoded = gFalse;
}
void JBIG2Stream::close() {
@@ -1259,6 +1229,9 @@ void JBIG2Stream::close() {
}
int JBIG2Stream::getChar() {
+ if (!decoded) {
+ decodeImage();
+ }
if (dataPtr && dataPtr < dataEnd) {
return (*dataPtr++ ^ 0xff) & 0xff;
}
@@ -1266,6 +1239,9 @@ int JBIG2Stream::getChar() {
}
int JBIG2Stream::lookChar() {
+ if (!decoded) {
+ decodeImage();
+ }
if (dataPtr && dataPtr < dataEnd) {
return (*dataPtr ^ 0xff) & 0xff;
}
@@ -1275,6 +1251,9 @@ int JBIG2Stream::lookChar() {
int JBIG2Stream::getBlock(char *blk, int size) {
int n, i;
+ if (!decoded) {
+ decodeImage();
+ }
if (size <= 0) {
return 0;
}
@@ -1298,6 +1277,42 @@ GBool JBIG2Stream::isBinary(GBool last) {
return str->isBinary(gTrue);
}
+void JBIG2Stream::decodeImage() {
+ GList *t;
+
+ // read the globals stream
+ if (globalsStream.isStream()) {
+ curStr = globalsStream.getStream();
+ curStr->reset();
+ arithDecoder->setStream(curStr);
+ huffDecoder->setStream(curStr);
+ mmrDecoder->setStream(curStr);
+ readSegments();
+ curStr->close();
+ // swap the newly read segments list into globalSegments
+ t = segments;
+ segments = globalSegments;
+ globalSegments = t;
+ }
+
+ // read the main stream
+ curStr = str;
+ curStr->reset();
+ arithDecoder->setStream(curStr);
+ huffDecoder->setStream(curStr);
+ mmrDecoder->setStream(curStr);
+ readSegments();
+
+ if (pageBitmap) {
+ dataPtr = pageBitmap->getDataPtr();
+ dataEnd = dataPtr + pageBitmap->getDataSize();
+ } else {
+ dataPtr = dataEnd = NULL;
+ }
+
+ decoded = gTrue;
+}
+
void JBIG2Stream::readSegments() {
Guint segNum, segFlags, segType, page, segLength;
Guint refFlags, nRefSegs;
@@ -2042,7 +2057,14 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
for (i = 0; i < nRefSegs; ++i) {
if ((seg = findSegment(refSegs[i]))) {
if (seg->getType() == jbig2SegSymbolDict) {
- numSyms += ((JBIG2SymbolDict *)seg)->getSize();
+ Guint segSize = ((JBIG2SymbolDict *)seg)->getSize();
+ if (segSize > INT_MAX || numSyms > INT_MAX - segSize) {
+ error(errSyntaxError, getPos(),
+ "Too many symbols in JBIG2 text region");
+ delete codeTables;
+ return;
+ }
+ numSyms += segSize;
} else if (seg->getType() == jbig2SegCodeTable) {
codeTables->append(seg);
}
@@ -3933,6 +3955,11 @@ void JBIG2Stream::readPageInfoSeg(Guint length) {
pageDefPixel = (flags >> 2) & 1;
defCombOp = (flags >> 3) & 3;
+ // this will only happen if there are multiple page info segments
+ if (pageBitmap) {
+ delete pageBitmap;
+ }
+
// allocate the page bitmap
if (pageH == 0xffffffff) {
curPageH = striping & 0x7fff;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
index cca722b4bfc..bb44ba1ab01 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
@@ -48,6 +48,7 @@ public:
private:
+ void decodeImage();
void readSegments();
GBool readSymbolDictSeg(Guint segNum, Guint length,
Guint *refSegs, Guint nRefSegs);
@@ -117,6 +118,7 @@ private:
GBool readULong(Guint *x);
GBool readLong(int *x);
+ GBool decoded;
Object globalsStream;
Guint pageW, pageH, curPageH;
Guint pageDefPixel;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
index d9c295bb12c..a1f7395dd57 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
@@ -230,6 +230,7 @@ JPXStream::JPXStream(Stream *strA):
{
bufStr = new BufStream(str, 3);
+ decoded = gFalse;
nComps = 0;
bpc = NULL;
width = height = 0;
@@ -270,15 +271,7 @@ Stream *JPXStream::copy() {
void JPXStream::reset() {
img.ySize = 0;
bufStr->reset();
- if (readBoxes() == jpxDecodeFatalError) {
- // readBoxes reported an error, so we go immediately to EOF
- curY = img.ySize >> reduction;
- } else {
- curY = img.yOffsetR;
- }
- curX = img.xOffsetR;
- curComp = 0;
- readBufLen = 0;
+ decoded = gFalse;
}
void JPXStream::close() {
@@ -363,9 +356,25 @@ void JPXStream::close() {
bufStr->close();
}
+void JPXStream::decodeImage() {
+ if (readBoxes() == jpxDecodeFatalError) {
+ // readBoxes reported an error, so we go immediately to EOF
+ curY = img.ySize >> reduction;
+ } else {
+ curY = img.yOffsetR;
+ }
+ curX = img.xOffsetR;
+ curComp = 0;
+ readBufLen = 0;
+ decoded = gTrue;
+}
+
int JPXStream::getChar() {
int c;
+ if (!decoded) {
+ decodeImage();
+ }
if (readBufLen < 8) {
fillReadBuf();
}
@@ -387,6 +396,9 @@ int JPXStream::getChar() {
int JPXStream::lookChar() {
int c;
+ if (!decoded) {
+ decodeImage();
+ }
if (readBufLen < 8) {
fillReadBuf();
}
@@ -420,10 +432,18 @@ void JPXStream::fillReadBuf() {
#else
tileComp = &img.tiles[tileIdx].tileComps[havePalette ? 0 : curComp];
#endif
- tx = jpxFloorDiv(curX - jpxCeilDivPow2(img.tiles[tileIdx].x0, reduction),
- tileComp->hSep);
- ty = jpxFloorDiv(curY - jpxCeilDivPow2(img.tiles[tileIdx].y0, reduction),
- tileComp->vSep);
+ tx = jpxFloorDiv(curX, tileComp->hSep);
+ if (tx < tileComp->x0r) {
+ tx = 0;
+ } else {
+ tx -= tileComp->x0r;
+ }
+ ty = jpxFloorDiv(curY, tileComp->vSep);
+ if (ty < tileComp->y0r) {
+ ty = 0;
+ } else {
+ ty -= tileComp->y0r;
+ }
pix = (int)tileComp->data[ty * tileComp->w + tx];
pixBits = tileComp->prec;
eol = gFalse;
@@ -1061,6 +1081,12 @@ JPXDecodeResult JPXStream::readCodestream(Guint len) {
error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
return jpxDecodeFatalError;
}
+ if (r > 0 && ((precinctSize & 0x0f) == 0 ||
+ (precinctSize & 0xf0) == 0)) {
+ error(errSyntaxError, getPos(),
+ "Invalid precinct size in JPX COD marker segment");
+ return jpxDecodeFatalError;
+ }
img.tiles[0].tileComps[0].resLevels[r].precinctWidth =
precinctSize & 0x0f;
img.tiles[0].tileComps[0].resLevels[r].precinctHeight =
@@ -1135,6 +1161,12 @@ JPXDecodeResult JPXStream::readCodestream(Guint len) {
error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
return jpxDecodeFatalError;
}
+ if (r > 0 && ((precinctSize & 0x0f) == 0 ||
+ (precinctSize & 0xf0) == 0)) {
+ error(errSyntaxError, getPos(),
+ "Invalid precinct size in JPX COD marker segment");
+ return jpxDecodeFatalError;
+ }
img.tiles[0].tileComps[comp].resLevels[r].precinctWidth =
precinctSize & 0x0f;
img.tiles[0].tileComps[comp].resLevels[r].precinctHeight =
@@ -1579,6 +1611,12 @@ GBool JPXStream::readTilePart() {
error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
return gFalse;
}
+ if (r > 0 && ((precinctSize & 0x0f) == 0 ||
+ (precinctSize & 0xf0) == 0)) {
+ error(errSyntaxError, getPos(),
+ "Invalid precinct size in JPX COD marker segment");
+ return gFalse;
+ }
img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth =
precinctSize & 0x0f;
img.tiles[tileIdx].tileComps[0].resLevels[r].precinctHeight =
@@ -1643,6 +1681,12 @@ GBool JPXStream::readTilePart() {
error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
return gFalse;
}
+ if (r > 0 && ((precinctSize & 0x0f) == 0 ||
+ (precinctSize & 0xf0) == 0)) {
+ error(errSyntaxError, getPos(),
+ "Invalid precinct size in JPX COD marker segment");
+ return gFalse;
+ }
img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth =
precinctSize & 0x0f;
img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctHeight =
@@ -1886,9 +1930,9 @@ GBool JPXStream::readTilePart() {
for (comp = 0; comp < img.nComps; ++comp) {
tileComp = &img.tiles[tileIdx].tileComps[comp];
qStyle = tileComp->quantStyle & 0x1f;
- if ((qStyle == 0 && tileComp->nQuantSteps < 3 * tileComp->nDecompLevels) ||
+ if ((qStyle == 0 && tileComp->nQuantSteps < 3 * tileComp->nDecompLevels + 1) ||
(qStyle == 1 && tileComp->nQuantSteps < 1) ||
- (qStyle == 2 && tileComp->nQuantSteps < 3 * tileComp->nDecompLevels)) {
+ (qStyle == 2 && tileComp->nQuantSteps < 3 * tileComp->nDecompLevels + 1)) {
error(errSyntaxError, getPos(), "Too few quant steps in JPX tile part");
return gFalse;
}
@@ -1917,6 +1961,7 @@ GBool JPXStream::readTilePart() {
tile->layer = 0;
tile->done = gFalse;
tile->maxNDecompLevels = 0;
+ tile->maxNPrecincts = 0;
for (comp = 0; comp < img.nComps; ++comp) {
tileComp = &tile->tileComps[comp];
if (tileComp->nDecompLevels > tile->maxNDecompLevels) {
@@ -1926,11 +1971,12 @@ GBool JPXStream::readTilePart() {
tileComp->y0 = jpxCeilDiv(tile->y0, tileComp->vSep);
tileComp->x1 = jpxCeilDiv(tile->x1, tileComp->hSep);
tileComp->y1 = jpxCeilDiv(tile->y1, tileComp->vSep);
- tileComp->w = jpxCeilDivPow2(tileComp->x1, reduction)
- - jpxCeilDivPow2(tileComp->x0, reduction);
- tileComp->h = jpxCeilDivPow2(tileComp->y1, reduction)
- - jpxCeilDivPow2(tileComp->y0, reduction);
- if (tileComp->w == 0 || tileComp->h == 0) {
+ tileComp->x0r = jpxCeilDivPow2(tileComp->x0, reduction);
+ tileComp->w = jpxCeilDivPow2(tileComp->x1, reduction) - tileComp->x0r;
+ tileComp->y0r = jpxCeilDivPow2(tileComp->y0, reduction);
+ tileComp->h = jpxCeilDivPow2(tileComp->y1, reduction) - tileComp->y0r;
+ if (tileComp->w == 0 || tileComp->h == 0 ||
+ tileComp->w > INT_MAX / tileComp->h) {
error(errSyntaxError, getPos(),
"Invalid tile size or sample separation in JPX stream");
return gFalse;
@@ -2008,6 +2054,9 @@ GBool JPXStream::readTilePart() {
resLevel->nPrecincts = (preCol1 - preCol0) * (preRow1 - preRow0);
resLevel->precincts = (JPXPrecinct *)gmallocn(resLevel->nPrecincts,
sizeof(JPXPrecinct));
+ if (resLevel->nPrecincts > tile->maxNPrecincts) {
+ tile->maxNPrecincts = resLevel->nPrecincts;
+ }
for (pre = 0; pre < resLevel->nPrecincts; ++pre) {
resLevel->precincts[pre].subbands = NULL;
}
@@ -2169,14 +2218,15 @@ GBool JPXStream::readTilePartData(Guint tileIdx,
tile = &img.tiles[tileIdx];
- // if the tile is finished, just skip this tile part
- if (tile->done) {
- bufStr->discardChars(tilePartLen);
- return gTrue;
- }
-
// read all packets from this tile-part
while (1) {
+
+ // if the tile is finished, skip any remaining data
+ if (tile->done) {
+ bufStr->discardChars(tilePartLen);
+ return gTrue;
+ }
+
if (tilePartToEOC) {
//~ peek for an EOC marker
cover(93);
@@ -2425,90 +2475,110 @@ GBool JPXStream::readTilePartData(Guint tileIdx,
switch (tile->progOrder) {
case 0: // layer, resolution level, component, precinct
cover(58);
- resLevel = &tile->tileComps[tile->comp].resLevels[tile->res];
- if (++tile->precinct == resLevel->nPrecincts) {
- tile->precinct = 0;
- if (++tile->comp == img.nComps) {
- tile->comp = 0;
- if (++tile->res == tile->maxNDecompLevels + 1) {
- tile->res = 0;
- if (++tile->layer == tile->nLayers) {
- tile->layer = 0;
- tile->done = gTrue;
+ do {
+ if (++tile->precinct == tile->maxNPrecincts) {
+ tile->precinct = 0;
+ if (++tile->comp == img.nComps) {
+ tile->comp = 0;
+ if (++tile->res == tile->maxNDecompLevels + 1) {
+ tile->res = 0;
+ if (++tile->layer == tile->nLayers) {
+ tile->layer = 0;
+ tile->done = gTrue;
+ }
}
}
}
- }
+ } while (!tile->done &&
+ (tile->res > tile->tileComps[tile->comp].nDecompLevels ||
+ tile->precinct >= tile->tileComps[tile->comp]
+ .resLevels[tile->res].nPrecincts));
break;
case 1: // resolution level, layer, component, precinct
cover(59);
- resLevel = &tile->tileComps[tile->comp].resLevels[tile->res];
- if (++tile->precinct == resLevel->nPrecincts) {
- tile->precinct = 0;
- if (++tile->comp == img.nComps) {
- tile->comp = 0;
- if (++tile->layer == tile->nLayers) {
- tile->layer = 0;
- if (++tile->res == tile->maxNDecompLevels + 1) {
- tile->res = 0;
- tile->done = gTrue;
+ do {
+ if (++tile->precinct == tile->maxNPrecincts) {
+ tile->precinct = 0;
+ if (++tile->comp == img.nComps) {
+ tile->comp = 0;
+ if (++tile->layer == tile->nLayers) {
+ tile->layer = 0;
+ if (++tile->res == tile->maxNDecompLevels + 1) {
+ tile->res = 0;
+ tile->done = gTrue;
+ }
}
}
}
- }
+ } while (!tile->done &&
+ (tile->res > tile->tileComps[tile->comp].nDecompLevels ||
+ tile->precinct >= tile->tileComps[tile->comp]
+ .resLevels[tile->res].nPrecincts));
break;
case 2: // resolution level, precinct, component, layer
cover(60);
//~ this is incorrect if there are subsampled components (?)
- if (++tile->layer == tile->nLayers) {
- tile->layer = 0;
- if (++tile->comp == img.nComps) {
- tile->comp = 0;
- resLevel = &tile->tileComps[tile->comp].resLevels[tile->res];
- if (++tile->precinct == resLevel->nPrecincts) {
- tile->precinct = 0;
- if (++tile->res == tile->maxNDecompLevels + 1) {
- tile->res = 0;
- tile->done = gTrue;
+ do {
+ if (++tile->layer == tile->nLayers) {
+ tile->layer = 0;
+ if (++tile->comp == img.nComps) {
+ tile->comp = 0;
+ if (++tile->precinct == tile->maxNPrecincts) {
+ tile->precinct = 0;
+ if (++tile->res == tile->maxNDecompLevels + 1) {
+ tile->res = 0;
+ tile->done = gTrue;
+ }
}
}
}
- }
+ } while (!tile->done &&
+ (tile->res > tile->tileComps[tile->comp].nDecompLevels ||
+ tile->precinct >= tile->tileComps[tile->comp]
+ .resLevels[tile->res].nPrecincts));
break;
case 3: // precinct, component, resolution level, layer
cover(61);
//~ this is incorrect if there are subsampled components (?)
- if (++tile->layer == tile->nLayers) {
- tile->layer = 0;
- if (++tile->res == tile->maxNDecompLevels + 1) {
- tile->res = 0;
- if (++tile->comp == img.nComps) {
- tile->comp = 0;
- resLevel = &tile->tileComps[tile->comp].resLevels[tile->res];
- if (++tile->precinct == resLevel->nPrecincts) {
- tile->precinct = 0;
- tile->done = gTrue;
+ do {
+ if (++tile->layer == tile->nLayers) {
+ tile->layer = 0;
+ if (++tile->res == tile->maxNDecompLevels + 1) {
+ tile->res = 0;
+ if (++tile->comp == img.nComps) {
+ tile->comp = 0;
+ if (++tile->precinct == tile->maxNPrecincts) {
+ tile->precinct = 0;
+ tile->done = gTrue;
+ }
}
}
}
- }
+ } while (!tile->done &&
+ (tile->res > tile->tileComps[tile->comp].nDecompLevels ||
+ tile->precinct >= tile->tileComps[tile->comp]
+ .resLevels[tile->res].nPrecincts));
break;
case 4: // component, precinct, resolution level, layer
cover(62);
- if (++tile->layer == tile->nLayers) {
- tile->layer = 0;
- if (++tile->res == tile->maxNDecompLevels + 1) {
- tile->res = 0;
- resLevel = &tile->tileComps[tile->comp].resLevels[tile->res];
- if (++tile->precinct == resLevel->nPrecincts) {
- tile->precinct = 0;
- if (++tile->comp == img.nComps) {
- tile->comp = 0;
- tile->done = gTrue;
+ do {
+ if (++tile->layer == tile->nLayers) {
+ tile->layer = 0;
+ if (++tile->res == tile->maxNDecompLevels + 1) {
+ tile->res = 0;
+ if (++tile->precinct == tile->maxNPrecincts) {
+ tile->precinct = 0;
+ if (++tile->comp == img.nComps) {
+ tile->comp = 0;
+ tile->done = gTrue;
+ }
}
}
}
- }
+ } while (!tile->done &&
+ (tile->res > tile->tileComps[tile->comp].nDecompLevels ||
+ tile->precinct >= tile->tileComps[tile->comp]
+ .resLevels[tile->res].nPrecincts));
break;
}
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
index 510826cd162..4b8587b0fb2 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
@@ -202,6 +202,7 @@ struct JPXTileComp {
//----- computed
Guint x0, y0, x1, y1; // bounds of the tile-comp, in ref coords
+ Guint x0r, y0r; // x0 >> reduction, y0 >> reduction
Guint w, h; // data size = {x1 - x0, y1 - y0} >> reduction
//----- image data
@@ -228,6 +229,8 @@ struct JPXTile {
Guint x0, y0, x1, y1; // bounds of the tile, in ref coords
Guint maxNDecompLevels; // max number of decomposition levels used
// in any component in this tile
+ Guint maxNPrecincts; // max number of precints in any
+ // component/res level in this tile
//----- progression order loop counters
Guint comp; // component
@@ -294,6 +297,7 @@ public:
private:
+ void decodeImage();
void fillReadBuf();
void getImageParams2(int *bitsPerComponent, StreamColorSpaceMode *csMode);
JPXDecodeResult readBoxes();
@@ -329,6 +333,7 @@ private:
BufStream *bufStr; // buffered stream (for lookahead)
+ GBool decoded; // set when the image has been decoded
Guint nComps; // number of components
Guint *bpc; // bits per component, for each component
Guint width, height; // image size
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h
index 6fe7eeedb4e..54483cfcc43 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h
@@ -229,10 +229,10 @@ public:
virtual void psXObject(Stream *psStream, Stream *level1Stream) {}
//----- transparency groups and soft masks
- virtual void beginTransparencyGroup(GfxState *state, double *bbox,
- GfxColorSpace *blendingColorSpace,
- GBool isolated, GBool knockout,
- GBool forSoftMask) {}
+ virtual GBool beginTransparencyGroup(GfxState *state, double *bbox,
+ GfxColorSpace *blendingColorSpace,
+ GBool isolated, GBool knockout,
+ GBool forSoftMask) { return gTrue; }
virtual void endTransparencyGroup(GfxState *state) {}
virtual void paintTransparencyGroup(GfxState *state, double *bbox) {}
virtual void setSoftMask(GfxState *state, double *bbox, GBool alpha,
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
index 877bcb88255..b833d5dabf0 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
@@ -421,7 +421,15 @@ void PDFCore::finishUpdate(GBool addToHist, GBool checkForChangedFile) {
}
// redraw
- invalidateWholeWindow();
+ // - if the bitmap is available (e.g., we just scrolled), we want to
+ // redraw immediately; if not, postpone the redraw until a
+ // 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) {
+ invalidateWholeWindow();
+ }
updateScrollbars();
// add to history
@@ -436,21 +444,28 @@ void PDFCore::addToHistory() {
cur = &history[historyCur];
h.page = tileMap->getMidPage();
+ h.fileName = NULL;
#ifdef _WIN32
if (doc->getFileNameU()) {
- h.fileName = (wchar_t *)gmallocn(MAX_PATH + 1, sizeof(wchar_t));
- if (GetFullPathNameW(doc->getFileNameU(), MAX_PATH + 1,
- h.fileName, NULL) == 0) {
- h.fileName = NULL;
+ wchar_t dummy;
+ // NB: if the buffer is too small, GetFullPathNameW returns a
+ // *maximum* required buffer size, which may be larger than the
+ // size actually used by the second call (it looks like it just
+ // adds the size of the current directory and the sizef of the
+ // input path)
+ DWORD nChars = GetFullPathNameW(doc->getFileNameU(), 1, &dummy, NULL);
+ if (nChars > 0) {
+ h.fileName = (wchar_t *)gmallocn(nChars, sizeof(wchar_t));
+ if (GetFullPathNameW(doc->getFileNameU(), nChars,
+ h.fileName, NULL) == 0) {
+ gfree(h.fileName);
+ h.fileName = NULL;
+ }
}
- } else {
- h.fileName = NULL;
}
#else
if (doc->getFileName()) {
h.fileName = doc->getFileName()->copy();
- } else {
- h.fileName = NULL;
}
#endif
if (historyBLen > 0 && h.page == cur->page) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
index 6efd4aac6c4..a6663ea4222 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
@@ -125,11 +125,11 @@ PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GString *ownerPassword,
init(coreA);
// handle a Windows shortcut
- wchar_t wPath[MAX_PATH + 1];
- int n = fileNameLen < MAX_PATH ? fileNameLen : MAX_PATH;
+ wchar_t wPath[winMaxLongPath + 1];
+ int n = fileNameLen < winMaxLongPath ? fileNameLen : winMaxLongPath;
memcpy(wPath, fileNameA, n * sizeof(wchar_t));
wPath[n] = L'\0';
- readWindowsShortcut(wPath, MAX_PATH + 1);
+ readWindowsShortcut(wPath, winMaxLongPath + 1);
int wPathLen = (int)wcslen(wPath);
// save both Unicode and 8-bit copies of the file name
@@ -166,33 +166,32 @@ PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GString *ownerPassword,
PDFDoc::PDFDoc(char *fileNameA, GString *ownerPassword,
GString *userPassword, PDFCore *coreA) {
-/*
+#if 0
#ifdef _WIN32
OSVERSIONINFO version;
#endif
-*/
+#endif /* 0 */
Object obj;
-/*
+#if 0
#ifdef _WIN32
Unicode u;
int i, j;
#endif
-*/
-
+#endif /* 0 */
init(coreA);
fileName = new GString(fileNameA);
#if defined(_WIN32)
#if 0
- wchar_t wPath[MAX_PATH + 1];
+ wchar_t wPath[winMaxLongPath + 1];
i = 0;
j = 0;
- while (j < MAX_PATH && getUTF8(fileName, &i, &u)) {
+ while (j < winMaxLongPath && getUTF8(fileName, &i, &u)) {
wPath[j++] = (wchar_t)u;
}
wPath[j] = L'\0';
- readWindowsShortcut(wPath, MAX_PATH + 1);
+ readWindowsShortcut(wPath, winMaxLongPath + 1);
int wPathLen = (int)wcslen(wPath);
fileNameU = (wchar_t *)gmallocn(wPathLen + 1, sizeof(wchar_t));
@@ -462,6 +461,11 @@ void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage,
int page;
for (page = firstPage; page <= lastPage; ++page) {
+ if (globalParams->getPrintStatusInfo()) {
+ fflush(stderr);
+ printf("[processing page %d]\n", page);
+ fflush(stdout);
+ }
displayPage(out, page, hDPI, vDPI, rotate, useMediaBox, crop, printing,
abortCheckCbk, abortCheckCbkData);
catalog->doneWithPage(page);
@@ -607,31 +611,31 @@ GBool PDFDoc::saveEmbeddedFileU(int idx, const char *path) {
GBool PDFDoc::saveEmbeddedFile(int idx, const wchar_t *path, int pathLen) {
FILE *f;
OSVERSIONINFO version;
- wchar_t path2w[_MAX_PATH + 1];
- char path2c[_MAX_PATH + 1];
+ wchar_t path2w[winMaxLongPath + 1];
+ char path2c[MAX_PATH + 1];
int i;
GBool ret;
// NB: _wfopen is only available in NT
-/*
+#if 0
version.dwOSVersionInfoSize = sizeof(version);
GetVersionEx(&version);
if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- for (i = 0; i < pathLen && i < _MAX_PATH; ++i) {
+ for (i = 0; i < pathLen && i < winMaxLongPath; ++i) {
path2w[i] = path[i];
}
path2w[i] = 0;
f = _wfopen(path2w, L"wb");
} else {
-*/
- for (i = 0; i < pathLen && i < _MAX_PATH; ++i) {
+#endif /* 0 */
+ for (i = 0; i < pathLen && i < MAX_PATH; ++i) {
path2c[i] = (char)path[i];
}
path2c[i] = 0;
f = fopen(path2c, "wb");
-/*
+#if 0
}
-*/
+#endif /* 0 */
if (!f) {
return gFalse;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h
index 5069cb78689..2b8eba2cba7 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h
@@ -162,6 +162,10 @@ public:
GBool okToAddNotes(GBool ignoreOwnerPW = gFalse)
{ return xref->okToAddNotes(ignoreOwnerPW); }
+ // Is the PDF file damaged? This checks to see if the xref table
+ // was constructed by the repair code.
+ GBool isDamaged() { return xref->isRepaired(); }
+
// Is this document linearized?
GBool isLinearized();
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
index 0c39472ba85..b9fff4ffaed 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
@@ -1481,6 +1481,7 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
rotate0 = -1;
clipLLX0 = clipLLY0 = 0;
clipURX0 = clipURY0 = -1;
+ expandSmallPages = globalParams->getPSExpandSmaller();
// initialize font lists, etc.
for (i = 0; i < 14; ++i) {
@@ -1581,6 +1582,11 @@ PSOutputDev::~PSOutputDev() {
customColors = cc->next;
delete cc;
}
+ if (t3String) {
+ // this will only happen if the 'd1' operator is used outside of a
+ // Type 3 CharProc
+ delete t3String;
+ }
}
GBool PSOutputDev::checkIO() {
@@ -3827,6 +3833,7 @@ void PSOutputDev::setupImage(Ref id, Stream *str, GBool mask,
}
// filters
+ str->disableDecompressionBombChecking();
if (level < psLevel2) {
useLZW = useRLE = gFalse;
useCompressed = gFalse;
@@ -4265,6 +4272,7 @@ GBool PSOutputDev::checkPageSlice(Page *page, double hDPI, double vDPI,
}
break;
case psLevel1Sep:
+#if SPLASH_CMYK
writePSFmt("{0:d} {1:d} 8 [{2:d} 0 0 {3:d} 0 {4:d}] pdfIm1Sep\n",
w, h, w, -h, h);
p = bitmap->getDataPtr() + (h - 1) * bitmap->getRowSize();
@@ -4299,6 +4307,8 @@ GBool PSOutputDev::checkPageSlice(Page *page, double hDPI, double vDPI,
processColors |= psProcessBlack;
}
break;
+ // if !SPLASH_CMYK: fall through
+#endif
case psLevel2:
case psLevel2Gray:
case psLevel2Sep:
@@ -4510,7 +4520,7 @@ void PSOutputDev::startPage(int pageNum, GfxState *state) {
} else if ((globalParams->getPSShrinkLarger() &&
(width * userUnit > imgWidth2 ||
height * userUnit > imgHeight2)) ||
- (globalParams->getPSExpandSmaller() &&
+ (expandSmallPages &&
(width * userUnit < imgWidth2 &&
height * userUnit < imgHeight2))) {
xScale = (double)imgWidth2 / (double)width;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h
index 466f81f1992..b7223c6cdd8 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h
@@ -264,6 +264,8 @@ public:
{ rotate0 = rotateA; }
void setClip(double llx, double lly, double urx, double ury)
{ clipLLX0 = llx; clipLLY0 = lly; clipURX0 = urx; clipURY0 = ury; }
+ void setExpandSmallPages(GBool expand)
+ { expandSmallPages = expand; }
void setUnderlayCbk(void (*cbk)(PSOutputDev *psOut, void *data),
void *data)
{ underlayCbk = cbk; underlayCbkData = data; }
@@ -474,6 +476,7 @@ private:
int rotate0; // rotation angle (0, 90, 180, 270)
double clipLLX0, clipLLY0,
clipURX0, clipURY0;
+ GBool expandSmallPages; // expand smaller pages to fill paper
double tx, ty; // global translation for current page
double xScale, yScale; // global scaling for current page
int rotate; // rotation angle for current page
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc
index ace0b33d85c..368bc68dd8a 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc
@@ -64,7 +64,7 @@ void PDFRectangle::clipTo(PDFRectangle *rect) {
// PageAttrs
//------------------------------------------------------------------------
-PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
+PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict, XRef *xref) {
Object obj1;
// get old/default values
@@ -73,7 +73,6 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
cropBox = attrs->cropBox;
haveCropBox = attrs->haveCropBox;
rotate = attrs->rotate;
- attrs->resources.copy(&resources);
} else {
// set default MediaBox to 8.5" x 11" -- this shouldn't be necessary
// but some (non-compliant) PDF files don't specify a MediaBox
@@ -84,7 +83,6 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
cropBox.x1 = cropBox.y1 = cropBox.x2 = cropBox.y2 = 0;
haveCropBox = gFalse;
rotate = 0;
- resources.initNull();
}
// media box
@@ -137,12 +135,59 @@ PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
obj1.free();
// resource dictionary
- dict->lookup("Resources", &obj1);
- if (obj1.isDict()) {
- resources.free();
- obj1.copy(&resources);
+ Object childResDictObj;
+ dict->lookup("Resources", &childResDictObj);
+ if (attrs && attrs->resources.isDict() && childResDictObj.isDict()) {
+ // merge this node's resources into the parent's resources
+ // (some PDF files violate the PDF spec and expect this merging)
+ resources.initDict(xref);
+ Dict *resDict = resources.getDict();
+ Dict *parentResDict = attrs->resources.getDict();
+ for (int i = 0; i < parentResDict->getLength(); ++i) {
+ char *resType = parentResDict->getKey(i);
+ Object subdictObj1;
+ if (parentResDict->getVal(i, &subdictObj1)->isDict()) {
+ Dict *subdict1 = subdictObj1.getDict();
+ Object subdictObj2;
+ subdictObj2.initDict(xref);
+ Dict *subdict2 = subdictObj2.getDict();
+ for (int j = 0; j < subdict1->getLength(); ++j) {
+ subdict1->getValNF(j, &obj1);
+ subdict2->add(copyString(subdict1->getKey(j)), &obj1);
+ }
+ resDict->add(copyString(resType), &subdictObj2);
+ }
+ subdictObj1.free();
+ }
+ Dict *childResDict = childResDictObj.getDict();
+ for (int i = 0; i < childResDict->getLength(); ++i) {
+ char *resType = childResDict->getKey(i);
+ Object subdictObj1;
+ if (childResDict->getVal(i, &subdictObj1)->isDict()) {
+ Object subdictObj2;
+ if (resDict->lookup(resType, &subdictObj2)->isDict()) {
+ Dict *subdict1 = subdictObj1.getDict();
+ Dict *subdict2 = subdictObj2.getDict();
+ for (int j = 0; j < subdict1->getLength(); ++j) {
+ subdict1->getValNF(j, &obj1);
+ subdict2->add(copyString(subdict1->getKey(j)), &obj1);
+ }
+ subdictObj2.free();
+ } else {
+ subdictObj2.free();
+ resDict->add(copyString(resType), subdictObj1.copy(&subdictObj2));
+ }
+ }
+ subdictObj1.free();
+ }
+ } else if (attrs && attrs->resources.isDict()) {
+ attrs->resources.copy(&resources);
+ } else if (childResDictObj.isDict()) {
+ childResDictObj.copy(&resources);
+ } else {
+ resources.initNull();
}
- obj1.free();
+ childResDictObj.free();
}
PageAttrs::PageAttrs() {
@@ -160,6 +205,7 @@ PageAttrs::PageAttrs() {
metadata.initNull();
pieceInfo.initNull();
separationInfo.initNull();
+ userUnit = 1;
resources.initNull();
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h
index 8ec5a10995a..fe579e7b3af 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h
@@ -46,7 +46,7 @@ public:
// Construct a new PageAttrs object by merging a dictionary
// (of type Pages or Page) into another PageAttrs object. If
// <attrs> is NULL, uses defaults.
- PageAttrs(PageAttrs *attrs, Dict *dict);
+ PageAttrs(PageAttrs *attrs, Dict *dict, XRef *xref);
// Construct a new PageAttrs object for an empty page (only used
// when there is an error in the page tree).
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc
index 87e3fc5e24b..4fad6afae13 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc
@@ -152,36 +152,35 @@ Object *Parser::getObj(Object *obj, GBool simpleOnly,
Stream *Parser::makeStream(Object *dict, Guchar *fileKey,
CryptAlgorithm encAlgorithm, int keyLength,
int objNum, int objGen, int recursion) {
- Object obj;
- BaseStream *baseStr;
- Stream *str, *str2;
- GFileOffset pos, endPos, length;
- char endstreamBuf[8];
- GBool foundEndstream;
- int c, i;
-
// get stream start position
lexer->skipToNextLine();
- if (!(str = lexer->getStream())) {
+ Stream *curStr = lexer->getStream();
+ if (!curStr) {
return NULL;
}
- pos = str->getPos();
+ GFileOffset pos = curStr->getPos();
+
+ GBool haveLength = gFalse;
+ GFileOffset length = 0;
+ GFileOffset endPos;
// check for length in damaged file
if (xref && xref->getStreamEnd(pos, &endPos)) {
length = endPos - pos;
+ haveLength = gTrue;
// get length from the stream object
} else {
+ Object obj;
dict->dictLookup("Length", &obj, recursion);
if (obj.isInt()) {
length = (GFileOffset)(Guint)obj.getInt();
- obj.free();
+ haveLength = gTrue;
} else {
- error(errSyntaxError, getPos(), "Bad 'Length' attribute in stream");
- obj.free();
- return NULL;
+ error(errSyntaxError, getPos(),
+ "Missing or invalid 'Length' attribute in stream");
}
+ obj.free();
}
// in badly damaged PDF files, we can run off the end of the input
@@ -189,47 +188,78 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey,
if (!lexer->getStream()) {
return NULL;
}
+
// copy the base stream (Lexer will free stream objects when it gets
// to end of stream -- which can happen in the shift() calls below)
- baseStr = (BaseStream *)lexer->getStream()->getBaseStream()->copy();
+ BaseStream *baseStr =
+ (BaseStream *)lexer->getStream()->getBaseStream()->copy();
+
+ // 'Length' attribute is missing -- search for 'endstream'
+ if (!haveLength) {
+ GBool foundEndstream = gFalse;
+ char endstreamBuf[8];
+ if ((curStr = lexer->getStream())) {
+ int c;
+ while ((c = curStr->getChar()) != EOF) {
+ if (c == 'e' &&
+ curStr->getBlock(endstreamBuf, 8) == 8 &&
+ !memcmp(endstreamBuf, "ndstream", 8)) {
+ length = curStr->getPos() - 9 - pos;
+ foundEndstream = gTrue;
+ break;
+ }
+ }
+ }
+ if (!foundEndstream) {
+ error(errSyntaxError, getPos(), "Couldn't find 'endstream' for stream");
+ delete baseStr;
+ return NULL;
+ }
+ }
// make new base stream
- str = baseStr->makeSubStream(pos, gTrue, length, dict);
+ Stream *str = baseStr->makeSubStream(pos, gTrue, length, dict);
- // skip over stream data
- lexer->setPos(pos + length);
+ // look for the 'endstream' marker
+ if (haveLength) {
+ // skip over stream data
+ lexer->setPos(pos + length);
- // check for 'endstream'
- // NB: we never reuse the Parser object to parse objects after a
- // stream, and we could (if the PDF file is damaged) be in the
- // middle of binary data at this point, so we check the stream data
- // directly for 'endstream', rather than calling shift() to parse
- // objects
- foundEndstream = gFalse;
- if ((str2 = lexer->getStream())) {
- // skip up to 100 whitespace chars
- for (i = 0; i < 100; ++i) {
- c = str2->getChar();
- if (!Lexer::isSpace(c)) {
- break;
+ // check for 'endstream'
+ // NB: we never reuse the Parser object to parse objects after a
+ // stream, and we could (if the PDF file is damaged) be in the
+ // middle of binary data at this point, so we check the stream
+ // data directly for 'endstream', rather than calling shift() to
+ // parse objects
+ GBool foundEndstream = gFalse;
+ char endstreamBuf[8];
+ if ((curStr = lexer->getStream())) {
+ // skip up to 100 whitespace chars
+ int c;
+ for (int i = 0; i < 100; ++i) {
+ c = curStr->getChar();
+ if (!Lexer::isSpace(c)) {
+ break;
+ }
}
- }
- if (c == 'e') {
- if (str2->getBlock(endstreamBuf, 8) == 8 ||
- !memcmp(endstreamBuf, "ndstream", 8)) {
- foundEndstream = gTrue;
+ if (c == 'e') {
+ if (curStr->getBlock(endstreamBuf, 8) == 8 &&
+ !memcmp(endstreamBuf, "ndstream", 8)) {
+ foundEndstream = gTrue;
+ }
}
}
- }
- if (!foundEndstream) {
- error(errSyntaxError, getPos(), "Missing 'endstream'");
- // kludge for broken PDF files: just add 5k to the length, and
- // hope it's enough
- // (dict is now owned by str, so we need to copy it before deleting str)
- dict->copy(&obj);
- delete str;
- length += 5000;
- str = baseStr->makeSubStream(pos, gTrue, length, &obj);
+ if (!foundEndstream) {
+ error(errSyntaxError, getPos(), "Missing 'endstream'");
+ // kludge for broken PDF files: just add 5k to the length, and
+ // hope it's enough
+ // (dict is now owned by str, so we need to copy it before deleting str)
+ Object obj;
+ dict->copy(&obj);
+ delete str;
+ length += 5000;
+ str = baseStr->makeSubStream(pos, gTrue, length, &obj);
+ }
}
// free the copied base stream
@@ -237,8 +267,25 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey,
// handle decryption
if (fileKey) {
- str = new DecryptStream(str, fileKey, encAlgorithm, keyLength,
- objNum, objGen);
+ // the 'Crypt' filter is used to mark unencrypted metadata streams
+ //~ this should also check for an empty DecodeParams entry
+ GBool encrypted = gTrue;
+ Object obj;
+ dict->dictLookup("Filter", &obj, recursion);
+ if (obj.isName("Crypt")) {
+ encrypted = gFalse;
+ } else if (obj.isArray() && obj.arrayGetLength() >= 1) {
+ Object obj2;
+ if (obj.arrayGet(0, &obj2)->isName("Crypt")) {
+ encrypted = gFalse;
+ }
+ obj2.free();
+ }
+ obj.free();
+ if (encrypted) {
+ str = new DecryptStream(str, fileKey, encAlgorithm, keyLength,
+ objNum, objGen);
+ }
}
// get filters
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc
index e5e00b85f51..29f26c00cee 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc
@@ -248,13 +248,14 @@ void PreScanOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
gdi = gFalse;
}
-void PreScanOutputDev::beginTransparencyGroup(
- GfxState *state, double *bbox,
- GfxColorSpace *blendingColorSpace,
- GBool isolated, GBool knockout,
- GBool forSoftMask) {
+GBool PreScanOutputDev::beginTransparencyGroup(
+ GfxState *state, double *bbox,
+ GfxColorSpace *blendingColorSpace,
+ GBool isolated, GBool knockout,
+ GBool forSoftMask) {
transparency = gTrue;
gdi = gFalse;
+ return gTrue;
}
void PreScanOutputDev::check(GfxState *state,
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h
index 253733772bf..ee21e98b148 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h
@@ -103,10 +103,10 @@ public:
double *matte, GBool interpolate);
//----- transparency groups and soft masks
- virtual void beginTransparencyGroup(GfxState *state, double *bbox,
- GfxColorSpace *blendingColorSpace,
- GBool isolated, GBool knockout,
- GBool forSoftMask);
+ virtual GBool beginTransparencyGroup(GfxState *state, double *bbox,
+ GfxColorSpace *blendingColorSpace,
+ GBool isolated, GBool knockout,
+ GBool forSoftMask);
//----- special access
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc
index 4a7d0954c40..a61a84e8fa2 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc
@@ -203,18 +203,15 @@ StandardSecurityHandler::StandardSecurityHandler(PDFDoc *docA,
fileKeyLength = cfLengthObj.getInt();
}
cfLengthObj.free();
- if (fileKeyLength == 16) {
- // this isn't allowed by the spec, but Adobe supports it
- encVersion = 2;
- encRevision = 3;
- encAlgorithm = cryptAES;
- } else {
- encVersion = 5;
- if (encRevision != 5 && encRevision != 6) {
- encRevision = 6;
- }
- encAlgorithm = cryptAES256;
+ encVersion = 5;
+ if (encRevision != 5 && encRevision != 6) {
+ encRevision = 6;
}
+ encAlgorithm = cryptAES256;
+ // The PDF 2.0 spec says Length and CF.Length are both deprecated.
+ // Acrobat X honors Length and ignores CF.Length.
+ // I think it's safest to ignore both.
+ fileKeyLength = 32;
}
cfmObj.free();
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
index 89c7c02a7b6..d758e25b306 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
@@ -1882,10 +1882,10 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
idet = 1 / idet;
clipXC = 0.5 * (clipXMin + clipXMax);
clipYC = 0.5 * (clipYMin + clipYMax);
- ix = (int)((yStepX * (tileYMin - clipYC) - (tileXMin - clipXC) * yStepY)
- * idet + 0.5);
- iy = (int)((xStepX * (clipYC - tileYMin) - (clipXC - tileXMin) * xStepY)
- * idet + 0.5);
+ ix = (int)floor((yStepX * (tileYMin - clipYC)
+ - (tileXMin - clipXC) * yStepY) * idet + 0.5);
+ iy = (int)floor((xStepX * (clipYC - tileYMin)
+ - (clipXC - tileXMin) * xStepY) * idet + 0.5);
adjXMin = (int)floor(tileXMin + ix * xStepX + iy * yStepX + 0.5);
adjYMin = (int)floor(tileYMin + ix * xStepY + iy * yStepY + 0.5);
sx = tileW / (tileXMax - tileXMin);
@@ -1896,38 +1896,6 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
yStepY = (int)floor(sy * yStepY + 0.5);
}
- // compute tile matrix = PTM * BTM * Mtranslate * Mscale * iCTM
- // = mat * CTM * Mtranslate * Mscale * iCTM
- ctm = state->getCTM();
- idet = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
- ictm[0] = ctm[3] * idet;
- ictm[1] = -ctm[1] * idet;
- ictm[2] = -ctm[2] * idet;
- ictm[3] = ctm[0] * idet;
- ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * idet;
- ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * idet;
- // mat * CTM
- mat1[0] = mat[0] * ctm[0] + mat[1] * ctm[2];
- mat1[1] = mat[0] * ctm[1] + mat[1] * ctm[3];
- mat1[2] = mat[2] * ctm[0] + mat[3] * ctm[2];
- mat1[3] = mat[2] * ctm[1] + mat[3] * ctm[3];
- mat1[4] = mat[4] * ctm[0] + mat[5] * ctm[2] + ctm[4];
- mat1[5] = mat[4] * ctm[1] + mat[5] * ctm[3] + ctm[5];
- // mat * CTM * (Mtranslate * Mscale)
- mat2[0] = mat1[0] * sx;
- mat2[1] = mat1[1] * sy;
- mat2[2] = mat1[2] * sx;
- mat2[3] = mat1[3] * sy;
- mat2[4] = mat1[4] * sx - sx * tileXMin;
- mat2[5] = mat1[5] * sy - sy * tileYMin;
- // mat * CTM * (Mtranslate * Mscale) * iCTM
- tileMat[0] = mat2[0] * ictm[0] + mat2[1] * ictm[2];
- tileMat[1] = mat2[0] * ictm[1] + mat2[1] * ictm[3];
- tileMat[2] = mat2[2] * ictm[0] + mat2[3] * ictm[2];
- tileMat[3] = mat2[2] * ictm[1] + mat2[3] * ictm[3];
- tileMat[4] = mat2[4] * ictm[0] + mat2[5] * ictm[2] + ictm[4];
- tileMat[5] = mat2[4] * ictm[1] + mat2[5] * ictm[3] + ictm[5];
-
// compute tiling range:
// - look at the four corners of the clipping bbox
// - solve for the (ix,iy) tile position at each corner
@@ -1989,10 +1957,65 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
} else if (ty > tyMax) {
tyMax = ty;
}
- ixMin = (int)floor(txMin);
- ixMax = (int)ceil(txMax);
- iyMin = (int)floor(tyMin);
- iyMax = (int)ceil(tyMax);
+ ixMin = (int)ceil(txMin);
+ ixMax = (int)floor(txMax) + 1;
+ iyMin = (int)ceil(tyMin);
+ iyMax = (int)floor(tyMax) + 1;
+
+ // special case: pattern tile is larger than clipping bbox
+ if (ixMax - ixMin == 1 && iyMax - iyMin == 1) {
+ // reduce the tile size to just the clipping bbox -- this improves
+ // performance in cases where just a small portion of one tile is
+ // needed
+ tileW = (int)(clipXMax - clipXMin + 0.5);
+ tileH = (int)(clipYMax - clipYMin + 0.5);
+ if (tileW < 1) {
+ tileW = 1;
+ }
+ if (tileH < 1) {
+ tileH = 1;
+ }
+ tileXMin += clipXMin - (adjXMin + ixMin * xStepX + iyMin * yStepX);
+ tileYMin += clipYMin - (adjYMin + ixMin * xStepY + iyMin * yStepY);
+ ixMin = 0;
+ iyMin = 0;
+ ixMax = 1;
+ iyMax = 1;
+ adjXMin = clipXMin;
+ adjYMin = clipYMin;
+ }
+
+ // compute tile matrix = PTM * BTM * Mtranslate * Mscale * iCTM
+ // = mat * CTM * Mtranslate * Mscale * iCTM
+ ctm = state->getCTM();
+ idet = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
+ ictm[0] = ctm[3] * idet;
+ ictm[1] = -ctm[1] * idet;
+ ictm[2] = -ctm[2] * idet;
+ ictm[3] = ctm[0] * idet;
+ ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * idet;
+ ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * idet;
+ // mat * CTM
+ mat1[0] = mat[0] * ctm[0] + mat[1] * ctm[2];
+ mat1[1] = mat[0] * ctm[1] + mat[1] * ctm[3];
+ mat1[2] = mat[2] * ctm[0] + mat[3] * ctm[2];
+ mat1[3] = mat[2] * ctm[1] + mat[3] * ctm[3];
+ mat1[4] = mat[4] * ctm[0] + mat[5] * ctm[2] + ctm[4];
+ mat1[5] = mat[4] * ctm[1] + mat[5] * ctm[3] + ctm[5];
+ // mat * CTM * (Mtranslate * Mscale)
+ mat2[0] = mat1[0] * sx;
+ mat2[1] = mat1[1] * sy;
+ mat2[2] = mat1[2] * sx;
+ mat2[3] = mat1[3] * sy;
+ mat2[4] = mat1[4] * sx - sx * tileXMin;
+ mat2[5] = mat1[5] * sy - sy * tileYMin;
+ // mat * CTM * (Mtranslate * Mscale) * iCTM
+ tileMat[0] = mat2[0] * ictm[0] + mat2[1] * ictm[2];
+ tileMat[1] = mat2[0] * ictm[1] + mat2[1] * ictm[3];
+ tileMat[2] = mat2[2] * ictm[0] + mat2[3] * ictm[2];
+ tileMat[3] = mat2[2] * ictm[1] + mat2[3] * ictm[3];
+ tileMat[4] = mat2[4] * ictm[0] + mat2[5] * ictm[2] + ictm[4];
+ tileMat[5] = mat2[4] * ictm[1] + mat2[5] * ictm[3] + ictm[5];
// create a temporary bitmap
origBitmap = bitmap;
@@ -2068,8 +2091,8 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
} else {
for (iy = iyMin; iy < iyMax; ++iy) {
for (ix = ixMin; ix < ixMax; ++ix) {
- x = (int)(adjXMin + ix * xStepX + iy * yStepX + 0.5);
- y = (int)(adjYMin + ix * xStepY + iy * yStepY + 0.5);
+ x = (int)floor(adjXMin + ix * xStepX + iy * yStepX + 0.5);
+ y = (int)floor(adjYMin + ix * xStepY + iy * yStepY + 0.5);
if (overprintMaskBitmap) {
splash->compositeWithOverprint(tileBitmap, overprintMaskBitmap,
0, 0, x, y, tileW, tileH,
@@ -2722,7 +2745,8 @@ void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
imgTag = makeImageTag(ref, gfxRenderingIntentRelativeColorimetric, NULL);
splash->fillImageMask(imgTag,
&imageMaskSrc, &imgMaskData, width, height, mat,
- t3GlyphStack != NULL, interpolate);
+ t3GlyphStack != NULL, interpolate,
+ globalParams->getImageMaskAntialias());
if (inlineImg) {
while (imgMaskData.y < height) {
@@ -2772,12 +2796,16 @@ void SplashOutputDev::setSoftMaskFromImageMask(GfxState *state,
mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
maskSplash->setEnablePathSimplification(
globalParams->getEnablePathSimplification());
+ if (splash->getSoftMask()) {
+ maskSplash->setSoftMask(splash->getSoftMask(), gFalse);
+ }
clearMaskRegion(state, maskSplash, 0, 0, 1, 1);
maskColor[0] = 0xff;
maskSplash->setFillPattern(new SplashSolidColor(maskColor));
imgTag = makeImageTag(ref, gfxRenderingIntentRelativeColorimetric, NULL);
maskSplash->fillImageMask(imgTag, &imageMaskSrc, &imgMaskData,
- width, height, mat, gFalse, interpolate);
+ width, height, mat, gFalse, interpolate,
+ globalParams->getImageMaskAntialias());
delete imgTag;
delete imgMaskData.imgStr;
str->close();
@@ -3273,7 +3301,8 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
maskSplash->setFillPattern(new SplashSolidColor(maskColor));
// use "glyph mode" here to get the correct scaled size
maskSplash->fillImageMask(NULL, &imageMaskSrc, &imgMaskData,
- maskWidth, maskHeight, mat, gTrue, interpolate);
+ maskWidth, maskHeight, mat, gTrue, interpolate,
+ globalParams->getImageMaskAntialias());
delete imgMaskData.imgStr;
maskStr->close();
delete maskSplash;
@@ -3818,10 +3847,10 @@ void SplashOutputDev::clearMaskRegion(GfxState *state,
}
}
-void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
- GfxColorSpace *blendingColorSpace,
- GBool isolated, GBool knockout,
- GBool forSoftMask) {
+GBool SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
+ GfxColorSpace *blendingColorSpace,
+ GBool isolated, GBool knockout,
+ GBool forSoftMask) {
SplashTransparencyGroup *transpGroup;
SplashBitmap *backdropBitmap;
SplashColor color;
@@ -3916,6 +3945,28 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
h = 1;
}
+ // optimization: a non-isolated group drawn with alpha=1 and
+ // Blend=Normal and backdrop alpha=0 is equivalent to drawing
+ // directly onto the backdrop (i.e., a regular non-t-group Form)
+ // notes:
+ // - if we are already in a non-isolated group, it means the
+ // backdrop alpha is non-zero (otherwise the parent non-isolated
+ // group would have been optimized away)
+ // - if there is a soft mask in place, then source alpha is not 1
+ // (i.e., source alpha = fillOpacity * softMask)
+ // - both the parent and child groups must be non-knockout
+ if (!isolated &&
+ !splash->getInNonIsolatedGroup() &&
+ !knockout &&
+ !splash->getInKnockoutGroup() &&
+ !forSoftMask &&
+ !splash->getSoftMask() &&
+ state->getFillOpacity() == 1 &&
+ state->getBlendMode() == gfxBlendNormal &&
+ splash->checkTransparentRect(tx, ty, w, h)) {
+ return gFalse;
+ }
+
// push a new stack entry
transpGroup = new SplashTransparencyGroup();
transpGroup->tx = tx;
@@ -4042,6 +4093,8 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
state->shiftCTM(-tx, -ty);
updateCTM(state, 0, 0, 0, 0, 0, 0);
++nestCount;
+
+ return gTrue;
}
void SplashOutputDev::endTransparencyGroup(GfxState *state) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
index cbe47b61cb7..5ec70e95509 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
@@ -167,10 +167,10 @@ public:
double llx, double lly, double urx, double ury);
//----- transparency groups and soft masks
- virtual void beginTransparencyGroup(GfxState *state, double *bbox,
- GfxColorSpace *blendingColorSpace,
- GBool isolated, GBool knockout,
- GBool forSoftMask);
+ virtual GBool beginTransparencyGroup(GfxState *state, double *bbox,
+ GfxColorSpace *blendingColorSpace,
+ GBool isolated, GBool knockout,
+ GBool forSoftMask);
virtual void endTransparencyGroup(GfxState *state);
virtual void paintTransparencyGroup(GfxState *state, double *bbox);
virtual void setSoftMask(GfxState *state, double *bbox, GBool alpha,
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
index 601add89be4..383ac5478ff 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
@@ -52,6 +52,14 @@ static GBool setDJSYSFLAGS = gFalse;
#endif
//------------------------------------------------------------------------
+
+// An LZW/Flate decompression bomb is detected if the output size
+// exceeds decompressionBombSizeThreshold and the decompression ratio
+// exceeds decompressionBombRatioThreshold.
+#define decompressionBombSizeThreshold 50000000
+#define decompressionBombRatioThreshold 200
+
+//------------------------------------------------------------------------
// Stream (base class)
//------------------------------------------------------------------------
@@ -148,7 +156,7 @@ Stream *Stream::addFilters(Object *dict, int recursion) {
} else if (obj.isArray()) {
for (i = 0; i < obj.arrayGetLength(); ++i) {
obj.arrayGet(i, &obj2, recursion);
- if (params.isArray())
+ if (params.isArray() && i < params.arrayGetLength())
params.arrayGet(i, &params2, recursion);
else
params2.initNull();
@@ -305,6 +313,8 @@ Stream *Stream::makeFilter(char *name, Stream *str, Object *params,
globals.free();
} else if (!strcmp(name, "JPXDecode")) {
str = new JPXStream(str);
+ } else if (!strcmp(name, "Crypt")) {
+ // this is handled in Parser::makeStream()
} else {
error(errSyntaxError, getPos(), "Unknown filter '{0:s}'", name);
str = new EOFStream(str);
@@ -384,6 +394,7 @@ ImageStream::~ImageStream() {
}
void ImageStream::reset() {
+ str->disableDecompressionBombChecking();
str->reset();
}
@@ -935,7 +946,11 @@ void MemStream::setPos(GFileOffset pos, int dir) {
if (dir >= 0) {
i = (Guint)pos;
} else {
- i = (Guint)(start + length - pos);
+ if (pos > start + length) {
+ i = 0;
+ } else {
+ i = (Guint)(start + length - pos);
+ }
}
if (i < start) {
i = start;
@@ -1221,6 +1236,7 @@ LZWStream::LZWStream(Stream *strA, int predictor, int columns, int colors,
eof = gFalse;
inputBits = 0;
clearTable();
+ checkForDecompressionBombs = gTrue;
}
LZWStream::~LZWStream() {
@@ -1240,6 +1256,11 @@ Stream *LZWStream::copy() {
}
}
+void LZWStream::disableDecompressionBombChecking() {
+ checkForDecompressionBombs = gFalse;
+ FilterStream::disableDecompressionBombChecking();
+}
+
int LZWStream::getChar() {
if (pred) {
return pred->getChar();
@@ -1386,8 +1407,10 @@ GBool LZWStream::processNextCode() {
totalOut += seqLength;
// check for a 'decompression bomb'
- if (totalOut > 50000000 && totalIn < totalOut / 250) {
- error(errSyntaxError, getPos(), "Decompression bomb in flate stream");
+ if (checkForDecompressionBombs &&
+ totalOut > decompressionBombSizeThreshold &&
+ totalIn < totalOut / decompressionBombRatioThreshold) {
+ error(errSyntaxError, getPos(), "Decompression bomb in LZW stream");
eof = gTrue;
return gFalse;
}
@@ -2638,6 +2661,7 @@ DCTStream::DCTStream(Stream *strA, GBool colorXformA):
FilterStream(strA) {
int i;
+ prepared = gFalse;
colorXform = colorXformA;
progressive = interleaved = gFalse;
width = height = 0;
@@ -2683,6 +2707,7 @@ void DCTStream::reset() {
// force an EOF condition
progressive = gTrue;
y = height;
+ prepared = gTrue;
return;
}
@@ -2719,56 +2744,7 @@ void DCTStream::reset() {
}
}
- if (progressive || !interleaved) {
-
- // allocate a buffer for the whole image
- bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
- bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
- if (bufWidth <= 0 || bufHeight <= 0 ||
- bufWidth > INT_MAX / bufWidth / (int)sizeof(int)) {
- error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
- y = height;
- return;
- }
- for (i = 0; i < numComps; ++i) {
- frameBuf[i] = (int *)gmallocn(bufWidth * bufHeight, sizeof(int));
- memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
- }
-
- // read the image data
- do {
- restartMarker = 0xd0;
- restart();
- readScan();
- } while (readHeader(gFalse));
-
- // decode
- decodeImage();
-
- // initialize counters
- comp = 0;
- x = 0;
- y = 0;
-
- } else {
-
- if (scanInfo.numComps != numComps) {
- error(errSyntaxError, getPos(), "Invalid scan in sequential DCT stream");
- y = height;
- return;
- }
-
- // allocate a buffer for one row of MCUs
- bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
- rowBuf = (Guchar *)gmallocn(numComps * mcuHeight, bufWidth);
- rowBufPtr = rowBufEnd = rowBuf;
-
- // initialize counters
- y = -mcuHeight;
-
- restartMarker = 0xd0;
- restart();
- }
+ prepared = gFalse;
}
GBool DCTStream::checkSequentialInterleaved() {
@@ -2808,6 +2784,9 @@ void DCTStream::close() {
int DCTStream::getChar() {
int c;
+ if (!prepared) {
+ prepare();
+ }
if (progressive || !interleaved) {
if (y >= height) {
return EOF;
@@ -2837,6 +2816,9 @@ int DCTStream::getChar() {
}
int DCTStream::lookChar() {
+ if (!prepared) {
+ prepare();
+ }
if (progressive || !interleaved) {
if (y >= height) {
return EOF;
@@ -2859,6 +2841,9 @@ int DCTStream::lookChar() {
int DCTStream::getBlock(char *blk, int size) {
int nRead, nAvail, n;
+ if (!prepared) {
+ prepare();
+ }
if (progressive || !interleaved) {
if (y >= height) {
return 0;
@@ -2900,6 +2885,76 @@ int DCTStream::getBlock(char *blk, int size) {
return nRead;
}
+void DCTStream::prepare() {
+ int i;
+
+ if (progressive || !interleaved) {
+
+ // allocate a buffer for the whole image
+ bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
+ bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
+ if (bufWidth <= 0 || bufHeight <= 0 ||
+ bufWidth > INT_MAX / bufWidth / (int)sizeof(int)) {
+ error(errSyntaxError, getPos(), "Invalid image size in DCT stream");
+ y = height;
+ prepared = gTrue;
+ return;
+ }
+#if USE_EXCEPTIONS
+ try {
+#endif
+ for (i = 0; i < numComps; ++i) {
+ frameBuf[i] = (int *)gmallocn(bufWidth * bufHeight, sizeof(int));
+ memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
+ }
+#if USE_EXCEPTIONS
+ } catch (GMemException) {
+ error(errSyntaxError, getPos(), "Out of memory in DCT stream");
+ y = height;
+ prepared = gTrue;
+ return;
+ }
+#endif
+
+ // read the image data
+ do {
+ restartMarker = 0xd0;
+ restart();
+ readScan();
+ } while (readHeader(gFalse));
+
+ // decode
+ decodeImage();
+
+ // initialize counters
+ comp = 0;
+ x = 0;
+ y = 0;
+
+ } else {
+
+ if (scanInfo.numComps != numComps) {
+ error(errSyntaxError, getPos(), "Invalid scan in sequential DCT stream");
+ y = height;
+ prepared = gTrue;
+ return;
+ }
+
+ // allocate a buffer for one row of MCUs
+ bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
+ rowBuf = (Guchar *)gmallocn(numComps * mcuHeight, bufWidth);
+ rowBufPtr = rowBufEnd = rowBuf;
+
+ // initialize counters
+ y = -mcuHeight;
+
+ restartMarker = 0xd0;
+ restart();
+ }
+
+ prepared = gTrue;
+}
+
void DCTStream::restart() {
int i;
@@ -3841,6 +3896,9 @@ GBool DCTStream::readHeader(GBool frame) {
if (!readScanInfo()) {
return gFalse;
}
+ if (frame) {
+ interleaved = scanInfo.numComps == numComps;
+ }
doScan = gTrue;
break;
case 0xdb: // DQT
@@ -4006,7 +4064,6 @@ GBool DCTStream::readScanInfo() {
error(errSyntaxError, getPos(), "Bad DCT scan info block");
return gFalse;
}
- interleaved = scanInfo.numComps == numComps;
for (j = 0; j < numComps; ++j) {
scanInfo.comp[j] = gFalse;
}
@@ -4911,6 +4968,7 @@ FlateStream::FlateStream(Stream *strA, int predictor, int columns,
litCodeTab.codes = NULL;
distCodeTab.codes = NULL;
memset(buf, 0, flateWindow);
+ checkForDecompressionBombs = gTrue;
}
FlateStream::~FlateStream() {
@@ -4936,6 +4994,11 @@ Stream *FlateStream::copy() {
}
}
+void FlateStream::disableDecompressionBombChecking() {
+ checkForDecompressionBombs = gFalse;
+ FilterStream::disableDecompressionBombChecking();
+}
+
void FlateStream::reset() {
int cmf, flg;
@@ -5198,7 +5261,9 @@ void FlateStream::readSome() {
totalOut += remain;
// check for a 'decompression bomb'
- if (totalOut > 50000000 && totalIn < totalOut / 250) {
+ if (checkForDecompressionBombs &&
+ totalOut > decompressionBombSizeThreshold &&
+ totalIn < totalOut / decompressionBombRatioThreshold) {
error(errSyntaxError, getPos(), "Decompression bomb in flate stream");
endOfBlock = eof = gTrue;
remain = 0;
@@ -5249,8 +5314,7 @@ GBool FlateStream::startBlock() {
goto err;
check |= (c & 0xff) << 8;
if (check != (~blockLen & 0xffff))
- error(errSyntaxError, getPos(),
- "Bad uncompressed block length in flate stream");
+ goto err;
codeBuf = 0;
codeSize = 0;
totalIn += 4;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
index 59cafadc14f..9d084c94895 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
@@ -80,6 +80,13 @@ public:
virtual GBool isEmbedStream() { return gFalse; }
+ // Disable checking for 'decompression bombs', i.e., cases where the
+ // encryption ratio looks suspiciously high. This should be called
+ // for things like images which (a) can have very high compression
+ // ratios in certain cases, and (b) have fixed data sizes controlled
+ // by the reader.
+ virtual void disableDecompressionBombChecking() {}
+
// Reset stream to beginning.
virtual void reset() = 0;
@@ -192,6 +199,8 @@ public:
FilterStream(Stream *strA);
virtual ~FilterStream();
+ virtual void disableDecompressionBombChecking()
+ { str->disableDecompressionBombChecking(); }
virtual void close();
virtual GFileOffset getPos() { return str->getPos(); }
virtual void setPos(GFileOffset pos, int dir = 0);
@@ -472,6 +481,7 @@ public:
virtual ~LZWStream();
virtual Stream *copy();
virtual StreamKind getKind() { return strLZW; }
+ virtual void disableDecompressionBombChecking();
virtual void reset();
virtual int getChar();
virtual int lookChar();
@@ -501,6 +511,7 @@ private:
int seqLength; // length of current sequence
int seqIndex; // index into current sequence
GBool first; // first code after a table clear
+ GBool checkForDecompressionBombs;
unsigned long long totalIn; // total number of encoded bytes read so far
unsigned long long totalOut; // total number of bytes decoded so far
@@ -693,6 +704,7 @@ private:
#else // HAVE_JPEGLIB
+ GBool prepared; // set after prepare() is called
GBool progressive; // set if in progressive mode
GBool interleaved; // set if in interleaved mode
int width, height; // image size
@@ -724,6 +736,7 @@ private:
int inputBuf; // input buffer for variable length codes
int inputBits; // number of valid bits in input buffer
+ void prepare();
void restart();
GBool readMCURow();
void readScan();
@@ -791,6 +804,7 @@ public:
virtual ~FlateStream();
virtual Stream *copy();
virtual StreamKind getKind() { return strFlate; }
+ virtual void disableDecompressionBombChecking();
virtual void reset();
virtual int getChar();
virtual int lookChar();
@@ -816,6 +830,7 @@ private:
int blockLen; // remaining length of uncompressed block
GBool endOfBlock; // set when end of block is reached
GBool eof; // set when end of stream is reached
+ GBool checkForDecompressionBombs;
unsigned long long totalIn; // total number of encoded bytes read so far
unsigned long long totalOut; // total number of bytes decoded so far
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
index 9ec906c7379..e2da940bb41 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
@@ -58,27 +58,42 @@
// considered to be equivalent.
#define splitGapSlack 0.2
-// The vertical gap threshold (minimum gap required to split
-// vertically) depends on the (approximate) number of lines in the
-// block:
-// threshold = (max + slope * nLines) * avgFontSize
-// with a min value of vertGapThresholdMin * avgFontSize.
-#define vertGapThresholdMin 0.8
-#define vertGapThresholdMax 3
-#define vertGapThresholdSlope -0.5
-
-// Vertical gap threshold for table mode.
-#define vertGapThresholdTableMin 0.2
-#define vertGapThresholdTableMax 0.5
-#define vertGapThresholdTableSlope -0.02
+// Gap area (width * height) must be larger than this to allow a
+// vertical split (or horizontal split if rot=1,3).
+#define minGapArea 3
+#define minTableGapArea 1.5
// A large character has a font size larger than
// largeCharThreshold * avgFontSize.
#define largeCharThreshold 1.5
-// A block will be split vertically only if the resulting chunk
-// widths are greater than vertSplitChunkThreshold * avgFontSize.
-#define vertSplitChunkThreshold 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
+// to this minimum chunk width criterion.
+#define minChunkWidth 2
+#define maxSingleLineHeight 1.5
+
+// Minimum vertical gap is minGapSize * minFontSize.
+// (horizontal gap for rot=1,3)
+#define minGapSize 0.2
+
+// Maximum vertical gap for a "small" split is maxWordGapSize *
+// avgFontSize.
+#define maxWordGapSize 2.5
+#define tableModeMaxWordGapSize 1.1
+
+// Adjacent lines can overlap by at most lineOverlapThreshold *
+// lineHeight.
+#define lineOverlapThreshold 0.33
+
+// Subscripts (superscripts) must overlap the next (previous) line by
+// minSubSuperscriptVertOverlap * fontSize.
+#define minSubSuperscriptVertOverlap 0.25
+
+// Subscripts (superscripts) may horizontally overlap adjacent
+// characters by up to maxSubSuperscriptHorizOverlap * fontSize.
+#define maxSubSuperscriptHorizOverlap 0.05
// Max difference in primary,secondary coordinates (as a fraction of
// the font size) allowed for duplicated text (fake boldface, drop
@@ -257,6 +272,16 @@ TextChar::TextChar(Unicode cA, int charPosA, int charLenA,
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;
+ }
+ }
rot = (Guchar)rotA;
rotated = (char)rotatedA;
clipped = (char)clippedA;
@@ -527,6 +552,35 @@ void TextGaps::addGap(double x, double w) {
}
//------------------------------------------------------------------------
+// SplitLine
+//------------------------------------------------------------------------
+
+class SplitLine {
+public:
+
+ SplitLine(int firstCharIdxA, int lastCharIdxA,
+ double yMinA, double yMaxA);
+ ~SplitLine();
+
+ int firstCharIdx, lastCharIdx;
+ double yMin, yMax; // xMin, xMax if rot = {1,3}
+ GList *chars; // [TextChar]
+};
+
+SplitLine::SplitLine(int firstCharIdxA, int lastCharIdxA,
+ double yMinA, double yMaxA) {
+ firstCharIdx = firstCharIdxA;
+ lastCharIdx = lastCharIdxA;
+ yMin = yMinA;
+ yMax = yMaxA;
+ chars = NULL;
+}
+
+SplitLine::~SplitLine() {
+ delete chars;
+}
+
+//------------------------------------------------------------------------
// TextSuperLine
//------------------------------------------------------------------------
@@ -671,6 +725,16 @@ TextFontInfo::TextFontInfo(GfxState *state) {
}
}
+TextFontInfo::TextFontInfo() {
+ fontID.num = -1;
+ fontID.gen = -1;
+ fontName = NULL;
+ flags = 0;
+ mWidth = 0;
+ ascent = 0;
+ descent = 0;
+}
+
TextFontInfo::~TextFontInfo() {
if (fontName) {
delete fontName;
@@ -1388,11 +1452,13 @@ void TextPage::addChar(GfxState *state, double x, double y,
}
}
- // skip space, tab, and non-breaking space characters
+ // skip various whitespace characters
// (ActualText spans can result in multiple space chars)
for (i = 0; i < uLen; ++i) {
if (u[i] != (Unicode)0x20 &&
u[i] != (Unicode)0x09 &&
+ u[i] != (Unicode)0x0a &&
+ u[i] != (Unicode)0x0d &&
u[i] != (Unicode)0xa0) {
break;
}
@@ -1507,6 +1573,36 @@ void TextPage::addChar(GfxState *state, double x, double y,
charPos += nBytes;
}
+void TextPage::addSpecialChar(double xMin, double yMin,
+ double xMax, double yMax,
+ int rot, TextFontInfo *font, double fontSize,
+ Unicode u) {
+ chars->append(new TextChar(u, 0, 0, xMin, yMin, xMax, yMax, rot,
+ gFalse, gFalse, gFalse, font, fontSize, 0, 0, 0));
+}
+
+//~ this is inefficient -- consider using some sort of tree
+//~ structure to store the chars (?)
+void TextPage::removeChars(double xMin, double yMin,
+ double xMax, double yMax,
+ double xOverlapThresh, double yOverlapThresh) {
+ int i = 0;
+ while (i < chars->getLength()) {
+ TextChar *ch = (TextChar *)chars->get(i);
+ double xOverlap = (ch->xMax < xMax ? ch->xMax : xMax)
+ - (ch->xMin > xMin ? ch->xMin : xMin);
+ double yOverlap = (ch->yMax < yMax ? ch->yMax : yMax)
+ - (ch->yMin > yMin ? ch->yMin : yMin);
+ if (xOverlap > xOverlapThresh * (ch->xMax - ch->xMin) &&
+ yOverlap > yOverlapThresh * (ch->yMax - ch->yMin)) {
+ chars->del(i);
+ delete ch;
+ } else {
+ ++i;
+ }
+ }
+}
+
void TextPage::incCharCount(int nChars) {
charPos += nChars;
}
@@ -2181,6 +2277,8 @@ void TextPage::writeRaw(void *outputStream,
void TextPage::encodeFragment(Unicode *text, int len, UnicodeMap *uMap,
GBool primaryLR, GString *s) {
char lre[8], rle[8], popdf[8], buf[8];
+ GBool open;
+ Unicode opposite;
int lreLen, rleLen, popdfLen, n;
int i, j, k;
@@ -2195,7 +2293,11 @@ void TextPage::encodeFragment(Unicode *text, int len, UnicodeMap *uMap,
i = 0;
while (i < len) {
// output a left-to-right section
- for (j = i; j < len && !unicodeTypeR(text[j]); ++j) ;
+ for (j = i;
+ j < len && !unicodeEffectiveTypeR(text[j],
+ j > 0 ? text[j-1] : 0,
+ j < len-1 ? text[j+1] : 0);
+ ++j) ;
for (k = i; k < j; ++k) {
n = uMap->mapUnicode(text[k], buf, sizeof(buf));
s->append(buf, n);
@@ -2203,12 +2305,18 @@ void TextPage::encodeFragment(Unicode *text, int len, UnicodeMap *uMap,
i = j;
// output a right-to-left section
for (j = i;
- j < len && !(unicodeTypeL(text[j]) || unicodeTypeNum(text[j]));
+ j < len && !unicodeEffectiveTypeLOrNum(text[j],
+ j > 0 ? text[j-1] : 0,
+ j < len-1 ? text[j+1] : 0);
++j) ;
if (j > i) {
s->append(rle, rleLen);
for (k = j - 1; k >= i; --k) {
- n = uMap->mapUnicode(text[k], buf, sizeof(buf));
+ if (unicodeBracketInfo(text[k], &open, &opposite)) {
+ n = uMap->mapUnicode(opposite, buf, sizeof(buf));
+ } else {
+ n = uMap->mapUnicode(text[k], buf, sizeof(buf));
+ }
s->append(buf, n);
}
s->append(popdf, popdfLen);
@@ -2216,26 +2324,32 @@ void TextPage::encodeFragment(Unicode *text, int len, UnicodeMap *uMap,
}
}
- } else {
+ } else { // !primaryLR
- // Note: This code treats numeric characters (European and
- // Arabic/Indic) as left-to-right, which isn't strictly correct
- // (incurs extra LRE/POPDF pairs), but does produce correct
- // visual formatting.
s->append(rle, rleLen);
i = len - 1;
while (i >= 0) {
// output a right-to-left section
for (j = i;
- j >= 0 && !(unicodeTypeL(text[j]) || unicodeTypeNum(text[j]));
+ j >= 0 && !unicodeEffectiveTypeLOrNum(text[j],
+ j > 0 ? text[j-1] : 0,
+ j < len-1 ? text[j+1] : 0);
--j) ;
for (k = i; k > j; --k) {
- n = uMap->mapUnicode(text[k], buf, sizeof(buf));
+ if (unicodeBracketInfo(text[k], &open, &opposite)) {
+ n = uMap->mapUnicode(opposite, buf, sizeof(buf));
+ } else {
+ n = uMap->mapUnicode(text[k], buf, sizeof(buf));
+ }
s->append(buf, n);
}
i = j;
// output a left-to-right section
- for (j = i; j >= 0 && !unicodeTypeR(text[j]); --j) ;
+ for (j = i;
+ j >= 0 && !unicodeEffectiveTypeR(text[j],
+ j > 0 ? text[j-1] : 0,
+ j < len-1 ? text[j+1] : 0);
+ --j) ;
if (j < i) {
s->append(lre, lreLen);
for (k = j + 1; k <= i; ++k) {
@@ -2257,6 +2371,45 @@ void TextPage::encodeFragment(Unicode *text, int len, UnicodeMap *uMap,
}
}
+// Returns true if [u] is LTR, in the context of [left]-[u]-[right].
+// NB: returns false if [u] is neutral.
+GBool TextPage::unicodeEffectiveTypeLOrNum(Unicode u, Unicode left,
+ Unicode right) {
+ GBool open;
+ Unicode opposite;
+ if (unicodeBracketInfo(u, &open, &opposite)) {
+ // bracket takes the direction of the first char inside the bracket
+ if (open) {
+ return unicodeTypeL(right) || unicodeTypeNum(right);
+ } else {
+ return unicodeTypeL(left) || unicodeTypeNum(left);
+ }
+ } else if (unicodeTypeNumSep(u)) {
+ // numeric separator is numeric if either side is a digit; neutral
+ // otherwise
+ return unicodeTypeDigit(left) || unicodeTypeDigit(right);
+ } else {
+ return unicodeTypeL(u) || unicodeTypeDigit(u);
+ }
+}
+
+// Returns true if [u] is RTL, in the context of [left]-[u]-[right].
+// NB: returns false if [u] is neutral.
+GBool TextPage::unicodeEffectiveTypeR(Unicode u, Unicode left, Unicode right) {
+ GBool open;
+ Unicode opposite;
+ if (unicodeBracketInfo(u, &open, &opposite)) {
+ // bracket takes the direction of the first char inside the bracket
+ if (open) {
+ return unicodeTypeR(right);
+ } else {
+ return unicodeTypeR(left);
+ }
+ } else {
+ return unicodeTypeR(u);
+ }
+}
+
//------------------------------------------------------------------------
// TextPage: layout analysis
//------------------------------------------------------------------------
@@ -3406,7 +3559,7 @@ TextBlock *TextPage::splitChars(GList *charsA) {
}
}
if (chars2->getLength() > 0) {
- tree[rot] = split(chars2, rot);
+ tree[rot] = split(chars2, rot, gFalse);
}
}
delete chars2;
@@ -3457,26 +3610,29 @@ TextBlock *TextPage::splitChars(GList *charsA) {
}
// Generate a tree of TextBlocks, marked as columns, lines, and words.
-TextBlock *TextPage::split(GList *charsA, int rot) {
+TextBlock *TextPage::split(GList *charsA, int rot, GBool vertOnly) {
TextBlock *blk;
GList *chars2, *chars3;
+ GList *splitLines;
TextGaps *horizGaps, *vertGaps;
TextChar *ch;
- double xMin, yMin, xMax, yMax, avgFontSize;
+ double xMin, yMin, xMax, yMax, avgFontSize, minFontSize;
double horizGapSize, vertGapSize, minHorizChunkWidth, minVertChunkWidth;
- double gap, nLines, vertGapThreshold, minChunk;
+ double gap, gapThreshold, smallSplitThreshold, blockHeight, minChunk;
double largeCharSize;
double x0, x1, y0, y1;
int nHorizGaps, nVertGaps, nLargeChars;
int i;
- GBool doHorizSplit, doVertSplit, smallSplit;
+ GBool singleLine;
+ GBool doHorizSplit, doVertSplit, doLineSplit, doLargeCharSplit, smallSplit;
//----- find all horizontal and vertical gaps
horizGaps = new TextGaps();
vertGaps = new TextGaps();
- findGaps(charsA, rot, &xMin, &yMin, &xMax, &yMax, &avgFontSize,
- horizGaps, vertGaps);
+ splitLines = new GList();
+ findGaps(charsA, rot, &xMin, &yMin, &xMax, &yMax, &avgFontSize, &minFontSize,
+ splitLines, horizGaps, vertGaps);
//----- find the largest horizontal and vertical gaps
@@ -3540,38 +3696,48 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
//----- compute splitting parameters
- // approximation of number of lines in block
- if (fabs(avgFontSize) < 0.001) {
- nLines = 1;
- } else if (rot & 1) {
- nLines = (xMax - xMin) / avgFontSize;
- } else {
- nLines = (yMax - yMin) / avgFontSize;
- }
+ // compute block height; check for single line
+ blockHeight = (rot & 1) ? xMax - xMin : yMax - yMin;
+ singleLine = blockHeight < maxSingleLineHeight * avgFontSize &&
+ splitLines->getLength() == 1;
// compute the minimum allowed vertical gap size
// (this is a horizontal gap threshold for rot=1,3
if (control.mode == textOutTableLayout) {
- vertGapThreshold = vertGapThresholdTableMax
- + vertGapThresholdTableSlope * nLines;
- if (vertGapThreshold < vertGapThresholdTableMin) {
- vertGapThreshold = vertGapThresholdTableMin;
+ if (rot & 1) {
+ gapThreshold = (minTableGapArea * avgFontSize * avgFontSize)
+ / (xMax - xMin);
+ } else {
+ gapThreshold = (minTableGapArea * avgFontSize * avgFontSize)
+ / (yMax - yMin);
+ }
+ if (minGapSize * avgFontSize > gapThreshold) {
+ gapThreshold = minGapSize * avgFontSize;
}
- } else if (control.mode == textOutSimpleLayout) {
- vertGapThreshold = simpleLayoutGapThreshold;
+ smallSplitThreshold = tableModeMaxWordGapSize * avgFontSize;
} else {
- vertGapThreshold = vertGapThresholdMax + vertGapThresholdSlope * nLines;
- if (vertGapThreshold < vertGapThresholdMin) {
- vertGapThreshold = vertGapThresholdMin;
+ if (rot & 1) {
+ gapThreshold = (minGapArea * avgFontSize * avgFontSize) / (xMax - xMin);
+ if (vertGapSize > gapThreshold) {
+ gapThreshold = vertGapSize;
+ }
+ } else {
+ gapThreshold = (minGapArea * avgFontSize * avgFontSize) / (yMax - yMin);
+ if (horizGapSize > gapThreshold) {
+ gapThreshold = horizGapSize;
+ }
+ }
+ if (minGapSize * avgFontSize > gapThreshold) {
+ gapThreshold = minGapSize * avgFontSize;
}
+ smallSplitThreshold = maxWordGapSize * avgFontSize;
}
- vertGapThreshold = vertGapThreshold * avgFontSize;
- // compute the minimum allowed chunk width
- if (control.mode == textOutTableLayout) {
+ if (control.mode == textOutTableLayout ||
+ singleLine) {
minChunk = 0;
} else {
- minChunk = vertSplitChunkThreshold * avgFontSize;
+ minChunk = minChunkWidth * avgFontSize;
}
// look for large chars
@@ -3593,49 +3759,68 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
}
// figure out which type of split to do
- doHorizSplit = doVertSplit = gFalse;
+ doHorizSplit = doVertSplit = doLineSplit = doLargeCharSplit = gFalse;
smallSplit = gFalse;
if (rot & 1) {
- if (control.mode == textOutSimpleLayout) {
+ if (vertOnly) {
+ if (nHorizGaps > 0 && horizGapSize > minGapSize * minFontSize) {
+ doHorizSplit = gTrue;
+ smallSplit = horizGapSize < smallSplitThreshold;
+ }
+ } else if (control.mode == textOutSimpleLayout) {
if (nVertGaps > 0) {
doVertSplit = gTrue;
- } else if (nHorizGaps > 0) {
+ } else if (nHorizGaps > 0 && horizGapSize > minGapSize * minFontSize) {
doHorizSplit = gTrue;
- smallSplit = horizGapSize <= vertGapThreshold;
+ smallSplit = horizGapSize < smallSplitThreshold;
+ } else if (!vertOnly && splitLines->getLength() > 1) {
+ doLineSplit = gTrue;
}
} else if (nHorizGaps > 0 &&
- (horizGapSize > vertGapSize ||
- control.mode == textOutTableLayout) &&
- horizGapSize > vertGapThreshold &&
- (minHorizChunkWidth > minChunk ||
- nVertGaps == 0)) {
+ ((horizGapSize > minGapSize * minFontSize &&
+ nVertGaps == 0 &&
+ splitLines->getLength() <= 1) ||
+ (horizGapSize > gapThreshold &&
+ minHorizChunkWidth > minChunk))) {
doHorizSplit = gTrue;
+ smallSplit = horizGapSize < smallSplitThreshold;
} else if (nVertGaps > 0) {
doVertSplit = gTrue;
- } else if (nLargeChars == 0 && nHorizGaps > 0) {
- doHorizSplit = gTrue;
- smallSplit = gTrue;
+ } else if (nLargeChars > 0) {
+ doLargeCharSplit = gTrue;
+ } else if (splitLines->getLength() > 1) {
+ doLineSplit = gTrue;
}
} else {
- if (control.mode == textOutSimpleLayout) {
+ if (vertOnly) {
+ if (nVertGaps > 0 &&
+ vertGapSize > minGapSize * minFontSize) {
+ doVertSplit = gTrue;
+ smallSplit = vertGapSize < smallSplitThreshold;
+ }
+ } else if (control.mode == textOutSimpleLayout) {
if (nHorizGaps > 0) {
doHorizSplit = gTrue;
- } else if (nVertGaps > 0) {
+ } else if (nVertGaps > 0 && vertGapSize > minGapSize * minFontSize) {
doVertSplit = gTrue;
- smallSplit = vertGapSize <= vertGapThreshold;
+ smallSplit = vertGapSize < smallSplitThreshold;
+ } else if (splitLines->getLength() > 1) {
+ doLineSplit = gTrue;
}
} else if (nVertGaps > 0 &&
- (vertGapSize > horizGapSize ||
- control.mode == textOutTableLayout) &&
- vertGapSize > vertGapThreshold &&
- (minVertChunkWidth > minChunk ||
- nHorizGaps == 0)) {
+ ((vertGapSize > minGapSize * minFontSize &&
+ nHorizGaps == 0 &&
+ splitLines->getLength() <= 1) ||
+ (vertGapSize > gapThreshold &&
+ minVertChunkWidth > minChunk))) {
doVertSplit = gTrue;
+ smallSplit = vertGapSize < smallSplitThreshold;
} else if (nHorizGaps > 0) {
doHorizSplit = gTrue;
- } else if (nLargeChars == 0 && nVertGaps > 0) {
- doVertSplit = gTrue;
- smallSplit = gTrue;
+ } else if (nLargeChars > 0) {
+ doLargeCharSplit = gTrue;
+ } else if (splitLines->getLength() > 1) {
+ doLineSplit = gTrue;
}
}
@@ -3662,13 +3847,13 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
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));
+ blk->addChild(split(chars2, rot, vertOnly));
delete chars2;
x0 = x1;
}
}
chars2 = getChars(charsA, x0, yMin - 1, xMax + 1, yMax + 1);
- blk->addChild(split(chars2, rot));
+ blk->addChild(split(chars2, rot, vertOnly));
delete chars2;
// split horizontally
@@ -3689,17 +3874,17 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
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));
+ blk->addChild(split(chars2, rot, gFalse));
delete chars2;
y0 = y1;
}
}
chars2 = getChars(charsA, xMin - 1, y0, xMax + 1, yMax + 1);
- blk->addChild(split(chars2, rot));
+ blk->addChild(split(chars2, rot, gFalse));
delete chars2;
// split into larger and smaller chars
- } else if (nLargeChars > 0) {
+ } else if (doLargeCharSplit) {
#if 0 //~debug
printf("large char split xMin=%g yMin=%g xMax=%g yMax=%g\n",
xMin, pageHeight - yMax, xMax, pageHeight - yMin);
@@ -3714,23 +3899,60 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
chars3->append(ch);
}
}
- blk = split(chars3, rot);
+ blk = split(chars3, rot, gFalse);
+ chars2->sort((rot & 1) ? &TextChar::cmpY : &TextChar::cmpX);
insertLargeChars(chars2, blk);
delete chars2;
delete chars3;
+ // split into lines -- this handles the case where lines overlap slightly
+ } else if (doLineSplit) {
+ mergeSplitLines(charsA, rot, splitLines);
+#if 0 //~debug
+ printf("line split xMin=%g yMin=%g xMax=%g yMax=%g\n",
+ xMin, pageHeight - yMax, xMax, pageHeight - yMin);
+ for (i = 0; i < splitLines->getLength(); ++i) {
+ SplitLine *splitLine = (SplitLine *)splitLines->get(i);
+ printf(" yMin=%g yMax=%g\n",
+ pageHeight - splitLine->yMax, pageHeight - splitLine->yMin);
+ }
+#endif
+ if (splitLines->getLength() == 1) {
+ // if merging sub/superscripts resulted in a single line, then
+ // it's a leaf
+ blk = new TextBlock(blkLeaf, rot);
+ SplitLine *splitLine = (SplitLine *)splitLines->get(0);
+ for (i = 0; i < splitLine->chars->getLength(); ++i) {
+ blk->addChild((TextChar *)splitLine->chars->get(i), gTrue);
+ }
+ } 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));
+ }
+ }
+
// create a leaf node
} else {
#if 0 //~debug
printf("leaf xMin=%g yMin=%g xMax=%g yMax=%g\n",
xMin, pageHeight - yMax, xMax, pageHeight - yMin);
+ printf(" ");
+ for (i = 0; i < charsA->getLength(); ++i) {
+ printf("%c", ((TextChar *)charsA->get(i))->c);
+ }
+ printf("\n");
#endif
blk = new TextBlock(blkLeaf, rot);
+ charsA->sort((rot & 1) ? &TextChar::cmpY : &TextChar::cmpX);
for (i = 0; i < charsA->getLength(); ++i) {
blk->addChild((TextChar *)charsA->get(i), gTrue);
}
}
+ deleteGList(splitLines, SplitLine);
delete horizGaps;
delete vertGaps;
@@ -3750,11 +3972,12 @@ GList *TextPage::getChars(GList *charsA, double xMin, double yMin,
ret = new GList();
for (i = 0; i < charsA->getLength(); ++i) {
ch = (TextChar *)charsA->get(i);
- // because of {ascent,descent}AdjustFactor, the y coords (or x
- // coords for rot 1,3) for the gaps will be a little bit tight --
- // so we use the center of the character here
+ // compute the center of the adjusted bbox, and check to see if
+ // that's inside the specified rectangle
x = 0.5 * (ch->xMin + ch->xMax);
- y = 0.5 * (ch->yMin + ch->yMax);
+ y = 0.5 * (ch->yMin + ch->yMax +
+ (ascentAdjustFactor - descentAdjustFactor) *
+ (ch->yMax - ch->yMin));
if (x > xMin && x < xMax && y > yMin && y < yMax) {
ret->append(ch);
}
@@ -3765,22 +3988,15 @@ GList *TextPage::getChars(GList *charsA, double xMin, double yMin,
void TextPage::findGaps(GList *charsA, int rot,
double *xMinOut, double *yMinOut,
double *xMaxOut, double *yMaxOut,
- double *avgFontSizeOut,
+ double *avgFontSizeOut, double *minFontSizeOut,
+ GList *splitLines,
TextGaps *horizGaps, TextGaps *vertGaps) {
- TextChar *ch;
- char *horizProfile, *vertProfile;
- double xMin, yMin, xMax, yMax, w;
- double minFontSize, avgFontSize, splitPrecision, invSplitPrecision;
- double ascentAdjust, descentAdjust;
- int xMinI, yMinI, xMaxI, yMaxI, xMinI2, yMinI2, xMaxI2, yMaxI2;
- int start, x, y, i;
-
- //----- compute bbox, min font size, average font size, and split precision
+ //----- compute bbox, min font size, and average font size
- xMin = yMin = xMax = yMax = 0; // make gcc happy
- minFontSize = avgFontSize = 0;
- for (i = 0; i < charsA->getLength(); ++i) {
- ch = (TextChar *)charsA->get(i);
+ double xMin = 0, yMin = 0, xMax = 0, yMax = 0;
+ double avgFontSize = 0, minFontSize = 0;
+ for (int i = 0; i < charsA->getLength(); ++i) {
+ TextChar *ch = (TextChar *)charsA->get(i);
if (i == 0 || ch->xMin < xMin) {
xMin = ch->xMin;
}
@@ -3799,115 +4015,338 @@ void TextPage::findGaps(GList *charsA, int rot,
}
}
avgFontSize /= charsA->getLength();
- splitPrecision = splitPrecisionMul * minFontSize;
- if (splitPrecision < minSplitPrecision) {
- splitPrecision = minSplitPrecision;
- }
- invSplitPrecision = 1 / splitPrecision;
*xMinOut = xMin;
*yMinOut = yMin;
*xMaxOut = xMax;
*yMaxOut = yMax;
*avgFontSizeOut = avgFontSize;
+ *minFontSizeOut = minFontSize;
- //----- compute the horizontal and vertical profiles
+ //----- find vertical gaps
- if (xMin * invSplitPrecision < 0.5 * INT_MIN ||
- xMax * invSplitPrecision > 0.5 * INT_MAX ||
- yMin * invSplitPrecision < 0.5 * INT_MIN ||
- yMax * invSplitPrecision > 0.5 * INT_MAX) {
- return;
- }
- // add some slack to the array bounds to avoid floating point
- // precision problems
- xMinI = (int)floor(xMin * invSplitPrecision) - 1;
- yMinI = (int)floor(yMin * invSplitPrecision) - 1;
- xMaxI = (int)floor(xMax * invSplitPrecision) + 1;
- yMaxI = (int)floor(yMax * invSplitPrecision) + 1;
- horizProfile = (char *)gmalloc(yMaxI - yMinI + 1);
- vertProfile = (char *)gmalloc(xMaxI - xMinI + 1);
- memset(horizProfile, 0, yMaxI - yMinI + 1);
- memset(vertProfile, 0, xMaxI - xMinI + 1);
- for (i = 0; i < charsA->getLength(); ++i) {
- ch = (TextChar *)charsA->get(i);
- // yMinI2 and yMaxI2 are adjusted to allow for slightly overlapping lines
- switch (rot) {
- case 0:
- default:
- xMinI2 = (int)floor(ch->xMin * invSplitPrecision);
- xMaxI2 = (int)floor(ch->xMax * invSplitPrecision);
- ascentAdjust = ascentAdjustFactor * (ch->yMax - ch->yMin);
- yMinI2 = (int)floor((ch->yMin + ascentAdjust) * invSplitPrecision);
- descentAdjust = descentAdjustFactor * (ch->yMax - ch->yMin);
- yMaxI2 = (int)floor((ch->yMax - descentAdjust) * invSplitPrecision);
- break;
- case 1:
- descentAdjust = descentAdjustFactor * (ch->xMax - ch->xMin);
- xMinI2 = (int)floor((ch->xMin + descentAdjust) * invSplitPrecision);
- ascentAdjust = ascentAdjustFactor * (ch->xMax - ch->xMin);
- xMaxI2 = (int)floor((ch->xMax - ascentAdjust) * invSplitPrecision);
- yMinI2 = (int)floor(ch->yMin * invSplitPrecision);
- yMaxI2 = (int)floor(ch->yMax * invSplitPrecision);
- break;
- case 2:
- xMinI2 = (int)floor(ch->xMin * invSplitPrecision);
- xMaxI2 = (int)floor(ch->xMax * invSplitPrecision);
- descentAdjust = descentAdjustFactor * (ch->yMax - ch->yMin);
- yMinI2 = (int)floor((ch->yMin + descentAdjust) * invSplitPrecision);
- ascentAdjust = ascentAdjustFactor * (ch->yMax - ch->yMin);
- yMaxI2 = (int)floor((ch->yMax - ascentAdjust) * invSplitPrecision);
- break;
- case 3:
- ascentAdjust = ascentAdjustFactor * (ch->xMax - ch->xMin);
- xMinI2 = (int)floor((ch->xMin + ascentAdjust) * invSplitPrecision);
- descentAdjust = descentAdjustFactor * (ch->xMax - ch->xMin);
- xMaxI2 = (int)floor((ch->xMax - descentAdjust) * invSplitPrecision);
- yMinI2 = (int)floor(ch->yMin * invSplitPrecision);
- yMaxI2 = (int)floor(ch->yMax * invSplitPrecision);
- break;
- }
- for (y = yMinI2; y <= yMaxI2; ++y) {
- horizProfile[y - yMinI] = 1;
+ if (rot & 1) {
+ charsA->sort(&TextChar::cmpY);
+ double yyMax = 0;
+ for (int i = 0; i < charsA->getLength(); ++i) {
+ TextChar *ch = (TextChar *)charsA->get(i);
+ if (i == 0) {
+ yyMax = ch->yMax;
+ } else if (ch->yMin <= yyMax) {
+ if (ch->yMax > yyMax) {
+ yyMax = ch->yMax;
+ }
+ } else {
+ horizGaps->addGap(0.5 * (ch->yMin + yyMax), ch->yMin - yyMax);
+ yyMax = ch->yMax;
+ }
}
- for (x = xMinI2; x <= xMaxI2; ++x) {
- vertProfile[x - xMinI] = 1;
+ } else {
+ charsA->sort(&TextChar::cmpX);
+ double xxMax = 0;
+ for (int i = 0; i < charsA->getLength(); ++i) {
+ TextChar *ch = (TextChar *)charsA->get(i);
+ if (i == 0) {
+ xxMax = ch->xMax;
+ } else if (ch->xMin <= xxMax) {
+ if (ch->xMax > xxMax) {
+ xxMax = ch->xMax;
+ }
+ } else {
+ vertGaps->addGap(0.5 * (ch->xMin + xxMax), ch->xMin - xxMax);
+ xxMax = ch->xMax;
+ }
}
}
- //----- build the list of horizontal gaps
+ //----- partition into lines and find horizontal gaps
- for (start = yMinI; start < yMaxI && !horizProfile[start - yMinI]; ++start) ;
- for (y = start; y < yMaxI; ++y) {
- if (horizProfile[y - yMinI]) {
- if (!horizProfile[y + 1 - yMinI]) {
- start = y;
+ if (rot & 1) {
+ charsA->sort(&TextChar::cmpX);
+ SplitLine *splitLine = NULL;
+ double xxMin = 0, 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;
+ xxMax = ch->xMax;
+ splitLine = new SplitLine(i, i, xxMin, xxMax);
+ splitLines->append(splitLine);
+ } else {
+ splitLine->lastCharIdx = i;
+ if (ch->xMax > xxMax) {
+ xxMax = ch->xMax;
+ splitLine->yMax = xxMax;
+ }
}
- } else {
- if (horizProfile[y + 1 - yMinI]) {
- w = (y - start) * splitPrecision;
- horizGaps->addGap((start + 1) * splitPrecision + 0.5 * w, w);
+ }
+ } else {
+ charsA->sort(&TextChar::cmpY);
+ SplitLine *splitLine = NULL;
+ double yyMin = 0, 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);
+ }
+ yyMin = ch->yMin;
+ yyMax = ch->yMax;
+ splitLine = new SplitLine(i, i, yyMin, yyMax);
+ splitLines->append(splitLine);
+ } else {
+ splitLine->lastCharIdx = i;
+ if (ch->yMax > yyMax) {
+ yyMax = ch->yMax;
+ splitLine->yMax = yyMax;
+ }
}
}
}
+}
- //----- build the list of vertical gaps
+void TextPage::mergeSplitLines(GList *charsA, int rot, GList *splitLines) {
+ if (rot & 1) {
- for (start = xMinI; start < xMaxI && !vertProfile[start - xMinI]; ++start) ;
- for (x = start; x < xMaxI; ++x) {
- if (vertProfile[x - xMinI]) {
- if (!vertProfile[x + 1 - xMinI]) {
- start = x;
+ // build the list of chars in each line, sort by y
+ for (int i = 0; i < splitLines->getLength(); ++i) {
+ SplitLine *splitLine = (SplitLine *)splitLines->get(i);
+ splitLine->chars = new GList();
+ for (int j = splitLine->firstCharIdx; j <= splitLine->lastCharIdx; ++j) {
+ splitLine->chars->append(charsA->get(j));
}
- } else {
- if (vertProfile[x + 1 - xMinI]) {
- w = (x - start) * splitPrecision;
- vertGaps->addGap((start + 1) * splitPrecision + 0.5 * w, w);
+ splitLine->chars->sort(&TextChar::cmpY);
+ }
+
+ // look for sub/superscripts accidentally split into separate lines
+ for (int i = 0; i < splitLines->getLength(); ++i) {
+ SplitLine *splitLine = (SplitLine *)splitLines->get(i);
+ SplitLine *prevLine = NULL;
+ SplitLine *nextLine = NULL;
+
+ // check for overlapping lines
+ GBool maybeSub = gFalse;
+ if (i > 0) {
+ prevLine = (SplitLine *)splitLines->get(i-1);
+ double minOverlap = minSubSuperscriptVertOverlap
+ * (prevLine->yMax - prevLine->yMin);
+ maybeSub = prevLine->yMax - splitLine->yMin > minOverlap;
+ }
+ GBool maybeSuper = gFalse;
+ if (i < splitLines->getLength() - 1) {
+ nextLine = (SplitLine *)splitLines->get(i+1);
+ double minOverlap = minSubSuperscriptVertOverlap
+ * (nextLine->yMax - nextLine->yMin);
+ maybeSuper = splitLine->yMax - nextLine->yMin > minOverlap;
+ }
+ if (!maybeSub && !maybeSuper) {
+ continue;
+ }
+
+ // check whether each char in the line is a subscript or
+ // superscript: look at the two chars above-left and above-right
+ // the subscript (or below-left and below-right the superscript)
+ // and check that they are either to the left and right of the
+ // subscript (superscript), or above the subscript (below the
+ // superscript) to account for cases with both a subscript and
+ // superscript
+ int idxAbove = 0;
+ int idxBelow = 0;
+ GBool allSubSuper = gTrue;
+ for (int idx = 0; idx < splitLine->chars->getLength(); ++idx) {
+ TextChar *ch = (TextChar *)splitLine->chars->get(idx);
+ double maxOverlap = maxSubSuperscriptHorizOverlap
+ * (ch->xMax - ch->xMin);
+ GBool isSub = gFalse;
+ if (maybeSub) {
+ while (idxAbove < prevLine->chars->getLength() &&
+ ((TextChar *)prevLine->chars->get(idxAbove))->yMin < ch->yMin) {
+ ++idxAbove;
+ }
+ isSub = ch->xMin < prevLine->yMax &&
+ (idxAbove == 0 ||
+ ch->yMin > ((TextChar *)prevLine->chars->get(idxAbove - 1))->yMax - maxOverlap ||
+ ch->xMin > ((TextChar *)prevLine->chars->get(idxAbove - 1))->xMax) &&
+ (idxAbove == prevLine->chars->getLength() ||
+ ch->yMax < ((TextChar *)prevLine->chars->get(idxAbove))->yMin + maxOverlap ||
+ ch->xMin > ((TextChar *)prevLine->chars->get(idxAbove))->xMax);
+ }
+ GBool isSuper = gFalse;
+ if (maybeSuper) {
+ while (idxBelow < nextLine->chars->getLength() &&
+ ((TextChar *)nextLine->chars->get(idxBelow))->yMin < ch->yMin) {
+ ++idxBelow;
+ }
+ isSuper = ch->xMax > nextLine->yMin &&
+ (idxBelow == 0 ||
+ ch->yMin > ((TextChar *)nextLine->chars->get(idxBelow - 1))->yMax - maxOverlap ||
+ ch->xMax < ((TextChar *)nextLine->chars->get(idxBelow - 1))->xMin) &&
+ (idxBelow == nextLine->chars->getLength() ||
+ ch->yMax < ((TextChar *)nextLine->chars->get(idxBelow))->yMin + maxOverlap ||
+ ch->xMax < ((TextChar *)nextLine->chars->get(idxBelow))->xMin);
+ }
+ if (!isSub && !isSuper) {
+ allSubSuper = gFalse;
+ break;
+ }
+ }
+
+ // merge sub/superscripts into correct lines
+ if (allSubSuper) {
+ 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);
+ if (ch->xMin < prevLine->yMin) {
+ prevLine->yMin = ch->xMin;
+ }
+ if (ch->xMax > prevLine->yMax) {
+ prevLine->yMax = ch->xMax;
+ }
+ } else {
+ nextLine->chars->append(ch);
+ if (ch->xMin < nextLine->yMin) {
+ nextLine->yMin = ch->xMin;
+ }
+ if (ch->xMax > nextLine->yMax) {
+ nextLine->yMax = ch->xMax;
+ }
+ }
+ }
+ if (maybeSub) {
+ prevLine->chars->sort(&TextChar::cmpY);
+ }
+ if (maybeSuper) {
+ nextLine->chars->sort(&TextChar::cmpY);
+ }
+ delete splitLine;
+ splitLines->del(i);
+ }
+ }
+
+ } else {
+
+ // build the list of chars in each line, sort by x
+ for (int i = 0; i < splitLines->getLength(); ++i) {
+ SplitLine *splitLine = (SplitLine *)splitLines->get(i);
+ splitLine->chars = new GList();
+ for (int j = splitLine->firstCharIdx; j <= splitLine->lastCharIdx; ++j) {
+ splitLine->chars->append(charsA->get(j));
+ }
+ splitLine->chars->sort(&TextChar::cmpX);
+ }
+
+ // look for sub/superscripts accidentally split into separate lines
+ for (int i = 0; i < splitLines->getLength(); ++i) {
+ SplitLine *splitLine = (SplitLine *)splitLines->get(i);
+ SplitLine *prevLine = NULL;
+ SplitLine *nextLine = NULL;
+
+ // check for overlapping lines
+ GBool maybeSub = gFalse;
+ if (i > 0) {
+ prevLine = (SplitLine *)splitLines->get(i-1);
+ double minOverlap = minSubSuperscriptVertOverlap
+ * (prevLine->yMax - prevLine->yMin);
+ maybeSub = prevLine->yMax - splitLine->yMin > minOverlap;
+ }
+ GBool maybeSuper = gFalse;
+ if (i < splitLines->getLength() - 1) {
+ nextLine = (SplitLine *)splitLines->get(i+1);
+ double minOverlap = minSubSuperscriptVertOverlap
+ * (nextLine->yMax - nextLine->yMin);
+ maybeSuper = splitLine->yMax - nextLine->yMin > minOverlap;
+ }
+ if (!maybeSub && !maybeSuper) {
+ continue;
+ }
+
+ // check whether each char in the line is a subscript or
+ // superscript: look at the two chars above-left and above-right
+ // the subscript (or below-left and below-right the superscript)
+ // and check that they are either to the left and right of the
+ // subscript (superscript), or above the subscript (below the
+ // superscript) to account for cases with both a subscript and
+ // superscript
+ int idxAbove = 0;
+ int idxBelow = 0;
+ GBool allSubSuper = gTrue;
+ for (int idx = 0; idx < splitLine->chars->getLength(); ++idx) {
+ TextChar *ch = (TextChar *)splitLine->chars->get(idx);
+ double maxOverlap = maxSubSuperscriptHorizOverlap
+ * (ch->yMax - ch->yMin);
+ GBool isSub = gFalse;
+ if (maybeSub) {
+ while (idxAbove < prevLine->chars->getLength() &&
+ ((TextChar *)prevLine->chars->get(idxAbove))->xMin < ch->xMin) {
+ ++idxAbove;
+ }
+ isSub = ch->yMin < prevLine->yMax &&
+ (idxAbove == 0 ||
+ ch->xMin > ((TextChar *)prevLine->chars->get(idxAbove - 1))->xMax - maxOverlap ||
+ ch->yMin > ((TextChar *)prevLine->chars->get(idxAbove - 1))->yMax) &&
+ (idxAbove == prevLine->chars->getLength() ||
+ ch->xMax < ((TextChar *)prevLine->chars->get(idxAbove))->xMin + maxOverlap ||
+ ch->yMin > ((TextChar *)prevLine->chars->get(idxAbove))->yMax);
+ }
+ GBool isSuper = gFalse;
+ if (maybeSuper) {
+ while (idxBelow < nextLine->chars->getLength() &&
+ ((TextChar *)nextLine->chars->get(idxBelow))->xMin < ch->xMin) {
+ ++idxBelow;
+ }
+ isSuper = ch->yMax > nextLine->yMin &&
+ (idxBelow == 0 ||
+ ch->xMin > ((TextChar *)nextLine->chars->get(idxBelow - 1))->xMax - maxOverlap ||
+ ch->yMax < ((TextChar *)nextLine->chars->get(idxBelow - 1))->yMin) &&
+ (idxBelow == nextLine->chars->getLength() ||
+ ch->xMax < ((TextChar *)nextLine->chars->get(idxBelow))->xMin + maxOverlap ||
+ ch->yMax < ((TextChar *)nextLine->chars->get(idxBelow))->yMin);
+ }
+ if (!isSub && !isSuper) {
+ allSubSuper = gFalse;
+ break;
+ }
+ }
+
+ // merge sub/superscripts into correct lines
+ if (allSubSuper) {
+ 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);
+ if (ch->yMin < prevLine->yMin) {
+ prevLine->yMin = ch->yMin;
+ }
+ if (ch->yMax > prevLine->yMax) {
+ prevLine->yMax = ch->yMax;
+ }
+ } else {
+ nextLine->chars->append(ch);
+ if (ch->yMin < nextLine->yMin) {
+ nextLine->yMin = ch->yMin;
+ }
+ if (ch->yMax > nextLine->yMax) {
+ nextLine->yMax = ch->yMax;
+ }
+ }
+ }
+ if (maybeSub) {
+ prevLine->chars->sort(&TextChar::cmpX);
+ }
+ if (maybeSuper) {
+ nextLine->chars->sort(&TextChar::cmpX);
+ }
+ delete splitLine;
+ splitLines->del(i);
}
}
- }
- gfree(horizProfile);
- gfree(vertProfile);
+ }
}
// Decide whether this block is a line, column, or multiple columns:
@@ -4668,7 +5107,12 @@ TextLine *TextPage::buildLine(GList *charsA, int rot,
while (i < charsA->getLength()) {
sp = wordSp - 1;
spaceAfter = gFalse;
- dir = getCharDirection((TextChar *)charsA->get(i));
+ dir = getCharDirection(
+ (TextChar *)charsA->get(i),
+ (i > 0 && !spaceAfter) ? (TextChar *)charsA->get(i-1)
+ : (TextChar *)NULL,
+ (i < charsA->getLength() - 1) ? (TextChar *)charsA->get(i+1)
+ : (TextChar *)NULL);
rotated = ((TextChar *)charsA->get(i))->rotated;
for (j = i+1; j < charsA->getLength(); ++j) {
ch = (TextChar *)charsA->get(j-1);
@@ -4684,7 +5128,10 @@ TextLine *TextPage::buildLine(GList *charsA, int rot,
spaceAfter = gTrue;
break;
}
- dir2 = getCharDirection(ch2);
+ dir2 = getCharDirection(
+ ch2, ch,
+ (j < charsA->getLength() - 1) ? (TextChar *)charsA->get(j+1)
+ : (TextChar *)NULL);
if (ch->font != ch2->font ||
fabs(ch->fontSize - ch2->fontSize) > 0.01 ||
(control.splitRotatedWords && ch2->rotated != rotated) ||
@@ -4830,7 +5277,7 @@ double TextPage::computeWordSpacingThreshold(GList *charsA, int rot) {
}
}
-// Check the characters direction: returns 1 for L or Num; -1 for R; 0
+// Check the character's direction: returns 1 for L or Num; -1 for R; 0
// for others.
int TextPage::getCharDirection(TextChar *ch) {
if (unicodeTypeL(ch->c) || unicodeTypeNum(ch->c)) {
@@ -4842,6 +5289,46 @@ int TextPage::getCharDirection(TextChar *ch) {
return 0;
}
+// Check the character's direction, in the context of the left and
+// right neighboring characters (either of which may be NULL).
+// Returns 1 for L or Num; -1 for R; 0 for others.
+int TextPage::getCharDirection(TextChar *ch, TextChar *left, TextChar *right) {
+ GBool open;
+ Unicode opposite;
+ if (unicodeBracketInfo(ch->c, &open, &opposite)) {
+ // bracket takes the direction of the first char inside the bracket
+ Unicode first = 0;
+ if (open && right) {
+ first = right->c;
+ } else if (!open && left) {
+ first = left->c;
+ }
+ if (unicodeTypeL(first) || unicodeTypeNum(first)) {
+ return 1;
+ }
+ if (unicodeTypeR(first)) {
+ return -1;
+ }
+ return 0;
+ } else if (unicodeTypeNumSep(ch->c)) {
+ // numeric separator is numeric if either side is a digit; neutral
+ // otherwise
+ if ((left && unicodeTypeDigit(left->c)) ||
+ (right && unicodeTypeDigit(right->c))) {
+ return 1;
+ }
+ return 0;
+ } else {
+ if (unicodeTypeL(ch->c) || unicodeTypeDigit(ch->c)) {
+ return 1;
+ }
+ if (unicodeTypeR(ch->c)) {
+ return -1;
+ }
+ return 0;
+ }
+}
+
int TextPage::assignPhysLayoutPositions(GList *columns) {
assignLinePhysPositions(columns);
return assignColumnPhysPositions(columns);
@@ -5130,11 +5617,11 @@ GBool TextPage::findText(Unicode *s, int len,
buildFindCols();
- // convert the search string to uppercase
+ // convert the search string to lowercase
if (!caseSensitive) {
s2 = (Unicode *)gmallocn(len, sizeof(Unicode));
for (i = 0; i < len; ++i) {
- s2[i] = unicodeToUpper(s[i]);
+ s2[i] = unicodeToLower(s[i]);
}
} else {
s2 = s;
@@ -5214,7 +5701,7 @@ GBool TextPage::findText(Unicode *s, int len,
continue;
}
- // convert the line to uppercase
+ // convert the line to lowercase
m = line->len;
if (!caseSensitive) {
if (m > txtSize) {
@@ -5222,7 +5709,7 @@ GBool TextPage::findText(Unicode *s, int len,
txtSize = m;
}
for (k = 0; k < m; ++k) {
- txt[k] = unicodeToUpper(line->text[k]);
+ txt[k] = unicodeToLower(line->text[k]);
}
} else {
txt = line->text;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
index a1d19c22d7d..302975cd5f1 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
@@ -99,7 +99,12 @@ public:
class TextFontInfo {
public:
+ // Create a TextFontInfo for the current font in [state].
TextFontInfo(GfxState *state);
+
+ // Create a dummy TextFontInfo.
+ TextFontInfo();
+
~TextFontInfo();
GBool matches(GfxState *state);
@@ -225,6 +230,7 @@ public:
double getBaseline();
int getRotation() { return rot; }
GList *getWords() { return words; }
+ Unicode *getUnicode() { return text; }
int getLength() { return len; }
double getEdge(int idx) { return edge[idx]; }
GBool getHyphenated() { return hyphenated; }
@@ -476,6 +482,16 @@ public:
// be problematic when converting text to Unicode.
GBool problematicForUnicode() { return problematic; }
+ // Add a 'special' character to this TextPage. This is currently
+ // used by pdftohtml to insert markers for form fields.
+ void addSpecialChar(double xMin, double yMin, double xMax, double yMax,
+ int rot, TextFontInfo *font, double fontSize,
+ Unicode u);
+
+ // Remove characters that fall inside a region.
+ void removeChars(double xMin, double yMin, double xMax, double yMax,
+ double xOverlapThresh, double yOverlapThresh);
+
private:
void startPage(GfxState *state);
@@ -524,6 +540,8 @@ private:
char *eol, int eolLen);
void encodeFragment(Unicode *text, int len, UnicodeMap *uMap,
GBool primaryLR, GString *s);
+ GBool unicodeEffectiveTypeLOrNum(Unicode u, Unicode left, Unicode right);
+ GBool unicodeEffectiveTypeR(Unicode u, Unicode left, Unicode right);
// analysis
int rotateChars(GList *charsA);
@@ -539,14 +557,16 @@ private:
GList *separateOverlappingText(GList *charsA);
TextColumn *buildOverlappingTextColumn(GList *overlappingChars);
TextBlock *splitChars(GList *charsA);
- TextBlock *split(GList *charsA, int rot);
+ TextBlock *split(GList *charsA, int rot, GBool vertOnly);
GList *getChars(GList *charsA, double xMin, double yMin,
double xMax, double yMax);
void findGaps(GList *charsA, int rot,
double *xMinOut, double *yMinOut,
double *xMaxOut, double *yMaxOut,
- double *avgFontSizeOut,
+ double *avgFontSizeOut, double *minFontSizeOut,
+ GList *splitLines,
TextGaps *horizGaps, TextGaps *vertGaps);
+ void mergeSplitLines(GList *charsA, int rot, GList *splitLines);
void tagBlock(TextBlock *blk);
void insertLargeChars(GList *largeChars, TextBlock *blk);
void insertLargeCharsInFirstLeaf(GList *largeChars, TextBlock *blk);
@@ -570,6 +590,7 @@ private:
void getLineChars(TextBlock *blk, GList *charsA);
double computeWordSpacingThreshold(GList *charsA, int rot);
int getCharDirection(TextChar *ch);
+ int getCharDirection(TextChar *ch, TextChar *left, TextChar *right);
int assignPhysLayoutPositions(GList *columns);
void assignLinePhysPositions(GList *columns);
void computeLinePhysWidth(TextLine *line, UnicodeMap *uMap);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
index d1a5aea2963..d5916627082 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
@@ -786,17 +786,18 @@ GBool TileMap::cvtDevToWindow(int pg, int xd, int yd,
break;
case displaySideBySideSingle:
- if (!(pg == state->getScrollPage() ||
- (pg == state->getScrollPage() + 1 &&
- state->getScrollPage() + 1 <= state->getDoc()->getNumPages()))) {
+ leftPg = (state->getScrollPage() - 1) | 1;
+ if (!(pg == leftPg ||
+ (pg == leftPg + 1 &&
+ leftPg + 1 <= state->getDoc()->getNumPages()))) {
*xw = *yw = 0;
return gFalse;
}
- pageW1 = pageW[state->getScrollPage() - 1];
- pageH1 = pageH[state->getScrollPage() - 1];
- if (state->getScrollPage() + 1 <= state->getDoc()->getNumPages()) {
- pageW2 = pageW[state->getScrollPage()];
- pageH2 = pageH[state->getScrollPage()];
+ pageW1 = pageW[leftPg - 1];
+ pageH1 = pageH[leftPg - 1];
+ if (leftPg + 1 <= state->getDoc()->getNumPages()) {
+ pageW2 = pageW[leftPg];
+ pageH2 = pageH[leftPg];
} else {
// display a single page as though there were a blank facing
// page of the same size
@@ -819,13 +820,12 @@ GBool TileMap::cvtDevToWindow(int pg, int xd, int yd,
} else {
offsetY = 0;
}
- if (pg == state->getScrollPage()) {
+ if (pg == leftPg) {
*xw = xd + offsetX - state->getScrollX();
- *yw = yd + offsetY - state->getScrollY();
} else {
*xw = xd + offsetX2 - state->getScrollX();
- *yw = yd + offsetY - state->getScrollY();
}
+ *yw = yd + offsetY - state->getScrollY();
break;
case displaySideBySideContinuous:
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMapTables.h b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMapTables.h
index 60ac55d124e..d103c2ea382 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMapTables.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMapTables.h
@@ -11,8 +11,7 @@ static UnicodeMapRange latin1UnicodeMapRanges[] = {
{ 0x000c, 0x000d, 0x0c, 1 },
{ 0x0020, 0x007e, 0x20, 1 },
{ 0x00a0, 0x00a0, 0x20, 1 },
- { 0x00a1, 0x00ac, 0xa1, 1 },
- { 0x00ae, 0x00ff, 0xae, 1 },
+ { 0x00a1, 0x00ff, 0xa1, 1 },
{ 0x010c, 0x010c, 0x43, 1 },
{ 0x010d, 0x010d, 0x63, 1 },
{ 0x0131, 0x0131, 0x69, 1 },
@@ -29,7 +28,7 @@ static UnicodeMapRange latin1UnicodeMapRanges[] = {
{ 0x02da, 0x02da, 0xb0, 1 },
{ 0x02dc, 0x02dc, 0x7e, 1 },
{ 0x2010, 0x2010, 0x2d, 1 },
- { 0x2013, 0x2013, 0xad, 1 },
+ { 0x2013, 0x2013, 0x2d, 1 },
{ 0x2014, 0x2014, 0x2d2d, 2 },
{ 0x2018, 0x2018, 0x60, 1 },
{ 0x2019, 0x2019, 0x27, 1 },
@@ -76,6 +75,7 @@ static UnicodeMapRange ascii7UnicodeMapRanges[] = {
{ 0x000c, 0x000d, 0x0c, 1 },
{ 0x0020, 0x005f, 0x20, 1 },
{ 0x0061, 0x007e, 0x61, 1 },
+ { 0x00a0, 0x00a0, 0x20, 1 },
{ 0x00a6, 0x00a6, 0x7c, 1 },
{ 0x00a9, 0x00a9, 0x286329, 3 },
{ 0x00ae, 0x00ae, 0x285229, 3 },
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc
index e4f09e19ae3..72dbc0e159c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.cc
@@ -83,7 +83,7 @@ UnicodeRemapping::~UnicodeRemapping() {
}
void UnicodeRemapping::addRemapping(Unicode in, Unicode *out, int len) {
- int i;
+ int i, j;
if (in < 256 && len == 1) {
page0[in] = out[0];
@@ -96,11 +96,16 @@ void UnicodeRemapping::addRemapping(Unicode in, Unicode *out, int len) {
sMap = (UnicodeRemappingString *)
greallocn(sMap, sMapSize, sizeof(UnicodeRemappingString));
}
- sMap[sMapLen].in = in;
- for (i = 0; i < len && i < maxUnicodeString; ++i) {
- sMap[sMapLen].out[i] = out[i];
+ i = findSMap(in);
+ if (i < sMapLen) {
+ memmove(sMap + i + 1, sMap + i,
+ (sMapLen - i) * sizeof(UnicodeRemappingString));
}
- sMap[sMapLen].len = i;
+ sMap[i].in = in;
+ for (j = 0; j < len && j < maxUnicodeString; ++j) {
+ sMap[i].out[j] = out[j];
+ }
+ sMap[i].len = j;
++sMapLen;
}
}
@@ -148,6 +153,24 @@ void UnicodeRemapping::parseFile(GString *fileName) {
fclose(f);
}
+// Determine the location in sMap to insert/replace the entry for [u].
+int UnicodeRemapping::findSMap(Unicode u) {
+ int a, b, m;
+
+ a = -1;
+ b = sMapLen;
+ // invariant: sMap[a].in < u <= sMap[b].in
+ while (b - a > 1) {
+ m = (a + b) / 2;
+ if (sMap[m].in < u) {
+ a = m;
+ } else {
+ b = m;
+ }
+ }
+ return b;
+}
+
int UnicodeRemapping::map(Unicode in, Unicode *out, int size) {
int a, b, m, i;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h
index 950c93afc8e..dbf435e7dd1 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeRemapping.h
@@ -43,6 +43,8 @@ public:
private:
+ int findSMap(Unicode u);
+
Unicode page0[256];
UnicodeRemappingString *sMap;
int sMapLen, sMapSize;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc
index 328d2478167..e6a91af2756 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc
@@ -2,7 +2,7 @@
//
// UnicodeTypeTable.cc
//
-// Copyright 2004-2013 Glyph & Cog, LLC
+// Copyright 2004-2021 Glyph & Cog, LLC
//
//========================================================================
@@ -25,54 +25,54 @@ static UnicodeMapTableEntry typeTable[256] = {
{ "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN...NNNNN.....##########.NNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN.N....NNNNLNNNNN..##NLNNN#LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL", 'X' },
{ NULL, 'L' },
{ "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLNNNNNNNNNNNNNNLLNNNNNNNNNNNNNNLLLLLNNNNNNNNNLNNNNNNNNNNNNNNNNN", 'X' },
- { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLNNNNNNNNNNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLL", 'X' },
+ { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLNNLLLLLLLLNLNNNNNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLL", 'X' },
{ "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNRNRNNRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR", 'X' },
- { "RRRR.........RNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNN#################.##RRRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNRNNNNNNNRRNNNNNNNRR##########RRRRRR", 'X' },
- { "RRRRRRRRRRRRRRNNRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNNNNNNNNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNRNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
- { NULL, 'N' },
- { "NNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNLLLLNLLLNNNNLLLLLLLLLLLLLNNLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNLLLLLLLLNLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLL..LLLLLLLNNNNN", 'X' },
- { "NNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNLLLLNLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLL..NNNNNNNNNNNNNN", 'X' },
- { "NNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLNLNNNLLLLLLLLLNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNN.NLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNLLLLNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", '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' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNLNNNNNLNNLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLNNNNNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { NULL, 'L' },
- { NULL, 'L' },
- { NULL, 'L' },
- { NULL, 'L' },
- { NULL, 'L' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNLLLLLLLLNLLNNNNNNNNNNNLLLLLLL.LNLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNN", 'X' },
- { "NNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLNNNNNLLLLLLNLLLLLLNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
- { NULL, 'L' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNLNNNNNLNNLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLNNNNNNLNNLLNNLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLNNNLLLLLLLLLLLLLLLLNNNNLLLLLLLLLLLLLNLLNNLLLLLLNLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
{ NULL, 'L' },
{ NULL, 'L' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNN", 'X' },
+ { "NLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
{ NULL, 'L' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLNNNNNNNLLLLLLLLNLLNNNNNNNNNNNLLLLLLL.LNLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+ { "NNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLNNLLLLLLLLLNLLLLLLNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLNNLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNNNNNNNLNLLNNNNNNNNLLLLLLNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+ { "NNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNNNLNLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNLLLLLLLLLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLNNLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNLLLNLNNNLLLLLLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNLNNNNNNNNNNNNNLNNNNNNNLLLLNLLLLLLNLLLNNLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
{ NULL, 'L' },
{ "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNLLLLLLLLLLLNNNLLLLLLLLLLLLNNNNLLLLLLLLLLLLLNNNLLLLLLLLLLLLLNNN", 'X' },
- { "NNNNNNNNNNNNNNLRNNNNNNNNNNNNNNNNNNNNNNNNNNLRNLRN.....NNNNNNNNNNNNNNN.NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN#L########..NNNL##########..NNN...................................NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
- { "NNLNNNNLNNLLLLLLLLLLNLNNNLLLLLNNNNNNLNLNLNLLLL.LLLNLLLLLLLNNLLLLNNNNNLLLLLNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+ { "NNNNNNNNNNNNNNLRNNNNNNNNNNNNNNNNNNNNNNNNNNLRNLR......NNNNNNNNNNNNNNN.NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLRNNNNNNNN#L########..NNNL##########..NNNLLLLLLLLLLLLLL...................................NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+ { "NNLNNNNLNNLLLLLLLLLLNLNNNLLLLLNNNNNNLNLNLNLLLL.LLLLLLLLLLLNNLLLLNNNNNLLLLLNNNNLLNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
{ "NNNNNNNNNNNNNNNNNN..NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
{ "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
{ "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN####################LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNN", 'X' },
{ NULL, 'N' },
- { NULL, 'N' },
+ { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
{ NULL, 'N' },
{ NULL, 'L' },
{ NULL, 'N' },
{ NULL, 'N' },
{ NULL, 'N' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLNNNLLNNNNNNNNNNNN", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
{ NULL, 'N' },
{ NULL, 'N' },
- { NULL, 'N' },
- { NULL, 'N' },
- { "NNNNNLLLNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLNNNNNNNLLLLLNNLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLL", 'X' },
- { NULL, 'L' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "NNNNNLLLNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLNNNNLLNLLLLLNNLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
{ "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN", 'X' },
{ NULL, 'L' },
{ NULL, 'L' },
@@ -99,7 +99,7 @@ static UnicodeMapTableEntry typeTable[256] = {
{ NULL, 'L' },
{ NULL, 'L' },
{ NULL, 'L' },
- { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN", 'X' },
{ NULL, 'L' },
{ NULL, 'L' },
{ NULL, 'L' },
@@ -188,12 +188,12 @@ static UnicodeMapTableEntry typeTable[256] = {
{ NULL, 'L' },
{ "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
{ NULL, 'L' },
- { NULL, 'L' },
- { NULL, 'L' },
- { NULL, 'L' },
- { NULL, 'L' },
- { NULL, 'L' },
- { NULL, 'L' },
+ { "LLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLNNNNNNNN", 'X' },
+ { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "LLNLLLNLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLNNLNNNNNLLLLLLLLLLL..LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLN", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNNNNLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLNNLLNNLLLLLLLLLLLLNLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNLLNNLLLLLNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLNLLLLLLLLL", 'X' },
+ { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNLLLLNLLLLLLLLLLLLLLLLLL", 'X' },
{ NULL, 'L' },
{ NULL, 'L' },
{ NULL, 'L' },
@@ -356,9 +356,9 @@ static UnicodeCaseTableVector caseTable02 = {{
0x019e, 0x0221, 0x0223, 0x0223, 0x0225, 0x0225, 0x0227, 0x0227,
0x0229, 0x0229, 0x022b, 0x022b, 0x022d, 0x022d, 0x022f, 0x022f,
0x0231, 0x0231, 0x0233, 0x0233, 0x0234, 0x0235, 0x0236, 0x0237,
- 0x0238, 0x0239, 0x023a, 0x023b, 0x023c, 0x023d, 0x023e, 0x023f,
- 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247,
- 0x0248, 0x0249, 0x024a, 0x024b, 0x024c, 0x024d, 0x024e, 0x024f,
+ 0x0238, 0x0239, 0x2c65, 0x023c, 0x023c, 0x019a, 0x2c66, 0x023f,
+ 0x0240, 0x0242, 0x0242, 0x0180, 0x0289, 0x028c, 0x0247, 0x0247,
+ 0x0249, 0x0249, 0x024b, 0x024b, 0x024d, 0x024d, 0x024f, 0x024f,
0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0257,
0x0258, 0x0259, 0x025a, 0x025b, 0x025c, 0x025d, 0x025e, 0x025f,
0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, 0x0267,
@@ -397,8 +397,8 @@ static UnicodeCaseTableVector caseTable03 = {{
0x0358, 0x0359, 0x035a, 0x035b, 0x035c, 0x035d, 0x035e, 0x035f,
0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367,
0x0368, 0x0369, 0x036a, 0x036b, 0x036c, 0x036d, 0x036e, 0x036f,
- 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376, 0x0377,
- 0x0378, 0x0379, 0x037a, 0x037b, 0x037c, 0x037d, 0x037e, 0x037f,
+ 0x0371, 0x0371, 0x0373, 0x0373, 0x0374, 0x0375, 0x0377, 0x0377,
+ 0x0378, 0x0379, 0x037a, 0x037b, 0x037c, 0x037d, 0x037e, 0x03f3,
0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x03ac, 0x0387,
0x03ad, 0x03ae, 0x03af, 0x038b, 0x03cc, 0x038d, 0x03cd, 0x03ce,
0x0390, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
@@ -408,13 +408,13 @@ static UnicodeCaseTableVector caseTable03 = {{
0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
0x03c0, 0x03c1, 0x03c3, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
- 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x03cf,
+ 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x03d7,
0x03b2, 0x03b8, 0x03d2, 0x03d3, 0x03d4, 0x03c6, 0x03c0, 0x03d7,
0x03d9, 0x03d9, 0x03db, 0x03db, 0x03dd, 0x03dd, 0x03df, 0x03df,
0x03e1, 0x03e1, 0x03e3, 0x03e3, 0x03e5, 0x03e5, 0x03e7, 0x03e7,
0x03e9, 0x03e9, 0x03eb, 0x03eb, 0x03ed, 0x03ed, 0x03ef, 0x03ef,
0x03ba, 0x03c1, 0x03f2, 0x03f3, 0x03b8, 0x03b5, 0x03f6, 0x03f8,
- 0x03f8, 0x03f2, 0x03fb, 0x03fb, 0x03fc, 0x03fd, 0x03fe, 0x03ff
+ 0x03f8, 0x03f2, 0x03fb, 0x03fb, 0x03fc, 0x037b, 0x037c, 0x037d
}};
static UnicodeCaseTableVector caseTable04 = {{
0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
@@ -441,22 +441,22 @@ static UnicodeCaseTableVector caseTable04 = {{
0x04a9, 0x04a9, 0x04ab, 0x04ab, 0x04ad, 0x04ad, 0x04af, 0x04af,
0x04b1, 0x04b1, 0x04b3, 0x04b3, 0x04b5, 0x04b5, 0x04b7, 0x04b7,
0x04b9, 0x04b9, 0x04bb, 0x04bb, 0x04bd, 0x04bd, 0x04bf, 0x04bf,
- 0x04c0, 0x04c2, 0x04c2, 0x04c4, 0x04c4, 0x04c6, 0x04c6, 0x04c8,
+ 0x04cf, 0x04c2, 0x04c2, 0x04c4, 0x04c4, 0x04c6, 0x04c6, 0x04c8,
0x04c8, 0x04ca, 0x04ca, 0x04cc, 0x04cc, 0x04ce, 0x04ce, 0x04cf,
0x04d1, 0x04d1, 0x04d3, 0x04d3, 0x04d5, 0x04d5, 0x04d7, 0x04d7,
0x04d9, 0x04d9, 0x04db, 0x04db, 0x04dd, 0x04dd, 0x04df, 0x04df,
0x04e1, 0x04e1, 0x04e3, 0x04e3, 0x04e5, 0x04e5, 0x04e7, 0x04e7,
0x04e9, 0x04e9, 0x04eb, 0x04eb, 0x04ed, 0x04ed, 0x04ef, 0x04ef,
- 0x04f1, 0x04f1, 0x04f3, 0x04f3, 0x04f5, 0x04f5, 0x04f6, 0x04f7,
- 0x04f9, 0x04f9, 0x04fa, 0x04fb, 0x04fc, 0x04fd, 0x04fe, 0x04ff
+ 0x04f1, 0x04f1, 0x04f3, 0x04f3, 0x04f5, 0x04f5, 0x04f7, 0x04f7,
+ 0x04f9, 0x04f9, 0x04fb, 0x04fb, 0x04fd, 0x04fd, 0x04ff, 0x04ff
}};
static UnicodeCaseTableVector caseTable05 = {{
0x0501, 0x0501, 0x0503, 0x0503, 0x0505, 0x0505, 0x0507, 0x0507,
0x0509, 0x0509, 0x050b, 0x050b, 0x050d, 0x050d, 0x050f, 0x050f,
- 0x0510, 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517,
- 0x0518, 0x0519, 0x051a, 0x051b, 0x051c, 0x051d, 0x051e, 0x051f,
- 0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527,
- 0x0528, 0x0529, 0x052a, 0x052b, 0x052c, 0x052d, 0x052e, 0x052f,
+ 0x0511, 0x0511, 0x0513, 0x0513, 0x0515, 0x0515, 0x0517, 0x0517,
+ 0x0519, 0x0519, 0x051b, 0x051b, 0x051d, 0x051d, 0x051f, 0x051f,
+ 0x0521, 0x0521, 0x0523, 0x0523, 0x0525, 0x0525, 0x0527, 0x0527,
+ 0x0529, 0x0529, 0x052b, 0x052b, 0x052d, 0x052d, 0x052f, 0x052f,
0x0530, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567,
0x0568, 0x0569, 0x056a, 0x056b, 0x056c, 0x056d, 0x056e, 0x056f,
0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577,
@@ -484,6 +484,108 @@ static UnicodeCaseTableVector caseTable05 = {{
0x05f0, 0x05f1, 0x05f2, 0x05f3, 0x05f4, 0x05f5, 0x05f6, 0x05f7,
0x05f8, 0x05f9, 0x05fa, 0x05fb, 0x05fc, 0x05fd, 0x05fe, 0x05ff
}};
+static UnicodeCaseTableVector caseTable10 = {{
+ 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
+ 0x1008, 0x1009, 0x100a, 0x100b, 0x100c, 0x100d, 0x100e, 0x100f,
+ 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
+ 0x1018, 0x1019, 0x101a, 0x101b, 0x101c, 0x101d, 0x101e, 0x101f,
+ 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
+ 0x1028, 0x1029, 0x102a, 0x102b, 0x102c, 0x102d, 0x102e, 0x102f,
+ 0x1030, 0x1031, 0x1032, 0x1033, 0x1034, 0x1035, 0x1036, 0x1037,
+ 0x1038, 0x1039, 0x103a, 0x103b, 0x103c, 0x103d, 0x103e, 0x103f,
+ 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047,
+ 0x1048, 0x1049, 0x104a, 0x104b, 0x104c, 0x104d, 0x104e, 0x104f,
+ 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057,
+ 0x1058, 0x1059, 0x105a, 0x105b, 0x105c, 0x105d, 0x105e, 0x105f,
+ 0x1060, 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067,
+ 0x1068, 0x1069, 0x106a, 0x106b, 0x106c, 0x106d, 0x106e, 0x106f,
+ 0x1070, 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, 0x1076, 0x1077,
+ 0x1078, 0x1079, 0x107a, 0x107b, 0x107c, 0x107d, 0x107e, 0x107f,
+ 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087,
+ 0x1088, 0x1089, 0x108a, 0x108b, 0x108c, 0x108d, 0x108e, 0x108f,
+ 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097,
+ 0x1098, 0x1099, 0x109a, 0x109b, 0x109c, 0x109d, 0x109e, 0x109f,
+ 0x2d00, 0x2d01, 0x2d02, 0x2d03, 0x2d04, 0x2d05, 0x2d06, 0x2d07,
+ 0x2d08, 0x2d09, 0x2d0a, 0x2d0b, 0x2d0c, 0x2d0d, 0x2d0e, 0x2d0f,
+ 0x2d10, 0x2d11, 0x2d12, 0x2d13, 0x2d14, 0x2d15, 0x2d16, 0x2d17,
+ 0x2d18, 0x2d19, 0x2d1a, 0x2d1b, 0x2d1c, 0x2d1d, 0x2d1e, 0x2d1f,
+ 0x2d20, 0x2d21, 0x2d22, 0x2d23, 0x2d24, 0x2d25, 0x10c6, 0x2d27,
+ 0x10c8, 0x10c9, 0x10ca, 0x10cb, 0x10cc, 0x2d2d, 0x10ce, 0x10cf,
+ 0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7,
+ 0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df,
+ 0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7,
+ 0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef,
+ 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7,
+ 0x10f8, 0x10f9, 0x10fa, 0x10fb, 0x10fc, 0x10fd, 0x10fe, 0x10ff
+}};
+static UnicodeCaseTableVector caseTable13 = {{
+ 0x1300, 0x1301, 0x1302, 0x1303, 0x1304, 0x1305, 0x1306, 0x1307,
+ 0x1308, 0x1309, 0x130a, 0x130b, 0x130c, 0x130d, 0x130e, 0x130f,
+ 0x1310, 0x1311, 0x1312, 0x1313, 0x1314, 0x1315, 0x1316, 0x1317,
+ 0x1318, 0x1319, 0x131a, 0x131b, 0x131c, 0x131d, 0x131e, 0x131f,
+ 0x1320, 0x1321, 0x1322, 0x1323, 0x1324, 0x1325, 0x1326, 0x1327,
+ 0x1328, 0x1329, 0x132a, 0x132b, 0x132c, 0x132d, 0x132e, 0x132f,
+ 0x1330, 0x1331, 0x1332, 0x1333, 0x1334, 0x1335, 0x1336, 0x1337,
+ 0x1338, 0x1339, 0x133a, 0x133b, 0x133c, 0x133d, 0x133e, 0x133f,
+ 0x1340, 0x1341, 0x1342, 0x1343, 0x1344, 0x1345, 0x1346, 0x1347,
+ 0x1348, 0x1349, 0x134a, 0x134b, 0x134c, 0x134d, 0x134e, 0x134f,
+ 0x1350, 0x1351, 0x1352, 0x1353, 0x1354, 0x1355, 0x1356, 0x1357,
+ 0x1358, 0x1359, 0x135a, 0x135b, 0x135c, 0x135d, 0x135e, 0x135f,
+ 0x1360, 0x1361, 0x1362, 0x1363, 0x1364, 0x1365, 0x1366, 0x1367,
+ 0x1368, 0x1369, 0x136a, 0x136b, 0x136c, 0x136d, 0x136e, 0x136f,
+ 0x1370, 0x1371, 0x1372, 0x1373, 0x1374, 0x1375, 0x1376, 0x1377,
+ 0x1378, 0x1379, 0x137a, 0x137b, 0x137c, 0x137d, 0x137e, 0x137f,
+ 0x1380, 0x1381, 0x1382, 0x1383, 0x1384, 0x1385, 0x1386, 0x1387,
+ 0x1388, 0x1389, 0x138a, 0x138b, 0x138c, 0x138d, 0x138e, 0x138f,
+ 0x1390, 0x1391, 0x1392, 0x1393, 0x1394, 0x1395, 0x1396, 0x1397,
+ 0x1398, 0x1399, 0x139a, 0x139b, 0x139c, 0x139d, 0x139e, 0x139f,
+ 0x13a0, 0x13a1, 0x13a2, 0x13a3, 0x13a4, 0x13a5, 0x13a6, 0x13a7,
+ 0x13a8, 0x13a9, 0x13aa, 0x13ab, 0x13ac, 0x13ad, 0x13ae, 0x13af,
+ 0x13b0, 0x13b1, 0x13b2, 0x13b3, 0x13b4, 0x13b5, 0x13b6, 0x13b7,
+ 0x13b8, 0x13b9, 0x13ba, 0x13bb, 0x13bc, 0x13bd, 0x13be, 0x13bf,
+ 0x13c0, 0x13c1, 0x13c2, 0x13c3, 0x13c4, 0x13c5, 0x13c6, 0x13c7,
+ 0x13c8, 0x13c9, 0x13ca, 0x13cb, 0x13cc, 0x13cd, 0x13ce, 0x13cf,
+ 0x13d0, 0x13d1, 0x13d2, 0x13d3, 0x13d4, 0x13d5, 0x13d6, 0x13d7,
+ 0x13d8, 0x13d9, 0x13da, 0x13db, 0x13dc, 0x13dd, 0x13de, 0x13df,
+ 0x13e0, 0x13e1, 0x13e2, 0x13e3, 0x13e4, 0x13e5, 0x13e6, 0x13e7,
+ 0x13e8, 0x13e9, 0x13ea, 0x13eb, 0x13ec, 0x13ed, 0x13ee, 0x13ef,
+ 0x13f0, 0x13f1, 0x13f2, 0x13f3, 0x13f4, 0x13f5, 0x13f6, 0x13f7,
+ 0x13f0, 0x13f1, 0x13f2, 0x13f3, 0x13f4, 0x13f5, 0x13fe, 0x13ff
+}};
+static UnicodeCaseTableVector caseTable1c = {{
+ 0x1c00, 0x1c01, 0x1c02, 0x1c03, 0x1c04, 0x1c05, 0x1c06, 0x1c07,
+ 0x1c08, 0x1c09, 0x1c0a, 0x1c0b, 0x1c0c, 0x1c0d, 0x1c0e, 0x1c0f,
+ 0x1c10, 0x1c11, 0x1c12, 0x1c13, 0x1c14, 0x1c15, 0x1c16, 0x1c17,
+ 0x1c18, 0x1c19, 0x1c1a, 0x1c1b, 0x1c1c, 0x1c1d, 0x1c1e, 0x1c1f,
+ 0x1c20, 0x1c21, 0x1c22, 0x1c23, 0x1c24, 0x1c25, 0x1c26, 0x1c27,
+ 0x1c28, 0x1c29, 0x1c2a, 0x1c2b, 0x1c2c, 0x1c2d, 0x1c2e, 0x1c2f,
+ 0x1c30, 0x1c31, 0x1c32, 0x1c33, 0x1c34, 0x1c35, 0x1c36, 0x1c37,
+ 0x1c38, 0x1c39, 0x1c3a, 0x1c3b, 0x1c3c, 0x1c3d, 0x1c3e, 0x1c3f,
+ 0x1c40, 0x1c41, 0x1c42, 0x1c43, 0x1c44, 0x1c45, 0x1c46, 0x1c47,
+ 0x1c48, 0x1c49, 0x1c4a, 0x1c4b, 0x1c4c, 0x1c4d, 0x1c4e, 0x1c4f,
+ 0x1c50, 0x1c51, 0x1c52, 0x1c53, 0x1c54, 0x1c55, 0x1c56, 0x1c57,
+ 0x1c58, 0x1c59, 0x1c5a, 0x1c5b, 0x1c5c, 0x1c5d, 0x1c5e, 0x1c5f,
+ 0x1c60, 0x1c61, 0x1c62, 0x1c63, 0x1c64, 0x1c65, 0x1c66, 0x1c67,
+ 0x1c68, 0x1c69, 0x1c6a, 0x1c6b, 0x1c6c, 0x1c6d, 0x1c6e, 0x1c6f,
+ 0x1c70, 0x1c71, 0x1c72, 0x1c73, 0x1c74, 0x1c75, 0x1c76, 0x1c77,
+ 0x1c78, 0x1c79, 0x1c7a, 0x1c7b, 0x1c7c, 0x1c7d, 0x1c7e, 0x1c7f,
+ 0x0432, 0x0434, 0x043e, 0x0441, 0x0442, 0x0442, 0x044a, 0x0463,
+ 0xa64b, 0x1c89, 0x1c8a, 0x1c8b, 0x1c8c, 0x1c8d, 0x1c8e, 0x1c8f,
+ 0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7,
+ 0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df,
+ 0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7,
+ 0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef,
+ 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7,
+ 0x10f8, 0x10f9, 0x10fa, 0x1cbb, 0x1cbc, 0x10fd, 0x10fe, 0x10ff,
+ 0x1cc0, 0x1cc1, 0x1cc2, 0x1cc3, 0x1cc4, 0x1cc5, 0x1cc6, 0x1cc7,
+ 0x1cc8, 0x1cc9, 0x1cca, 0x1ccb, 0x1ccc, 0x1ccd, 0x1cce, 0x1ccf,
+ 0x1cd0, 0x1cd1, 0x1cd2, 0x1cd3, 0x1cd4, 0x1cd5, 0x1cd6, 0x1cd7,
+ 0x1cd8, 0x1cd9, 0x1cda, 0x1cdb, 0x1cdc, 0x1cdd, 0x1cde, 0x1cdf,
+ 0x1ce0, 0x1ce1, 0x1ce2, 0x1ce3, 0x1ce4, 0x1ce5, 0x1ce6, 0x1ce7,
+ 0x1ce8, 0x1ce9, 0x1cea, 0x1ceb, 0x1cec, 0x1ced, 0x1cee, 0x1cef,
+ 0x1cf0, 0x1cf1, 0x1cf2, 0x1cf3, 0x1cf4, 0x1cf5, 0x1cf6, 0x1cf7,
+ 0x1cf8, 0x1cf9, 0x1cfa, 0x1cfb, 0x1cfc, 0x1cfd, 0x1cfe, 0x1cff
+}};
static UnicodeCaseTableVector caseTable1e = {{
0x1e01, 0x1e01, 0x1e03, 0x1e03, 0x1e05, 0x1e05, 0x1e07, 0x1e07,
0x1e09, 0x1e09, 0x1e0b, 0x1e0b, 0x1e0d, 0x1e0d, 0x1e0f, 0x1e0f,
@@ -504,7 +606,7 @@ static UnicodeCaseTableVector caseTable1e = {{
0x1e81, 0x1e81, 0x1e83, 0x1e83, 0x1e85, 0x1e85, 0x1e87, 0x1e87,
0x1e89, 0x1e89, 0x1e8b, 0x1e8b, 0x1e8d, 0x1e8d, 0x1e8f, 0x1e8f,
0x1e91, 0x1e91, 0x1e93, 0x1e93, 0x1e95, 0x1e95, 0x1e96, 0x1e97,
- 0x1e98, 0x1e99, 0x1e9a, 0x1e61, 0x1e9c, 0x1e9d, 0x1e9e, 0x1e9f,
+ 0x1e98, 0x1e99, 0x1e9a, 0x1e61, 0x1e9c, 0x1e9d, 0x00df, 0x1e9f,
0x1ea1, 0x1ea1, 0x1ea3, 0x1ea3, 0x1ea5, 0x1ea5, 0x1ea7, 0x1ea7,
0x1ea9, 0x1ea9, 0x1eab, 0x1eab, 0x1ead, 0x1ead, 0x1eaf, 0x1eaf,
0x1eb1, 0x1eb1, 0x1eb3, 0x1eb3, 0x1eb5, 0x1eb5, 0x1eb7, 0x1eb7,
@@ -516,7 +618,7 @@ static UnicodeCaseTableVector caseTable1e = {{
0x1ee1, 0x1ee1, 0x1ee3, 0x1ee3, 0x1ee5, 0x1ee5, 0x1ee7, 0x1ee7,
0x1ee9, 0x1ee9, 0x1eeb, 0x1eeb, 0x1eed, 0x1eed, 0x1eef, 0x1eef,
0x1ef1, 0x1ef1, 0x1ef3, 0x1ef3, 0x1ef5, 0x1ef5, 0x1ef7, 0x1ef7,
- 0x1ef9, 0x1ef9, 0x1efa, 0x1efb, 0x1efc, 0x1efd, 0x1efe, 0x1eff
+ 0x1ef9, 0x1ef9, 0x1efb, 0x1efb, 0x1efd, 0x1efd, 0x1eff, 0x1eff
}};
static UnicodeCaseTableVector caseTable1f = {{
0x1f00, 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07,
@@ -559,7 +661,7 @@ static UnicodeCaseTableVector caseTable21 = {{
0x2118, 0x2119, 0x211a, 0x211b, 0x211c, 0x211d, 0x211e, 0x211f,
0x2120, 0x2121, 0x2122, 0x2123, 0x2124, 0x2125, 0x03c9, 0x2127,
0x2128, 0x2129, 0x006b, 0x00e5, 0x212c, 0x212d, 0x212e, 0x212f,
- 0x2130, 0x2131, 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137,
+ 0x2130, 0x2131, 0x214e, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137,
0x2138, 0x2139, 0x213a, 0x213b, 0x213c, 0x213d, 0x213e, 0x213f,
0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2145, 0x2146, 0x2147,
0x2148, 0x2149, 0x214a, 0x214b, 0x214c, 0x214d, 0x214e, 0x214f,
@@ -569,7 +671,7 @@ static UnicodeCaseTableVector caseTable21 = {{
0x2178, 0x2179, 0x217a, 0x217b, 0x217c, 0x217d, 0x217e, 0x217f,
0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
0x2178, 0x2179, 0x217a, 0x217b, 0x217c, 0x217d, 0x217e, 0x217f,
- 0x2180, 0x2181, 0x2182, 0x2183, 0x2184, 0x2185, 0x2186, 0x2187,
+ 0x2180, 0x2181, 0x2182, 0x2184, 0x2184, 0x2185, 0x2186, 0x2187,
0x2188, 0x2189, 0x218a, 0x218b, 0x218c, 0x218d, 0x218e, 0x218f,
0x2190, 0x2191, 0x2192, 0x2193, 0x2194, 0x2195, 0x2196, 0x2197,
0x2198, 0x2199, 0x219a, 0x219b, 0x219c, 0x219d, 0x219e, 0x219f,
@@ -620,6 +722,142 @@ static UnicodeCaseTableVector caseTable24 = {{
0x24f0, 0x24f1, 0x24f2, 0x24f3, 0x24f4, 0x24f5, 0x24f6, 0x24f7,
0x24f8, 0x24f9, 0x24fa, 0x24fb, 0x24fc, 0x24fd, 0x24fe, 0x24ff
}};
+static UnicodeCaseTableVector caseTable2c = {{
+ 0x2c30, 0x2c31, 0x2c32, 0x2c33, 0x2c34, 0x2c35, 0x2c36, 0x2c37,
+ 0x2c38, 0x2c39, 0x2c3a, 0x2c3b, 0x2c3c, 0x2c3d, 0x2c3e, 0x2c3f,
+ 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,
+ 0x2c30, 0x2c31, 0x2c32, 0x2c33, 0x2c34, 0x2c35, 0x2c36, 0x2c37,
+ 0x2c38, 0x2c39, 0x2c3a, 0x2c3b, 0x2c3c, 0x2c3d, 0x2c3e, 0x2c3f,
+ 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, 0x2c5f,
+ 0x2c61, 0x2c61, 0x026b, 0x1d7d, 0x027d, 0x2c65, 0x2c66, 0x2c68,
+ 0x2c68, 0x2c6a, 0x2c6a, 0x2c6c, 0x2c6c, 0x0251, 0x0271, 0x0250,
+ 0x0252, 0x2c71, 0x2c73, 0x2c73, 0x2c74, 0x2c76, 0x2c76, 0x2c77,
+ 0x2c78, 0x2c79, 0x2c7a, 0x2c7b, 0x2c7c, 0x2c7d, 0x023f, 0x0240,
+ 0x2c81, 0x2c81, 0x2c83, 0x2c83, 0x2c85, 0x2c85, 0x2c87, 0x2c87,
+ 0x2c89, 0x2c89, 0x2c8b, 0x2c8b, 0x2c8d, 0x2c8d, 0x2c8f, 0x2c8f,
+ 0x2c91, 0x2c91, 0x2c93, 0x2c93, 0x2c95, 0x2c95, 0x2c97, 0x2c97,
+ 0x2c99, 0x2c99, 0x2c9b, 0x2c9b, 0x2c9d, 0x2c9d, 0x2c9f, 0x2c9f,
+ 0x2ca1, 0x2ca1, 0x2ca3, 0x2ca3, 0x2ca5, 0x2ca5, 0x2ca7, 0x2ca7,
+ 0x2ca9, 0x2ca9, 0x2cab, 0x2cab, 0x2cad, 0x2cad, 0x2caf, 0x2caf,
+ 0x2cb1, 0x2cb1, 0x2cb3, 0x2cb3, 0x2cb5, 0x2cb5, 0x2cb7, 0x2cb7,
+ 0x2cb9, 0x2cb9, 0x2cbb, 0x2cbb, 0x2cbd, 0x2cbd, 0x2cbf, 0x2cbf,
+ 0x2cc1, 0x2cc1, 0x2cc3, 0x2cc3, 0x2cc5, 0x2cc5, 0x2cc7, 0x2cc7,
+ 0x2cc9, 0x2cc9, 0x2ccb, 0x2ccb, 0x2ccd, 0x2ccd, 0x2ccf, 0x2ccf,
+ 0x2cd1, 0x2cd1, 0x2cd3, 0x2cd3, 0x2cd5, 0x2cd5, 0x2cd7, 0x2cd7,
+ 0x2cd9, 0x2cd9, 0x2cdb, 0x2cdb, 0x2cdd, 0x2cdd, 0x2cdf, 0x2cdf,
+ 0x2ce1, 0x2ce1, 0x2ce3, 0x2ce3, 0x2ce4, 0x2ce5, 0x2ce6, 0x2ce7,
+ 0x2ce8, 0x2ce9, 0x2cea, 0x2cec, 0x2cec, 0x2cee, 0x2cee, 0x2cef,
+ 0x2cf0, 0x2cf1, 0x2cf3, 0x2cf3, 0x2cf4, 0x2cf5, 0x2cf6, 0x2cf7,
+ 0x2cf8, 0x2cf9, 0x2cfa, 0x2cfb, 0x2cfc, 0x2cfd, 0x2cfe, 0x2cff
+}};
+static UnicodeCaseTableVector caseTablea6 = {{
+ 0xa600, 0xa601, 0xa602, 0xa603, 0xa604, 0xa605, 0xa606, 0xa607,
+ 0xa608, 0xa609, 0xa60a, 0xa60b, 0xa60c, 0xa60d, 0xa60e, 0xa60f,
+ 0xa610, 0xa611, 0xa612, 0xa613, 0xa614, 0xa615, 0xa616, 0xa617,
+ 0xa618, 0xa619, 0xa61a, 0xa61b, 0xa61c, 0xa61d, 0xa61e, 0xa61f,
+ 0xa620, 0xa621, 0xa622, 0xa623, 0xa624, 0xa625, 0xa626, 0xa627,
+ 0xa628, 0xa629, 0xa62a, 0xa62b, 0xa62c, 0xa62d, 0xa62e, 0xa62f,
+ 0xa630, 0xa631, 0xa632, 0xa633, 0xa634, 0xa635, 0xa636, 0xa637,
+ 0xa638, 0xa639, 0xa63a, 0xa63b, 0xa63c, 0xa63d, 0xa63e, 0xa63f,
+ 0xa641, 0xa641, 0xa643, 0xa643, 0xa645, 0xa645, 0xa647, 0xa647,
+ 0xa649, 0xa649, 0xa64b, 0xa64b, 0xa64d, 0xa64d, 0xa64f, 0xa64f,
+ 0xa651, 0xa651, 0xa653, 0xa653, 0xa655, 0xa655, 0xa657, 0xa657,
+ 0xa659, 0xa659, 0xa65b, 0xa65b, 0xa65d, 0xa65d, 0xa65f, 0xa65f,
+ 0xa661, 0xa661, 0xa663, 0xa663, 0xa665, 0xa665, 0xa667, 0xa667,
+ 0xa669, 0xa669, 0xa66b, 0xa66b, 0xa66d, 0xa66d, 0xa66e, 0xa66f,
+ 0xa670, 0xa671, 0xa672, 0xa673, 0xa674, 0xa675, 0xa676, 0xa677,
+ 0xa678, 0xa679, 0xa67a, 0xa67b, 0xa67c, 0xa67d, 0xa67e, 0xa67f,
+ 0xa681, 0xa681, 0xa683, 0xa683, 0xa685, 0xa685, 0xa687, 0xa687,
+ 0xa689, 0xa689, 0xa68b, 0xa68b, 0xa68d, 0xa68d, 0xa68f, 0xa68f,
+ 0xa691, 0xa691, 0xa693, 0xa693, 0xa695, 0xa695, 0xa697, 0xa697,
+ 0xa699, 0xa699, 0xa69b, 0xa69b, 0xa69c, 0xa69d, 0xa69e, 0xa69f,
+ 0xa6a0, 0xa6a1, 0xa6a2, 0xa6a3, 0xa6a4, 0xa6a5, 0xa6a6, 0xa6a7,
+ 0xa6a8, 0xa6a9, 0xa6aa, 0xa6ab, 0xa6ac, 0xa6ad, 0xa6ae, 0xa6af,
+ 0xa6b0, 0xa6b1, 0xa6b2, 0xa6b3, 0xa6b4, 0xa6b5, 0xa6b6, 0xa6b7,
+ 0xa6b8, 0xa6b9, 0xa6ba, 0xa6bb, 0xa6bc, 0xa6bd, 0xa6be, 0xa6bf,
+ 0xa6c0, 0xa6c1, 0xa6c2, 0xa6c3, 0xa6c4, 0xa6c5, 0xa6c6, 0xa6c7,
+ 0xa6c8, 0xa6c9, 0xa6ca, 0xa6cb, 0xa6cc, 0xa6cd, 0xa6ce, 0xa6cf,
+ 0xa6d0, 0xa6d1, 0xa6d2, 0xa6d3, 0xa6d4, 0xa6d5, 0xa6d6, 0xa6d7,
+ 0xa6d8, 0xa6d9, 0xa6da, 0xa6db, 0xa6dc, 0xa6dd, 0xa6de, 0xa6df,
+ 0xa6e0, 0xa6e1, 0xa6e2, 0xa6e3, 0xa6e4, 0xa6e5, 0xa6e6, 0xa6e7,
+ 0xa6e8, 0xa6e9, 0xa6ea, 0xa6eb, 0xa6ec, 0xa6ed, 0xa6ee, 0xa6ef,
+ 0xa6f0, 0xa6f1, 0xa6f2, 0xa6f3, 0xa6f4, 0xa6f5, 0xa6f6, 0xa6f7,
+ 0xa6f8, 0xa6f9, 0xa6fa, 0xa6fb, 0xa6fc, 0xa6fd, 0xa6fe, 0xa6ff
+}};
+static UnicodeCaseTableVector caseTablea7 = {{
+ 0xa700, 0xa701, 0xa702, 0xa703, 0xa704, 0xa705, 0xa706, 0xa707,
+ 0xa708, 0xa709, 0xa70a, 0xa70b, 0xa70c, 0xa70d, 0xa70e, 0xa70f,
+ 0xa710, 0xa711, 0xa712, 0xa713, 0xa714, 0xa715, 0xa716, 0xa717,
+ 0xa718, 0xa719, 0xa71a, 0xa71b, 0xa71c, 0xa71d, 0xa71e, 0xa71f,
+ 0xa720, 0xa721, 0xa723, 0xa723, 0xa725, 0xa725, 0xa727, 0xa727,
+ 0xa729, 0xa729, 0xa72b, 0xa72b, 0xa72d, 0xa72d, 0xa72f, 0xa72f,
+ 0xa730, 0xa731, 0xa733, 0xa733, 0xa735, 0xa735, 0xa737, 0xa737,
+ 0xa739, 0xa739, 0xa73b, 0xa73b, 0xa73d, 0xa73d, 0xa73f, 0xa73f,
+ 0xa741, 0xa741, 0xa743, 0xa743, 0xa745, 0xa745, 0xa747, 0xa747,
+ 0xa749, 0xa749, 0xa74b, 0xa74b, 0xa74d, 0xa74d, 0xa74f, 0xa74f,
+ 0xa751, 0xa751, 0xa753, 0xa753, 0xa755, 0xa755, 0xa757, 0xa757,
+ 0xa759, 0xa759, 0xa75b, 0xa75b, 0xa75d, 0xa75d, 0xa75f, 0xa75f,
+ 0xa761, 0xa761, 0xa763, 0xa763, 0xa765, 0xa765, 0xa767, 0xa767,
+ 0xa769, 0xa769, 0xa76b, 0xa76b, 0xa76d, 0xa76d, 0xa76f, 0xa76f,
+ 0xa770, 0xa771, 0xa772, 0xa773, 0xa774, 0xa775, 0xa776, 0xa777,
+ 0xa778, 0xa77a, 0xa77a, 0xa77c, 0xa77c, 0x1d79, 0xa77f, 0xa77f,
+ 0xa781, 0xa781, 0xa783, 0xa783, 0xa785, 0xa785, 0xa787, 0xa787,
+ 0xa788, 0xa789, 0xa78a, 0xa78c, 0xa78c, 0x0265, 0xa78e, 0xa78f,
+ 0xa791, 0xa791, 0xa793, 0xa793, 0xa794, 0xa795, 0xa797, 0xa797,
+ 0xa799, 0xa799, 0xa79b, 0xa79b, 0xa79d, 0xa79d, 0xa79f, 0xa79f,
+ 0xa7a1, 0xa7a1, 0xa7a3, 0xa7a3, 0xa7a5, 0xa7a5, 0xa7a7, 0xa7a7,
+ 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,
+ 0xa7c8, 0xa7ca, 0xa7ca, 0xa7cb, 0xa7cc, 0xa7cd, 0xa7ce, 0xa7cf,
+ 0xa7d0, 0xa7d1, 0xa7d2, 0xa7d3, 0xa7d4, 0xa7d5, 0xa7d6, 0xa7d7,
+ 0xa7d8, 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,
+ 0xa7f8, 0xa7f9, 0xa7fa, 0xa7fb, 0xa7fc, 0xa7fd, 0xa7fe, 0xa7ff
+}};
+static UnicodeCaseTableVector caseTableab = {{
+ 0xab00, 0xab01, 0xab02, 0xab03, 0xab04, 0xab05, 0xab06, 0xab07,
+ 0xab08, 0xab09, 0xab0a, 0xab0b, 0xab0c, 0xab0d, 0xab0e, 0xab0f,
+ 0xab10, 0xab11, 0xab12, 0xab13, 0xab14, 0xab15, 0xab16, 0xab17,
+ 0xab18, 0xab19, 0xab1a, 0xab1b, 0xab1c, 0xab1d, 0xab1e, 0xab1f,
+ 0xab20, 0xab21, 0xab22, 0xab23, 0xab24, 0xab25, 0xab26, 0xab27,
+ 0xab28, 0xab29, 0xab2a, 0xab2b, 0xab2c, 0xab2d, 0xab2e, 0xab2f,
+ 0xab30, 0xab31, 0xab32, 0xab33, 0xab34, 0xab35, 0xab36, 0xab37,
+ 0xab38, 0xab39, 0xab3a, 0xab3b, 0xab3c, 0xab3d, 0xab3e, 0xab3f,
+ 0xab40, 0xab41, 0xab42, 0xab43, 0xab44, 0xab45, 0xab46, 0xab47,
+ 0xab48, 0xab49, 0xab4a, 0xab4b, 0xab4c, 0xab4d, 0xab4e, 0xab4f,
+ 0xab50, 0xab51, 0xab52, 0xab53, 0xab54, 0xab55, 0xab56, 0xab57,
+ 0xab58, 0xab59, 0xab5a, 0xab5b, 0xab5c, 0xab5d, 0xab5e, 0xab5f,
+ 0xab60, 0xab61, 0xab62, 0xab63, 0xab64, 0xab65, 0xab66, 0xab67,
+ 0xab68, 0xab69, 0xab6a, 0xab6b, 0xab6c, 0xab6d, 0xab6e, 0xab6f,
+ 0x13a0, 0x13a1, 0x13a2, 0x13a3, 0x13a4, 0x13a5, 0x13a6, 0x13a7,
+ 0x13a8, 0x13a9, 0x13aa, 0x13ab, 0x13ac, 0x13ad, 0x13ae, 0x13af,
+ 0x13b0, 0x13b1, 0x13b2, 0x13b3, 0x13b4, 0x13b5, 0x13b6, 0x13b7,
+ 0x13b8, 0x13b9, 0x13ba, 0x13bb, 0x13bc, 0x13bd, 0x13be, 0x13bf,
+ 0x13c0, 0x13c1, 0x13c2, 0x13c3, 0x13c4, 0x13c5, 0x13c6, 0x13c7,
+ 0x13c8, 0x13c9, 0x13ca, 0x13cb, 0x13cc, 0x13cd, 0x13ce, 0x13cf,
+ 0x13d0, 0x13d1, 0x13d2, 0x13d3, 0x13d4, 0x13d5, 0x13d6, 0x13d7,
+ 0x13d8, 0x13d9, 0x13da, 0x13db, 0x13dc, 0x13dd, 0x13de, 0x13df,
+ 0x13e0, 0x13e1, 0x13e2, 0x13e3, 0x13e4, 0x13e5, 0x13e6, 0x13e7,
+ 0x13e8, 0x13e9, 0x13ea, 0x13eb, 0x13ec, 0x13ed, 0x13ee, 0x13ef,
+ 0xabc0, 0xabc1, 0xabc2, 0xabc3, 0xabc4, 0xabc5, 0xabc6, 0xabc7,
+ 0xabc8, 0xabc9, 0xabca, 0xabcb, 0xabcc, 0xabcd, 0xabce, 0xabcf,
+ 0xabd0, 0xabd1, 0xabd2, 0xabd3, 0xabd4, 0xabd5, 0xabd6, 0xabd7,
+ 0xabd8, 0xabd9, 0xabda, 0xabdb, 0xabdc, 0xabdd, 0xabde, 0xabdf,
+ 0xabe0, 0xabe1, 0xabe2, 0xabe3, 0xabe4, 0xabe5, 0xabe6, 0xabe7,
+ 0xabe8, 0xabe9, 0xabea, 0xabeb, 0xabec, 0xabed, 0xabee, 0xabef,
+ 0xabf0, 0xabf1, 0xabf2, 0xabf3, 0xabf4, 0xabf5, 0xabf6, 0xabf7,
+ 0xabf8, 0xabf9, 0xabfa, 0xabfb, 0xabfc, 0xabfd, 0xabfe, 0xabff
+}};
static UnicodeCaseTableVector caseTableff = {{
0xff00, 0xff01, 0xff02, 0xff03, 0xff04, 0xff05, 0xff06, 0xff07,
0xff08, 0xff09, 0xff0a, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f,
@@ -671,8 +909,10 @@ static UnicodeCaseTableVector *caseTable[256] = {
NULL,
NULL,
NULL,
+ &caseTable10,
NULL,
NULL,
+ &caseTable13,
NULL,
NULL,
NULL,
@@ -681,9 +921,7 @@ static UnicodeCaseTableVector *caseTable[256] = {
NULL,
NULL,
NULL,
- NULL,
- NULL,
- NULL,
+ &caseTable1c,
NULL,
&caseTable1e,
&caseTable1f,
@@ -699,6 +937,7 @@ static UnicodeCaseTableVector *caseTable[256] = {
NULL,
NULL,
NULL,
+ &caseTable2c,
NULL,
NULL,
NULL,
@@ -820,9 +1059,12 @@ static UnicodeCaseTableVector *caseTable[256] = {
NULL,
NULL,
NULL,
+ &caseTablea6,
+ &caseTablea7,
NULL,
NULL,
NULL,
+ &caseTableab,
NULL,
NULL,
NULL,
@@ -906,11 +1148,640 @@ static UnicodeCaseTableVector *caseTable[256] = {
NULL,
NULL,
NULL,
+ &caseTableff
+};
+
+static Unicode bracketTable00[256] = {
+ 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,
+ 0x80000029, 0x0028, 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, 0, 0x8000005d, 0, 0x005b, 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, 0x8000007d, 0, 0x007b, 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, 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, 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 bracketTable0f[256] = {
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0x80000f3b, 0x0f3a, 0x80000f3d, 0x0f3c, 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, 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, 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, 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, 0, 0
+};
+static Unicode bracketTable16[256] = {
+ 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,
+ 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,
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0x8000169c, 0x169b, 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, 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, 0, 0, 0
+};
+static Unicode bracketTable20[256] = {
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0x80002046, 0x2045, 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, 0,
+ 0, 0, 0, 0, 0, 0x8000207e, 0x207d, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0x8000208e, 0x208d, 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, 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+static Unicode bracketTable23[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x80002309, 0x2308, 0x8000230b, 0x230a, 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, 0x8000232a, 0x2329, 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, 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, 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, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+static Unicode bracketTable27[256] = {
+ 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,
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x80002769, 0x2768, 0x8000276b, 0x276a, 0x8000276d, 0x276c, 0x8000276f, 0x276e,
+ 0x80002771, 0x2770, 0x80002773, 0x2772, 0x80002775, 0x2774, 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, 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, 0x800027c6, 0x27c5, 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, 0x800027e7, 0x27e6,
+ 0x800027e9, 0x27e8, 0x800027eb, 0x27ea, 0x800027ed, 0x27ec, 0x800027ef, 0x27ee,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+static Unicode bracketTable29[256] = {
+ 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,
+ 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,
+ 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, 0x80002984, 0x2983, 0x80002986, 0x2985, 0x80002988,
+ 0x2987, 0x8000298a, 0x2989, 0x8000298c, 0x298b, 0x80002990, 0x298f, 0x8000298e,
+ 0x298d, 0x80002992, 0x2991, 0x80002994, 0x2993, 0x80002996, 0x2995, 0x80002998,
+ 0x2997, 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, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x800029d9, 0x29d8, 0x800029db, 0x29da, 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, 0x800029fd, 0x29fc, 0, 0
+};
+static Unicode bracketTable2e[256] = {
+ 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, 0x80002e23, 0x2e22, 0x80002e25, 0x2e24, 0x80002e27, 0x2e26,
+ 0x80002e29, 0x2e28, 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, 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, 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, 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, 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] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x80003009, 0x3008, 0x8000300b, 0x300a, 0x8000300d, 0x300c, 0x8000300f, 0x300e,
+ 0x80003011, 0x3010, 0, 0, 0x80003015, 0x3014, 0x80003017, 0x3016,
+ 0x80003019, 0x3018, 0x8000301b, 0x301a, 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, 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, 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, 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, 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 bracketTablefe[256] = {
+ 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,
+ 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, 0x8000fe5a, 0xfe59, 0x8000fe5c, 0xfe5b, 0x8000fe5e, 0xfe5d, 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, 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, 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+static Unicode bracketTableff[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x8000ff09, 0xff08, 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, 0, 0x8000ff3d, 0, 0xff3b, 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, 0x8000ff5d, 0, 0xff5b, 0, 0x8000ff60,
+ 0xff5f, 0, 0x8000ff63, 0xff62, 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, 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+static Unicode *bracketTable[256] = {
+ bracketTable00,
NULL,
NULL,
NULL,
NULL,
- &caseTableff
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ bracketTable0f,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ bracketTable16,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ bracketTable20,
+ NULL,
+ NULL,
+ bracketTable23,
+ NULL,
+ NULL,
+ NULL,
+ bracketTable27,
+ NULL,
+ bracketTable29,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ bracketTable2e,
+ NULL,
+ bracketTable30,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ bracketTablefe,
+ bracketTableff
};
static inline char getType(Unicode c) {
@@ -936,6 +1807,14 @@ GBool unicodeTypeR(Unicode c) {
return getType(c) == 'R';
}
+GBool unicodeTypeDigit(Unicode c) {
+ return getType(c) == '#';
+}
+
+GBool unicodeTypeNumSep(Unicode c) {
+ return getType(c) == '.';
+}
+
GBool unicodeTypeNum(Unicode c) {
char t;
@@ -957,7 +1836,7 @@ GBool unicodeTypeWord(Unicode c) {
return t == 'L' || t == 'R' || t == '#';
}
-Unicode unicodeToUpper(Unicode c) {
+Unicode unicodeToLower(Unicode c) {
int i;
if (c > 0xffff) {
@@ -970,3 +1849,28 @@ Unicode unicodeToUpper(Unicode c) {
return c;
}
+GBool unicodeBracketInfo(Unicode c, GBool *open, Unicode *opposite) {
+ int i;
+ Unicode bracket;
+
+ if (c > 0xffff) {
+ return gFalse;
+ }
+ i = (c >> 8) & 0xff;
+ if (!bracketTable[i]) {
+ return gFalse;
+ }
+ bracket = bracketTable[i][c & 0xff];
+ if (!bracket) {
+ return gFalse;
+ }
+ if (bracket & 0x80000000) {
+ *open = gTrue;
+ *opposite = bracket & 0x7fffffff;
+ } else {
+ *open = gFalse;
+ *opposite = bracket;
+ }
+ return gTrue;
+}
+
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h
index 3230d927891..e1149fd6bc2 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.h
@@ -15,12 +15,18 @@ extern GBool unicodeTypeL(Unicode c);
extern GBool unicodeTypeR(Unicode c);
+extern GBool unicodeTypeDigit(Unicode c);
+
+extern GBool unicodeTypeNumSep(Unicode c);
+
extern GBool unicodeTypeNum(Unicode c);
extern GBool unicodeTypeAlphaNum(Unicode c);
extern GBool unicodeTypeWord(Unicode c);
-extern Unicode unicodeToUpper(Unicode c);
+extern Unicode unicodeToLower(Unicode c);
+
+extern GBool unicodeBracketInfo(Unicode c, GBool *open, Unicode *opposite);
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc
index 9ae636226ae..c04b52f937a 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc
@@ -71,8 +71,11 @@ static void writeToFile(void *stream, const char *data, int len) {
fwrite(data, 1, len, (FILE *)stream);
}
-GBool WebFont::writeTTF(const char *fontFilePath) {
- FILE *out;
+static void writeToString(void *stream, const char *data, int len) {
+ ((GString *)stream)->append(data, len);
+}
+
+GBool WebFont::generateTTF(FoFiOutputFunc outFunc, void *stream) {
int *codeToGID;
Guchar *cmapTable;
GBool freeCodeToGID;
@@ -100,22 +103,35 @@ GBool WebFont::writeTTF(const char *fontFilePath) {
if (!cmapTable) {
return gFalse;
}
- if (!(out = fopen(fontFilePath, "wb"))) {
- gfree(cmapTable);
- return gFalse;
- }
- ffTrueType->writeTTF(writeToFile, out, NULL, NULL,
+ ffTrueType->writeTTF(outFunc, stream, NULL, NULL,
cmapTable, cmapTableLength);
- fclose(out);
gfree(cmapTable);
return gTrue;
}
-GBool WebFont::writeOTF(const char *fontFilePath) {
+GBool WebFont::writeTTF(const char *fontFilePath) {
+ FILE *out = fopen(fontFilePath, "wb");
+ if (!out) {
+ return gFalse;
+ }
+ GBool ret = generateTTF(writeToFile, out);
+ fclose(out);
+ return ret;
+}
+
+GString *WebFont::getTTFData() {
+ GString *s = new GString();
+ if (!generateTTF(writeToString, s)) {
+ delete s;
+ return NULL;
+ }
+ return s;
+}
+
+GBool WebFont::generateOTF(FoFiOutputFunc outFunc, void *stream) {
int *codeToGID;
Gushort *widths;
Guchar *cmapTable;
- FILE *out;
int nCodes, nWidths, cmapTableLength;
if (ffType1C) {
@@ -138,27 +154,13 @@ GBool WebFont::writeOTF(const char *fontFilePath) {
widths = makeCIDType0CWidths(codeToGID, nCodes, &nWidths);
gfree(codeToGID);
}
- if (!(out = fopen(fontFilePath, "wb"))) {
- gfree(cmapTable);
- gfree(widths);
- return gFalse;
- }
- ffType1C->convertToOpenType(writeToFile, out,
- nWidths, widths,
+ ffType1C->convertToOpenType(outFunc, stream, nWidths, widths,
cmapTable, cmapTableLength);
- fclose(out);
gfree(cmapTable);
gfree(widths);
} else if (isOpenType) {
- if (!(out = fopen(fontFilePath, "wb"))) {
- return gFalse;
- }
- if (fwrite(fontBuf, 1, fontLength, out) != (Guint)fontLength) {
- fclose(out);
- return gFalse;
- }
- fclose(out);
+ outFunc(stream, fontBuf, fontLength);
} else {
return gFalse;
@@ -167,6 +169,25 @@ GBool WebFont::writeOTF(const char *fontFilePath) {
return gTrue;
}
+GBool WebFont::writeOTF(const char *fontFilePath) {
+ FILE *out = fopen(fontFilePath, "wb");
+ if (!out) {
+ return gFalse;
+ }
+ GBool ret = generateOTF(writeToFile, out);
+ fclose(out);
+ return ret;
+}
+
+GString *WebFont::getOTFData() {
+ GString *s = new GString();
+ if (!generateOTF(writeToString, s)) {
+ delete s;
+ return NULL;
+ }
+ return s;
+}
+
Gushort *WebFont::makeType1CWidths(int *codeToGID, int nCodes,
int *nWidths) {
Gushort *widths;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h b/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h
index a967e2e490a..283bdbe914d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h
@@ -18,6 +18,7 @@
#endif
#include "gtypes.h"
+#include "FoFiBase.h"
#include "GfxFont.h"
class FoFiTrueType;
@@ -45,13 +46,23 @@ public:
// called if canWriteTTF() returns true. Returns true on success.
GBool writeTTF(const char *fontFilePath);
+ // Return the TrueType file as a string. This can only be called if
+ // canWriteTTF() returns true. Returns null on error.
+ GString *getTTFData();
+
// Write an OpenType (.otf) file to [fontFilePath]. This can only
// be called if canWriteOTF() returns true. Returns true on
// success.
GBool writeOTF(const char *fontFilePath);
+ // Return the OpenType file as a string. This can only be called if
+ // canWriteOTF() returns true. Returns null on error.
+ GString *getOTFData();
+
private:
+ GBool generateTTF(FoFiOutputFunc outFunc, void *stream);
+ GBool generateOTF(FoFiOutputFunc outFunc, void *stream);
Gushort *makeType1CWidths(int *codeToGID, int nCodes, int *nWidths);
Gushort *makeCIDType0CWidths(int *codeToGID, int nCodes, int *nWidths);
Guchar *makeUnicodeCmapTable(int *codeToGID, int nCodes,
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc
index 6928fa9c9a8..8002a07a7f6 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAScanner.cc
@@ -293,8 +293,10 @@ void XFAScanner::scanNode(ZxElement *elem,
}
if (elem->isElement("field")) {
- scanField(elem, childName, childFullName, exclGroupName,
- dataElem, formValues);
+ if (childName && childFullName) {
+ scanField(elem, childName, childFullName, exclGroupName,
+ dataElem, formValues);
+ }
} else {
GString *childExclGroupName;
if (elem->isElement("exclGroup")) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc
index 0c364638b39..51af86db5ba 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc
@@ -299,6 +299,7 @@ XRef::XRef(BaseStream *strA, GBool repair) {
ok = gTrue;
errCode = errNone;
+ repaired = gFalse;
size = 0;
last = -1;
entries = NULL;
@@ -336,6 +337,7 @@ XRef::XRef(BaseStream *strA, GBool repair) {
errCode = errDamaged;
return;
}
+ repaired = gTrue;
// if the 'repair' flag is not set, read the xref table
} else {
@@ -512,7 +514,7 @@ GBool XRef::readXRefTable(GFileOffset *pos, int offset, XRefPosSet *posSet) {
char buf[6];
GFileOffset off, pos2;
GBool more;
- int first, n, newSize, gen, i, c;
+ int first, n, digit, newSize, gen, i, c;
str->setPos(start + *pos + offset);
@@ -531,7 +533,11 @@ GBool XRef::readXRefTable(GFileOffset *pos, int offset, XRefPosSet *posSet) {
}
first = 0;
do {
- first = (first * 10) + (c - '0');
+ digit = c - '0';
+ if (first > (INT_MAX - digit) / 10) {
+ goto err1;
+ }
+ first = (first * 10) + digit;
c = str->getChar();
} while (c >= '0' && c <= '9');
if (!Lexer::isSpace(c)) {
@@ -542,13 +548,17 @@ GBool XRef::readXRefTable(GFileOffset *pos, int offset, XRefPosSet *posSet) {
} while (Lexer::isSpace(c));
n = 0;
do {
- n = (n * 10) + (c - '0');
+ digit = c - '0';
+ if (n > (INT_MAX - digit) / 10) {
+ goto err1;
+ }
+ n = (n * 10) + digit;
c = str->getChar();
} while (c >= '0' && c <= '9');
if (!Lexer::isSpace(c)) {
goto err1;
}
- if (first < 0 || n < 0 || first > INT_MAX - n) {
+ if (first > INT_MAX - n) {
goto err1;
}
if (first + n > size) {
@@ -822,7 +832,8 @@ GBool XRef::readXRefStreamSection(Stream *xrefStr, int *w, int first, int n) {
}
gen = (gen << 8) + c;
}
- if (gen < 0 || gen > INT_MAX) {
+ // some PDF generators include a free entry with gen=0xffffffff
+ if ((gen < 0 || gen > INT_MAX) && type != 0) {
return gFalse;
}
if (entries[i].offset == (GFileOffset)-1) {
@@ -908,7 +919,9 @@ GBool XRef::constructXRef() {
// skip any PDF whitespace except for '\0'
while (*p == '\t' || *p == '\n' || *p == '\x0c' ||
*p == '\r' || *p == ' ') {
- startOfLine = *p == '\n' || *p == '\r';
+ if (*p == '\n' || *p == '\r') {
+ startOfLine = gTrue;
+ }
++p;
}
if (!strncmp(p, "stream", 6)) {
@@ -924,7 +937,11 @@ GBool XRef::constructXRef() {
startOfLine = gFalse;
}
} else {
- startOfLine = *p == '\n' || *p == '\r';
+ if (*p == '\n' || *p == '\r') {
+ startOfLine = gTrue;
+ } else if (!Lexer::isSpace(*p & 0xff)) {
+ startOfLine = gFalse;
+ }
++p;
}
}
@@ -949,6 +966,16 @@ GBool XRef::constructXRef() {
gfree(streamObjNums);
+ // if the file is encrypted, then any objects fetched here will be
+ // incorrect (because decryption is not yet enabled), so clear the
+ // cache to avoid that problem
+ for (int i = 0; i < xrefCacheSize; ++i) {
+ if (cache[i].num >= 0) {
+ cache[i].obj.free();
+ cache[i].num = -1;
+ }
+ }
+
if (rootNum < 0) {
error(errSyntaxError, -1, "Couldn't find trailer dictionary");
return gFalse;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h b/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h
index 00a8644f3a9..10e4e6a7501 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h
@@ -70,6 +70,9 @@ public:
// Get the error code (if isOk() returns false).
int getErrorCode() { return errCode; }
+ // Was the xref constructed by the repair code?
+ GBool isRepaired() { return repaired; }
+
// Set the encryption parameters.
void setEncryption(int permFlagsA, GBool ownerPasswordOkA,
Guchar *fileKeyA, int keyLengthA, int encVersionA,
@@ -135,6 +138,8 @@ private:
int rootNum, rootGen; // catalog dict
GBool ok; // true if xref table is valid
int errCode; // error code (if <ok> is false)
+ GBool repaired; // set if the xref table was constructed by
+ // the repair code
Object trailerDict; // trailer dictionary
GFileOffset lastXRefPos; // offset of last xref table
GFileOffset lastStartxrefPos; // offset of 'startxref' at end of file
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/config.h b/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
index 39cade1682c..b41dd492248 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
@@ -2,7 +2,7 @@
//
// config.h
//
-// Copyright 1996-2021 Glyph & Cog, LLC
+// Copyright 1996-2022 Glyph & Cog, LLC
//
//========================================================================
@@ -14,13 +14,13 @@
//------------------------------------------------------------------------
// xpdf version
-#define xpdfVersion "4.03"
-#define xpdfVersionNum 4.03
+#define xpdfVersion "4.04"
+#define xpdfVersionNum 4.04
#define xpdfMajorVersion 4
-#define xpdfMinorVersion 3
+#define xpdfMinorVersion 4
#define xpdfUpdateVersion 0
#define xpdfMajorVersionStr "4"
-#define xpdfMinorVersionStr "3"
+#define xpdfMinorVersionStr "4"
#define xpdfUpdateVersionStr "0"
// supported PDF version
@@ -28,11 +28,11 @@
#define supportedPDFVersionNum 2.0
// copyright notice
-#define xpdfCopyright "Copyright 1996-2021 Glyph & Cog, LLC"
+#define xpdfCopyright "Copyright 1996-2022 Glyph & Cog, LLC"
// Windows resource file stuff
-#define winxpdfVersion "WinXpdf 4.03"
-#define xpdfCopyrightAmp "Copyright 1996-2021 Glyph && Cog, LLC"
+#define winxpdfVersion "WinXpdf 4.04"
+#define xpdfCopyrightAmp "Copyright 1996-2022 Glyph && Cog, LLC"
//------------------------------------------------------------------------
// paper size
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc
index e8b74381017..581383fe730 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc
@@ -94,6 +94,10 @@ int main(int argc, char *argv[]) {
fileName = argv[1];
// read config file
+ if (cfgFileName[0] && !pathIsFile(cfgFileName)) {
+ error(errConfig, -1, "Config file '{0:s}' doesn't exist or isn't a file",
+ cfgFileName);
+ }
globalParams = new GlobalParams(cfgFileName);
if (textEncName[0]) {
globalParams->setTextEncoding(textEncName);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
index 42c46223d8b..bde57557c3c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
@@ -123,6 +123,10 @@ int main(int argc, char *argv[]) {
fileName = argv[1];
// read config file
+ if (cfgFileName[0] && !pathIsFile(cfgFileName)) {
+ error(errConfig, -1, "Config file '{0:s}' doesn't exist or isn't a file",
+ cfgFileName);
+ }
globalParams = new GlobalParams(cfgFileName);
globalParams->setupBaseFonts(NULL);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc
index cd5d34014f4..346346bce77 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc
@@ -35,6 +35,7 @@ static GBool dumpRaw = gFalse;
static GBool list = gFalse;
static char ownerPassword[33] = "\001";
static char userPassword[33] = "\001";
+static GBool verbose = gFalse;
static GBool quiet = gFalse;
static char cfgFileName[256] = "";
static GBool printVersion = gFalse;
@@ -55,6 +56,8 @@ static ArgDesc argDesc[] = {
"owner password (for encrypted files)"},
{"-upw", argString, userPassword, sizeof(userPassword),
"user password (for encrypted files)"},
+ {"-verbose", argFlag, &verbose, 0,
+ "print per-page status information"},
{"-q", argFlag, &quiet, 0,
"don't print any messages or errors"},
{"-cfg", argString, cfgFileName, sizeof(cfgFileName),
@@ -98,7 +101,14 @@ int main(int argc, char *argv[]) {
imgRoot = argv[2];
// read config file
+ if (cfgFileName[0] && !pathIsFile(cfgFileName)) {
+ error(errConfig, -1, "Config file '{0:s}' doesn't exist or isn't a file",
+ cfgFileName);
+ }
globalParams = new GlobalParams(cfgFileName);
+ if (verbose) {
+ globalParams->setPrintStatusInfo(verbose);
+ }
if (quiet) {
globalParams->setErrQuiet(quiet);
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc
index 621fb69ea6f..88829b993c3 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc
@@ -126,6 +126,10 @@ int main(int argc, char *argv[]) {
fileName = argv[1];
// read config file
+ if (cfgFileName[0] && !pathIsFile(cfgFileName)) {
+ error(errConfig, -1, "Config file '{0:s}' doesn't exist or isn't a file",
+ cfgFileName);
+ }
globalParams = new GlobalParams(cfgFileName);
if (textEncName[0]) {
globalParams->setTextEncoding(textEncName);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
index af8fe93fbd5..4c98afed50c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
@@ -31,48 +31,66 @@ static int firstPage = 1;
static int lastPage = 0;
static double zoom = 1;
static int resolution = 150;
+static double vStretch = 1;
+static GBool embedBackground = gFalse;
static GBool noFonts = gFalse;
+static GBool embedFonts = gFalse;
static GBool skipInvisible = gFalse;
static GBool allInvisible = gFalse;
+static GBool formFields = gFalse;
+static GBool tableMode = gFalse;
static char ownerPassword[33] = "\001";
static char userPassword[33] = "\001";
+static GBool verbose = gFalse;
static GBool quiet = gFalse;
static char cfgFileName[256] = "";
static GBool printVersion = gFalse;
static GBool printHelp = gFalse;
static ArgDesc argDesc[] = {
- {"-f", argInt, &firstPage, 0,
+ {"-f", argInt, &firstPage, 0,
"first page to convert"},
- {"-l", argInt, &lastPage, 0,
+ {"-l", argInt, &lastPage, 0,
"last page to convert"},
- {"-z", argFP, &zoom, 0,
+ {"-z", argFP, &zoom, 0,
"initial zoom level (1.0 means 72dpi)"},
- {"-r", argInt, &resolution, 0,
+ {"-r", argInt, &resolution, 0,
"resolution, in DPI (default is 150)"},
- {"-nofonts", argFlag, &noFonts, 0,
+ {"-vstretch", argFP, &vStretch, 0,
+ "vertical stretch factor (1.0 means no stretching)"},
+ {"-embedbackground", argFlag, &embedBackground, 0,
+ "embed the background image as base64-encoded data" },
+ {"-nofonts", argFlag, &noFonts, 0,
"do not extract embedded fonts"},
- {"-skipinvisible", argFlag, &skipInvisible, 0,
+ {"-embedfonts", argFlag, &embedFonts, 0,
+ "embed the fonts as base64-encoded data" },
+ {"-skipinvisible", argFlag, &skipInvisible, 0,
"do not draw invisible text"},
- {"-allinvisible", argFlag, &allInvisible, 0,
+ {"-allinvisible", argFlag, &allInvisible, 0,
"treat all text as invisible"},
- {"-opw", argString, ownerPassword, sizeof(ownerPassword),
+ {"-formfields", argFlag, &formFields, 0,
+ "convert form fields to HTML"},
+ {"-table", argFlag, &tableMode, 0,
+ "use table mode for text extraction"},
+ {"-opw", argString, ownerPassword, sizeof(ownerPassword),
"owner password (for encrypted files)"},
- {"-upw", argString, userPassword, sizeof(userPassword),
+ {"-upw", argString, userPassword, sizeof(userPassword),
"user password (for encrypted files)"},
- {"-q", argFlag, &quiet, 0,
+ {"-verbose", argFlag, &verbose, 0,
+ "print per-page status information"},
+ {"-q", argFlag, &quiet, 0,
"don't print any messages or errors"},
- {"-cfg", argString, cfgFileName, sizeof(cfgFileName),
+ {"-cfg", argString, cfgFileName, sizeof(cfgFileName),
"configuration file to use in place of .xpdfrc"},
- {"-v", argFlag, &printVersion, 0,
+ {"-v", argFlag, &printVersion, 0,
"print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
+ {"-h", argFlag, &printHelp, 0,
"print usage information"},
- {"-help", argFlag, &printHelp, 0,
+ {"-help", argFlag, &printHelp, 0,
"print usage information"},
- {"--help", argFlag, &printHelp, 0,
+ {"--help", argFlag, &printHelp, 0,
"print usage information"},
- {"-?", argFlag, &printHelp, 0,
+ {"-?", argFlag, &printHelp, 0,
"print usage information"},
{NULL}
};
@@ -111,7 +129,14 @@ int main(int argc, char *argv[]) {
htmlDir = argv[2];
// read config file
+ if (cfgFileName[0] && !pathIsFile(cfgFileName)) {
+ error(errConfig, -1, "Config file '{0:s}' doesn't exist or isn't a file",
+ cfgFileName);
+ }
globalParams = new GlobalParams(cfgFileName);
+ if (verbose) {
+ globalParams->setPrintStatusInfo(verbose);
+ }
if (quiet) {
globalParams->setErrQuiet(quiet);
}
@@ -166,19 +191,28 @@ int main(int argc, char *argv[]) {
}
// set up the HTMLGen object
- htmlGen = new HTMLGen(resolution);
+ htmlGen = new HTMLGen(resolution, tableMode);
if (!htmlGen->isOk()) {
exitCode = 99;
goto err1;
}
htmlGen->setZoom(zoom);
+ htmlGen->setVStretch(vStretch);
htmlGen->setDrawInvisibleText(!skipInvisible);
htmlGen->setAllTextInvisible(allInvisible);
+ htmlGen->setEmbedBackgroundImage(embedBackground);
htmlGen->setExtractFontFiles(!noFonts);
+ htmlGen->setEmbedFonts(embedFonts);
+ htmlGen->setConvertFormFields(formFields);
htmlGen->startDoc(doc);
// convert the pages
for (pg = firstPage; pg <= lastPage; ++pg) {
+ if (globalParams->getPrintStatusInfo()) {
+ fflush(stderr);
+ printf("[processing page %d]\n", pg);
+ fflush(stdout);
+ }
htmlFileName = GString::format("{0:s}/page{1:d}.html", htmlDir, pg);
pngFileName = GString::format("{0:s}/page{1:d}.png", htmlDir, pg);
if (!(htmlFile = openFile(htmlFileName->getCString(), "wb"))) {
@@ -187,12 +221,16 @@ int main(int argc, char *argv[]) {
delete pngFileName;
goto err2;
}
- if (!(pngFile = openFile(pngFileName->getCString(), "wb"))) {
- error(errIO, -1, "Couldn't open PNG file '{0:t}'", pngFileName);
- fclose(htmlFile);
- delete htmlFileName;
- delete pngFileName;
- goto err2;
+ if (embedBackground) {
+ pngFile = NULL;
+ } else {
+ if (!(pngFile = openFile(pngFileName->getCString(), "wb"))) {
+ error(errIO, -1, "Couldn't open PNG file '{0:t}'", pngFileName);
+ fclose(htmlFile);
+ delete htmlFileName;
+ delete pngFileName;
+ goto err2;
+ }
}
pngURL = GString::format("page{0:d}.png", pg);
err = htmlGen->convertPage(pg, pngURL->getCString(), htmlDir,
@@ -200,7 +238,9 @@ int main(int argc, char *argv[]) {
&writeToFile, pngFile);
delete pngURL;
fclose(htmlFile);
- fclose(pngFile);
+ if (!embedBackground) {
+ fclose(pngFile);
+ }
delete htmlFileName;
delete pngFileName;
if (err != errNone) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
index f19baccf581..7f3b97b9d94 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
@@ -25,6 +25,7 @@
#include "SplashBitmap.h"
#include "Splash.h"
#include "SplashOutputDev.h"
+#include "Error.h"
#include "config.h"
static int firstPage = 1;
@@ -39,6 +40,7 @@ static char antialiasStr[16] = "";
static char vectorAntialiasStr[16] = "";
static char ownerPassword[33] = "";
static char userPassword[33] = "";
+static GBool verbose = gFalse;
static GBool quiet = gFalse;
static char cfgFileName[256] = "";
static GBool printVersion = gFalse;
@@ -71,6 +73,8 @@ static ArgDesc argDesc[] = {
"owner password (for encrypted files)"},
{"-upw", argString, userPassword, sizeof(userPassword),
"user password (for encrypted files)"},
+ {"-verbose", argFlag, &verbose, 0,
+ "print per-page status information"},
{"-q", argFlag, &quiet, 0,
"don't print any messages or errors"},
{"-cfg", argString, cfgFileName, sizeof(cfgFileName),
@@ -102,7 +106,7 @@ int main(int argc, char *argv[]) {
GString *ownerPW, *userPW;
SplashColor paperColor;
SplashOutputDev *splashOut;
- GBool ok;
+ GBool ok, toStdout, printStatusInfo;
int exitCode;
int pg;
png_structp png;
@@ -134,6 +138,10 @@ int main(int argc, char *argv[]) {
pngRoot = argv[2];
// read config file
+ if (cfgFileName[0] && !pathIsFile(cfgFileName)) {
+ error(errConfig, -1, "Config file '{0:s}' doesn't exist or isn't a file",
+ cfgFileName);
+ }
globalParams = new GlobalParams(cfgFileName);
globalParams->setupBaseFonts(NULL);
if (enableFreeTypeStr[0]) {
@@ -151,6 +159,9 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "Bad '-aaVector' value on command line\n");
}
}
+ if (verbose) {
+ globalParams->setPrintStatusInfo(verbose);
+ }
if (quiet) {
globalParams->setErrQuiet(quiet);
}
@@ -185,6 +196,10 @@ int main(int argc, char *argv[]) {
lastPage = doc->getNumPages();
+ // check for stdout; set up to print per-page status info
+ toStdout = !strcmp(pngRoot, "-");
+ printStatusInfo = !toStdout && globalParams->getPrintStatusInfo();
+
// write PNG files
if (mono) {
paperColor[0] = 0xff;
@@ -201,10 +216,15 @@ int main(int argc, char *argv[]) {
}
splashOut->startDoc(doc->getXRef());
for (pg = firstPage; pg <= lastPage; ++pg) {
+ if (printStatusInfo) {
+ fflush(stderr);
+ printf("[processing page %d]\n", pg);
+ fflush(stdout);
+ }
doc->displayPage(splashOut, pg, resolution, resolution, rotate,
gFalse, gTrue, gFalse);
if (mono) {
- if (!strcmp(pngRoot, "-")) {
+ if (toStdout) {
f = stdout;
#ifdef _WIN32
_setmode(_fileno(f), _O_BINARY);
@@ -222,7 +242,7 @@ int main(int argc, char *argv[]) {
finishPNG(&png, &pngInfo);
fclose(f);
} else if (gray) {
- if (!strcmp(pngRoot, "-")) {
+ if (toStdout) {
f = stdout;
#ifdef _WIN32
_setmode(_fileno(f), _O_BINARY);
@@ -241,7 +261,7 @@ int main(int argc, char *argv[]) {
finishPNG(&png, &pngInfo);
fclose(f);
} else { // RGB
- if (!strcmp(pngRoot, "-")) {
+ if (toStdout) {
f = stdout;
#ifdef _WIN32
_setmode(_fileno(f), _O_BINARY);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc
index 0b084b014e5..28861ef948b 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc
@@ -26,6 +26,7 @@
#include "SplashBitmap.h"
#include "Splash.h"
#include "SplashOutputDev.h"
+#include "Error.h"
#include "config.h"
static int firstPage = 1;
@@ -42,6 +43,7 @@ static char antialiasStr[16] = "";
static char vectorAntialiasStr[16] = "";
static char ownerPassword[33] = "";
static char userPassword[33] = "";
+static GBool verbose = gFalse;
static GBool quiet = gFalse;
static char cfgFileName[256] = "";
static GBool printVersion = gFalse;
@@ -76,6 +78,8 @@ static ArgDesc argDesc[] = {
"owner password (for encrypted files)"},
{"-upw", argString, userPassword, sizeof(userPassword),
"user password (for encrypted files)"},
+ {"-verbose", argFlag, &verbose, 0,
+ "print per-page status information"},
{"-q", argFlag, &quiet, 0,
"don't print any messages or errors"},
{"-cfg", argString, cfgFileName, sizeof(cfgFileName),
@@ -101,7 +105,7 @@ int main(int argc, char *argv[]) {
GString *ownerPW, *userPW;
SplashColor paperColor;
SplashOutputDev *splashOut;
- GBool ok;
+ GBool ok, toStdout, printStatusInfo;
int exitCode;
int pg, n;
const char *ext;
@@ -147,6 +151,10 @@ int main(int argc, char *argv[]) {
ppmRoot = argv[2];
// read config file
+ if (cfgFileName[0] && !pathIsFile(cfgFileName)) {
+ error(errConfig, -1, "Config file '{0:s}' doesn't exist or isn't a file",
+ cfgFileName);
+ }
globalParams = new GlobalParams(cfgFileName);
globalParams->setupBaseFonts(NULL);
if (enableFreeTypeStr[0]) {
@@ -164,6 +172,9 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "Bad '-aaVector' value on command line\n");
}
}
+ if (verbose) {
+ globalParams->setPrintStatusInfo(verbose);
+ }
if (quiet) {
globalParams->setErrQuiet(quiet);
}
@@ -211,6 +222,10 @@ int main(int argc, char *argv[]) {
}
+ // check for stdout; set up to print per-page status info
+ toStdout = !strcmp(ppmRoot, "-");
+ printStatusInfo = !toStdout && globalParams->getPrintStatusInfo();
+
// write PPM files
if (mono) {
paperColor[0] = 0xff;
@@ -229,9 +244,14 @@ int main(int argc, char *argv[]) {
}
splashOut->startDoc(doc->getXRef());
for (pg = firstPage; pg <= lastPage; ++pg) {
+ if (printStatusInfo) {
+ fflush(stderr);
+ printf("[processing page %d]\n", pg);
+ fflush(stdout);
+ }
doc->displayPage(splashOut, pg, resolution, resolution, rotate,
gFalse, gTrue, gFalse);
- if (!strcmp(ppmRoot, "-")) {
+ if (toStdout) {
#ifdef _WIN32
_setmode(_fileno(stdout), _O_BINARY);
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc
index 36294551a3b..77e90fe0165 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc
@@ -64,6 +64,7 @@ static GBool userUnit = gFalse;
static GBool duplex = gFalse;
static char ownerPassword[33] = "\001";
static char userPassword[33] = "\001";
+static GBool verbose = gFalse;
static GBool quiet = gFalse;
static char cfgFileName[256] = "";
static GBool printVersion = gFalse;
@@ -132,6 +133,8 @@ static ArgDesc argDesc[] = {
"owner password (for encrypted files)"},
{"-upw", argString, userPassword, sizeof(userPassword),
"user password (for encrypted files)"},
+ {"-verbose", argFlag, &verbose, 0,
+ "print per-page status information"},
{"-q", argFlag, &quiet, 0,
"don't print any messages or errors"},
{"-cfg", argString, cfgFileName, sizeof(cfgFileName),
@@ -231,6 +234,10 @@ int main(int argc, char *argv[]) {
fileName = argv[1];
// read config file
+ if (cfgFileName[0] && !pathIsFile(cfgFileName)) {
+ error(errConfig, -1, "Config file '{0:s}' doesn't exist or isn't a file",
+ cfgFileName);
+ }
globalParams = new GlobalParams(cfgFileName);
#if HAVE_SPLASH
globalParams->setupBaseFonts(NULL);
@@ -291,6 +298,9 @@ int main(int argc, char *argv[]) {
globalParams->setPSOPI(doOPI);
}
#endif
+ if (verbose) {
+ globalParams->setPrintStatusInfo(verbose);
+ }
if (quiet) {
globalParams->setErrQuiet(quiet);
}
@@ -337,6 +347,9 @@ int main(int argc, char *argv[]) {
}
psFileName->append(doEPS ? ".eps" : ".ps");
}
+ if (psFileName->cmp("-") == 0) {
+ globalParams->setPrintStatusInfo(gFalse);
+ }
// get page range
if (firstPage < 1) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
index 975cd6a1959..d8bf6df5e67 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
@@ -58,6 +58,7 @@ static double marginTop = 0;
static double marginBottom = 0;
static char ownerPassword[33] = "\001";
static char userPassword[33] = "\001";
+static GBool verbose = gFalse;
static GBool quiet = gFalse;
static char cfgFileName[256] = "";
static GBool listEncodings = gFalse;
@@ -94,7 +95,7 @@ static ArgDesc argDesc[] = {
{"-eol", argString, textEOL, sizeof(textEOL),
"output end-of-line convention (unix, dos, or mac)"},
{"-nopgbrk", argFlag, &noPageBreaks, 0,
- "don't insert page breaks between pages"},
+ "don't insert a page break at the end of each page"},
{"-bom", argFlag, &insertBOM, 0,
"insert a Unicode BOM at the start of the text file"},
{"-marginl", argFP, &marginLeft, 0,
@@ -109,6 +110,8 @@ static ArgDesc argDesc[] = {
"owner password (for encrypted files)"},
{"-upw", argString, userPassword, sizeof(userPassword),
"user password (for encrypted files)"},
+ {"-verbose", argFlag, &verbose, 0,
+ "print per-page status information"},
{"-q", argFlag, &quiet, 0,
"don't print any messages or errors"},
{"-cfg", argString, cfgFileName, sizeof(cfgFileName),
@@ -162,6 +165,10 @@ int main(int argc, char *argv[]) {
ok = parseArgs(argDesc, &argc, argv);
if (ok && listEncodings) {
// list available encodings
+ if (cfgFileName[0] && !pathIsFile(cfgFileName)) {
+ error(errConfig, -1, "Config file '{0:s}' doesn't exist or isn't a file",
+ cfgFileName);
+ }
globalParams = new GlobalParams(cfgFileName);
GList *encs = globalParams->getAvailableTextEncodings();
for (int i = 0; i < encs->getLength(); ++i) {
@@ -182,6 +189,10 @@ int main(int argc, char *argv[]) {
fileName = argv[1];
// read config file
+ if (cfgFileName[0] && !pathIsFile(cfgFileName)) {
+ error(errConfig, -1, "Config file '{0:s}' doesn't exist or isn't a file",
+ cfgFileName);
+ }
globalParams = new GlobalParams(cfgFileName);
if (textEncName[0]) {
globalParams->setTextEncoding(textEncName);
@@ -194,6 +205,9 @@ int main(int argc, char *argv[]) {
if (noPageBreaks) {
globalParams->setTextPageBreaks(gFalse);
}
+ if (verbose) {
+ globalParams->setPrintStatusInfo(verbose);
+ }
if (quiet) {
globalParams->setErrQuiet(quiet);
}
@@ -247,6 +261,9 @@ int main(int argc, char *argv[]) {
}
textFileName->append(".txt");
}
+ if (textFileName->cmp("-") == 0) {
+ globalParams->setPrintStatusInfo(gFalse);
+ }
// get page range
if (firstPage < 1) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/winLongPath.exe.manifest b/Build/source/libs/xpdf/xpdf-src/xpdf/winLongPath.exe.manifest
new file mode 100644
index 00000000000..f46054662fc
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/winLongPath.exe.manifest
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+ <application xmlns="urn:schemas-microsoft-com:asm.v3">
+ <windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
+ <ws2:longPathAware>true</ws2:longPathAware>
+ </windowsSettings>
+ </application>
+</assembly>