summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2019-09-29 10:00:12 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2019-09-29 10:00:12 +0000
commit268dff1b06a01bd6be5f1ae08216c0beff08336c (patch)
treec8f90365823a9711e674704157dff65babb709b9
parentee6ffc65c0eb84ded1fc7d19eeb90a87541f896d (diff)
xpdf 4.02
git-svn-id: svn://tug.org/texlive/trunk@52203 c570f23f-e606-0410-a88d-b1316a301751
-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-bunched91
-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/ANNOUNCE24
-rw-r--r--Build/source/libs/xpdf/xpdf-src/CHANGES96
-rw-r--r--Build/source/libs/xpdf/xpdf-src/INSTALL16
-rw-r--r--Build/source/libs/xpdf/xpdf-src/README4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/aconf2.h10
-rw-r--r--Build/source/libs/xpdf/xpdf-src/cmake-config.txt49
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdffonts.14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfimages.14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftopng.14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftops.14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftotext.124
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat24
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/xpdf.195
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat203
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.519
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat26
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc3
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc34
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h15
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc41
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc403
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h13
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/GMutex.h1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/gfile.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/gfile.h1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/gmem.cc8
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/gmem.h6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/Splash.cc777
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/Splash.h64
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc51
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h10
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc16
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h61
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc16
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt55
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc367
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h20
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc97
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Function.h14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc184
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc79
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h17
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc82
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h11
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc271
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h16
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc173
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h19
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc45
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h3
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc58
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h15
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc55
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc30
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFDocEncoding.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc42
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc220
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc109
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h47
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc273
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h7
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc15
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc384
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h69
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc116
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h7
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/config.h14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc12
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc3
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc16
101 files changed, 4326 insertions, 965 deletions
diff --git a/Build/source/libs/README b/Build/source/libs/README
index 94bc8899a8d..08341cc7513 100644
--- a/Build/source/libs/README
+++ b/Build/source/libs/README
@@ -59,7 +59,7 @@ poppler 0.68.0 - checked 20aug18
teckit 2.5.9 - checked 03may19
https://github.com/silnrsi/teckit/archive/2.5.9.tar.gz
-xpdf 4.01.01 - checked 03may19
+xpdf 4.02 - checked 29sep19
http://www.xpdfreader.com/download.html
with modifications for pdftex
diff --git a/Build/source/libs/xpdf/ChangeLog b/Build/source/libs/xpdf/ChangeLog
index c27bc8cd203..7b963d2a8ee 100644
--- a/Build/source/libs/xpdf/ChangeLog
+++ b/Build/source/libs/xpdf/ChangeLog
@@ -1,3 +1,8 @@
+2019-09-29 Akira Kakuto <kakuto@w32tex.org>
+
+ * Import xpdf-4.02.
+ * version.ac: Adjust.
+
2019-05-03 Akira Kakuto <kakuto@w32tex.org>
* Import xpdf-4.01.01.
diff --git a/Build/source/libs/xpdf/TLpatches/ChangeLog b/Build/source/libs/xpdf/TLpatches/ChangeLog
index 4069c13a8fb..50d6fb98c82 100644
--- a/Build/source/libs/xpdf/TLpatches/ChangeLog
+++ b/Build/source/libs/xpdf/TLpatches/ChangeLog
@@ -1,3 +1,7 @@
+2019-09-29 Akira Kakuto <kakuto@w32tex.org>
+
+ * patch-bunched: Adjust.
+
2019-05-03 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 15f6253ca51..af5874a4765 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.01.01/ tree as obtained from:
+Changes applied to the xpdf-4.02/ 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 10885d1ad33..b842eb4d2ef 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.01.01/goo/gfile.cc xpdf-src/goo/gfile.cc
---- xpdf-4.01.01/goo/gfile.cc Fri Mar 15 06:01:02 2019
-+++ xpdf-src/goo/gfile.cc Mon Feb 25 11:09:32 2019
+diff -ur xpdf-4.02/goo/gfile.cc xpdf-src/goo/gfile.cc
+--- xpdf-4.02/goo/gfile.cc Thu Sep 26 04:54:33 2019
++++ xpdf-src/goo/gfile.cc Sun Sep 29 11:23:53 2019
@@ -7,6 +7,9 @@
// Copyright 1996-2003 Glyph & Cog, LLC
//
@@ -11,7 +11,7 @@ diff -ur xpdf-4.01.01/goo/gfile.cc xpdf-src/goo/gfile.cc
#include <aconf.h>
-@@ -52,7 +55,11 @@
+@@ -54,7 +57,11 @@
char *s;
GString *ret;
@@ -23,7 +23,7 @@ diff -ur xpdf-4.01.01/goo/gfile.cc xpdf-src/goo/gfile.cc
ret = new GString(s);
else
ret = new GString(".");
-@@ -401,6 +408,7 @@
+@@ -403,6 +410,7 @@
#endif
}
@@ -31,7 +31,7 @@ diff -ur xpdf-4.01.01/goo/gfile.cc xpdf-src/goo/gfile.cc
GBool openTempFile(GString **name, FILE **f,
const char *mode, const char *ext) {
#if defined(_WIN32)
-@@ -515,10 +523,11 @@
+@@ -517,10 +525,11 @@
return gTrue;
#endif
}
@@ -44,7 +44,7 @@ diff -ur xpdf-4.01.01/goo/gfile.cc xpdf-src/goo/gfile.cc
#else
return !mkdir(path, mode);
#endif
-@@ -572,6 +581,8 @@
+@@ -574,6 +583,8 @@
FILE *openFile(const char *path, const char *mode) {
#if defined(_WIN32)
@@ -53,7 +53,7 @@ diff -ur xpdf-4.01.01/goo/gfile.cc xpdf-src/goo/gfile.cc
OSVERSIONINFO version;
wchar_t wPath[_MAX_PATH + 1];
char nPath[_MAX_PATH + 1];
-@@ -628,6 +639,7 @@
+@@ -630,6 +641,7 @@
nPath[i] = '\0';
return fopen(nPath, mode);
}
@@ -61,7 +61,7 @@ diff -ur xpdf-4.01.01/goo/gfile.cc xpdf-src/goo/gfile.cc
#elif defined(VMS)
return fopen(path, mode, "ctx=stm");
#else
-@@ -688,6 +700,7 @@
+@@ -690,6 +702,7 @@
#endif
}
@@ -69,15 +69,15 @@ diff -ur xpdf-4.01.01/goo/gfile.cc xpdf-src/goo/gfile.cc
void fixCommandLine(int *argc, char **argv[]) {
#ifdef _WIN32
int argcw;
-@@ -713,3 +726,4 @@
+@@ -715,3 +728,4 @@
LocalFree(argvw);
#endif
}
+#endif /* !PDF_PARSER_ONLY */
-diff -ur xpdf-4.01.01/goo/gfile.h xpdf-src/goo/gfile.h
---- xpdf-4.01.01/goo/gfile.h Fri Mar 15 06:01:02 2019
-+++ xpdf-src/goo/gfile.h Mon Feb 25 11:07:26 2019
-@@ -114,6 +114,8 @@
+diff -ur xpdf-4.02/goo/gfile.h xpdf-src/goo/gfile.h
+--- xpdf-4.02/goo/gfile.h Thu Sep 26 04:54:33 2019
++++ xpdf-src/goo/gfile.h Sun Sep 29 11:25:19 2019
+@@ -115,6 +115,8 @@
// On Windows, this gets the Unicode command line and converts it to
// UTF-8. On other systems, this is a nop.
@@ -86,9 +86,9 @@ diff -ur xpdf-4.01.01/goo/gfile.h xpdf-src/goo/gfile.h
+#endif /* !PDF_PARSER_ONLY */
#endif
-diff -ur xpdf-4.01.01/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
---- xpdf-4.01.01/xpdf/GlobalParams.cc Fri Mar 15 06:01:02 2019
-+++ xpdf-src/xpdf/GlobalParams.cc Mon Feb 25 08:01:11 2019
+diff -ur xpdf-4.02/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
+--- xpdf-4.02/xpdf/GlobalParams.cc Thu Sep 26 04:54:33 2019
++++ xpdf-src/xpdf/GlobalParams.cc Sun Sep 29 11:32:58 2019
@@ -5,6 +5,9 @@
// Copyright 2001-2003 Glyph & Cog, LLC
//
@@ -99,7 +99,7 @@ diff -ur xpdf-4.01.01/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
#include <aconf.h>
-@@ -39,8 +42,12 @@
+@@ -44,8 +47,12 @@
#include "GlobalParams.h"
#ifdef _WIN32
@@ -114,7 +114,7 @@ diff -ur xpdf-4.01.01/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
#endif
#if MULTITHREADED
-@@ -684,6 +691,7 @@
+@@ -803,6 +810,7 @@
f = NULL;
fileName = NULL;
if (cfgFileName && cfgFileName[0]) {
@@ -122,7 +122,7 @@ diff -ur xpdf-4.01.01/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
fileName = new GString(cfgFileName);
if (!(f = fopen(fileName->getCString(), "r"))) {
delete fileName;
-@@ -716,6 +724,7 @@
+@@ -835,6 +843,7 @@
parseFile(fileName, f);
delete fileName;
fclose(f);
@@ -130,7 +130,7 @@ diff -ur xpdf-4.01.01/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
}
}
-@@ -2092,8 +2101,11 @@
+@@ -2265,8 +2274,11 @@
base14->fontNum,
displayFontTab[i].obliqueFactor));
} else {
@@ -142,9 +142,9 @@ diff -ur xpdf-4.01.01/xpdf/GlobalParams.cc xpdf-src/xpdf/GlobalParams.cc
}
}
}
-diff -ur xpdf-4.01.01/xpdf/GlobalParams.h xpdf-src/xpdf/GlobalParams.h
---- xpdf-4.01.01/xpdf/GlobalParams.h Fri Mar 15 06:01:02 2019
-+++ xpdf-src/xpdf/GlobalParams.h Mon Feb 25 08:02:36 2019
+diff -ur xpdf-4.02/xpdf/GlobalParams.h xpdf-src/xpdf/GlobalParams.h
+--- xpdf-4.02/xpdf/GlobalParams.h Thu Sep 26 04:54:33 2019
++++ xpdf-src/xpdf/GlobalParams.h Sun Sep 29 11:34:12 2019
@@ -5,6 +5,9 @@
// Copyright 2001-2003 Glyph & Cog, LLC
//
@@ -155,7 +155,7 @@ diff -ur xpdf-4.01.01/xpdf/GlobalParams.h xpdf-src/xpdf/GlobalParams.h
#ifndef GLOBALPARAMS_H
#define GLOBALPARAMS_H
-@@ -218,7 +221,7 @@
+@@ -219,7 +222,7 @@
// Initialize the global parameters by attempting to read a config
// file.
@@ -164,10 +164,10 @@ diff -ur xpdf-4.01.01/xpdf/GlobalParams.h xpdf-src/xpdf/GlobalParams.h
~GlobalParams();
-diff -ur xpdf-4.01.01/xpdf/PDFDoc.cc xpdf-src/xpdf/PDFDoc.cc
---- xpdf-4.01.01/xpdf/PDFDoc.cc Fri Mar 15 06:01:02 2019
-+++ xpdf-src/xpdf/PDFDoc.cc Sun Mar 17 08:59:43 2019
-@@ -147,20 +147,25 @@
+diff -ur xpdf-4.02/xpdf/PDFDoc.cc xpdf-src/xpdf/PDFDoc.cc
+--- xpdf-4.02/xpdf/PDFDoc.cc Thu Sep 26 04:54:33 2019
++++ xpdf-src/xpdf/PDFDoc.cc Sun Sep 29 11:41:09 2019
+@@ -156,20 +156,25 @@
PDFDoc::PDFDoc(char *fileNameA, GString *ownerPassword,
GString *userPassword, PDFCore *coreA) {
@@ -193,20 +193,19 @@ diff -ur xpdf-4.01.01/xpdf/PDFDoc.cc xpdf-src/xpdf/PDFDoc.cc
n = 0;
i = 0;
while (getUTF8(fileName, &i, &u)) {
-@@ -178,8 +183,12 @@
+@@ -187,8 +192,11 @@
if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- file = _wfopen(fileNameU, L"rb");
+ file = _wfopen(fileNameU, wfopenReadMode);
} else {
+#endif /* 0 */
- file = fopen(fileName->getCString(), "rb");
+ file = fopen(fileName->getCString(), fopenReadMode);
+#if 0
}
+#endif /* 0 */
-+
#elif defined(VMS)
- file = fopen(fileName->getCString(), "rb", "ctx=stm");
+ file = fopen(fileName->getCString(), fopenReadMode, "ctx=stm");
#else
-@@ -572,6 +581,7 @@
+@@ -581,6 +589,7 @@
GBool ret;
// NB: _wfopen is only available in NT
@@ -214,7 +213,7 @@ diff -ur xpdf-4.01.01/xpdf/PDFDoc.cc xpdf-src/xpdf/PDFDoc.cc
version.dwOSVersionInfoSize = sizeof(version);
GetVersionEx(&version);
if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-@@ -581,12 +591,15 @@
+@@ -590,12 +599,15 @@
path2w[i] = 0;
f = _wfopen(path2w, L"wb");
} else {
@@ -230,9 +229,9 @@ diff -ur xpdf-4.01.01/xpdf/PDFDoc.cc xpdf-src/xpdf/PDFDoc.cc
if (!f) {
return gFalse;
}
-diff -ur xpdf-4.01.01/xpdf/Page.cc xpdf-src/xpdf/Page.cc
---- xpdf-4.01.01/xpdf/Page.cc Fri Mar 15 06:01:02 2019
-+++ xpdf-src/xpdf/Page.cc Mon Feb 25 08:19:00 2019
+diff -ur xpdf-4.02/xpdf/Page.cc xpdf-src/xpdf/Page.cc
+--- xpdf-4.02/xpdf/Page.cc Thu Sep 26 04:54:33 2019
++++ xpdf-src/xpdf/Page.cc Sun Sep 29 11:43:12 2019
@@ -480,9 +480,9 @@
delete links;
}
@@ -251,10 +250,10 @@ diff -ur xpdf-4.01.01/xpdf/Page.cc xpdf-src/xpdf/Page.cc
-}
#endif
+}
-diff -ur xpdf-4.01.01/xpdf/XFAForm.cc xpdf-src/xpdf/XFAForm.cc
---- xpdf-4.01.01/xpdf/XFAForm.cc Fri Mar 15 06:01:02 2019
-+++ xpdf-src/xpdf/XFAForm.cc Mon Feb 25 08:20:00 2019
-@@ -28,8 +28,10 @@
+diff -ur xpdf-4.02/xpdf/XFAForm.cc xpdf-src/xpdf/XFAForm.cc
+--- xpdf-4.02/xpdf/XFAForm.cc Thu Sep 26 04:54:33 2019
++++ xpdf-src/xpdf/XFAForm.cc Sun Sep 29 11:44:10 2019
+@@ -29,8 +29,10 @@
#include "XFAForm.h"
#ifdef _WIN32
@@ -267,9 +266,9 @@ diff -ur xpdf-4.01.01/xpdf/XFAForm.cc xpdf-src/xpdf/XFAForm.cc
#endif
//------------------------------------------------------------------------
-diff -ur xpdf-4.01.01/xpdf/config.h xpdf-src/xpdf/config.h
---- xpdf-4.01.01/xpdf/config.h Fri Mar 15 06:01:02 2019
-+++ xpdf-src/xpdf/config.h Sun Mar 17 16:09:03 2019
+diff -ur xpdf-4.02/xpdf/config.h xpdf-src/xpdf/config.h
+--- xpdf-4.02/xpdf/config.h Thu Sep 26 04:54:33 2019
++++ xpdf-src/xpdf/config.h Sun Sep 29 11:45:39 2019
@@ -78,11 +78,6 @@
// popen
//------------------------------------------------------------------------
diff --git a/Build/source/libs/xpdf/configure b/Build/source/libs/xpdf/configure
index 4c19707f4cf..f4f5004df77 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.69 for xpdf (TeX Live) 4.01.01.
+# Generated by GNU Autoconf 2.69 for xpdf (TeX Live) 4.02.
#
# Report bugs to <tex-k@tug.org>.
#
@@ -580,8 +580,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='xpdf (TeX Live)'
PACKAGE_TARNAME='xpdf--tex-live-'
-PACKAGE_VERSION='4.01.01'
-PACKAGE_STRING='xpdf (TeX Live) 4.01.01'
+PACKAGE_VERSION='4.02'
+PACKAGE_STRING='xpdf (TeX Live) 4.02'
PACKAGE_BUGREPORT='tex-k@tug.org'
PACKAGE_URL=''
@@ -1290,7 +1290,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.01.01 to adapt to many kinds of systems.
+\`configure' configures xpdf (TeX Live) 4.02 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1356,7 +1356,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of xpdf (TeX Live) 4.01.01:";;
+ short | recursive ) echo "Configuration of xpdf (TeX Live) 4.02:";;
esac
cat <<\_ACEOF
@@ -1460,7 +1460,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-xpdf (TeX Live) configure 4.01.01
+xpdf (TeX Live) configure 4.02
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1867,7 +1867,7 @@ 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.01.01, which was
+It was created by xpdf (TeX Live) $as_me 4.02, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3791,7 +3791,7 @@ fi
# Define the identity of the package.
PACKAGE='xpdf--tex-live-'
- VERSION='4.01.01'
+ VERSION='4.02'
# Some tools Automake needs.
@@ -6704,7 +6704,7 @@ 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.01.01, which was
+This file was extended by xpdf (TeX Live) $as_me 4.02, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -6774,7 +6774,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-xpdf (TeX Live) config.status 4.01.01
+xpdf (TeX Live) config.status 4.02
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/Build/source/libs/xpdf/version.ac b/Build/source/libs/xpdf/version.ac
index 0a757d708db..71f3a1da85d 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.01.01])
+m4_define([xpdf_version], [4.02])
diff --git a/Build/source/libs/xpdf/xpdf-src/ANNOUNCE b/Build/source/libs/xpdf/xpdf-src/ANNOUNCE
index 67ef1bad48b..025303c44de 100644
--- a/Build/source/libs/xpdf/xpdf-src/ANNOUNCE
+++ b/Build/source/libs/xpdf/xpdf-src/ANNOUNCE
@@ -1,25 +1,27 @@
-Subject: ANNOUNCE: Xpdf 4.01 - a PDF viewer and related tools
+Subject: ANNOUNCE: Xpdf 4.02 - a PDF viewer and related tools
Glyph & Cog, LLC is pleased to announce a new version of Xpdf, the
open source Portable Document Format (PDF) viewer. The Xpdf project
also includes a PDF text extractor, PDF-to-PostScript converter, and
various other utilities.
-*** The Xpdf web site has moved to www.xpdfreader.com ***
-
Xpdf uses the Qt toolkit and runs on Linux and Windows. The
non-graphical components (pdftops, pdftotext, etc.) run on Linux,
Unix, Windows, MacOSX, and pretty much any other system with a decent
C++ compiler.
-4.01 is primarily a bug fix release. There are some new features:
-* Added remote server mode back into xpdf.
-* Added support for Unicode file names for the command line tools on
- Windows.
-* Added the tabStateFile setting, the saveTabState/loadTabState
- commands, and the "-tabstate" switch to xpdf. [Thanks to Christian
- Barthel for the suggestion.]
-* Added the defaultPrinter xpdfrc setting.
+4.02 is primarily a bug fix release. There are some new features:
+
+* Pdftohtml now extracts embedded fonts.
+
+* Various user interface tweaks in XpdfReader: added a button to
+ toggle sidebar visibilty, added menu items to toggle the sidebar and
+ toolbar, added the 'initialDisplayMode', 'initialToolbarState', and
+ 'initialSelectMode' xpdfrc settings.
+
+* If XpdfReader is already running, double-clicking on a PDF file (or
+ dragging-and-dropping it on the XpdfReader icon) opens the file in a
+ new tab (via the new '-open' command line switch).
See the `CHANGES' file for a complete list of changes.
diff --git a/Build/source/libs/xpdf/xpdf-src/CHANGES b/Build/source/libs/xpdf/xpdf-src/CHANGES
index 0114145987c..e707ff01afa 100644
--- a/Build/source/libs/xpdf/xpdf-src/CHANGES
+++ b/Build/source/libs/xpdf/xpdf-src/CHANGES
@@ -2550,3 +2550,99 @@ If the "U" string used for RC4 decryption is short, Adobe apparently
Pdffonts now checks more carefully for loops between objects.
Fixed a problem parsing large real numbers. [Thanks to Loginsoft for
the bug report.]
+
+4.02 (2019-sep-25)
+------------------
+Pdftohtml now extracts embedded fonts (TrueType and CFF only).
+Added the margin settings (-marginl -marginr -margint -marginb) to
+ pdftotext.
+Various user interface tweaks:
+ - added a toolbar button to toggle (show/hide) the sidebar
+ - added view menu items to toggle (show/hide) the sidebar and
+ toolbar
+ - added the 'showToolbar', 'hideToolbar', 'toggleToolbar',
+ 'expandSidebar', and 'shrinkSidebar' commands
+ - added the 'initialDisplayMode', 'initialToolbarState', and
+ 'initialSelectMode' xpdfrc settings
+ - rearranged the xpdf toolbar
+Implemented drag-and-drop, so that PDF files can be drag-and-dropped
+ onto an already-open xpdf window.
+Added the option to display page labels, rather than page numbers.
+Implemented the missing 'openInNewWin' command.
+Added the 'openFileIn', 'openFileAtDestIn', 'openFileAtPageIn', and
+ 'openIn' commands; removed the 'openInNewWin' command.
+Added the '-open' switch to xpdf.
+Added the reverseVideoInvertImages setting.
+Page-up and page-down now "snap" to the nearest page, if it's within a
+ few pixels. This avoids annoying behavior when the window is a tiny
+ bit too short or too tall for a page.
+Properly handle overprint in non-isolated transparency groups.
+Missing null check in Gfx::opSetExtGState(). [Thanks to
+ pwd@360TeamSeri0us for the bug report.]
+The DCT decoder doesn't handle a sampling factor of 3 -- check for
+ this and report an error. [Thanks for Agostino Sarubbo of Gentoo
+ for the bug report.]
+Check for images with a Pattern color space, and report an error.
+ [Thanks to TeamSeri0us for the bug report.]
+Check that the Width, Height, and BitsPerComponent are valid in image
+ soft masks. [Thanks to TeamSeri0us for the bug report.]
+Check for zero page width/height in PSOutputDev. [Thanks to
+ TeamSeri0us for the bug report.]
+Check for divide-by-zero in PostScript functions. [Thanks to
+ TeamSeri0us for the bug report.]
+Properly handle overprint in shading pattern strokes.
+The "save image" feature in Xpdf wasn't getting the user-specified
+ page number correctly.
+PostScript doesn't support progressive or non-interleaved DCT (JPEG)
+ streams, so check for those and re-encode them in PS output.
+Splash now caches the most recent scaled image, in case it is
+ immediately reused -- this results in a significant speedup in
+ certain cases.
+Fixed a problem with parsing the TrueType loca table. [Thanks to
+ Pangu Lab for the bug report.]
+Fixed a problem with int overflow on image bounds. [Thanks to
+ Pangu Lab for the bug report.]
+Fixed a problem with TrueType font parsing where there is gibberish in
+ the TrueType table directory. [Thanks to Pangu Lab for the bug
+ report.]
+Fixed a problem with JPX image resolution reduction. [Thanks to Pangu
+ Lab for the bug report.]
+Fixed a problem with non-isolated transparency groups in 1-bit
+ monochrome mode. [Thanks to Pangu Lab for the bug report.]
+Fixed various bugs in FoFi. [Thanks to Pangu Lab for the bug
+ reports.]
+Added a missing bounds check to Annot::setFillColor(). [Thanks to
+ Pangu Lab for the bug report.]
+Added a check on the DCT quant table selector. [Thanks to Pangu Lab
+ for the bug report.]
+Fixed a problem with the Type 3 font cache running out of entries.
+ [Thanks to Pangu Lab for the bug report.]
+Fixed an integer overflow bug in SampledFunction. [Thanks to Pangu
+ Lab for the bug report.]
+Fixed an integer overflow bug in the tiling pattern size. [Thanks to
+ Martin Muskens at Ergosoft for the bug report.]
+Fixed a read-past-end-of-buffer in the Type 1 font parser. [Thanks to
+ Pangu Lab for the bug report.]
+Fixed an int overflow bug in the JBIG2 decoder. [Thanks to
+ TeamSeri0us for the bug report.]
+Added a missing bounds check to GfxPatchMeshShading::parse(). [Thanks
+ to TeamSeri0us for the bug report.]
+JPEG 2000 tile indexes were being computed incorrectly. [Thanks to
+ TeamSeri0us for the bug report.]
+Large sample separation values in a JPX stream were resulting in
+ zero-width/height tiles, which caused problems. [Thanks to Pangu
+ Lab for the bug report.]
+The XFA parser now looks for "ancestor matches" when searching for
+ data to fill a form field.
+Fixed an uninitialized variable in BuiltinFontWidths::getWidth().
+ [Thanks to Martin Muskens at Ergosoft for the bug report.]
+If there are no popupMenuCmd instances, construct a popup menu with
+ basic instructions pointing to 'popupMenuCmd'.
+Ignore color operators in uncolored tiling patterns. [Thanks to
+ Martin Muskens at Ergosoft for the bug report.]
+Pdftotext raw mode output looks for space characters.
+Increased the width of the font name column in the pdffonts output.
+Function objects weren't checking their input/output counts properly.
+ [Thanks to Pangu Lab for the bug report.]
+TextPage::findGaps() wasn't checking the x/y min/max values for int
+ overflow. [Thanks to Taolaw for the bugf report.]
diff --git a/Build/source/libs/xpdf/xpdf-src/INSTALL b/Build/source/libs/xpdf/xpdf-src/INSTALL
index f45ce6bad37..b7e184538c8 100644
--- a/Build/source/libs/xpdf/xpdf-src/INSTALL
+++ b/Build/source/libs/xpdf/xpdf-src/INSTALL
@@ -1,8 +1,8 @@
Xpdf
====
-version 4.01.01
-2019-mar-14
+version 4.02
+2019-sep-25
The Xpdf software and documentation are
copyright 1996-2019 Glyph & Cog, LLC.
@@ -97,6 +97,11 @@ different systems.
Enables support for generation of OPI (Open Prepress
Interface) comments with pdftops.
+ -DNO_FONTCONFIG=ON
+ Disables use of libfontconfig, which is used to locate system
+ fonts on Linux/Unix systems. The default is to search for the
+ library, and to use it if found.
+
-DMULTITHREADED=0
Disables multithreading, which also disables building the GUI
viewer (xpdf). This does not affect the command line tools.
@@ -104,13 +109,18 @@ different systems.
building with a compiler other than gcc, clang, or Microsoft
Visual Studio.
+ -DXPDFWIDGET_PRINTING=OFF
+ Disable printing support.
+
-DSYSTEM_XPDFRC="/etc/xpdfrc"
Look for a system-wide xpdfrc config file in this directory.
-DCMAKE_DISABLE_FIND_PACKAGE_Qt4=1
-DCMAKE_DISABLE_FIND_PACKAGE_Qt5Widgets=1
Do not search for the Qt4/Qt5 libraries. This will disable
- building the GUI viewer (xpdf).
+ building the GUI viewer (xpdf). Cmake will look for a "qmake"
+ binary -- make sure the first qmake binary on your executable
+ search path matches the desired version of Qt.
-DCMAKE_C_FLAGS="..."
-DCMAKE_CXX_FLAGS="..."
diff --git a/Build/source/libs/xpdf/xpdf-src/README b/Build/source/libs/xpdf/xpdf-src/README
index 25e4f110eba..ebecfe97c3e 100644
--- a/Build/source/libs/xpdf/xpdf-src/README
+++ b/Build/source/libs/xpdf/xpdf-src/README
@@ -1,8 +1,8 @@
Xpdf
====
-version 4.01.01
-2019-mar-14
+version 4.02
+2019-sep-25
The Xpdf software and documentation are
copyright 1996-2019 Glyph & Cog, LLC.
diff --git a/Build/source/libs/xpdf/xpdf-src/aconf2.h b/Build/source/libs/xpdf/xpdf-src/aconf2.h
index 8bef688075d..05d785c274a 100644
--- a/Build/source/libs/xpdf/xpdf-src/aconf2.h
+++ b/Build/source/libs/xpdf/xpdf-src/aconf2.h
@@ -28,4 +28,14 @@
# endif
#endif
+/*
+ * Speed up Windows compilation. This will only work for the command
+ * line tools.
+ */
+/*
+ *#ifdef _WIN32
+ *# define WIN32_LEAN_AND_MEAN
+ *#endif
+ */
+
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/cmake-config.txt b/Build/source/libs/xpdf/xpdf-src/cmake-config.txt
index 1fbd6e59eb6..3fe2faf125c 100644
--- a/Build/source/libs/xpdf/xpdf-src/cmake-config.txt
+++ b/Build/source/libs/xpdf/xpdf-src/cmake-config.txt
@@ -81,6 +81,7 @@ option(MULTITHREADED "include support for multithreading" ON)
option(USE_EXCEPTIONS "use C++ exceptions" ON)
option(USE_FIXEDPOINT "use fixed point (instead of floating point) arithmetic" OFF)
option(SPLASH_CMYK "include support for CMYK rasterization" OFF)
+option(NO_FONTCONFIG "disable support for libfontconfig" OFF)
option(SYSTEM_XPDFRC "full path for system-wide xpdfrc file" "")
if (SYSTEM_XPDFRC)
set(SYSTEM_XPDFRC_DEFINE "#define SYSTEM_XPDFRC \"${SYSTEM_XPDFRC}\"")
@@ -193,20 +194,14 @@ if (Qt5Widgets_FOUND)
find_package(Qt5Network)
find_package(Qt5PrintSupport)
else ()
- find_package(Qt4)
+ find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED)
endif ()
if(Qt5Widgets_FOUND)
message(STATUS "Qt5 found")
if (XPDFWIDGET_PRINTING)
set(QT_INCLUDES "${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5PrintSupport_INCLUDE_DIRS}")
set(QT_DEFINITIONS "${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS} ${Qt5PrintSupport_DEFINITIONS}")
- if (APPLE)
- set(QT_LIBRARIES Qt5::Widgets Qt5::Network Qt5::PrintSupport "-framework ApplicationServices")
- elseif (UNIX)
- set(QT_LIBRARIES Qt5::Widgets Qt5::Network Qt5::PrintSupport cups)
- else ()
- set(QT_LIBRARIES Qt5::Widgets Qt5::Network Qt5::PrintSupport)
- endif ()
+ set(QT_LIBRARIES Qt5::Widgets Qt5::Network Qt5::PrintSupport)
else ()
set(QT_INCLUDES "${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS}")
set(QT_DEFINITIONS "${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS}")
@@ -216,7 +211,12 @@ if(Qt5Widgets_FOUND)
if (APPLE)
set(EXTRA_QT_LIBRARIES "-framework ApplicationServices")
elseif (UNIX)
- set(EXTRA_QT_LIBRARIES cups)
+ find_package(Cups)
+ if (CUPS_FOUND)
+ set(EXTRA_QT_LIBRARIES ${CUPS_LIBRARIES})
+ else ()
+ set (XPDFWIDGET_PRINTING OFF)
+ endif ()
else ()
set(EXTRA_QT_LIBRARIES "")
endif ()
@@ -229,7 +229,12 @@ elseif(QT4_FOUND)
if (APPLE)
set(EXTRA_QT_LIBRARIES "-framework ApplicationServices")
elseif (UNIX)
- set(EXTRA_QT_LIBRARIES cups)
+ find_package(Cups)
+ if (CUPS_FOUND)
+ set(EXTRA_QT_LIBRARIES ${CUPS_LIBRARIES})
+ else ()
+ set (XPDFWIDGET_PRINTING OFF)
+ endif ()
else ()
set(EXTRA_QT_LIBRARIES "")
endif ()
@@ -250,8 +255,30 @@ else ()
set(PAPER_LIBRARY "")
endif ()
+#--- look for fontconfig
+if (NOT NO_FONTCONFIG)
+ find_library(FONTCONFIG_LIBRARY
+ NAMES fontconfig libfontconfig
+ PATH_SUFFIXES lib64 lib
+ )
+ if (FONTCONFIG_LIBRARY)
+ set(HAVE_FONTCONFIG TRUE)
+ message(STATUS "Found fontconfig")
+ else ()
+ set(HAVE_FONTCONFIG FALSE)
+ set(FONTCONFIG_LIBRARY "")
+ endif ()
+else ()
+ set(HAVE_FONTCONFIG FALSE)
+ set(FONTCONFIG_LIBRARY "")
+endif ()
+
#--- look for pthreads
-find_package(Threads)
+if (MULTITHREADED)
+ find_package(Threads)
+else ()
+ set(CMAKE_THREAD_LIBS_INIT "")
+endif ()
#--- create aconf.h
configure_file("aconf.h.in" "aconf.h")
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1 b/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1
index bed56b58b56..82497df84fc 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-2019 Glyph & Cog, LLC
-.TH pdfdetach 1 "18 Feb 2019"
+.TH pdfdetach 1 "25 Sep 2019"
.SH NAME
pdfdetach \- Portable Document Format (PDF) document embedded file
-extractor (version 4.01)
+extractor (version 4.02)
.SH SYNOPSIS
.B pdfdetach
[options]
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat
index 30fc3ce53ed..3d4b026e701 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.01)
+ extractor (version 4.02)
SYNOPSIS
pdfdetach [options] [PDF-file]
@@ -89,4 +89,4 @@ SEE ALSO
- 18 Feb 2019 pdfdetach(1)
+ 25 Sep 2019 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 c57ce66706e..b8ffaa22b2b 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-2019 Glyph & Cog, LLC
-.TH pdffonts 1 "18 Feb 2019"
+.TH pdffonts 1 "25 Sep 2019"
.SH NAME
pdffonts \- Portable Document Format (PDF) font analyzer (version
-4.01)
+4.02)
.SH SYNOPSIS
.B pdffonts
[options]
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat
index a1dab79714d..363699cf1c5 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.01)
+ pdffonts - Portable Document Format (PDF) font analyzer (version 4.02)
SYNOPSIS
pdffonts [options] [PDF-file]
@@ -115,4 +115,4 @@ SEE ALSO
- 18 Feb 2019 pdffonts(1)
+ 25 Sep 2019 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 cc16c197d90..bef93eeaba8 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-2019 Glyph & Cog, LLC
-.TH pdfimages 1 "18 Feb 2019"
+.TH pdfimages 1 "25 Sep 2019"
.SH NAME
pdfimages \- Portable Document Format (PDF) image extractor
-(version 4.01)
+(version 4.02)
.SH SYNOPSIS
.B pdfimages
[options]
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat
index 0830f1d86e8..74b7ace12d0 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.01)
+ 4.02)
SYNOPSIS
pdfimages [options] PDF-file image-root
@@ -95,4 +95,4 @@ SEE ALSO
- 18 Feb 2019 pdfimages(1)
+ 25 Sep 2019 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 9811ac01b96..c095e88bbfa 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-2019 Glyph & Cog, LLC
-.TH pdfinfo 1 "18 Feb 2019"
+.TH pdfinfo 1 "25 Sep 2019"
.SH NAME
pdfinfo \- Portable Document Format (PDF) document information
-extractor (version 4.01)
+extractor (version 4.02)
.SH SYNOPSIS
.B pdfinfo
[options]
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat
index 6fce0425b7c..1f2ed6bd637 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.01)
+ (version 4.02)
SYNOPSIS
pdfinfo [options] [PDF-file]
@@ -114,4 +114,4 @@ SEE ALSO
- 18 Feb 2019 pdfinfo(1)
+ 25 Sep 2019 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 5217b268d0a..f37bf5c4424 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-2019 Glyph & Cog, LLC
-.TH pdftohtml 1 "18 Feb 2019"
+.TH pdftohtml 1 "25 Sep 2019"
.SH NAME
pdftohtml \- Portable Document Format (PDF) to HTML converter
-(version 4.01)
+(version 4.02)
.SH SYNOPSIS
.B pdftohtml
[options]
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat
index d29a01ecdad..5f3a0bb8fad 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.01)
+ 4.02)
SYNOPSIS
pdftohtml [options] PDF-file HTML-dir
@@ -107,4 +107,4 @@ SEE ALSO
- 18 Feb 2019 pdftohtml(1)
+ 25 Sep 2019 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 5d9cd44a7e7..c0745ced65b 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-2019 Glyph & Cog, LLC
-.TH pdftopng 1 "18 Feb 2019"
+.TH pdftopng 1 "25 Sep 2019"
.SH NAME
pdftopng \- Portable Document Format (PDF) to Portable Network Graphics
-(PNG) converter (version 4.01)
+(PNG) converter (version 4.02)
.SH SYNOPSIS
.B pdftopng
[options]
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat
index 7e6de4654a8..0241fee5956 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.01)
+ (PNG) converter (version 4.02)
SYNOPSIS
pdftopng [options] PDF-file PNG-root
@@ -97,4 +97,4 @@ SEE ALSO
- 18 Feb 2019 pdftopng(1)
+ 25 Sep 2019 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 05424a3a9fa..5ad6541d5bb 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-2019 Glyph & Cog, LLC
-.TH pdftoppm 1 "18 Feb 2019"
+.TH pdftoppm 1 "25 Sep 2019"
.SH NAME
pdftoppm \- Portable Document Format (PDF) to Portable Pixmap (PPM)
-converter (version 4.01)
+converter (version 4.02)
.SH SYNOPSIS
.B pdftoppm
[options]
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat
index cad6636e274..45e1bf1f255 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.01)
+ verter (version 4.02)
SYNOPSIS
pdftoppm [options] PDF-file PPM-root
@@ -96,4 +96,4 @@ SEE ALSO
- 18 Feb 2019 pdftoppm(1)
+ 25 Sep 2019 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 6089566d528..360e042121f 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-2019 Glyph & Cog, LLC
-.TH pdftops 1 "18 Feb 2019"
+.TH pdftops 1 "25 Sep 2019"
.SH NAME
pdftops \- Portable Document Format (PDF) to PostScript converter
-(version 4.01)
+(version 4.02)
.SH SYNOPSIS
.B pdftops
[options]
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat
index 5669e050500..5b2d9d3e0bb 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.01)
+ sion 4.02)
SYNOPSIS
pdftops [options] [PDF-file [PS-file]]
@@ -211,4 +211,4 @@ SEE ALSO
- 18 Feb 2019 pdftops(1)
+ 25 Sep 2019 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 96b6a68ea3f..d0190491ac6 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-2019 Glyph & Cog, LLC
-.TH pdftotext 1 "18 Feb 2019"
+.TH pdftotext 1 "25 Sep 2019"
.SH NAME
pdftotext \- Portable Document Format (PDF) to text converter
-(version 4.01)
+(version 4.02)
.SH SYNOPSIS
.B pdftotext
[options]
@@ -125,6 +125,26 @@ Don't insert page breaks (form feed characters) between pages.
Insert a Unicode byte order marker (BOM) at the start of the text
output.
.TP
+.BI \-marginl " number"
+Specifies the left margin, in points. Text in the left margin (i.e.,
+within that many points of the left edge of the page) is discarded.
+The default value is zero.
+.TP
+.BI \-marginr " number"
+Specifies the right margin, in points. Text in the right margin
+(i.e., within that many points of the right edge of the page) is
+discarded. The default value is zero.
+.TP
+.BI \-margint " number"
+Specifies the top margin, in points. Text in the top margin (i.e.,
+within that many points of the top edge of the page) is discarded.
+The default value is zero.
+.TP
+.BI \-marginb " number"
+Specifies the bottom margin, in points. Text in the bottom margin
+(i.e., within that many points of the bottom edge of the page) is
+discarded. The default value is zero.
+.TP
.BI \-opw " password"
Specify the owner password for the PDF file. Providing this will
bypass all security restrictions.
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat
index 2de518cb3b0..ec51212f332 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.01)
+ 4.02)
SYNOPSIS
pdftotext [options] [PDF-file [text-file]]
@@ -102,6 +102,26 @@ OPTIONS
-bom Insert a Unicode byte order marker (BOM) at the start of the
text output.
+ -marginl number
+ Specifies the left margin, in points. Text in the left margin
+ (i.e., within that many points of the left edge of the page) is
+ discarded. The default value is zero.
+
+ -marginr number
+ Specifies the right margin, in points. Text in the right margin
+ (i.e., within that many points of the right edge of the page) is
+ discarded. The default value is zero.
+
+ -margint number
+ Specifies the top margin, in points. Text in the top margin
+ (i.e., within that many points of the top edge of the page) is
+ discarded. The default value is zero.
+
+ -marginb number
+ Specifies the bottom margin, in points. Text in the bottom mar-
+ gin (i.e., within that many points of the bottom edge of the
+ page) is discarded. The default value is zero.
+
-opw password
Specify the owner password for the PDF file. Providing this
will bypass all security restrictions.
@@ -148,4 +168,4 @@ SEE ALSO
- 18 Feb 2019 pdftotext(1)
+ 25 Sep 2019 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 63f3efd3fc9..c1aedbd80cc 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-2019 Glyph & Cog, LLC
-.TH xpdf 1 "18 Feb 2019"
+.TH xpdf 1 "25 Sep 2019"
.SH NAME
-xpdf \- Portable Document Format (PDF) file viewer (version 4.01)
+xpdf \- Portable Document Format (PDF) file viewer (version 4.02)
.SH SYNOPSIS
.B xpdf
[options]
@@ -12,6 +12,11 @@ xpdf \- Portable Document Format (PDF) file viewer (version 4.01)
[options]
.B -remote
.IR remote-name " [" command " ...]"
+.PP
+.B xpdf
+[options]
+.B -open
+.RI "[" PDF-file "]"
.SH DESCRIPTION
.B Xpdf
is a viewer for Portable Document Format (PDF) files. (These are also
@@ -74,6 +79,14 @@ Set the initial window geometry.
.BI \-title " title"
Set the window title. By default, the title will be "xpdf: foo.pdf".
.TP
+.BI \-open " \fR[\fPPDF-file\fR]\fP"
+This option sets up a default remote server. If Xpdf is already
+running (with the "-open" switch), the PDF file (if any) is opened in
+a new tab. If Xpdf (with the "-open" switch) is not already running,
+starts Xpdf and opens the PDF file (if any). This is useful for GUI
+desktop environments, e.g., the typical double-click on a PDF file
+case.
+.TP
.B \-rv
Set reverse video mode. This reverses the colors of everything except
images. It may not always produce great results for PDF files which
@@ -155,11 +168,25 @@ and
are equivalent.)
.PP
.SH CONTROLS
-.SS Tool bar
+.SS Toolbar
.TP
-.B "\'page' entry box"
+.B "toggle sidebar button"
+Toggles (i.e., shows or hides) the sidebar.
+.TP
+.B "status indicator"
+This icon is animated while Xpdf is rendering a page. It turns red
+when an error or warning has been issued. Clicking on it opens the
+error dialog.
+.TP
+.B "selection mode"
+This icon is an "I-beam" in linear selection mode, and an arrow in
+block selection mode. Clicking on it toggles between the two
+selection modes.
+.TP
+.B "page number entry box"
Move to a specific page number. Click in the box to activate it, type
-the page number, then hit return.
+the page number, then hit return. This will instead display and
+accept page labels, if the "view - page labels" menu item is checked.
.TP
.B "left/right arrow buttons"
Go backward or forward along the history path.
@@ -176,12 +203,7 @@ Change the zoom factor to fit the page width to the window width.
.B "fit page button"
Change the zoom factor to fit the page to the window size.
.TP
-.B "working/error indicator"
-This icon is animated while Xpdf is rendering a page. It turns red
-when an error or warning has been issued. Clicking on it opens the
-error dialog.
-.TP
-.B "\'find' box"
+.B "find entry box"
Find a text string. Click in the box to activate it, type a search
string, then hit return.
.TP
@@ -196,11 +218,11 @@ Display the current find settings: case sensitive (on/off), find whole
words (on/off).
.PP
.SS Menu bar
-The menu bar is above the tool bar. The menu items should be
+The menu bar is above the toolbar. The menu items should be
self-explanatory.
.PP
.SS Tab list
-The tab list is on the left, just below the tool bar. It lists all
+The tab list is on the left, just below the toolbar. It lists all
open tabs.
.PP
.SS Outline/layers/attachments pane
@@ -291,6 +313,9 @@ Open a new window.
Close the current tab. Closes the window if this was the last open
tab. Quits the application if this was the last open window.
.TP
+.B control-l
+Toggle between full-screen and window modes.
+.TP
.B control-q
Quit.
.TP
@@ -433,6 +458,11 @@ End a pan operation.
.B endSelection
End a selection.
.TP
+.BI expandSidebar( n )
+Expand the sidebar by
+.I n
+pixels. Opens the sidebar if it is currently closed.
+.TP
.B find
Set keyboard focus to the \'find' box.
.TP
@@ -497,6 +527,9 @@ Go to the specified page.
.BI help
Open the help URL.
.TP
+.B hideToolbar
+Hide the toolbar.
+.TP
.B horizontalContinuousMode
Switch to horizontal continuous view mode.
.TP
@@ -526,7 +559,7 @@ Go to the next page, with the current relative scroll position.
Switch to the next tab.
.TP
.B open
-Open a PDF file in this tab, using the open dialog.
+Open a PDF file in the current tab, using the open dialog.
.TP
.B openErrorWindow
Open the error window.
@@ -538,9 +571,25 @@ Open the specified file in the current tab.
Open the specified file in the current tab at the specified named
destination.
.TP
+.BI openFileAtDestIn( file, dest, location )
+Open the specified file at the specified named destination. Location
+must be "win" for a new window or "tab" for a new tab.
+.TP
.BI openFileAtPage( file, page )
Open the specified file in the current tab at the specified page.
.TP
+.BI openFileAtPageIn( file, page, location )
+Open the specified file at the specified page. Location must be "win"
+for a new window or "tab" for a new tab.
+.TP
+.BI openFileIn( file, location )
+Open the specified file. Location must be "win" for a new window or
+"tab" for a new tab.
+.TP
+.BI openIn( location )
+Open a PDF file, using the open dialog. Location must be "win" for a
+new window or "tab" for a new tab.
+.TP
.B openSidebar
Open the sidebar.
.TP
@@ -705,6 +754,15 @@ pixels, moving to the previous page if appropriate.
.BI setSelection( pg , ulx , uly , lrx , lry )
Set the selection to the specified coordinates on the specified page.
.TP
+.B showToolbar
+Show the toolbar.
+.TP
+.BI shrinkSidebar( n )
+Shrink the sidebar by
+.I n
+pixels. Closes the sidebar if shrinking it would go below the minimum
+allowed side.
+.TP
.B sideBySideContinuousMode
Switch to side-by-side continuous view mode.
.TP
@@ -743,6 +801,15 @@ the document stays in the same place on the screen.
Toggle the sidebar between open and closed, resizing the window so
that the document size doesn't change.
.TP
+.B toggleToolbar
+Toggle the toolbar between shown and hidden.
+.TP
+.B viewPageLabels
+Show page labels (if the PDF file has them), rather than page numbers.
+.TP
+.B viewPageNumbers
+Show page numbers, rather than page labels.
+.TP
.B windowMode
Go to window (non-full-screen) mode.
.TP
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat b/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat
index b3c6ce7cabc..30c841c45ad 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat
@@ -3,13 +3,15 @@ xpdf(1) General Commands Manual xpdf(1)
NAME
- xpdf - Portable Document Format (PDF) file viewer (version 4.01)
+ xpdf - Portable Document Format (PDF) file viewer (version 4.02)
SYNOPSIS
xpdf [options] [PDF-file [:page | +dest]] ...
xpdf [options] -remote remote-name [command ...]
+ xpdf [options] -open [PDF-file]
+
DESCRIPTION
Xpdf is a viewer for Portable Document Format (PDF) files. (These are
also sometimes also called 'Acrobat' files, from the name of Adobe's
@@ -61,15 +63,23 @@ OPTIONS
Set the window title. By default, the title will be "xpdf:
foo.pdf".
- -rv Set reverse video mode. This reverses the colors of everything
- except images. It may not always produce great results for PDF
- files which do weird things with color. This also causes the
+ -open [PDF-file]
+ This option sets up a default remote server. If Xpdf is already
+ running (with the "-open" switch), the PDF file (if any) is
+ opened in a new tab. If Xpdf (with the "-open" switch) is not
+ already running, starts Xpdf and opens the PDF file (if any).
+ This is useful for GUI desktop environments, e.g., the typical
+ double-click on a PDF file case.
+
+ -rv Set reverse video mode. This reverses the colors of everything
+ except images. It may not always produce great results for PDF
+ files which do weird things with color. This also causes the
paper color to default to black.
-papercolor color
Set the "paper color", i.e., the background of the page display.
- The color can be #RRGGBB (hexadecimal) or a named color. This
- option will not work well with PDF files that do things like
+ The color can be #RRGGBB (hexadecimal) or a named color. This
+ option will not work well with PDF files that do things like
filling in white behind the text. [config file: paperColor]
-mattecolor color
@@ -78,18 +88,18 @@ OPTIONS
a named color. [config file: matteColor]
-fsmattecolor color
- Set the matte color for full-screen mode. The color can be
- #RRGGBB (hexadecimal) or a named color. [config file:
+ Set the matte color for full-screen mode. The color can be
+ #RRGGBB (hexadecimal) or a named color. [config file:
fullScreenMatteColor]
-z zoom
Set the initial zoom factor. A number specifies a zoom percent-
- age, where 100 means 72 dpi. You may also specify 'page', to
- fit the page to the window size, or 'width', to fit the page
+ age, where 100 means 72 dpi. You may also specify 'page', to
+ fit the page to the window size, or 'width', to fit the page
width to the window width. [config file: initialZoom]
-aa yes | no
- Enable or disable font anti-aliasing. This defaults to "yes".
+ Enable or disable font anti-aliasing. This defaults to "yes".
[config file: antialias]
-aaVector yes | no
@@ -97,27 +107,27 @@ OPTIONS
[config file: vectorAntialias]
-enc encoding-name
- Sets the encoding to use for text output. The encoding-name
- must be defined with the unicodeMap command (see xpdfrc(5)).
+ Sets the encoding to use for text output. The encoding-name
+ must be defined with the unicodeMap command (see xpdfrc(5)).
This defaults to "Latin1" (which is a built-in encoding). [con-
fig file: textEncoding]
-pw password
- Specify the password for the PDF file. This can be either the
- owner password (which will bypass all security restrictions) or
+ Specify the password for the PDF file. This can be either the
+ owner password (which will bypass all security restrictions) or
the user password.
-fullscreen
Open xpdf in full-screen mode, useful for presentations.
-remote remote-name
- Start Xpdf in remote server mode. See the REMOVE SERVER MODE
+ Start Xpdf in remote server mode. See the REMOVE SERVER MODE
section.
-display display
Set the X display (only available with X11).
- -cmd Print commands as they're executed (useful for debugging).
+ -cmd Print commands as they're executed (useful for debugging).
[config file: printCommands]
-cfg config-file
@@ -129,10 +139,25 @@ OPTIONS
-h Print usage information. (-help and --help are equivalent.)
CONTROLS
- Tool bar
- 'page' entry box
- Move to a specific page number. Click in the box to activate
- it, type the page number, then hit return.
+ Toolbar
+ toggle sidebar button
+ Toggles (i.e., shows or hides) the sidebar.
+
+ status indicator
+ This icon is animated while Xpdf is rendering a page. It turns
+ red when an error or warning has been issued. Clicking on it
+ opens the error dialog.
+
+ selection mode
+ This icon is an "I-beam" in linear selection mode, and an arrow
+ in block selection mode. Clicking on it toggles between the two
+ selection modes.
+
+ page number entry box
+ Move to a specific page number. Click in the box to activate
+ it, type the page number, then hit return. This will instead
+ display and accept page labels, if the "view - page labels" menu
+ item is checked.
left/right arrow buttons
Go backward or forward along the history path.
@@ -141,23 +166,18 @@ CONTROLS
Zoom out or in (i.e., change magnification) incrementally.
zoom popup menu
- Change the zoom factor (see the description of the -z option
+ Change the zoom factor (see the description of the -z option
above).
fit width button
- Change the zoom factor to fit the page width to the window
+ Change the zoom factor to fit the page width to the window
width.
fit page button
Change the zoom factor to fit the page to the window size.
- working/error indicator
- This icon is animated while Xpdf is rendering a page. It turns
- red when an error or warning has been issued. Clicking on it
- opens the error dialog.
-
- 'find' box
- Find a text string. Click in the box to activate it, type a
+ find entry box
+ Find a text string. Click in the box to activate it, type a
search string, then hit return.
find next button
@@ -171,41 +191,41 @@ CONTROLS
whole words (on/off).
Menu bar
- The menu bar is above the tool bar. The menu items should be self-
+ The menu bar is above the toolbar. The menu items should be self-
explanatory.
Tab list
- The tab list is on the left, just below the tool bar. It lists all
- open tabs.
+ The tab list is on the left, just below the toolbar. It lists all open
+ tabs.
Outline/layers/attachments pane
- This pane is on the left, below the tab list. The popup allows you to
+ This pane is on the left, below the tab list. The popup allows you to
select from outline, layers, or attachments.
- The outline is a tree-like structure of bookmarks that allows moving
+ The outline is a tree-like structure of bookmarks that allows moving
within the PDF file. Not all PDF files have outlines.
- Layers (a.k.a. optional content) allow parts of the PDF content to be
+ Layers (a.k.a. optional content) allow parts of the PDF content to be
shown or hidden. Not all PDF files have layers.
- Attachments are other files embedded within the PDF file. There is a
- 'save' button for each attached file. Not all PDF files have attach-
+ Attachments are other files embedded within the PDF file. There is a
+ 'save' button for each attached file. Not all PDF files have attach-
ments.
Text selection
- Dragging the mouse with the left button held down will highlight an
- arbitrary rectangle. Selected text can be copied to the clipboard
- (with the edit/copy menu item). On X11, selected text will be avail-
+ Dragging the mouse with the left button held down will highlight an
+ arbitrary rectangle. Selected text can be copied to the clipboard
+ (with the edit/copy menu item). On X11, selected text will be avail-
able in the X selection buffer.
Links
- When the mouse is over a hyperlink, the link target will be shown in a
+ When the mouse is over a hyperlink, the link target will be shown in a
popup near the bottom of the window.
Clicking on a hyperlink will jump to the link's destination. A link to
- another PDF document will make xpdf load that document. A 'launch'
- link to an executable program will display a dialog, and if you click
- 'ok', execute the program. URL links are opened in a system-dependent
+ another PDF document will make xpdf load that document. A 'launch'
+ link to an executable program will display a dialog, and if you click
+ 'ok', execute the program. URL links are opened in a system-dependent
way. (On UNIX, Qt uses the $BROWSER environment variable.)
Mouse bindings
@@ -215,19 +235,19 @@ CONTROLS
Dragging the mouse with the middle button held down pans the window.
- The right mouse button opens a popup menu (see popupMenuCmd in
+ The right mouse button opens a popup menu (see popupMenuCmd in
xpdfrc(5)).
Key bindings
- This section lists the default key bindings. Bindings can be changed
+ This section lists the default key bindings. Bindings can be changed
using the config file (see xpdfrc(5)).
control-o
Open a new PDF file via a file requester.
control-r
- Reload the current PDF file. Note that Xpdf will reload the
- file automatically (on a page change or redraw) if it has
+ Reload the current PDF file. Note that Xpdf will reload the
+ file automatically (on a page change or redraw) if it has
changed since it was last loaded.
control-f
@@ -261,10 +281,13 @@ CONTROLS
Open a new window.
control-w
- Close the current tab. Closes the window if this was the last
- open tab. Quits the application if this was the last open win-
+ Close the current tab. Closes the window if this was the last
+ open tab. Quits the application if this was the last open win-
dow.
+ control-l
+ Toggle between full-screen and window modes.
+
control-q
Quit.
@@ -294,11 +317,11 @@ CONTROLS
Go to the last page.
<space> or <PageDown>
- Scroll down on the current page; if already at bottom, move to
+ Scroll down on the current page; if already at bottom, move to
next page.
control-<PageDown> or control-<down-arrow>
- Go to the next page. If <ScrollLock> is active, this maintains
+ Go to the next page. If <ScrollLock> is active, this maintains
the relative position on the page.
<PageUp>
@@ -306,7 +329,7 @@ CONTROLS
ous page.
control-<PageUp> or control-<up-arrow>
- Go to the previous page. If <ScrollLock> is active, this main-
+ Go to the previous page. If <ScrollLock> is active, this main-
tains the relative position on the page.
<esc> Exit full-screen mode.
@@ -320,20 +343,20 @@ CONTROLS
w Set the zoom factor to 'width' (fit page width to window).
Full-screen mode
- Xpdf can be placed into full-screen mode via the -fullscreen command
- line option, the 'full screen' menu item, or a binding to the
+ Xpdf can be placed into full-screen mode via the -fullscreen command
+ line option, the 'full screen' menu item, or a binding to the
fullScreenMode or toggleFullScreenMode command.
- Entering full-screen mode automatically switches to single-page view
+ Entering full-screen mode automatically switches to single-page view
mode and to the fit-page zoom factor.
- Full-screen mode can be exited via the default <esc> key binding, or
+ Full-screen mode can be exited via the default <esc> key binding, or
via a binding to the windowMode or toggleFullScreenModecommand.
COMMANDS
Xpdf's key and mouse bindings are user-configurable, using the bind and
- unbind commands in the config file (see xpdfrc(5)). The bind command
- allows you to bind a key or mouse button to a sequence of one or more
+ unbind commands in the config file (see xpdfrc(5)). The bind command
+ allows you to bind a key or mouse button to a sequence of one or more
commands.
The following commands are supported:
@@ -349,11 +372,11 @@ COMMANDS
Check that file is open in the current tab, and open it if not.
checkOpenFileAtDest(file,dest)
- Check that file is open in the current tab, and open it if not.
+ Check that file is open in the current tab, and open it if not.
In either case go to the specified named destination.
checkOpenFileAtPage(file,page)
- Check that file is open in the current tab, and open it if not.
+ Check that file is open in the current tab, and open it if not.
In either case go to the specified page.
closeSidebar
@@ -385,6 +408,10 @@ COMMANDS
endSelection
End a selection.
+ expandSidebar(n)
+ Expand the sidebar by n pixels. Opens the sidebar if it is cur-
+ rently closed.
+
find Set keyboard focus to the 'find' box.
findFirst
@@ -448,6 +475,9 @@ COMMANDS
help Open the help URL.
+ hideToolbar
+ Hide the toolbar.
+
horizontalContinuousMode
Switch to horizontal continuous view mode.
@@ -475,7 +505,7 @@ COMMANDS
nextTab
Switch to the next tab.
- open Open a PDF file in this tab, using the open dialog.
+ open Open a PDF file in the current tab, using the open dialog.
openErrorWindow
Open the error window.
@@ -487,10 +517,26 @@ COMMANDS
Open the specified file in the current tab at the specified
named destination.
+ openFileAtDestIn(file,dest,location)
+ Open the specified file at the specified named destination.
+ Location must be "win" for a new window or "tab" for a new tab.
+
openFileAtPage(file,page)
- Open the specified file in the current tab at the specified
+ Open the specified file in the current tab at the specified
page.
+ openFileAtPageIn(file,page,location)
+ Open the specified file at the specified page. Location must be
+ "win" for a new window or "tab" for a new tab.
+
+ openFileIn(file,location)
+ Open the specified file. Location must be "win" for a new win-
+ dow or "tab" for a new tab.
+
+ openIn(location)
+ Open a PDF file, using the open dialog. Location must be "win"
+ for a new window or "tab" for a new tab.
+
openSidebar
Open the sidebar.
@@ -632,6 +678,13 @@ COMMANDS
Set the selection to the specified coordinates on the specified
page.
+ showToolbar
+ Show the toolbar.
+
+ shrinkSidebar(n)
+ Shrink the sidebar by n pixels. Closes the sidebar if shrinking
+ it would go below the minimum allowed side.
+
sideBySideContinuousMode
Switch to side-by-side continuous view mode.
@@ -642,11 +695,11 @@ COMMANDS
Switch to single-page view mode.
startPan
- Start a pan operation at the current mouse position, which will
+ Start a pan operation at the current mouse position, which will
scroll the document as the mouse moves.
startSelection
- Start a selection at the current mouse position, which will be
+ Start a selection at the current mouse position, which will be
extended as the mouse moves.
toggleContinuousMode
@@ -662,14 +715,24 @@ COMMANDS
Toggle the sidebar between open and closed.
toggleSidebarMoveResizeWin
- Toggle the sidebar between open and closed, resizing the window
- so that the document size doesn't change, and moving the window
+ Toggle the sidebar between open and closed, resizing the window
+ so that the document size doesn't change, and moving the window
so that the document stays in the same place on the screen.
toggleSidebarResizeWin
- Toggle the sidebar between open and closed, resizing the window
+ Toggle the sidebar between open and closed, resizing the window
so that the document size doesn't change.
+ toggleToolbar
+ Toggle the toolbar between shown and hidden.
+
+ viewPageLabels
+ Show page labels (if the PDF file has them), rather than page
+ numbers.
+
+ viewPageNumbers
+ Show page numbers, rather than page labels.
+
windowMode
Go to window (non-full-screen) mode.
@@ -732,4 +795,4 @@ SEE ALSO
- 18 Feb 2019 xpdf(1)
+ 25 Sep 2019 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 2e440f72c59..bde3b5a5973 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5
+++ b/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5
@@ -1,7 +1,7 @@
.\" Copyright 2002-2019 Glyph & Cog, LLC
-.TH xpdfrc 5 "18 Feb 2019"
+.TH xpdfrc 5 "25 Sep 2019"
.SH NAME
-xpdfrc \- configuration file for Xpdf tools (version 4.01)
+xpdfrc \- configuration file for Xpdf tools (version 4.02)
.SH DESCRIPTION
All of the Xpdf tools read a single configuration file. If you have a
.I .xpdfrc
@@ -537,11 +537,21 @@ 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.
.TP
+.BR initialDisplayMode " single | continuous | sideBySideSingle | sideBySideContinuous | horizontalContinuous"
+Sets the initial display mode. The default setting is "continuous".
+.TP
+.BI initialToolbarState " yes | no"
+If set to "yes", xpdf opens with the toolbar visible. If set to "no",
+xpdf opens with the toolbar hidden. The default is "yes".
+.TP
.BI initialSidebarState " yes | no"
If set to "yes", xpdf opens with the sidebar (tabs, outline, etc.)
visible. If set to "no", xpdf opens with the sidebar collapsed. The
default is "yes".
.TP
+.BR initialSelectMode " block | linear"
+Sets the initial selection mode. The default setting is "linear".
+.TP
.BI paperColor " color"
Set the "paper color", i.e., the background of the page display. The
color can be #RRGGBB (hexadecimal) or a named color. This option will
@@ -557,6 +567,11 @@ color.
Set the matte color for full-screen mode. The color can be #RRGGBB
(hexadecimal) or a named color.
.TP
+.BI reverseVideoInvertImages " yes | no"
+If set to "no", xpdf's reverse-video mode inverts text and vector
+graphic content, but not images. If set to "yes", xpdf inverts images
+as well. The default is "no".
+.TP
.BI popupMenuCmd " title command ..."
Add a command to the popup menu.
.I Title
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat b/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat
index d1e6e07ebce..f2412bd3420 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat
@@ -3,7 +3,7 @@ xpdfrc(5) File Formats Manual xpdfrc(5)
NAME
- xpdfrc - configuration file for Xpdf tools (version 4.01)
+ xpdfrc - configuration file for Xpdf tools (version 4.02)
DESCRIPTION
All of the Xpdf tools read a single configuration file. If you have a
@@ -493,11 +493,24 @@ VIEWER SETTINGS
window at this zoom factor (which must be a percentage). The
default value is based on the screen resolution.
+ initialDisplayMode single | continuous | sideBySideSingle | sideBySide-
+ Continuous | horizontalContinuous
+ Sets the initial display mode. The default setting is "continu-
+ ous".
+
+ initialToolbarState yes | no
+ If set to "yes", xpdf opens with the toolbar visible. If set to
+ "no", xpdf opens with the toolbar hidden. The default is "yes".
+
initialSidebarState yes | no
- If set to "yes", xpdf opens with the sidebar (tabs, outline,
- etc.) visible. If set to "no", xpdf opens with the sidebar
+ If set to "yes", xpdf opens with the sidebar (tabs, outline,
+ etc.) visible. If set to "no", xpdf opens with the sidebar
collapsed. The default is "yes".
+ initialSelectMode block | linear
+ Sets the initial selection mode. The default setting is "lin-
+ ear".
+
paperColor color
Set the "paper color", i.e., the background of the page display.
The color can be #RRGGBB (hexadecimal) or a named color. This
@@ -513,6 +526,11 @@ VIEWER SETTINGS
Set the matte color for full-screen mode. The color can be
#RRGGBB (hexadecimal) or a named color.
+ reverseVideoInvertImages yes | no
+ If set to "no", xpdf's reverse-video mode inverts text and vec-
+ tor graphic content, but not images. If set to "yes", xpdf
+ inverts images as well. The default is "no".
+
popupMenuCmd title command ...
Add a command to the popup menu. Title is the text to be dis-
played in the menu. Command is an Xpdf command (see the COM-
@@ -716,4 +734,4 @@ SEE ALSO
- 18 Feb 2019 xpdfrc(5)
+ 25 Sep 2019 xpdfrc(5)
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc
index 07cc3fcd52f..e1951b08b9f 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc
@@ -171,6 +171,7 @@ Guint FoFiBase::getUVarBE(int pos, int size, GBool *ok) {
GBool FoFiBase::checkRegion(int pos, int size) {
return pos >= 0 &&
- pos + size >= pos &&
+ size >= 0 &&
+ size <= INT_MAX - pos &&
pos + size <= len;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc
index 3709a1f2809..0f5b5bc7230 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc
@@ -320,6 +320,7 @@ FoFiTrueType::FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA,
nCmaps = 0;
nameToGID = NULL;
isDfont = isDfontA;
+ isTTC = gFalse;
parsedOk = gFalse;
parse(fontNum, allowHeadlessCFF);
@@ -985,7 +986,8 @@ void FoFiTrueType::convertToType0(char *psName, int *cidMap, int nCIDs,
GBool FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
void *outputStream, char *name,
- int *codeToGID) {
+ int *codeToGID, Guchar *replacementCmapTable,
+ int replacementCmapTableLen) {
// this substitute cmap table maps char code ffff to glyph 0,
// with tables for MacRoman and MS Unicode
static char cmapTab[44] = {
@@ -1188,7 +1190,7 @@ GBool FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
if (!missingCmap && !missingName && !missingPost && !missingOS2 &&
!unsortedLoca && !emptyCmap && !badCmapLen && !abbrevHMTX &&
nZeroLengthTables == 0 && nBogusTables == 0 &&
- !name && !codeToGID && !isDfont) {
+ !name && !codeToGID && !replacementCmapTable && !isDfont && !isTTC) {
(*outputFunc)(outputStream, (char *)file, len);
gfree(locaTable);
return gFalse;
@@ -1306,7 +1308,7 @@ GBool FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
}
// construct the new cmap table
- if (codeToGID) {
+ if (codeToGID && !replacementCmapTable) {
newCmapLen = 44 + 256 * 2;
newCmapTab = (char *)gmalloc(newCmapLen);
newCmapTab[0] = 0; // table version number = 0
@@ -1435,8 +1437,15 @@ GBool FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
// don't include the file checksum
newTables[j].checksum -= getU32BE(tables[i].offset + 8, &ok);
}
+ } else {
+ // we'll write four zero bytes for this table
+ newTables[j].len = 4;
}
- if (newTables[j].tag == cmapTag && codeToGID) {
+ if (newTables[j].tag == cmapTag && replacementCmapTable) {
+ newTables[j].len = replacementCmapTableLen;
+ newTables[j].checksum = computeTableChecksum(replacementCmapTable,
+ replacementCmapTableLen);
+ } else if (newTables[j].tag == cmapTag && codeToGID) {
newTables[j].len = newCmapLen;
newTables[j].checksum = computeTableChecksum((Guchar *)newCmapTab,
newCmapLen);
@@ -1470,7 +1479,11 @@ GBool FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
}
if (missingCmap) {
newTables[j].tag = cmapTag;
- if (codeToGID) {
+ if (replacementCmapTable) {
+ newTables[j].checksum = computeTableChecksum(replacementCmapTable,
+ replacementCmapTableLen);
+ newTables[j].len = replacementCmapTableLen;
+ } else if (codeToGID) {
newTables[j].checksum = computeTableChecksum((Guchar *)newCmapTab,
newCmapLen);
newTables[j].len = newCmapLen;
@@ -1588,6 +1601,9 @@ GBool FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
(*outputFunc)(outputStream, "\0", 1);
}
}
+ } else if (newTables[i].tag == cmapTag && replacementCmapTable) {
+ (*outputFunc)(outputStream, (char *)replacementCmapTable,
+ newTables[i].len);
} else if (newTables[i].tag == cmapTag && codeToGID) {
(*outputFunc)(outputStream, newCmapTab, newTables[i].len);
} else if (newTables[i].tag == cmapTag && missingCmap) {
@@ -1816,7 +1832,8 @@ void FoFiTrueType::cvtSfnts(FoFiOutputFunc outputFunc,
} else {
locaTable[i].origOffset = 2 * getU16BE(pos + i*2, &ok);
}
- if (locaTable[i].origOffset > glyfTableLen) {
+ if (locaTable[i].origOffset < 0 ||
+ locaTable[i].origOffset > glyfTableLen) {
locaTable[i].origOffset = glyfTableLen;
}
}
@@ -2172,7 +2189,9 @@ void FoFiTrueType::parse(int fontNum, GBool allowHeadlessCFF) {
tables[j].checksum = getU32BE(offset + pos + 4, &parsedOk);
tables[j].offset = offset + (int)getU32BE(offset + pos + 8, &parsedOk);
tables[j].len = (int)getU32BE(offset + pos + 12, &parsedOk);
- if (tables[j].offset + tables[j].len >= tables[j].offset &&
+ if (tables[j].offset >= 0 &&
+ tables[j].len >= 0 &&
+ tables[j].offset + tables[j].len >= tables[j].offset &&
tables[j].offset + tables[j].len <= len) {
// ignore any bogus entries in the table directory
++j;
@@ -2274,6 +2293,7 @@ void FoFiTrueType::parse(int fontNum, GBool allowHeadlessCFF) {
void FoFiTrueType::parseTTC(int fontNum, int *pos) {
int nFonts;
+ isTTC = gTrue;
nFonts = getU32BE(8, &parsedOk);
if (!parsedOk) {
return;
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h
index a0f759b2a6f..619e1bd6676 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h
@@ -95,6 +95,9 @@ public:
// for OpenType CFF fonts.)
void getFontMatrix(double *mat);
+ // Return the number of glyphs in the font.
+ int getNumGlyphs() { return nGlyphs; }
+
// Returns true if this looks like a CJK font that uses bytecode
// instructions to assemble glyphs.
GBool checkForTrickyCJK();
@@ -154,10 +157,15 @@ public:
// various other errors. If <name> is non-NULL, the font is renamed
// to <name>. If <codeToGID> is non-NULL, the font is re-encoded,
// using a Windows Unicode cmap. If <name> is NULL and the font is
- // complete and correct, it will be written unmodified. (Not useful
- // for OpenType CFF fonts.) Returns true if the font was modified.
+ // complete and correct, it will be written unmodified. If
+ // <replacementCmapTable> is non-NULL it will be used as the cmap
+ // table in the written font (overriding any existing cmap table
+ // and/or the codeToGID arg). (Not useful for OpenType CFF fonts.)
+ // Returns true if the font was modified.
GBool writeTTF(FoFiOutputFunc outputFunc, void *outputStream,
- char *name = NULL, int *codeToGID = NULL);
+ char *name = NULL, int *codeToGID = NULL,
+ Guchar *replacementCmapTable = NULL,
+ int replacementCmapTableLen = 0);
// Returns a pointer to the CFF font embedded in this OpenType font.
// If successful, sets *<start> and *<length>, and returns true.
@@ -200,6 +208,7 @@ private:
GBool openTypeCFF;
GBool headlessCFF;
GBool isDfont;
+ GBool isTTC;
GBool parsedOk;
};
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc
index 4f5972a7bbb..0d067b5c5a9 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc
@@ -99,7 +99,7 @@ void FoFiType1::writeEncoded(const char **newEncoding,
// copy everything up to the encoding
for (line = (char *)file;
- line && strncmp(line, "/Encoding", 9);
+ line && line + 9 <= (char *)file + len && strncmp(line, "/Encoding", 9);
line = getNextLine(line)) ;
if (!line) {
// no encoding - just copy the whole font file
@@ -122,7 +122,8 @@ void FoFiType1::writeEncoded(const char **newEncoding,
// find the end of the encoding data
//~ this ought to parse PostScript tokens
- if (!strncmp(line, "/Encoding StandardEncoding def", 30)) {
+ if (line + 30 <= (char *)file + len &&
+ !strncmp(line, "/Encoding StandardEncoding def", 30)) {
line = getNextLine(line);
} else {
// skip "/Encoding" + one whitespace char,
@@ -144,16 +145,18 @@ void FoFiType1::writeEncoded(const char **newEncoding,
// check for a second one here
if (line) {
for (line2 = line, i = 0;
- i < 20 && line2 && strncmp(line2, "/Encoding", 9);
+ i < 20 && line2 && line2 + 9 <= (char *)file + len &&
+ strncmp(line2, "/Encoding", 9);
line2 = getNextLine(line2), ++i) ;
if (i < 20 && line2) {
(*outputFunc)(outputStream, line, (int)(line2 - line));
- if (!strncmp(line2, "/Encoding StandardEncoding def", 30)) {
+ if (line2 + 30 <= (char *)file + len &&
+ !strncmp(line2, "/Encoding StandardEncoding def", 30)) {
line = getNextLine(line2);
} else {
- // skip "/Encoding" + one whitespace char,
+ // skip "/Encoding",
// then look for 'def' preceded by PostScript whitespace
- p = line2 + 10;
+ p = line2 + 9;
line = NULL;
for (; p < (char *)file + len; ++p) {
if ((*p == ' ' || *p == '\t' || *p == '\x0a' ||
@@ -203,9 +206,14 @@ void FoFiType1::parse() {
++i) {
// get font name
- if (!name && !strncmp(line, "/FontName", 9)) {
- strncpy(buf, line, 255);
- buf[255] = '\0';
+ if (!name && line + 9 <= (char *)file + len &&
+ !strncmp(line, "/FontName", 9)) {
+ n = 255;
+ if (line + n > (char *)file + len) {
+ n = (int)(((char *)file + len) - line);
+ }
+ strncpy(buf, line, n);
+ buf[n] = '\0';
if ((p = strchr(buf+9, '/')) &&
(p = strtok(p+1, " \t\n\r"))) {
name = copyString(p);
@@ -213,10 +221,10 @@ void FoFiType1::parse() {
line = getNextLine(line);
// get encoding
- } else if (!encoding &&
+ } else if (!encoding && line + 30 <= (char *)file + len &&
!strncmp(line, "/Encoding StandardEncoding def", 30)) {
encoding = (char **)fofiType1StandardEncoding;
- } else if (!encoding &&
+ } else if (!encoding && line + 19 <= (char *)file + len &&
!strncmp(line, "/Encoding 256 array", 19)) {
encoding = (char **)gmallocn(256, sizeof(char *));
for (j = 0; j < 256; ++j) {
@@ -284,9 +292,14 @@ void FoFiType1::parse() {
}
//~ check for getinterval/putinterval junk
- } else if (!gotMatrix && !strncmp(line, "/FontMatrix", 11)) {
- strncpy(buf, line + 11, 255);
- buf[255] = '\0';
+ } else if (!gotMatrix && line + 11 <= (char *)file + len &&
+ !strncmp(line, "/FontMatrix", 11)) {
+ n = 255;
+ if (line + 11 + n > (char *)file + len) {
+ n = (int)(((char *)file + len) - (line + 11));
+ }
+ strncpy(buf, line + 11, n);
+ buf[n] = '\0';
if ((p = strchr(buf, '['))) {
++p;
if ((p2 = strchr(p, ']'))) {
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc
index cdb767ae8bf..13c045f8b97 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc
@@ -18,6 +18,7 @@
#include "gmem.h"
#include "gmempp.h"
#include "GString.h"
+#include "GHash.h"
#include "FoFiEncodings.h"
#include "FoFiType1C.h"
@@ -152,6 +153,23 @@ GString *FoFiType1C::getGlyphName(int gid) {
return new GString(buf);
}
+GHash *FoFiType1C::getNameToGIDMap() {
+ GHash *map;
+ char name[256];
+ GBool ok;
+ int gid;
+
+ map = new GHash(gTrue);
+ for (gid = 0; gid < nGlyphs; ++gid) {
+ ok = gTrue;
+ getString(charset[gid], name, &ok);
+ if (ok) {
+ map->add(new GString(name), gid);
+ }
+ }
+ return map;
+}
+
int *FoFiType1C::getCIDToGIDMap(int *nCIDs) {
int *map;
int n, i;
@@ -2183,6 +2201,371 @@ void FoFiType1C::writePSString(char *s, FoFiOutputFunc outputFunc,
(*outputFunc)(outputStream, buf, i);
}
+void FoFiType1C::convertToOpenType(FoFiOutputFunc outputFunc,
+ void *outputStream,
+ int nWidths, Gushort *widths,
+ Guchar *cmapTable, int cmapTableLen) {
+ // dummy OS/2 table (taken from FoFiTrueType::writeTTF)
+ static Guchar os2Tab[86] = {
+ 0, 1, // version
+ 0, 1, // xAvgCharWidth
+ 0x01, 0x90, // usWeightClass
+ 0, 5, // usWidthClass
+ 0, 0, // fsType
+ 0, 0, // ySubscriptXSize
+ 0, 0, // ySubscriptYSize
+ 0, 0, // ySubscriptXOffset
+ 0, 0, // ySubscriptYOffset
+ 0, 0, // ySuperscriptXSize
+ 0, 0, // ySuperscriptYSize
+ 0, 0, // ySuperscriptXOffset
+ 0, 0, // ySuperscriptYOffset
+ 0, 0, // yStrikeoutSize
+ 0, 0, // yStrikeoutPosition
+ 0, 0, // sFamilyClass
+ 0, 0, 0, 0, 0, // panose
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, // ulUnicodeRange1
+ 0, 0, 0, 0, // ulUnicodeRange2
+ 0, 0, 0, 0, // ulUnicodeRange3
+ 0, 0, 0, 0, // ulUnicodeRange4
+ 0, 0, 0, 0, // achVendID
+ 0, 0, // fsSelection
+ 0, 0, // usFirstCharIndex
+ 0, 0, // usLastCharIndex
+ 0, 0, // sTypoAscender
+ 0, 0, // sTypoDescender
+ 0, 0, // sTypoLineGap
+ 0x20, 0x00, // usWinAscent
+ 0x20, 0x00, // usWinDescent
+ 0, 0, 0, 1, // ulCodePageRange1
+ 0, 0, 0, 0 // ulCodePageRange2
+ };
+ Guchar headTable[54], hheaTable[36], maxpTable[6];
+ Guchar nameTable[26], postTable[32];
+ Guchar *hmtxTable;
+ static const char *tableTag[9] = {
+ "CFF ",
+ "OS/2",
+ "cmap",
+ "head",
+ "hhea",
+ "hmtx",
+ "maxp",
+ "name",
+ "post"
+ };
+ Guchar *tableData[9];
+ int tableLength[9];
+ Guchar header[12 + 9*16];
+ double mat[6];
+ Gushort maxWidth;
+ Guint checksum, fileChecksum;
+ int unitsPerEm, xMin, yMin, xMax, yMax, offset, i;
+
+ //--- CFF_ table
+ tableData[0] = file;
+ tableLength[0] = len;
+
+ //--- OS/2 table
+ tableData[1] = os2Tab;
+ tableLength[1] = 86;
+
+ //--- cmap table
+ tableData[2] = cmapTable;
+ tableLength[2] = cmapTableLen;
+
+ //--- head table
+ getFontMatrix(mat);
+ if (mat[0] == 0) {
+ unitsPerEm = 1000;
+ } else {
+ unitsPerEm = (int)(1 / mat[0] + 0.5);
+ }
+ xMin = (int)(topDict.fontBBox[0] + 0.5);
+ yMin = (int)(topDict.fontBBox[1] + 0.5);
+ xMax = (int)(topDict.fontBBox[2] + 0.5);
+ yMax = (int)(topDict.fontBBox[3] + 0.5);
+ headTable[ 0] = 0x00; // version
+ headTable[ 1] = 0x01;
+ headTable[ 2] = 0x00;
+ headTable[ 3] = 0x00;
+ headTable[ 4] = 0x00; // revision
+ headTable[ 5] = 0x00;
+ headTable[ 6] = 0x00;
+ headTable[ 7] = 0x00;
+ headTable[ 8] = 0x00; // checksumAdjustment
+ headTable[ 9] = 0x00; // (set later)
+ headTable[10] = 0x00;
+ headTable[11] = 0x00;
+ headTable[12] = 0x5f; // magicNumber
+ headTable[13] = 0x0f;
+ headTable[14] = 0x3c;
+ headTable[15] = 0xf5;
+ headTable[16] = 0x00; // flags
+ headTable[17] = 0x03;
+ headTable[18] = (Guchar)(unitsPerEm >> 8); // unitsPerEm
+ headTable[19] = (Guchar)unitsPerEm;
+ headTable[20] = 0x00; // created
+ headTable[21] = 0x00;
+ headTable[22] = 0x00;
+ headTable[23] = 0x00;
+ headTable[24] = 0x00;
+ headTable[25] = 0x00;
+ headTable[26] = 0x00;
+ headTable[27] = 0x00;
+ headTable[28] = 0x00; // modified
+ headTable[29] = 0x00;
+ headTable[30] = 0x00;
+ headTable[31] = 0x00;
+ headTable[32] = 0x00;
+ headTable[33] = 0x00;
+ headTable[34] = 0x00;
+ headTable[35] = 0x00;
+ headTable[36] = (Guchar)(xMin >> 8); // xMin
+ headTable[37] = (Guchar)xMin;
+ headTable[38] = (Guchar)(yMin >> 8); // yMin
+ headTable[39] = (Guchar)yMin;
+ headTable[40] = (Guchar)(xMax >> 8); // xMax
+ headTable[41] = (Guchar)xMax;
+ headTable[42] = (Guchar)(yMax >> 8); // yMax
+ headTable[43] = (Guchar)yMax;
+ headTable[44] = 0; // macStyle
+ headTable[45] = 0;
+ headTable[46] = 0; // lowestRecPPEM
+ headTable[47] = 3;
+ headTable[48] = 0; // fontDirectionHint
+ headTable[49] = 2; // (deprecated)
+ headTable[50] = 0; // indexToLocFormat
+ headTable[51] = 0; // (n/a to CFF fonts)
+ headTable[52] = 0; // glyphDataFormat
+ headTable[53] = 0; // (n/a to CFF fonts)
+ tableData[3] = headTable;
+ tableLength[3] = 54;
+
+ //--- hhea table
+ maxWidth = widths[0];
+ for (i = 1; i < nWidths; ++i) {
+ if (widths[i] > maxWidth) {
+ maxWidth = widths[i];
+ }
+ }
+ hheaTable[ 0] = 0x00; // version
+ hheaTable[ 1] = 0x01;
+ hheaTable[ 2] = 0x00;
+ hheaTable[ 3] = 0x00;
+ hheaTable[ 4] = (Guchar)(yMax >> 8); // ascender
+ hheaTable[ 5] = (Guchar)yMax;
+ hheaTable[ 6] = (Guchar)(yMin >> 8); // descender
+ hheaTable[ 7] = (Guchar)yMin;
+ hheaTable[ 8] = 0; // lineGap
+ hheaTable[ 9] = 0;
+ hheaTable[10] = (Guchar)(maxWidth >> 8); // advanceWidthMax
+ hheaTable[11] = (Guchar)maxWidth;
+ hheaTable[12] = 0; // minLeftSideBearing
+ hheaTable[13] = 0;
+ hheaTable[14] = 0; // minRightSideBearing
+ hheaTable[15] = 0;
+ hheaTable[16] = (Guchar)(maxWidth >> 8); // xMaxExtent
+ hheaTable[17] = (Guchar)maxWidth;
+ hheaTable[18] = 0; // caretSlopeRise
+ hheaTable[19] = 1;
+ hheaTable[20] = 0; // caretSlopeRun
+ hheaTable[21] = 0;
+ hheaTable[22] = 0; // caretOffset
+ hheaTable[23] = 0;
+ hheaTable[24] = 0; // reserved
+ hheaTable[25] = 0;
+ hheaTable[26] = 0; // reserved
+ hheaTable[27] = 0;
+ hheaTable[28] = 0; // reserved
+ hheaTable[29] = 0;
+ hheaTable[30] = 0; // reserved
+ hheaTable[31] = 0;
+ hheaTable[32] = 0; // metricDataFormat
+ hheaTable[33] = 0;
+ hheaTable[34] = (Guchar)(nWidths >> 8); // numberOfHMetrics
+ hheaTable[35] = (Guchar)nWidths;
+ tableData[4] = hheaTable;
+ tableLength[4] = 36;
+
+ //--- hmtx table
+ //~ this currently sets LSB to 0 for all glyphs
+ hmtxTable = (Guchar *)gmallocn(nWidths, 4);
+ for (i = 0; i < nWidths; ++i) {
+ hmtxTable[4*i ] = (Guchar)(widths[i] >> 8);
+ hmtxTable[4*i+1] = (Guchar)widths[i];
+ hmtxTable[4*i+2] = 0;
+ hmtxTable[4*i+3] = 0;
+ }
+ tableData[5] = hmtxTable;
+ tableLength[5] = 4 * nWidths;
+
+ //--- maxp table
+ maxpTable[0] = 0x00; // version = 0.5
+ maxpTable[1] = 0x00;
+ maxpTable[2] = 0x50;
+ maxpTable[3] = 0x00;
+ maxpTable[4] = (Guchar)(nGlyphs >> 8); // numGlyphs
+ maxpTable[5] = (Guchar)nGlyphs;
+ tableData[6] = maxpTable;
+ tableLength[6] = 6;
+
+ //--- name table
+ nameTable[ 0] = 0x00; // format
+ nameTable[ 1] = 0x00;
+ nameTable[ 2] = 0x00; // count
+ nameTable[ 3] = 0x01;
+ nameTable[ 4] = 0x00; // stringOffset
+ nameTable[ 5] = 0x12;
+ nameTable[ 6] = 0x00; // platformID
+ nameTable[ 7] = 0x00;
+ nameTable[ 8] = 0x00; // encodingID
+ nameTable[ 9] = 0x03;
+ nameTable[10] = 0x00; // languageID
+ nameTable[11] = 0x00;
+ nameTable[12] = 0x00; // nameID
+ nameTable[13] = 0x00;
+ nameTable[14] = 0x00; // length
+ nameTable[15] = 0x08;
+ nameTable[16] = 0x00; // offset
+ nameTable[17] = 0x00;
+ nameTable[18] = 0x00; // string data
+ nameTable[19] = (Guchar)'n';
+ nameTable[20] = 0x00;
+ nameTable[21] = (Guchar)'o';
+ nameTable[22] = 0x00;
+ nameTable[23] = (Guchar)'n';
+ nameTable[24] = 0x00;
+ nameTable[25] = (Guchar)'e';
+ tableData[7] = nameTable;
+ tableLength[7] = 26;
+
+ //--- post table
+ postTable[ 0] = 0x00; // version = 3.0
+ postTable[ 1] = 0x03;
+ postTable[ 2] = 0x00;
+ postTable[ 3] = 0x00;
+ postTable[ 4] = 0x00; // italicAngle
+ postTable[ 5] = 0x00;
+ postTable[ 6] = 0x00;
+ postTable[ 7] = 0x00;
+ postTable[ 8] = 0x00; // underlinePosition
+ postTable[ 9] = 0x00;
+ postTable[10] = 0x00; // underlineThickness
+ postTable[11] = 0x00;
+ postTable[12] = 0x00; // isFixedPitch
+ postTable[13] = 0x00;
+ postTable[14] = 0x00;
+ postTable[15] = 0x00;
+ postTable[16] = 0x00; // minMemType42
+ postTable[17] = 0x00;
+ postTable[18] = 0x00;
+ postTable[19] = 0x00;
+ postTable[20] = 0x00; // maxMemType42
+ postTable[21] = 0x00;
+ postTable[22] = 0x00;
+ postTable[23] = 0x00;
+ postTable[24] = 0x00; // minMemType1
+ postTable[25] = 0x00;
+ postTable[26] = 0x00;
+ postTable[27] = 0x00;
+ postTable[28] = 0x00; // maxMemType1
+ postTable[29] = 0x00;
+ postTable[30] = 0x00;
+ postTable[31] = 0x00;
+ tableData[8] = postTable;
+ tableLength[8] = 32;
+
+ //--- header and table directory
+ header[ 0] = 'O'; // sfnt version
+ header[ 1] = 'T';
+ header[ 2] = 'T';
+ header[ 3] = 'O';
+ header[ 4] = 0x00; // numTables
+ header[ 5] = 0x09;
+ header[ 6] = 0x00; // searchRange
+ header[ 7] = 0x80;
+ header[ 8] = 0x00; // entrySelector
+ header[ 9] = 0x03;
+ header[10] = 0x00; // rangeShift
+ header[11] = 0x10;
+ offset = 12 + 9*16;
+ fileChecksum = 0;
+ for (i = 0; i < 9; ++i) {
+ header[12 + i*16 + 0] = tableTag[i][0];
+ header[12 + i*16 + 1] = tableTag[i][1];
+ header[12 + i*16 + 2] = tableTag[i][2];
+ header[12 + i*16 + 3] = tableTag[i][3];
+ checksum = computeOpenTypeTableChecksum(tableData[i], tableLength[i]);
+ fileChecksum += checksum;
+ header[12 + i*16 + 4] = (Guchar)(checksum >> 24);
+ header[12 + i*16 + 5] = (Guchar)(checksum >> 16);
+ header[12 + i*16 + 6] = (Guchar)(checksum >> 8);
+ header[12 + i*16 + 7] = (Guchar)checksum;
+ header[12 + i*16 + 8] = (Guchar)(offset >> 24);
+ header[12 + i*16 + 9] = (Guchar)(offset >> 16);
+ header[12 + i*16 + 10] = (Guchar)(offset >> 8);
+ header[12 + i*16 + 11] = (Guchar)offset;
+ header[12 + i*16 + 12] = (Guchar)(tableLength[i] >> 24);
+ header[12 + i*16 + 13] = (Guchar)(tableLength[i] >> 16);
+ header[12 + i*16 + 14] = (Guchar)(tableLength[i] >> 8);
+ header[12 + i*16 + 15] = (Guchar)tableLength[i];
+ offset += tableLength[i];
+ if (tableLength[i] & 3) {
+ offset += 4 - (tableLength[i] & 3);
+ }
+ }
+
+ //--- file checksum
+ fileChecksum += computeOpenTypeTableChecksum(header, 12 + 9*16);
+ fileChecksum = 0xb1b0afba - fileChecksum;
+ headTable[ 8] = (Guchar)(fileChecksum >> 24);
+ headTable[ 9] = (Guchar)(fileChecksum >> 16);
+ headTable[10] = (Guchar)(fileChecksum >> 8);
+ headTable[11] = (Guchar)fileChecksum;
+
+ //--- write the OpenType font
+ (*outputFunc)(outputStream, (char *)header, 12 + 9*16);
+ for (i = 0; i < 9; ++i) {
+ (*outputFunc)(outputStream, (char *)tableData[i], tableLength[i]);
+ if (tableLength[i] & 3) {
+ (*outputFunc)(outputStream, "\0\0\0", 4 - (tableLength[i] & 3));
+ }
+ }
+
+ gfree(hmtxTable);
+}
+
+Guint FoFiType1C::computeOpenTypeTableChecksum(Guchar *data, int length) {
+ Guint checksum, word;
+ int i;
+
+ checksum = 0;
+ for (i = 0; i+3 < length; i += 4) {
+ word = ((data[i ] & 0xff) << 24) +
+ ((data[i+1] & 0xff) << 16) +
+ ((data[i+2] & 0xff) << 8) +
+ (data[i+3] & 0xff);
+ checksum += word;
+ }
+ if (length & 3) {
+ word = 0;
+ i = length & ~3;
+ switch (length & 3) {
+ case 3:
+ word |= (data[i+2] & 0xff) << 8;
+ case 2:
+ word |= (data[i+1] & 0xff) << 16;
+ case 1:
+ word |= (data[i ] & 0xff) << 24;
+ break;
+ }
+ checksum += word;
+ }
+ return checksum;
+}
+
GBool FoFiType1C::parse() {
Type1CIndex fdIdx;
Type1CIndexVal val;
@@ -2577,7 +2960,14 @@ void FoFiType1C::readFDSelect() {
parsedOk = gFalse;
return;
}
- memcpy(fdSelect, file + pos, nGlyphs);
+ for (gid0 = 0; gid0 < nGlyphs; ++gid0) {
+ if (file[pos + gid0] >= nFDs) {
+ //~ error(-1, "Bad FDSelect table in CID font");
+ parsedOk = gFalse;
+ return;
+ }
+ fdSelect[gid0] = file[pos + gid0];
+ }
} else if (fdSelectFmt == 3) {
nRanges = getU16BE(pos, &parsedOk);
pos += 2;
@@ -2590,7 +2980,7 @@ void FoFiType1C::readFDSelect() {
return;
}
pos += 2;
- if (gid0 > gid1 || gid1 > nGlyphs) {
+ if (gid0 > gid1 || gid1 > nGlyphs || fd >= nFDs) {
//~ error(-1, "Bad FDSelect table in CID font");
parsedOk = gFalse;
return;
@@ -2703,10 +3093,19 @@ GBool FoFiType1C::readCharset() {
if (topDict.charsetOffset == 0) {
charset = fofiType1CISOAdobeCharset;
+ if (nGlyphs > 229) {
+ nGlyphs = 229;
+ }
} else if (topDict.charsetOffset == 1) {
charset = fofiType1CExpertCharset;
+ if (nGlyphs > 166) {
+ nGlyphs = 166;
+ }
} else if (topDict.charsetOffset == 2) {
charset = fofiType1CExpertSubsetCharset;
+ if (nGlyphs > 87) {
+ nGlyphs = 87;
+ }
} else {
charset = (Gushort *)gmallocn(nGlyphs, sizeof(Gushort));
for (i = 0; i < nGlyphs; ++i) {
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h
index ae869687898..eb75dce330d 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h
@@ -18,6 +18,7 @@
#include "gtypes.h"
#include "FoFiBase.h"
+class GHash;
class GString;
//------------------------------------------------------------------------
@@ -169,6 +170,10 @@ public:
int getNumGlyphs() { return nGlyphs; }
GString *getGlyphName(int gid);
+ // Returns a hash mapping glyph names to GIDs. This is only useful
+ // with 8-bit fonts.
+ GHash *getNameToGIDMap();
+
// Return the mapping from CIDs to GIDs, and return the number of
// CIDs in *<nCIDs>. This is only useful for CID fonts.
int *getCIDToGIDMap(int *nCIDs);
@@ -208,6 +213,13 @@ public:
void convertToType0(char *psName, int *codeMap, int nCodes,
FoFiOutputFunc outputFunc, void *outputStream);
+ // Write an OpenType file, encapsulating the CFF font. <widths>
+ // provides the glyph widths (in design units) for <nWidths> glyphs.
+ // The cmap table must be supplied by the caller.
+ void convertToOpenType(FoFiOutputFunc outputFunc, void *outputStream,
+ int nWidths, Gushort *widths,
+ Guchar *cmapTable, int cmapTableLen);
+
private:
FoFiType1C(char *fileA, int lenA, GBool freeFileDataA);
@@ -224,6 +236,7 @@ private:
void eexecWrite(Type1CEexecBuf *eb, const char *s);
void eexecWriteCharstring(Type1CEexecBuf *eb, Guchar *s, int n);
void writePSString(char *s, FoFiOutputFunc outputFunc, void *outputStream);
+ Guint computeOpenTypeTableChecksum(Guchar *data, int length);
GBool parse();
void readTopDict();
void readFD(int offset, int length, Type1CPrivateDict *pDict);
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h b/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h
index 438343fc585..a0baa70b61f 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h
+++ b/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h
@@ -36,7 +36,7 @@ public:
FixedPoint(const FixedPoint &x) { val = x.val; }
FixedPoint(double x) { val = (int)(x * (1 << fixptShift) + 0.5); }
FixedPoint(int x) { val = x << fixptShift; }
- FixedPoint(long x) { val = x << fixptShift; }
+ FixedPoint(long x) { val = (int)x << fixptShift; }
operator float()
{ return (float) val * ((float)1 / (float)(1 << fixptShift)); }
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/GMutex.h b/Build/source/libs/xpdf/xpdf-src/goo/GMutex.h
index d73366bddd0..aef4aec4859 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/GMutex.h
+++ b/Build/source/libs/xpdf/xpdf-src/goo/GMutex.h
@@ -12,6 +12,7 @@
#ifndef GMUTEX_H
#define GMUTEX_H
+#include <aconf.h>
#ifdef _WIN32
# include <windows.h>
# include <intrin.h>
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc b/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc
index 40cf9054153..e7112b2039d 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc
+++ b/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc
@@ -14,6 +14,8 @@
#include <aconf.h>
#ifdef _WIN32
+# undef WIN32_LEAN_AND_MEAN
+# include <windows.h>
# include <time.h>
# include <direct.h>
#else
@@ -613,7 +615,7 @@ FILE *openFile(const char *path, const char *mode) {
}
}
wPath[i] = (wchar_t)0;
- for (i = 0; mode[i] && i < sizeof(wMode) - 1; ++i) {
+ for (i = 0; mode[i] && i < sizeof(wMode)/sizeof(wchar_t) - 1; ++i) {
wMode[i] = (wchar_t)(mode[i] & 0xff);
}
wMode[i] = (wchar_t)0;
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/gfile.h b/Build/source/libs/xpdf/xpdf-src/goo/gfile.h
index 6bd870ecb90..c0e75073ed0 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/gfile.h
+++ b/Build/source/libs/xpdf/xpdf-src/goo/gfile.h
@@ -11,6 +11,7 @@
#ifndef GFILE_H
#define GFILE_H
+#include <aconf.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/gmem.cc b/Build/source/libs/xpdf/xpdf-src/goo/gmem.cc
index 7cf9581321f..7291f2099bb 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/gmem.cc
+++ b/Build/source/libs/xpdf/xpdf-src/goo/gmem.cc
@@ -11,7 +11,9 @@
#include <stdlib.h>
#include <stddef.h>
// older compilers won't define SIZE_MAX in stdint.h without this
-#define __STDC_LIMIT_MACROS 1
+#ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS 1
+#endif
#include <stdint.h>
#include <string.h>
#include <limits.h>
@@ -107,12 +109,12 @@ void *gmalloc(int size, int ignore) GMEM_EXCEP {
trl = (unsigned long *)(mem + gMemHdrSize + size1);
hdr->magic = gMemMagic;
hdr->size = size;
+ gMemLock;
if (ignore) {
hdr->index = -1;
} else {
hdr->index = gMemIndex++;
}
- gMemLock;
if (gMemTail) {
gMemTail->next = hdr;
hdr->prev = gMemTail;
@@ -233,12 +235,12 @@ void *gmalloc64(size_t size, int ignore) GMEM_EXCEP {
trl = (unsigned long *)(mem + gMemHdrSize + size1);
hdr->magic = gMemMagic;
hdr->size = size;
+ gMemLock;
if (ignore) {
hdr->index = -1;
} else {
hdr->index = gMemIndex++;
}
- gMemLock;
if (gMemTail) {
gMemTail->next = hdr;
hdr->prev = gMemTail;
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/gmem.h b/Build/source/libs/xpdf/xpdf-src/goo/gmem.h
index e152199325b..87a32f0324c 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/gmem.h
+++ b/Build/source/libs/xpdf/xpdf-src/goo/gmem.h
@@ -20,7 +20,11 @@ public:
~GMemException() {}
};
-#define GMEM_EXCEP throw(GMemException)
+// This used to be:
+// #define GMEM_EXCEP throw(GMemException)
+// but the throw decl was never really very useful, and is deprecated
+// as of C++11 and illegal as of C++17.
+#define GMEM_EXCEP
#else // USE_EXCEPTIONS
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
index 77718abbe70..44f87a9dcd2 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
@@ -18,6 +18,7 @@
#include <math.h>
#include "gmem.h"
#include "gmempp.h"
+#include "GString.h"
#include "SplashErrorCodes.h"
#include "SplashMath.h"
#include "SplashBitmap.h"
@@ -257,6 +258,22 @@ inline void Splash::pipeInit(SplashPipe *pipe, SplashPattern *pattern,
pipe->run = &Splash::pipeRunAACMYK8;
#endif
}
+ } else if (!pipe->pattern && !pipe->noTransparency && !state->softMask &&
+ usesShape &&
+ state->inNonIsolatedGroup && groupBackBitmap->alpha &&
+ !state->inKnockoutGroup &&
+ !state->blendFunc && !pipe->nonIsolatedGroup) {
+ if (mode == splashModeMono8 && bitmap->alpha) {
+ pipe->run = &Splash::pipeRunNonIsoMono8;
+ } else if (mode == splashModeRGB8 && bitmap->alpha) {
+ pipe->run = &Splash::pipeRunNonIsoRGB8;
+ } else if (mode == splashModeBGR8 && bitmap->alpha) {
+ pipe->run = &Splash::pipeRunNonIsoBGR8;
+#if SPLASH_CMYK
+ } else if (mode == splashModeCMYK8 && bitmap->alpha) {
+ pipe->run = &Splash::pipeRunNonIsoCMYK8;
+#endif
+ }
}
}
@@ -276,6 +293,7 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
Guchar *alpha0Ptr;
SplashColorPtr softMaskPtr;
#if SPLASH_CMYK
+ Guchar aPrev;
SplashColor cSrc2, cDest2;
#endif
@@ -514,25 +532,38 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
break;
#if SPLASH_CMYK
case splashModeCMYK8:
+ if (alpha0Ptr) { // non-isolated group
+ if (color0Ptr) { // non-isolated, knockout group
+ aPrev = *alpha0Ptr;
+ } else { // non-isolated, non-knockout group
+ aPrev = (Guchar)(*alpha0Ptr + aDest - div255(*alpha0Ptr * aDest));
+ }
+ } else { // isolated group
+ if (color0Ptr) { // isolated, knockout group
+ aPrev = 0;
+ } else { // isolated, non-knockout group
+ aPrev = aDest;
+ }
+ }
if (state->overprintMask & 0x01) {
cSrc[0] = state->cmykTransferC[cSrcPtr[0]];
} else {
- cSrc[0] = div255(aDest * cDest[0]);
+ cSrc[0] = div255(aPrev * cDest[0]);
}
if (state->overprintMask & 0x02) {
cSrc[1] = state->cmykTransferM[cSrcPtr[1]];
} else {
- cSrc[1] = div255(aDest * cDest[1]);
+ cSrc[1] = div255(aPrev * cDest[1]);
}
if (state->overprintMask & 0x04) {
cSrc[2] = state->cmykTransferY[cSrcPtr[2]];
} else {
- cSrc[2] = div255(aDest * cDest[2]);
+ cSrc[2] = div255(aPrev * cDest[2]);
}
if (state->overprintMask & 0x08) {
cSrc[3] = state->cmykTransferK[cSrcPtr[3]];
} else {
- cSrc[3] = div255(aDest * cDest[3]);
+ cSrc[3] = div255(aPrev * cDest[3]);
}
break;
#endif
@@ -1986,6 +2017,398 @@ void Splash::pipeRunAACMYK8(SplashPipe *pipe, int x0, int x1, int y,
#endif
+void Splash::pipeRunNonIsoMono8(SplashPipe *pipe, int x0, int x1, int y,
+ Guchar *shapePtr, SplashColorPtr cSrcPtr) {
+ Guchar shape, aSrc, aDest, alphaI, alpha0, aResult;
+ Guchar cSrc0, cDest0, cResult0;
+ SplashColorPtr destColorPtr;
+ Guchar *destAlphaPtr;
+ Guchar *alpha0Ptr;
+ int cSrcStride, x, lastX;
+
+ if (cSrcPtr) {
+ cSrcStride = 1;
+ } else {
+ cSrcPtr = pipe->cSrcVal;
+ cSrcStride = 0;
+ }
+ for (; x0 <= x1; ++x0) {
+ if (*shapePtr) {
+ break;
+ }
+ cSrcPtr += cSrcStride;
+ ++shapePtr;
+ }
+ if (x0 > x1) {
+ return;
+ }
+ updateModX(x0);
+ updateModY(y);
+ lastX = x0;
+
+ destColorPtr = &bitmap->data[y * bitmap->rowSize + x0];
+ destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0];
+ alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + y)
+ * groupBackBitmap->alphaRowSize +
+ (groupBackX + x0)];
+
+ for (x = x0; x <= x1; ++x) {
+
+ //----- shape
+ shape = *shapePtr;
+ if (!shape) {
+ destColorPtr += 1;
+ ++destAlphaPtr;
+ ++alpha0Ptr;
+ cSrcPtr += cSrcStride;
+ ++shapePtr;
+ continue;
+ }
+ lastX = x;
+
+ //----- read destination pixel
+ cDest0 = destColorPtr[0];
+ aDest = *destAlphaPtr;
+
+ //----- source color
+ cSrc0 = state->grayTransfer[cSrcPtr[0]];
+
+ //----- source alpha
+ aSrc = div255(pipe->aInput * shape);
+
+ //----- result alpha and non-isolated group element correction
+ aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest));
+ alpha0 = *alpha0Ptr++;
+ alphaI = (Guchar)(aResult + alpha0 - div255(aResult * alpha0));
+
+ //----- result color
+ if (alphaI == 0) {
+ cResult0 = 0;
+ } else {
+ cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI);
+ }
+
+ //----- write destination pixel
+ *destColorPtr++ = cResult0;
+ *destAlphaPtr++ = aResult;
+
+ cSrcPtr += cSrcStride;
+ ++shapePtr;
+ } // for (x ...)
+
+ updateModX(lastX);
+}
+
+void Splash::pipeRunNonIsoRGB8(SplashPipe *pipe, int x0, int x1, int y,
+ Guchar *shapePtr, SplashColorPtr cSrcPtr) {
+ Guchar shape, aSrc, aDest, alphaI, alpha0, aResult;
+ Guchar cSrc0, cSrc1, cSrc2;
+ Guchar cDest0, cDest1, cDest2;
+ Guchar cResult0, cResult1, cResult2;
+ SplashColorPtr destColorPtr;
+ Guchar *destAlphaPtr;
+ Guchar *alpha0Ptr;
+ int cSrcStride, x, lastX;
+
+ if (cSrcPtr) {
+ cSrcStride = 3;
+ } else {
+ cSrcPtr = pipe->cSrcVal;
+ cSrcStride = 0;
+ }
+ for (; x0 <= x1; ++x0) {
+ if (*shapePtr) {
+ break;
+ }
+ cSrcPtr += cSrcStride;
+ ++shapePtr;
+ }
+ if (x0 > x1) {
+ return;
+ }
+ updateModX(x0);
+ updateModY(y);
+ lastX = x0;
+
+ destColorPtr = &bitmap->data[y * bitmap->rowSize + x0 * 3];
+ destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0];
+ alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + y)
+ * groupBackBitmap->alphaRowSize +
+ (groupBackX + x0)];
+
+ for (x = x0; x <= x1; ++x) {
+
+ //----- shape
+ shape = *shapePtr;
+ if (!shape) {
+ destColorPtr += 3;
+ ++destAlphaPtr;
+ ++alpha0Ptr;
+ cSrcPtr += cSrcStride;
+ ++shapePtr;
+ continue;
+ }
+ lastX = x;
+
+ //----- read destination pixel
+ cDest0 = destColorPtr[0];
+ cDest1 = destColorPtr[1];
+ cDest2 = destColorPtr[2];
+ aDest = *destAlphaPtr;
+
+ //----- source color
+ cSrc0 = state->rgbTransferR[cSrcPtr[0]];
+ cSrc1 = state->rgbTransferG[cSrcPtr[1]];
+ cSrc2 = state->rgbTransferB[cSrcPtr[2]];
+
+ //----- source alpha
+ aSrc = div255(pipe->aInput * shape);
+
+ //----- result alpha and non-isolated group element correction
+ aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest));
+ alpha0 = *alpha0Ptr++;
+ alphaI = (Guchar)(aResult + alpha0 - div255(aResult * alpha0));
+
+ //----- result color
+ if (alphaI == 0) {
+ cResult0 = 0;
+ cResult1 = 0;
+ cResult2 = 0;
+ } else {
+ cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI);
+ cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI);
+ cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI);
+ }
+
+ //----- write destination pixel
+ destColorPtr[0] = cResult0;
+ destColorPtr[1] = cResult1;
+ destColorPtr[2] = cResult2;
+ destColorPtr += 3;
+ *destAlphaPtr++ = aResult;
+
+ cSrcPtr += cSrcStride;
+ ++shapePtr;
+ } // for (x ...)
+
+ updateModX(lastX);
+}
+
+void Splash::pipeRunNonIsoBGR8(SplashPipe *pipe, int x0, int x1, int y,
+ Guchar *shapePtr, SplashColorPtr cSrcPtr) {
+ Guchar shape, aSrc, aDest, alphaI, alpha0, aResult;
+ Guchar cSrc0, cSrc1, cSrc2;
+ Guchar cDest0, cDest1, cDest2;
+ Guchar cResult0, cResult1, cResult2;
+ SplashColorPtr destColorPtr;
+ Guchar *destAlphaPtr;
+ Guchar *alpha0Ptr;
+ int cSrcStride, x, lastX;
+
+ if (cSrcPtr) {
+ cSrcStride = 3;
+ } else {
+ cSrcPtr = pipe->cSrcVal;
+ cSrcStride = 0;
+ }
+ for (; x0 <= x1; ++x0) {
+ if (*shapePtr) {
+ break;
+ }
+ cSrcPtr += cSrcStride;
+ ++shapePtr;
+ }
+ if (x0 > x1) {
+ return;
+ }
+ updateModX(x0);
+ updateModY(y);
+ lastX = x0;
+
+ destColorPtr = &bitmap->data[y * bitmap->rowSize + x0 * 3];
+ destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0];
+ alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + y)
+ * groupBackBitmap->alphaRowSize +
+ (groupBackX + x0)];
+
+ for (x = x0; x <= x1; ++x) {
+
+ //----- shape
+ shape = *shapePtr;
+ if (!shape) {
+ destColorPtr += 3;
+ ++destAlphaPtr;
+ ++alpha0Ptr;
+ cSrcPtr += cSrcStride;
+ ++shapePtr;
+ continue;
+ }
+ lastX = x;
+
+ //----- read destination pixel
+ cDest0 = destColorPtr[2];
+ cDest1 = destColorPtr[1];
+ cDest2 = destColorPtr[0];
+ aDest = *destAlphaPtr;
+
+ //----- source color
+ cSrc0 = state->rgbTransferR[cSrcPtr[0]];
+ cSrc1 = state->rgbTransferG[cSrcPtr[1]];
+ cSrc2 = state->rgbTransferB[cSrcPtr[2]];
+
+ //----- source alpha
+ aSrc = div255(pipe->aInput * shape);
+
+ //----- result alpha and non-isolated group element correction
+ aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest));
+ alpha0 = *alpha0Ptr++;
+ alphaI = (Guchar)(aResult + alpha0 - div255(aResult * alpha0));
+
+ //----- result color
+ if (alphaI == 0) {
+ cResult0 = 0;
+ cResult1 = 0;
+ cResult2 = 0;
+ } else {
+ cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI);
+ cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI);
+ cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI);
+ }
+
+ //----- write destination pixel
+ destColorPtr[0] = cResult2;
+ destColorPtr[1] = cResult1;
+ destColorPtr[2] = cResult0;
+ destColorPtr += 3;
+ *destAlphaPtr++ = aResult;
+
+ cSrcPtr += cSrcStride;
+ ++shapePtr;
+ } // for (x ...)
+
+ updateModX(lastX);
+}
+
+#if SPLASH_CMYK
+void Splash::pipeRunNonIsoCMYK8(SplashPipe *pipe, int x0, int x1, int y,
+ Guchar *shapePtr, SplashColorPtr cSrcPtr) {
+ Guchar shape, aSrc, aDest, alphaI, alpha0, aResult, aPrev;
+ Guchar cSrc0, cSrc1, cSrc2, cSrc3;
+ Guchar cDest0, cDest1, cDest2, cDest3;
+ Guchar cResult0, cResult1, cResult2, cResult3;
+ SplashColorPtr destColorPtr;
+ Guchar *destAlphaPtr;
+ Guchar *alpha0Ptr;
+ int cSrcStride, x, lastX;
+
+ if (cSrcPtr) {
+ cSrcStride = 4;
+ } else {
+ cSrcPtr = pipe->cSrcVal;
+ cSrcStride = 0;
+ }
+ for (; x0 <= x1; ++x0) {
+ if (*shapePtr) {
+ break;
+ }
+ cSrcPtr += cSrcStride;
+ ++shapePtr;
+ }
+ if (x0 > x1) {
+ return;
+ }
+ updateModX(x0);
+ updateModY(y);
+ lastX = x0;
+
+ destColorPtr = &bitmap->data[y * bitmap->rowSize + x0 * 4];
+ destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0];
+ alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + y)
+ * groupBackBitmap->alphaRowSize +
+ (groupBackX + x0)];
+
+ for (x = x0; x <= x1; ++x) {
+
+ //----- shape
+ shape = *shapePtr;
+ if (!shape) {
+ destColorPtr += 4;
+ ++destAlphaPtr;
+ ++alpha0Ptr;
+ cSrcPtr += cSrcStride;
+ ++shapePtr;
+ continue;
+ }
+ lastX = x;
+
+ //----- read destination pixel
+ cDest0 = destColorPtr[0];
+ cDest1 = destColorPtr[1];
+ cDest2 = destColorPtr[2];
+ cDest3 = destColorPtr[3];
+ aDest = *destAlphaPtr;
+
+ //----- overprint
+ aPrev = (Guchar)(*alpha0Ptr + aDest - div255(*alpha0Ptr * aDest));
+ if (state->overprintMask & 0x01) {
+ cSrc0 = state->cmykTransferC[cSrcPtr[0]];
+ } else {
+ cSrc0 = div255(aPrev * cDest0);
+ }
+ if (state->overprintMask & 0x02) {
+ cSrc1 = state->cmykTransferM[cSrcPtr[1]];
+ } else {
+ cSrc1 = div255(aPrev * cDest1);
+ }
+ if (state->overprintMask & 0x04) {
+ cSrc2 = state->cmykTransferY[cSrcPtr[2]];
+ } else {
+ cSrc2 = div255(aPrev * cDest2);
+ }
+ if (state->overprintMask & 0x08) {
+ cSrc3 = state->cmykTransferK[cSrcPtr[3]];
+ } else {
+ cSrc3 = div255(aPrev * cDest3);
+ }
+
+ //----- source alpha
+ aSrc = div255(pipe->aInput * shape);
+
+ //----- result alpha and non-isolated group element correction
+ aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest));
+ alpha0 = *alpha0Ptr++;
+ alphaI = (Guchar)(aResult + alpha0 - div255(aResult * alpha0));
+
+ //----- result color
+ if (alphaI == 0) {
+ cResult0 = 0;
+ cResult1 = 0;
+ cResult2 = 0;
+ cResult3 = 0;
+ } else {
+ cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI);
+ cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI);
+ cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI);
+ cResult3 = (Guchar)(((alphaI - aSrc) * cDest3 + aSrc * cSrc3) / alphaI);
+ }
+
+ //----- write destination pixel
+ destColorPtr[0] = cResult0;
+ destColorPtr[1] = cResult1;
+ destColorPtr[2] = cResult2;
+ destColorPtr[3] = cResult3;
+ destColorPtr += 4;
+ *destAlphaPtr++ = aResult;
+
+ cSrcPtr += cSrcStride;
+ ++shapePtr;
+ } // for (x ...)
+
+ updateModX(lastX);
+}
+#endif
+
+
//------------------------------------------------------------------------
// Transform a point from user space to device space.
@@ -2000,10 +2423,41 @@ inline void Splash::transform(SplashCoord *matrix,
}
//------------------------------------------------------------------------
+// SplashImageCache
+//------------------------------------------------------------------------
+
+SplashImageCache::SplashImageCache() {
+ tag = NULL;
+ image = NULL;
+ refCount = 1;
+}
+
+SplashImageCache::~SplashImageCache() {
+ if (tag) {
+ delete tag;
+ }
+ if (image) {
+ delete image;
+ }
+}
+
+void SplashImageCache::incRefCount() {
+ ++refCount;
+}
+
+void SplashImageCache::decRefCount() {
+ --refCount;
+ if (refCount == 0) {
+ delete this;
+ }
+}
+
+//------------------------------------------------------------------------
// Splash
//------------------------------------------------------------------------
Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
+ SplashImageCache *imageCacheA,
SplashScreenParams *screenParams) {
bitmap = bitmapA;
bitmapComps = splashColorModeNComps[bitmap->mode];
@@ -2021,10 +2475,17 @@ Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
minLineWidth = 0;
clearModRegion();
debugMode = gFalse;
+
+ if (imageCacheA) {
+ imageCache = imageCacheA;
+ imageCache->incRefCount();
+ } else {
+ imageCache = new SplashImageCache();
+ }
}
Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
- SplashScreen *screenA) {
+ SplashImageCache *imageCacheA, SplashScreen *screenA) {
bitmap = bitmapA;
bitmapComps = splashColorModeNComps[bitmap->mode];
vectorAntialias = vectorAntialiasA;
@@ -2041,9 +2502,18 @@ Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
minLineWidth = 0;
clearModRegion();
debugMode = gFalse;
+
+ if (imageCacheA) {
+ imageCache = imageCacheA;
+ imageCache->incRefCount();
+ } else {
+ imageCache = new SplashImageCache();
+ }
}
Splash::~Splash() {
+ imageCache->decRefCount();
+
while (state->next) {
restoreState();
}
@@ -3335,6 +3805,30 @@ SplashError Splash::fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph) {
void Splash::getImageBounds(SplashCoord xyMin, SplashCoord xyMax,
int *xyMinI, int *xyMaxI) {
if (state->strokeAdjust == splashStrokeAdjustOff) {
+ // make sure the coords fit in 32-bit ints
+#if USE_FIXEDPOINT
+ if (xyMin < -32767) {
+ xyMin = -32767;
+ } else if (xyMin > 32767) {
+ xyMin = 32767;
+ }
+ if (xyMax < -32767) {
+ xyMax = -32767;
+ } else if (xyMax > 32767) {
+ xyMax = 32767;
+ }
+#else
+ if (xyMin < -1e9) {
+ xyMin = -1e9;
+ } else if (xyMin > 1e9) {
+ xyMin = 1e9;
+ }
+ if (xyMax < -1e9) {
+ xyMax = -1e9;
+ } else if (xyMax > 1e9) {
+ xyMax = 1e9;
+ }
+#endif
*xyMinI = splashFloor(xyMin);
*xyMaxI = splashFloor(xyMax);
if (*xyMaxI <= *xyMinI) {
@@ -3347,7 +3841,8 @@ void Splash::getImageBounds(SplashCoord xyMin, SplashCoord xyMax,
// The glyphMode flag is not currently used, but may be useful if the
// stroke adjustment behavior is changed.
-SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
+SplashError Splash::fillImageMask(GString *imageTag,
+ SplashImageMaskSource src, void *srcData,
int w, int h, SplashCoord *mat,
GBool glyphMode, GBool interpolate) {
SplashBitmap *scaledMask;
@@ -3401,10 +3896,17 @@ SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledMask = scaleMask(src, srcData, w, h, scaledWidth, scaledHeight,
- interpolate);
+ scaledMask = scaleMask(imageTag, src, srcData, w, h,
+ scaledWidth, scaledHeight, interpolate);
+ if (imageCache->vertFlip) {
+ vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->vertFlip = gFalse;
+ }
+ if (imageCache->horizFlip) {
+ horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->horizFlip = gFalse;
+ }
blitMask(scaledMask, x0, y0, clipRes);
- delete scaledMask;
}
// scaling plus vertical flip
@@ -3417,11 +3919,17 @@ SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledMask = scaleMask(src, srcData, w, h, scaledWidth, scaledHeight,
- interpolate);
- vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ scaledMask = scaleMask(imageTag, src, srcData, w, h,
+ scaledWidth, scaledHeight, interpolate);
+ if (!imageCache->vertFlip) {
+ vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->vertFlip = gTrue;
+ }
+ if (imageCache->horizFlip) {
+ horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->horizFlip = gFalse;
+ }
blitMask(scaledMask, x0, y0, clipRes);
- delete scaledMask;
}
// scaling plus horizontal flip
@@ -3434,11 +3942,17 @@ SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledMask = scaleMask(src, srcData, w, h, scaledWidth, scaledHeight,
- interpolate);
- horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ scaledMask = scaleMask(imageTag, src, srcData, w, h,
+ scaledWidth, scaledHeight, interpolate);
+ if (imageCache->vertFlip) {
+ vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->vertFlip = gFalse;
+ }
+ if (!imageCache->horizFlip) {
+ horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->horizFlip = gTrue;
+ }
blitMask(scaledMask, x0, y0, clipRes);
- delete scaledMask;
}
// scaling plus horizontal and vertical flips
@@ -3451,17 +3965,23 @@ SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledMask = scaleMask(src, srcData, w, h, scaledWidth, scaledHeight,
- interpolate);
- vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
- horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ scaledMask = scaleMask(imageTag, src, srcData, w, h,
+ scaledWidth, scaledHeight, interpolate);
+ if (!imageCache->vertFlip) {
+ vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->vertFlip = gTrue;
+ }
+ if (!imageCache->horizFlip) {
+ horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->horizFlip = gTrue;
+ }
blitMask(scaledMask, x0, y0, clipRes);
- delete scaledMask;
}
// all other cases
} else {
- arbitraryTransformMask(src, srcData, w, h, mat, glyphMode, interpolate);
+ arbitraryTransformMask(imageTag, src, srcData, w, h,
+ mat, glyphMode, interpolate);
}
return splashOk;
@@ -3634,7 +4154,8 @@ void Splash::upscaleMask(SplashImageMaskSource src, void *srcData,
// The glyphMode flag is not currently used, but may be useful if the
// stroke adjustment behavior is changed.
-void Splash::arbitraryTransformMask(SplashImageMaskSource src, void *srcData,
+void Splash::arbitraryTransformMask(GString *imageTag,
+ SplashImageMaskSource src, void *srcData,
int srcWidth, int srcHeight,
SplashCoord *mat, GBool glyphMode,
GBool interpolate) {
@@ -3727,8 +4248,16 @@ void Splash::arbitraryTransformMask(SplashImageMaskSource src, void *srcData,
ir11 = r00 / det;
// scale the input image
- scaledMask = scaleMask(src, srcData, srcWidth, srcHeight,
+ scaledMask = scaleMask(imageTag, src, srcData, srcWidth, srcHeight,
scaledWidth, scaledHeight, interpolate);
+ if (imageCache->vertFlip) {
+ vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->vertFlip = gFalse;
+ }
+ if (imageCache->horizFlip) {
+ horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->horizFlip = gFalse;
+ }
// construct the three sections
i = 0;
@@ -3901,42 +4430,61 @@ void Splash::arbitraryTransformMask(SplashImageMaskSource src, void *srcData,
(this->*pipe.run)(&pipe, xa, xb - 1, y, scanBuf + xa, NULL);
}
}
-
- delete scaledMask;
}
// Scale an image mask into a SplashBitmap.
-SplashBitmap *Splash::scaleMask(SplashImageMaskSource src, void *srcData,
+SplashBitmap *Splash::scaleMask(GString *imageTag,
+ SplashImageMaskSource src, void *srcData,
int srcWidth, int srcHeight,
int scaledWidth, int scaledHeight,
GBool interpolate) {
- SplashBitmap *dest;
-
- dest = new SplashBitmap(scaledWidth, scaledHeight, 1, splashModeMono8,
- gFalse);
+ if (imageCache->tag && imageTag &&
+ !imageCache->tag->cmp(imageTag) &&
+ imageCache->isMask &&
+ imageCache->width == scaledWidth &&
+ imageCache->height == scaledHeight &&
+ imageCache->interpolate == interpolate) {
+ return imageCache->image;
+ }
+ if (imageCache->tag) {
+ delete imageCache->tag;
+ }
+ if (imageCache->image) {
+ delete imageCache->image;
+ }
+ imageCache->tag = imageTag ? imageTag->copy() : (GString *)NULL;
+ imageCache->isMask = gTrue;
+ imageCache->width = scaledWidth;
+ imageCache->height = scaledHeight;
+ imageCache->interpolate = interpolate;
+ imageCache->vertFlip = gFalse;
+ imageCache->horizFlip = gFalse;
+ imageCache->image = new SplashBitmap(scaledWidth, scaledHeight,
+ 1, splashModeMono8, gFalse,
+ gTrue, NULL);
if (scaledHeight < srcHeight) {
if (scaledWidth < srcWidth) {
scaleMaskYdXd(src, srcData, srcWidth, srcHeight,
- scaledWidth, scaledHeight, dest);
+ scaledWidth, scaledHeight, imageCache->image);
} else {
scaleMaskYdXu(src, srcData, srcWidth, srcHeight,
- scaledWidth, scaledHeight, dest);
+ scaledWidth, scaledHeight, imageCache->image);
}
} else {
if (scaledWidth < srcWidth) {
scaleMaskYuXd(src, srcData, srcWidth, srcHeight,
- scaledWidth, scaledHeight, dest);
+ scaledWidth, scaledHeight, imageCache->image);
} else {
if (interpolate) {
scaleMaskYuXuI(src, srcData, srcWidth, srcHeight,
- scaledWidth, scaledHeight, dest);
+ scaledWidth, scaledHeight, imageCache->image);
} else {
scaleMaskYuXu(src, srcData, srcWidth, srcHeight,
- scaledWidth, scaledHeight, dest);
+ scaledWidth, scaledHeight, imageCache->image);
}
}
}
- return dest;
+ return imageCache->image;
}
void Splash::scaleMaskYdXd(SplashImageMaskSource src, void *srcData,
@@ -4009,7 +4557,7 @@ void Splash::scaleMaskYdXd(SplashImageMaskSource src, void *srcData,
pix += pixBuf[xx++];
}
// (255 * pix) / xStep * yStep
- pix = (pix * d) >> 23;
+ pix = (pix * d + (1 << 22)) >> 23;
// store the pixel
*destPtr++ = (Guchar)pix;
@@ -4083,7 +4631,7 @@ void Splash::scaleMaskYdXu(SplashImageMaskSource src, void *srcData,
// compute the final pixel
pix = pixBuf[x];
// (255 * pix) / yStep
- pix = (pix * d) >> 23;
+ pix = (pix * d + (1 << 22)) >> 23;
// store the pixel
for (i = 0; i < xStep; ++i) {
@@ -4158,7 +4706,7 @@ void Splash::scaleMaskYuXd(SplashImageMaskSource src, void *srcData,
pix += lineBuf[xx++];
}
// (255 * pix) / xStep
- pix = (pix * d) >> 23;
+ pix = (pix * d + (1 << 22)) >> 23;
// store the pixel
for (i = 0; i < yStep; ++i) {
@@ -4403,7 +4951,8 @@ void Splash::blitMask(SplashBitmap *src, int xDest, int yDest,
}
}
-SplashError Splash::drawImage(SplashImageSource src, void *srcData,
+SplashError Splash::drawImage(GString *imageTag,
+ SplashImageSource src, void *srcData,
SplashColorMode srcMode, GBool srcAlpha,
int w, int h, SplashCoord *mat,
GBool interpolate) {
@@ -4489,10 +5038,18 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha, w, h,
+ scaledImg = scaleImage(imageTag,
+ src, srcData, srcMode, nComps, srcAlpha, w, h,
scaledWidth, scaledHeight, interpolate);
+ if (imageCache->vertFlip) {
+ vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->vertFlip = gFalse;
+ }
+ if (imageCache->horizFlip) {
+ horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->horizFlip = gFalse;
+ }
blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
- delete scaledImg;
}
// scaling plus vertical flip
@@ -4505,11 +5062,18 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha, w, h,
+ scaledImg = scaleImage(imageTag,
+ src, srcData, srcMode, nComps, srcAlpha, w, h,
scaledWidth, scaledHeight, interpolate);
- vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ if (!imageCache->vertFlip) {
+ vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->vertFlip = gTrue;
+ }
+ if (imageCache->horizFlip) {
+ horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->horizFlip = gFalse;
+ }
blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
- delete scaledImg;
}
// scaling plus horizontal flip
@@ -4522,11 +5086,18 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha, w, h,
+ scaledImg = scaleImage(imageTag,
+ src, srcData, srcMode, nComps, srcAlpha, w, h,
scaledWidth, scaledHeight, interpolate);
- horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ if (imageCache->vertFlip) {
+ vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->vertFlip = gFalse;
+ }
+ if (!imageCache->horizFlip) {
+ horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->horizFlip = gTrue;
+ }
blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
- delete scaledImg;
}
// scaling plus horizontal and vertical flips
@@ -4539,17 +5110,23 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha, w, h,
+ scaledImg = scaleImage(imageTag,
+ src, srcData, srcMode, nComps, srcAlpha, w, h,
scaledWidth, scaledHeight, interpolate);
- vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
- horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ if (!imageCache->vertFlip) {
+ vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->vertFlip = gTrue;
+ }
+ if (!imageCache->horizFlip) {
+ horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->horizFlip = gTrue;
+ }
blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
- delete scaledImg;
}
// all other cases
} else {
- arbitraryTransformImage(src, srcData, srcMode, nComps, srcAlpha,
+ arbitraryTransformImage(imageTag, src, srcData, srcMode, nComps, srcAlpha,
w, h, mat, interpolate);
}
@@ -4765,7 +5342,8 @@ void Splash::upscaleImage(SplashImageSource src, void *srcData,
gfree(unscaledAlpha);
}
-void Splash::arbitraryTransformImage(SplashImageSource src, void *srcData,
+void Splash::arbitraryTransformImage(GString *imageTag,
+ SplashImageSource src, void *srcData,
SplashColorMode srcMode, int nComps,
GBool srcAlpha,
int srcWidth, int srcHeight,
@@ -4860,9 +5438,17 @@ void Splash::arbitraryTransformImage(SplashImageSource src, void *srcData,
ir11 = r00 / det;
// scale the input image
- scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha,
+ scaledImg = scaleImage(imageTag, src, srcData, srcMode, nComps, srcAlpha,
srcWidth, srcHeight, scaledWidth, scaledHeight,
interpolate);
+ if (imageCache->vertFlip) {
+ vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->vertFlip = gFalse;
+ }
+ if (imageCache->horizFlip) {
+ horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->horizFlip = gFalse;
+ }
// construct the three sections
i = 0;
@@ -5045,41 +5631,70 @@ void Splash::arbitraryTransformImage(SplashImageSource src, void *srcData,
}
gfree(pixelBuf);
- delete scaledImg;
}
// Scale an image into a SplashBitmap.
-SplashBitmap *Splash::scaleImage(SplashImageSource src, void *srcData,
+SplashBitmap *Splash::scaleImage(GString *imageTag,
+ SplashImageSource src, void *srcData,
SplashColorMode srcMode, int nComps,
GBool srcAlpha, int srcWidth, int srcHeight,
int scaledWidth, int scaledHeight,
GBool interpolate) {
- SplashBitmap *dest;
-
- dest = new SplashBitmap(scaledWidth, scaledHeight, 1, srcMode, srcAlpha);
+ if (imageCache->tag && imageTag &&
+ !imageCache->tag->cmp(imageTag) &&
+ !imageCache->isMask &&
+ imageCache->width == scaledWidth &&
+ imageCache->height == scaledHeight &&
+ imageCache->mode == srcMode &&
+ imageCache->alpha == srcAlpha &&
+ imageCache->interpolate == interpolate) {
+ return imageCache->image;
+ }
+ if (imageCache->tag) {
+ delete imageCache->tag;
+ }
+ if (imageCache->image) {
+ delete imageCache->image;
+ }
+ imageCache->tag = imageTag ? imageTag->copy() : (GString *)NULL;
+ imageCache->isMask = gFalse;
+ imageCache->width = scaledWidth;
+ imageCache->height = scaledHeight;
+ imageCache->mode = srcMode;
+ imageCache->alpha = srcAlpha;
+ imageCache->interpolate = interpolate;
+ imageCache->vertFlip = gFalse;
+ imageCache->horizFlip = gFalse;
+ imageCache->image = new SplashBitmap(scaledWidth, scaledHeight, 1,
+ srcMode, srcAlpha, gTrue, NULL);
if (scaledHeight < srcHeight) {
if (scaledWidth < srcWidth) {
scaleImageYdXd(src, srcData, srcMode, nComps, srcAlpha,
- srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+ srcWidth, srcHeight, scaledWidth, scaledHeight,
+ imageCache->image);
} else {
scaleImageYdXu(src, srcData, srcMode, nComps, srcAlpha,
- srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+ srcWidth, srcHeight, scaledWidth, scaledHeight,
+ imageCache->image);
}
} else {
if (scaledWidth < srcWidth) {
scaleImageYuXd(src, srcData, srcMode, nComps, srcAlpha,
- srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+ srcWidth, srcHeight, scaledWidth, scaledHeight,
+ imageCache->image);
} else {
if (interpolate) {
scaleImageYuXuI(src, srcData, srcMode, nComps, srcAlpha,
- srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+ srcWidth, srcHeight, scaledWidth, scaledHeight,
+ imageCache->image);
} else {
scaleImageYuXu(src, srcData, srcMode, nComps, srcAlpha,
- srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+ srcWidth, srcHeight, scaledWidth, scaledHeight,
+ imageCache->image);
}
}
}
- return dest;
+ return imageCache->image;
}
void Splash::scaleImageYdXd(SplashImageSource src, void *srcData,
@@ -5177,7 +5792,7 @@ void Splash::scaleImageYdXd(SplashImageSource src, void *srcData,
pix0 += pixBuf[xx++];
}
// pix / xStep * yStep
- pix0 = (pix0 * d) >> 23;
+ pix0 = (pix0 * d + (1 << 22)) >> 23;
// store the pixel
*destPtr++ = (Guchar)pix0;
@@ -5194,9 +5809,9 @@ void Splash::scaleImageYdXd(SplashImageSource src, void *srcData,
xx += 3;
}
// pix / xStep * yStep
- pix0 = (pix0 * d) >> 23;
- pix1 = (pix1 * d) >> 23;
- pix2 = (pix2 * d) >> 23;
+ pix0 = (pix0 * d + (1 << 22)) >> 23;
+ pix1 = (pix1 * d + (1 << 22)) >> 23;
+ pix2 = (pix2 * d + (1 << 22)) >> 23;
// store the pixel
*destPtr++ = (Guchar)pix0;
@@ -5217,10 +5832,10 @@ void Splash::scaleImageYdXd(SplashImageSource src, void *srcData,
xx += 4;
}
// pix / xStep * yStep
- pix0 = (pix0 * d) >> 23;
- pix1 = (pix1 * d) >> 23;
- pix2 = (pix2 * d) >> 23;
- pix3 = (pix3 * d) >> 23;
+ pix0 = (pix0 * d + (1 << 22)) >> 23;
+ pix1 = (pix1 * d + (1 << 22)) >> 23;
+ pix2 = (pix2 * d + (1 << 22)) >> 23;
+ pix3 = (pix3 * d + (1 << 22)) >> 23;
// store the pixel
*destPtr++ = (Guchar)pix0;
@@ -5244,7 +5859,7 @@ void Splash::scaleImageYdXd(SplashImageSource src, void *srcData,
alpha += alphaPixBuf[xxa];
}
// alpha / xStep * yStep
- alpha = (alpha * d) >> 23;
+ alpha = (alpha * d + (1 << 22)) >> 23;
*destAlphaPtr++ = (Guchar)alpha;
}
}
@@ -5343,7 +5958,7 @@ void Splash::scaleImageYdXu(SplashImageSource src, void *srcData,
// compute the final pixel
for (i = 0; i < nComps; ++i) {
// pixBuf[] / yStep
- pix[i] = (pixBuf[x * nComps + i] * d) >> 23;
+ pix[i] = (pixBuf[x * nComps + i] * d + (1 << 22)) >> 23;
}
// store the pixel
@@ -5379,7 +5994,7 @@ void Splash::scaleImageYdXu(SplashImageSource src, void *srcData,
// process alpha
if (srcAlpha) {
// alphaPixBuf[] / yStep
- alpha = (alphaPixBuf[x] * d) >> 23;
+ alpha = (alphaPixBuf[x] * d + (1 << 22)) >> 23;
for (i = 0; i < xStep; ++i) {
*destAlphaPtr++ = (Guchar)alpha;
}
@@ -5474,7 +6089,7 @@ void Splash::scaleImageYuXd(SplashImageSource src, void *srcData,
}
for (i = 0; i < nComps; ++i) {
// pix[] / xStep
- pix[i] = (pix[i] * d) >> 23;
+ pix[i] = (pix[i] * d + (1 << 22)) >> 23;
}
// store the pixel
@@ -5517,7 +6132,7 @@ void Splash::scaleImageYuXd(SplashImageSource src, void *srcData,
alpha += alphaLineBuf[xxa];
}
// alpha / xStep
- alpha = (alpha * d) >> 23;
+ alpha = (alpha * d + (1 << 22)) >> 23;
for (i = 0; i < yStep; ++i) {
destAlphaPtr = destAlphaPtr0 + i * scaledWidth + x;
*destAlphaPtr = (Guchar)alpha;
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.h b/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
index 423ed360573..f35aa7eafd9 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
@@ -18,6 +18,7 @@
#include "SplashTypes.h"
#include "SplashClip.h"
+class GString;
class Splash;
class SplashBitmap;
struct SplashGlyphBitmap;
@@ -65,6 +66,34 @@ enum SplashPipeResultColorCtrl {
};
//------------------------------------------------------------------------
+// SplashImageCache
+//------------------------------------------------------------------------
+
+// This holds a cached image, and is shared by multiple Splash objects
+// in the same thread.
+class SplashImageCache {
+public:
+
+ SplashImageCache();
+ ~SplashImageCache();
+ void incRefCount();
+ void decRefCount();
+
+ GString *tag;
+ GBool isMask;
+ int width;
+ int height;
+ SplashColorMode mode;
+ GBool alpha;
+ GBool interpolate;
+ GBool vertFlip;
+ GBool horizFlip;
+ SplashBitmap *image;
+
+ int refCount;
+};
+
+//------------------------------------------------------------------------
// Splash
//------------------------------------------------------------------------
@@ -73,9 +102,10 @@ public:
// Create a new rasterizer object.
Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
+ SplashImageCache *imageCacheA,
SplashScreenParams *screenParams = NULL);
Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
- SplashScreen *screenA);
+ SplashImageCache *imageCacheA, SplashScreen *screenA);
~Splash();
@@ -173,7 +203,8 @@ public:
// Note that the Splash y axis points downward, and the image source
// is assumed to produce pixels in raster order, starting from the
// top line.
- SplashError fillImageMask(SplashImageMaskSource src, void *srcData,
+ SplashError fillImageMask(GString *imageTag,
+ SplashImageMaskSource src, void *srcData,
int w, int h, SplashCoord *mat,
GBool glyphMode, GBool interpolate);
@@ -191,7 +222,8 @@ public:
// BGR8 RGB8
// CMYK8 CMYK8
// The matrix behaves as for fillImageMask.
- SplashError drawImage(SplashImageSource src, void *srcData,
+ SplashError drawImage(GString *imageTag,
+ SplashImageSource src, void *srcData,
SplashColorMode srcMode, GBool srcAlpha,
int w, int h, SplashCoord *mat,
GBool interpolate);
@@ -255,6 +287,8 @@ public:
// Toggle debug mode on or off.
void setDebugMode(GBool debugModeA) { debugMode = debugModeA; }
+ SplashImageCache *getImageCache() { return imageCache; }
+
#if 1 //~tmp: turn off anti-aliasing temporarily
void setInShading(GBool sh) { inShading = sh; }
#endif
@@ -303,6 +337,16 @@ private:
void pipeRunAACMYK8(SplashPipe *pipe, int x0, int x1, int y,
Guchar *shapePtr, SplashColorPtr cSrcPtr);
#endif
+ void pipeRunNonIsoMono8(SplashPipe *pipe, int x0, int x1, int y,
+ Guchar *shapePtr, SplashColorPtr cSrcPtr);
+ void pipeRunNonIsoRGB8(SplashPipe *pipe, int x0, int x1, int y,
+ Guchar *shapePtr, SplashColorPtr cSrcPtr);
+ void pipeRunNonIsoBGR8(SplashPipe *pipe, int x0, int x1, int y,
+ Guchar *shapePtr, SplashColorPtr cSrcPtr);
+#if SPLASH_CMYK
+ void pipeRunNonIsoCMYK8(SplashPipe *pipe, int x0, int x1, int y,
+ Guchar *shapePtr, SplashColorPtr cSrcPtr);
+#endif
void transform(SplashCoord *matrix, SplashCoord xi, SplashCoord yi,
SplashCoord *xo, SplashCoord *yo);
void updateModX(int x);
@@ -331,11 +375,13 @@ private:
int srcWidth, int srcHeight,
SplashCoord *mat, GBool glyphMode,
GBool interpolate);
- void arbitraryTransformMask(SplashImageMaskSource src, void *srcData,
+ void arbitraryTransformMask(GString *imageTag,
+ SplashImageMaskSource src, void *srcData,
int srcWidth, int srcHeight,
SplashCoord *mat, GBool glyphMode,
GBool interpolate);
- SplashBitmap *scaleMask(SplashImageMaskSource src, void *srcData,
+ SplashBitmap *scaleMask(GString *imageTag,
+ SplashImageMaskSource src, void *srcData,
int srcWidth, int srcHeight,
int scaledWidth, int scaledHeight,
GBool interpolate);
@@ -365,12 +411,14 @@ private:
SplashColorMode srcMode, int nComps,
GBool srcAlpha, int srcWidth, int srcHeight,
SplashCoord *mat, GBool interpolate);
- void arbitraryTransformImage(SplashImageSource src, void *srcData,
+ void arbitraryTransformImage(GString *imageTag,
+ SplashImageSource src, void *srcData,
SplashColorMode srcMode, int nComps,
GBool srcAlpha,
int srcWidth, int srcHeight,
SplashCoord *mat, GBool interpolate);
- SplashBitmap *scaleImage(SplashImageSource src, void *srcData,
+ SplashBitmap *scaleImage(GString *imageTag,
+ SplashImageSource src, void *srcData,
SplashColorMode srcMode, int nComps,
GBool srcAlpha, int srcWidth, int srcHeight,
int scaledWidth, int scaledHeight,
@@ -432,6 +480,8 @@ private:
GBool vectorAntialias;
GBool inShading;
GBool debugMode;
+
+ SplashImageCache *imageCache;
};
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc
index aa916179df3..88ce49ca3b4 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc
@@ -25,7 +25,7 @@
SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
SplashColorMode modeA, GBool alphaA,
- GBool topDown) {
+ GBool topDown, SplashBitmap *parentA) {
// NB: this code checks that rowSize fits in a signed 32-bit
// integer, because some code (outside this class) makes that
// assumption
@@ -63,14 +63,35 @@ SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
}
rowSize += rowPad - 1;
rowSize -= rowSize % rowPad;
- data = (SplashColorPtr)gmallocn64(height, rowSize);
+
+ parent = parentA;
+ oldData = NULL;
+ oldAlpha = NULL;
+ oldRowSize = 0;
+ oldAlphaRowSize = 0;
+ oldHeight = 0;
+ if (parent && parent->oldData &&
+ parent->oldRowSize == rowSize &&
+ parent->oldHeight == height) {
+ data = parent->oldData;
+ parent->oldData = NULL;
+ } else {
+ data = (SplashColorPtr)gmallocn64(height, rowSize);
+ }
if (!topDown) {
data += (height - 1) * rowSize;
rowSize = -rowSize;
}
if (alphaA) {
alphaRowSize = width;
- alpha = (Guchar *)gmallocn64(height, alphaRowSize);
+ if (parent && parent->oldAlpha &&
+ parent->oldAlphaRowSize == alphaRowSize &&
+ parent->oldHeight == height) {
+ alpha = parent->oldAlpha;
+ parent->oldAlpha = NULL;
+ } else {
+ alpha = (Guchar *)gmallocn64(height, alphaRowSize);
+ }
} else {
alphaRowSize = 0;
alpha = NULL;
@@ -78,14 +99,24 @@ SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
}
SplashBitmap::~SplashBitmap() {
- if (data) {
- if (rowSize < 0) {
- gfree(data + (height - 1) * rowSize);
- } else {
- gfree(data);
- }
+ if (data && rowSize < 0) {
+ rowSize = -rowSize;
+ data -= (height - 1) * rowSize;
+ }
+ if (parent && rowSize > 10000000 / height) {
+ gfree(parent->oldData);
+ gfree(parent->oldAlpha);
+ parent->oldData = data;
+ parent->oldAlpha = alpha;
+ parent->oldRowSize = rowSize;
+ parent->oldAlphaRowSize = alphaRowSize;
+ parent->oldHeight = height;
+ } else {
+ gfree(data);
+ gfree(alpha);
}
- gfree(alpha);
+ gfree(oldData);
+ gfree(oldAlpha);
}
SplashError SplashBitmap::writePNMFile(char *fileName) {
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h
index d03f44c0884..44980833668 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h
@@ -44,7 +44,7 @@ public:
// upside-down, i.e., with the last row first in memory.
SplashBitmap(int widthA, int heightA, int rowPad,
SplashColorMode modeA, GBool alphaA,
- GBool topDown = gTrue);
+ GBool topDown, SplashBitmap *parentA);
~SplashBitmap();
@@ -79,6 +79,14 @@ private:
Guchar *alpha; // pointer to row zero of the alpha data
// (always top-down)
+ // save the last-allocated (large) bitmap data and reuse if possible
+ SplashBitmap *parent;
+ SplashColorPtr oldData;
+ Guchar *oldAlpha;
+ SplashBitmapRowSize oldRowSize;
+ size_t oldAlphaRowSize;
+ int oldHeight;
+
friend class Splash;
};
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc
index 2d0542d152b..fe377fe25f4 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc
@@ -132,10 +132,14 @@ SplashFontFile *SplashFontEngine::loadType1CFont(SplashFontFileID *idA,
char *fileName,
GBool deleteFile,
#endif
+ int *codeToGID,
const char **enc) {
SplashFontFile *fontFile;
fontFile = NULL;
+ if (!fontFile) {
+ gfree(codeToGID);
+ }
#if HAVE_FREETYPE_H
if (!fontFile && ftEngine) {
fontFile = ftEngine->loadType1CFont(idA,
@@ -168,10 +172,14 @@ SplashFontFile *SplashFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA,
char *fileName,
GBool deleteFile,
#endif
+ int *codeToGID,
const char **enc) {
SplashFontFile *fontFile;
fontFile = NULL;
+ if (!fontFile) {
+ gfree(codeToGID);
+ }
#if HAVE_FREETYPE_H
if (!fontFile && ftEngine) {
fontFile = ftEngine->loadOpenTypeT1CFont(idA,
@@ -221,6 +229,10 @@ SplashFontFile *SplashFontEngine::loadCIDFont(SplashFontFileID *idA,
}
#endif
+ if (!fontFile) {
+ gfree(codeToGID);
+ }
+
#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__)
// delete the (temporary) font file -- with Unix hard link
// semantics, this will remove the last link; otherwise it will
@@ -258,6 +270,10 @@ SplashFontFile *SplashFontEngine::loadOpenTypeCFFFont(SplashFontFileID *idA,
}
#endif
+ if (!fontFile) {
+ gfree(codeToGID);
+ }
+
#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__)
// delete the (temporary) font file -- with Unix hard link
// semantics, this will remove the last link; otherwise it will
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h
index ac2558ee52d..f9eab4d00f4 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h
@@ -68,14 +68,14 @@ public:
#else
char *fileName, GBool deleteFile,
#endif
- const char **enc);
+ int *codeToGID, const char **enc);
SplashFontFile *loadOpenTypeT1CFont(SplashFontFileID *idA,
#if LOAD_FONTS_FROM_MEM
GString *fontBuf,
#else
char *fileName, GBool deleteFile,
#endif
- const char **enc);
+ int *codeToGID, const char **enc);
SplashFontFile *loadCIDFont(SplashFontFileID *idA,
#if LOAD_FONTS_FROM_MEM
GString *fontBuf,
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h
index 71afa3cb5c7..45f4e53e6bb 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h
@@ -47,17 +47,13 @@ static inline int splashFloor(SplashCoord x) {
// NB: 64-bit x86 guarantees availability of SSE2.
__m128d m1, m2;
- __m128i m3;
- int s, i;
-
- m1 = _mm_set_sd(x); // m1 = x
- i = _mm_cvttsd_si32(m1); // i = trunc(x)
- m2 = _mm_cvtsi32_sd(m1, i); // m2 = (double)trunc(x)
- m1 = _mm_sub_sd(m1, m2); // m1 = x - trunc(x)
- m3 = _mm_castpd_si128(m1); // m3 = m1 (as 64-bit int)
- m3 = _mm_srli_epi64(m3, 63); // m3 = m3 >> 63
- s = _mm_cvtsi128_si32(m3); // s = m3 = sign bit of x - trunc(x)
- return i - s; // trunc(x) - sign bit
+ int i, s;
+
+ m1 = _mm_set_sd(x);
+ i = _mm_cvttsd_si32(m1);
+ m2 = _mm_cvtsi32_sd(m1, i);
+ s = _mm_ucomigt_sd(m2, m1);
+ return i - s;
#elif defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__)
@@ -123,17 +119,13 @@ static inline int splashCeil(SplashCoord x) {
// NB: 64-bit x86 guarantees availability of SSE2.
__m128d m1, m2;
- __m128i m3;
- int s, i;
-
- m1 = _mm_set_sd(x); // m1 = x
- i = _mm_cvttsd_si32(m1); // i = trunc(x)
- m2 = _mm_cvtsi32_sd(m1, i); // m2 = (double)trunc(x)
- m2 = _mm_sub_sd(m2, m1); // m2 = trunc(x) - x
- m3 = _mm_castpd_si128(m2); // m3 = m2 (as 64-bit int)
- m3 = _mm_srli_epi64(m3, 63); // m3 = m3 >> 63
- s = _mm_cvtsi128_si32(m3); // s = m3 = sign bit of x - trunc(x)
- return i + s; // trunc(x) + sign bit
+ int i, s;
+
+ m1 = _mm_set_sd(x);
+ i = _mm_cvttsd_si32(m1);
+ m2 = _mm_cvtsi32_sd(m1, i);
+ s = _mm_ucomilt_sd(m2, m1);
+ return i + s;
#elif defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__)
@@ -315,6 +307,31 @@ static inline void splashStrokeAdjust(SplashCoord xMin, SplashCoord xMax,
SplashCoord w = -1) {
int x0, x1;
+ // make sure the coords fit in 32-bit ints
+#if USE_FIXEDPOINT
+ if (xMin < -32767) {
+ xMin = -32767;
+ } else if (xMin > 32767) {
+ xMin = 32767;
+ }
+ if (xMax < -32767) {
+ xMax = -32767;
+ } else if (xMax > 32767) {
+ xMax = 32767;
+ }
+#else
+ if (xMin < -1e9) {
+ xMin = -1e9;
+ } else if (xMin > 1e9) {
+ xMin = 1e9;
+ }
+ if (xMax < -1e9) {
+ xMax = -1e9;
+ } else if (xMax > 1e9) {
+ xMax = 1e9;
+ }
+#endif
+
// this will never be called with strokeAdjMode == splashStrokeAdjustOff
if (strokeAdjMode == splashStrokeAdjustCAD) {
x0 = splashRound(xMin);
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
index f0164a85bd4..01a94987637 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
@@ -247,14 +247,14 @@ GBool SplashXPath::strokeAdjust(SplashXPathPoint *pts,
x2 = pts[hint->ctrl1 ].x; y2 = pts[hint->ctrl1 ].y;
x3 = pts[hint->ctrl1 + 1].x; y3 = pts[hint->ctrl1 + 1].y;
w = -1;
- if (x0 == x1 && x2 == x3) {
+ if (splashAbs(x0 - x1) < 0.01 && splashAbs(x2 - x3) < 0.01) {
adjusts[i].vert = gTrue;
adj0 = x0;
adj1 = x2;
if (hint->projectingCap) {
w = splashAbs(y1 - y0);
}
- } else if (y0 == y1 && y2 == y3) {
+ } else if (splashAbs(y0 - y1) < 0.01 && splashAbs(y2 - y3) < 0.01) {
adjusts[i].vert = gFalse;
adj0 = y0;
adj1 = y2;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
index 1d312e97428..c7f30405483 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
@@ -1542,10 +1542,11 @@ void AcroFormField::drawText(GString *text, GString *da, GfxFontDict *fontDict,
fontSize = atof(tok->getCString());
} else {
error(errSyntaxError, -1, "Missing 'Tf' operator in field's DA string");
- fontSize = 10;
+ fontSize = 0;
if (!daToks) {
daToks = new GList();
}
+ tfPos = daToks->getLength();
daToks->append(new GString("/xpdf_default_font"));
daToks->append(new GString("10"));
daToks->append(new GString("Tf"));
@@ -1583,7 +1584,7 @@ void AcroFormField::drawText(GString *text, GString *da, GfxFontDict *fontDict,
// compute font autosize
if (fontSize == 0) {
- for (fontSize = 20; fontSize > 1; --fontSize) {
+ for (fontSize = 10; fontSize > 1; --fontSize) {
y = dy - 3;
w2 = 0;
i = 0;
@@ -1596,7 +1597,7 @@ void AcroFormField::drawText(GString *text, GString *da, GfxFontDict *fontDict,
y -= fontSize;
}
// approximate the descender for the last line
- if (y >= 0.33 * fontSize) {
+ if (y >= 0.33 * fontSize && w <= wMax) {
break;
}
}
@@ -1697,6 +1698,9 @@ void AcroFormField::drawText(GString *text, GString *da, GfxFontDict *fontDict,
fontSize = w;
}
fontSize = floor(fontSize);
+ if (fontSize > 10) {
+ fontSize = 10;
+ }
if (tfPos >= 0) {
tok = (GString *)daToks->get(tfPos + 1);
tok->clear();
@@ -1783,6 +1787,9 @@ void AcroFormField::drawText(GString *text, GString *da, GfxFontDict *fontDict,
fontSize = fontSize2;
}
fontSize = floor(fontSize);
+ if (fontSize > 10) {
+ fontSize = 10;
+ }
if (tfPos >= 0) {
tok = (GString *)daToks->get(tfPos + 1);
tok->clear();
@@ -1936,6 +1943,9 @@ void AcroFormField::drawListBox(GString **text, GBool *selection,
fontSize = fontSize2;
}
fontSize = floor(fontSize);
+ if (fontSize > 10) {
+ fontSize = 10;
+ }
if (tfPos >= 0) {
tok = (GString *)daToks->get(tfPos + 1);
tok->clear();
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
index 850c6b25651..61a1d434abf 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
@@ -845,7 +845,7 @@ GBool Annot::setFillColor(Object *colorObj) {
if (!colorObj->isArray()) {
return gFalse;
}
- for (i = 0; i < colorObj->arrayGetLength(); ++i) {
+ for (i = 0; i < colorObj->arrayGetLength() && i < 4; ++i) {
if (colorObj->arrayGet(i, &obj)->isNum()) {
color[i] = obj.getNum();
} else {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc
index 01dbd110dca..d2f875e45fd 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc
@@ -51,6 +51,7 @@ GBool BuiltinFontWidths::getWidth(const char *name, Gushort *width) {
return gTrue;
}
}
+ *width = 0;
return gFalse;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt
index 8fb3f2050bb..4c88d1d351f 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt
@@ -111,7 +111,9 @@ if (HAVE_SPLASH)
${PAPER_LIBRARY}
${FREETYPE_LIBRARY} ${FREETYPE_OTHER_LIBS}
${DTYPE_LIBRARY}
- ${LCMS_LIBRARY})
+ ${LCMS_LIBRARY}
+ ${FONTCONFIG_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT})
else ()
add_executable(pdftops
$<TARGET_OBJECTS:xpdf_objs>
@@ -119,7 +121,11 @@ else ()
PSOutputDev.cc
pdftops.cc
)
- target_link_libraries(pdftops goo fofi ${PAPER_LIBRARY} ${LCMS_LIBRARY})
+ target_link_libraries(pdftops goo fofi
+ ${PAPER_LIBRARY}
+ ${LCMS_LIBRARY}
+ ${FONTCONFIG_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT})
endif ()
install(TARGETS pdftops RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftops.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
@@ -131,7 +137,11 @@ add_executable(pdftotext
TextOutputDev.cc
pdftotext.cc
)
-target_link_libraries(pdftotext goo fofi ${PAPER_LIBRARY} ${LCMS_LIBRARY})
+target_link_libraries(pdftotext goo fofi
+ ${PAPER_LIBRARY}
+ ${LCMS_LIBRARY}
+ ${FONTCONFIG_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS pdftotext RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftotext.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
@@ -143,13 +153,17 @@ if (HAVE_SPLASH AND PNG_FOUND)
HTMLGen.cc
SplashOutputDev.cc
TextOutputDev.cc
+ WebFont.cc
pdftohtml.cc
)
target_link_libraries(pdftohtml goo fofi splash
${PAPER_LIBRARY}
${FREETYPE_LIBRARY} ${FREETYPE_OTHER_LIBS}
${DTYPE_LIBRARY}
- ${LCMS_LIBRARY} ${PNG_LIBRARIES})
+ ${LCMS_LIBRARY}
+ ${PNG_LIBRARIES}
+ ${FONTCONFIG_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS pdftohtml RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftohtml.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
endif ()
@@ -160,7 +174,11 @@ add_executable(pdfinfo
$<TARGET_OBJECTS:xpdf_objs>
pdfinfo.cc
)
-target_link_libraries(pdfinfo goo fofi ${PAPER_LIBRARY} ${LCMS_LIBRARY})
+target_link_libraries(pdfinfo goo fofi
+ ${PAPER_LIBRARY}
+ ${LCMS_LIBRARY}
+ ${FONTCONFIG_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS pdfinfo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${PROJECT_SOURCE_DIR}/doc/pdfinfo.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
@@ -170,7 +188,11 @@ add_executable(pdffonts
$<TARGET_OBJECTS:xpdf_objs>
pdffonts.cc
)
-target_link_libraries(pdffonts goo fofi ${PAPER_LIBRARY} ${LCMS_LIBRARY})
+target_link_libraries(pdffonts goo fofi
+ ${PAPER_LIBRARY}
+ ${LCMS_LIBRARY}
+ ${FONTCONFIG_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS pdffonts RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${PROJECT_SOURCE_DIR}/doc/pdffonts.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
@@ -180,7 +202,11 @@ add_executable(pdfdetach
$<TARGET_OBJECTS:xpdf_objs>
pdfdetach.cc
)
-target_link_libraries(pdfdetach goo fofi ${PAPER_LIBRARY} ${LCMS_LIBRARY})
+target_link_libraries(pdfdetach goo fofi
+ ${PAPER_LIBRARY}
+ ${LCMS_LIBRARY}
+ ${FONTCONFIG_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS pdfdetach RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${PROJECT_SOURCE_DIR}/doc/pdfdetach.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
@@ -196,7 +222,9 @@ if (HAVE_SPLASH)
${PAPER_LIBRARY}
${FREETYPE_LIBRARY} ${FREETYPE_OTHER_LIBS}
${DTYPE_LIBRARY}
- ${LCMS_LIBRARY})
+ ${LCMS_LIBRARY}
+ ${FONTCONFIG_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS pdftoppm RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftoppm.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
endif ()
@@ -213,7 +241,10 @@ if (HAVE_SPLASH AND PNG_FOUND)
${PAPER_LIBRARY}
${FREETYPE_LIBRARY} ${FREETYPE_OTHER_LIBS}
${DTYPE_LIBRARY}
- ${LCMS_LIBRARY} ${PNG_LIBRARIES})
+ ${LCMS_LIBRARY}
+ ${PNG_LIBRARIES}
+ ${FONTCONFIG_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS pdftopng RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftopng.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
endif ()
@@ -225,7 +256,11 @@ add_executable(pdfimages
ImageOutputDev.cc
pdfimages.cc
)
-target_link_libraries(pdfimages goo fofi ${PAPER_LIBRARY} ${LCMS_LIBRARY})
+target_link_libraries(pdfimages goo fofi
+ ${PAPER_LIBRARY}
+ ${LCMS_LIBRARY}
+ ${FONTCONFIG_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS pdfimages RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${PROJECT_SOURCE_DIR}/doc/pdfimages.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
index 470807314a6..bec30a8dcfd 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
@@ -89,6 +89,59 @@ EmbeddedFile::~EmbeddedFile() {
}
//------------------------------------------------------------------------
+// PageLabelNode
+//------------------------------------------------------------------------
+
+class PageLabelNode {
+public:
+
+ PageLabelNode(int firstPageA, Dict *dict);
+ ~PageLabelNode();
+
+ int firstPage; // first page number covered by this node
+ int lastPage; // last page number covered by this node
+ TextString *prefix; // label prefix (may be empty)
+ int start; // value of the numeric portion of this
+ // label for the first page in the range
+ char style; // page label style
+};
+
+PageLabelNode::PageLabelNode(int firstPageA, Dict *dict) {
+ Object prefixObj, styleObj, startObj;
+
+ // convert page index to page number
+ firstPage = firstPageA + 1;
+
+ // lastPage will be filled in later
+ lastPage = -1;
+
+ if (dict->lookup("P", &prefixObj)->isString()) {
+ prefix = new TextString(prefixObj.getString());
+ } else {
+ prefix = new TextString();
+ }
+ prefixObj.free();
+
+ style = '\0';
+ if (dict->lookup("S", &styleObj)->isName()) {
+ if (strlen(styleObj.getName()) == 1) {
+ style = styleObj.getName()[0];
+ }
+ }
+ styleObj.free();
+
+ start = 1;
+ if (dict->lookup("St", &startObj)->isInt()) {
+ start = startObj.getInt();
+ }
+ startObj.free();
+}
+
+PageLabelNode::~PageLabelNode() {
+ delete prefix;
+}
+
+//------------------------------------------------------------------------
// Catalog
//------------------------------------------------------------------------
@@ -185,6 +238,15 @@ Catalog::Catalog(PDFDoc *docA) {
// get the list of embedded files
readEmbeddedFileList(catDict.getDict());
+ // get the ViewerPreferences object
+ catDict.dictLookupNF("ViewerPreferences", &viewerPrefs);
+
+ pageLabels = NULL;
+ if (catDict.dictLookup("PageLabels", &obj)->isDict()) {
+ readPageLabelTree(&obj);
+ }
+ obj.free();
+
catDict.free();
return;
@@ -229,6 +291,10 @@ Catalog::~Catalog() {
if (embeddedFiles) {
deleteGList(embeddedFiles, EmbeddedFile);
}
+ if (pageLabels) {
+ deleteGList(pageLabels, PageLabelNode);
+ }
+ viewerPrefs.free();
}
Page *Catalog::getPage(int i) {
@@ -833,107 +899,45 @@ Object *Catalog::getEmbeddedFileStreamObj(int idx, Object *strObj) {
return strObj;
}
-TextString *Catalog::getPageLabel(int pageNum) {
- Object catDict, node, pageLabelObj, start, prefix, style;
- GString *label, *s;
- TextString *ts;
- int firstPageIndex, pageRangeNum;
-
- if (!xref->getCatalog(&catDict)->isDict()) {
- catDict.free();
- return NULL;
- }
+void Catalog::readPageLabelTree(Object *root) {
+ PageLabelNode *label0, *label1;
+ int i;
- label = NULL;
- catDict.dictLookup("PageLabels", &node);
- if (findPageLabel(&node, pageNum - 1, &pageLabelObj, &firstPageIndex)) {
- if (pageLabelObj.isDict()) {
- if (pageLabelObj.dictLookup("P", &prefix)->isString()) {
- label = prefix.getString()->copy();
- } else {
- label = new GString();
- }
- prefix.free();
+ pageLabels = new GList();
+ readPageLabelTree2(root);
- pageRangeNum = pageNum - firstPageIndex;
- if (pageLabelObj.dictLookup("St", &start)->isInt()) {
- pageRangeNum += start.getInt() - 1;
- }
- start.free();
-
- if (pageLabelObj.dictLookup("S", &style)->isName()) {
- if (style.isName("D")) {
- label->appendf("{0:d}", pageRangeNum);
- } else if (style.isName("R")) {
- s = makeRomanNumeral(pageRangeNum, gTrue);
- label->append(s);
- delete s;
- } else if (style.isName("r")) {
- s = makeRomanNumeral(pageRangeNum, gFalse);
- label->append(s);
- delete s;
- } else if (style.isName("A")) {
- s = makeLetterLabel(pageRangeNum, gTrue);
- label->append(s);
- delete s;
- } else if (style.isName("a")) {
- s = makeLetterLabel(pageRangeNum, gFalse);
- label->append(s);
- delete s;
- }
- }
- style.free();
- }
- pageLabelObj.free();
+ if (pageLabels->getLength() == 0) {
+ deleteGList(pageLabels, PageLabelNode);
+ pageLabels = NULL;
+ return;
}
- node.free();
- catDict.free();
- ts = new TextString(label);
- delete label;
- return ts;
+ // set lastPage in each node
+ label0 = (PageLabelNode *)pageLabels->get(0);
+ for (i = 1; i < pageLabels->getLength(); ++i) {
+ label1 = (PageLabelNode *)pageLabels->get(i);
+ label0->lastPage = label1->firstPage - 1;
+ label0 = label1;
+ }
+ label0->lastPage = numPages;
}
-GBool Catalog::findPageLabel(Object *node, int pageIndex,
- Object *pageLabelObj, int *firstPageIndex) {
- Object limits, limit, nums, num, kids, kid;
+void Catalog::readPageLabelTree2(Object *node) {
+ Object nums, num, labelObj, kids, kid;
int i;
if (!node->isDict()) {
- return gFalse;
- }
-
- // we only check the lower limit because page labels are organized
- // into ranges based on their first page number -- the Nums and Kids
- // arrays are searched backward for the same reason
- if (node->dictLookup("Limits", &limits)->isArray() &&
- limits.arrayGetLength() == 2) {
- if (limits.arrayGet(0, &limit)->isInt()) {
- if (pageIndex < limit.getInt()) {
- limit.free();
- limits.free();
- return gFalse;
- }
- }
- limit.free();
+ return;
}
- limits.free();
if (node->dictLookup("Nums", &nums)->isArray()) {
- for (i = nums.arrayGetLength() / 2 - 1; i >= 0; --i) {
- if (nums.arrayGet(2*i, &num)->isInt()) {
- if (num.getInt() <= pageIndex) {
- nums.arrayGet(2*i + 1, pageLabelObj);
- *firstPageIndex = num.getInt();
- num.free();
- nums.free();
- return gTrue;
+ for (i = 0; i < nums.arrayGetLength() - 1; i += 2) {
+ if (nums.arrayGet(i, &num)->isInt()) {
+ if (nums.arrayGet(i+1, &labelObj)->isDict()) {
+ pageLabels->append(new PageLabelNode(num.getInt(),
+ labelObj.getDict()));
}
- } else {
- error(errSyntaxError, -1, "Invalid key in page label number tree");
- num.free();
- nums.free();
- return gFalse;
+ labelObj.free();
}
num.free();
}
@@ -941,20 +945,61 @@ GBool Catalog::findPageLabel(Object *node, int pageIndex,
nums.free();
if (node->dictLookup("Kids", &kids)->isArray()) {
- for (i = kids.arrayGetLength() - 1; i >= 0; --i) {
- if (kids.arrayGet(i, &kid)->isDict()) {
- if (findPageLabel(&kid, pageIndex, pageLabelObj, firstPageIndex)) {
- kid.free();
- kids.free();
- return gTrue;
- }
- }
+ for (i = 0; i < kids.arrayGetLength(); ++i) {
+ kids.arrayGet(i, &kid);
+ readPageLabelTree2(&kid);
kid.free();
}
}
kids.free();
+}
- return gFalse;
+TextString *Catalog::getPageLabel(int pageNum) {
+ PageLabelNode *label;
+ TextString *ts;
+ int pageRangeNum;
+ GString *suffix;
+
+ if (!pageLabels || !(label = findPageLabel(pageNum))) {
+ return NULL;
+ }
+
+ ts = new TextString(label->prefix);
+
+ pageRangeNum = label->start + (pageNum - label->firstPage);
+
+ suffix = NULL;
+ if (label->style == 'D') {
+ suffix = GString::format("{0:d}", pageRangeNum);
+ } else if (label->style == 'R') {
+ suffix = makeRomanNumeral(pageRangeNum, gTrue);
+ } else if (label->style == 'r') {
+ suffix = makeRomanNumeral(pageRangeNum, gFalse);
+ } else if (label->style == 'A') {
+ suffix = makeLetterLabel(pageRangeNum, gTrue);
+ } else if (label->style == 'a') {
+ suffix = makeLetterLabel(pageRangeNum, gFalse);
+ }
+ if (suffix) {
+ ts->append(suffix);
+ delete suffix;
+ }
+
+ return ts;
+}
+
+PageLabelNode *Catalog::findPageLabel(int pageNum) {
+ PageLabelNode *label;
+ int i;
+
+ //~ this could use a binary search
+ for (i = 0; i < pageLabels->getLength(); ++i) {
+ label = (PageLabelNode *)pageLabels->get(i);
+ if (pageNum >= label->firstPage && pageNum <= label->lastPage) {
+ return label;
+ }
+ }
+ return NULL;
}
GString *Catalog::makeRomanNumeral(int num, GBool uppercase) {
@@ -1022,3 +1067,131 @@ GString *Catalog::makeLetterLabel(int num, GBool uppercase) {
}
return s;
}
+
+int Catalog::getPageNumFromPageLabel(TextString *pageLabel) {
+ PageLabelNode *label;
+ int pageNum, prefixLength, i, n;
+
+ if (!pageLabels) {
+ return -1;
+ }
+ for (i = 0; i < pageLabels->getLength(); ++i) {
+ label = (PageLabelNode *)pageLabels->get(i);
+ prefixLength = label->prefix->getLength();
+ if (pageLabel->getLength() < prefixLength ||
+ memcmp(pageLabel->getUnicode(), label->prefix->getUnicode(),
+ prefixLength * sizeof(Unicode))) {
+ continue;
+ }
+ if (label->style == '\0' && pageLabel->getLength() == prefixLength) {
+ return label->firstPage;
+ }
+ if (!convertPageLabelToInt(pageLabel, prefixLength, label->style, &n)) {
+ continue;
+ }
+ if (n < label->start) {
+ continue;
+ }
+ pageNum = label->firstPage + n - label->start;
+ if (pageNum <= label->lastPage) {
+ return pageNum;
+ }
+ }
+ return -1;
+}
+
+// Attempts to convert pageLabel[prefixLength .. end] to an integer,
+// following the specified page label style. If successful, sets *n
+// and returns true; else returns false.
+GBool Catalog::convertPageLabelToInt(TextString *pageLabel, int prefixLength,
+ char style, int *n) {
+ Unicode *u;
+ Unicode delta;
+ int len, i;
+
+ len = pageLabel->getLength();
+ if (len <= prefixLength) {
+ return gFalse;
+ }
+ u = pageLabel->getUnicode();
+ if (style == 'D') {
+ *n = 0;
+ for (i = prefixLength; i < len; ++i) {
+ if (u[i] < (Unicode)'0' || u[i] > (Unicode)'9') {
+ return gFalse;
+ }
+ *n = *n * 10 + (u[i] - (Unicode)'0');
+ }
+ return gTrue;
+ } else if (style == 'R' || style == 'r') {
+ delta = style - 'R';
+ *n = 0;
+ i = prefixLength;
+ while (i < len && u[i] == (Unicode)'M' + delta) {
+ *n += 1000;
+ ++i;
+ }
+ if (i+1 < len && u[i] == (Unicode)'C' + delta &&
+ u[i+1] == (Unicode)'M' + delta) {
+ *n += 900;
+ i += 2;
+ } else if (i < len && u[i] == (Unicode)'D' + delta) {
+ *n += 500;
+ ++i;
+ } else if (i+1 < len && u[i] == (Unicode)'C' + delta &&
+ u[i+1] == (Unicode)'D' + delta) {
+ *n += 400;
+ i += 2;
+ }
+ while (i < len && u[i] == (Unicode)'C' + delta) {
+ *n += 100;
+ ++i;
+ }
+ if (i+1 < len && u[i] == (Unicode)'X' + delta &&
+ u[i+1] == (Unicode)'C' + delta) {
+ *n += 90;
+ i += 2;
+ } else if (i < len && u[i] == (Unicode)'L' + delta) {
+ *n += 50;
+ ++i;
+ } else if (i+1 < len && u[i] == (Unicode)'X' + delta &&
+ u[i+1] == (Unicode)'L' + delta) {
+ *n += 40;
+ i += 2;
+ }
+ while (i < len && u[i] == (Unicode)'X' + delta) {
+ *n += 10;
+ ++i;
+ }
+ if (i+1 < len && u[i] == (Unicode)'I' + delta &&
+ u[i+1] == (Unicode)'X' + delta) {
+ *n += 9;
+ i += 2;
+ } else if (i < len && u[i] == (Unicode)'V' + delta) {
+ *n += 5;
+ ++i;
+ } else if (i+1 < len && u[i] == (Unicode)'I' + delta &&
+ u[i+1] == (Unicode)'V' + delta) {
+ *n += 4;
+ i += 2;
+ }
+ while (i < len && u[i] == (Unicode)'I' + delta) {
+ *n += 1;
+ ++i;
+ }
+ return i == len;
+ } else if (style == 'A' || style == 'a') {
+ if (u[prefixLength] < (Unicode)style ||
+ u[prefixLength] > (Unicode)style + 25) {
+ return gFalse;
+ }
+ for (i = prefixLength + 1; i < len; ++i) {
+ if (u[i] != u[prefixLength]) {
+ return gFalse;
+ }
+ }
+ *n = (len - prefixLength - 1) * 26 + (u[i] - (Unicode)style) + 1;
+ return gTrue;
+ }
+ return gFalse;
+}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h
index 803550d7f96..b775ae9b9b8 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h
@@ -29,6 +29,7 @@ class PageAttrs;
struct Ref;
class LinkDest;
class PageTreeNode;
+class PageLabelNode;
class Form;
class TextString;
@@ -103,10 +104,20 @@ public:
Object *getEmbeddedFileStreamRef(int idx);
Object *getEmbeddedFileStreamObj(int idx, Object *strObj);
+ // Return true if the document has page labels.
+ GBool hasPageLabels() { return pageLabels != NULL; }
+
// Get the page label for page number [pageNum]. Returns NULL if
// the PDF file doesn't have page labels.
TextString *getPageLabel(int pageNum);
+ // Returns the page number corresponding to [pageLabel]. Returns -1
+ // if there is no matching page label, or if the document doesn't
+ // have page labels.
+ int getPageNumFromPageLabel(TextString *pageLabel);
+
+ Object *getViewerPreferences() { return &viewerPrefs; }
+
private:
PDFDoc *doc;
@@ -129,6 +140,8 @@ private:
Form *form; // parsed form
Object ocProperties; // OCProperties dictionary
GList *embeddedFiles; // embedded file list [EmbeddedFile]
+ GList *pageLabels; // page labels [PageLabelNode]
+ Object viewerPrefs; // ViewerPreferences object
GBool ok; // true if catalog is valid
Object *findDestInTree(Object *tree, GString *name, Object *obj);
@@ -141,10 +154,13 @@ private:
void readFileAttachmentAnnots(Object *pageNodeRef,
char *touchedObjs);
void readEmbeddedFile(Object *fileSpec, Object *name1);
- GBool findPageLabel(Object *node, int pageIndex,
- Object *pageLabelObj, int *firstPageIndex);
+ void readPageLabelTree(Object *root);
+ void readPageLabelTree2(Object *node);
+ PageLabelNode *findPageLabel(int pageNum);
GString *makeRomanNumeral(int num, GBool uppercase);
GString *makeLetterLabel(int num, GBool uppercase);
+ GBool convertPageLabelToInt(TextString *pageLabel, int prefixLength,
+ char style, int *n);
};
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc
index 72cadd9bed1..82f32b9dd93 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc
@@ -41,7 +41,8 @@ Function::Function() {
Function::~Function() {
}
-Function *Function::parse(Object *funcObj, int recursion) {
+Function *Function::parse(Object *funcObj, int expectedInputs,
+ int expectedOutputs, int recursion) {
Function *func;
Dict *dict;
int funcType;
@@ -57,7 +58,11 @@ Function *Function::parse(Object *funcObj, int recursion) {
} else if (funcObj->isDict()) {
dict = funcObj->getDict();
} else if (funcObj->isName("Identity")) {
- return new IdentityFunction();
+ if (expectedInputs != expectedOutputs) {
+ error(errSyntaxError, -1, "Invalid use of identity function");
+ return NULL;
+ }
+ return new IdentityFunction(expectedInputs);
} else {
error(errSyntaxError, -1, "Expected function dictionary or stream");
return NULL;
@@ -76,7 +81,8 @@ Function *Function::parse(Object *funcObj, int recursion) {
} else if (funcType == 2) {
func = new ExponentialFunction(funcObj, dict);
} else if (funcType == 3) {
- func = new StitchingFunction(funcObj, dict, recursion);
+ func = new StitchingFunction(funcObj, dict, expectedInputs,
+ expectedOutputs, recursion);
} else if (funcType == 4) {
func = new PostScriptFunction(funcObj, dict);
} else {
@@ -88,6 +94,14 @@ Function *Function::parse(Object *funcObj, int recursion) {
return NULL;
}
+ if (func->getInputSize() != expectedInputs ||
+ (expectedOutputs >= 0 && func->getOutputSize() != expectedOutputs)) {
+ error(errSyntaxError, -1,
+ "Incorrect number of function inputs or outputs");
+ delete func;
+ return NULL;
+ }
+
return func;
}
@@ -169,14 +183,12 @@ GBool Function::init(Dict *dict) {
// IdentityFunction
//------------------------------------------------------------------------
-IdentityFunction::IdentityFunction() {
+IdentityFunction::IdentityFunction(int nInputs) {
int i;
- // fill these in with arbitrary values just in case they get used
- // somewhere
- m = funcMaxInputs;
- n = funcMaxOutputs;
- for (i = 0; i < funcMaxInputs; ++i) {
+ m = n = nInputs;
+ // domain info shouldn't be used anywhere
+ for (i = 0; i < nInputs; ++i) {
domain[i][0] = 0;
domain[i][1] = 1;
}
@@ -189,7 +201,7 @@ IdentityFunction::~IdentityFunction() {
void IdentityFunction::transform(double *in, double *out) {
int i;
- for (i = 0; i < funcMaxOutputs; ++i) {
+ for (i = 0; i < m; ++i) {
out[i] = in[i];
}
}
@@ -347,8 +359,13 @@ SampledFunction::SampledFunction(Object *funcObj, Dict *dict) {
//----- samples
nSamples = n;
- for (i = 0; i < m; ++i)
+ for (i = 0; i < m; ++i) {
+ if (nSamples > INT_MAX / sampleSize[i]) {
+ error(errSyntaxError, -1, "Integer overflow in sampled function setup");
+ goto err1;
+ }
nSamples *= sampleSize[i];
+ }
samples = (double *)gmallocn(nSamples, sizeof(double));
buf = 0;
bits = 0;
@@ -623,6 +640,7 @@ void ExponentialFunction::transform(double *in, double *out) {
//------------------------------------------------------------------------
StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict,
+ int expectedInputs, int expectedOutputs,
int recursion) {
Object obj1, obj2;
int i;
@@ -643,7 +661,8 @@ StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict,
}
//----- Functions
- if (!dict->lookup("Functions", &obj1)->isArray()) {
+ if (!dict->lookup("Functions", &obj1)->isArray() ||
+ obj1.arrayGetLength() < 1) {
error(errSyntaxError, -1,
"Missing 'Functions' entry in stitching function");
goto err1;
@@ -658,11 +677,14 @@ StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict,
}
for (i = 0; i < k; ++i) {
if (!(funcs[i] = Function::parse(obj1.arrayGet(i, &obj2),
+ expectedInputs, expectedOutputs,
recursion + 1))) {
goto err2;
}
- if (funcs[i]->getInputSize() != 1 ||
- (i > 0 && funcs[i]->getOutputSize() != funcs[0]->getOutputSize())) {
+ if (i == 0) {
+ n = funcs[0]->getOutputSize();
+ }
+ if (funcs[i]->getInputSize() != 1 || funcs[i]->getOutputSize() != n) {
error(errSyntaxError, -1,
"Incompatible subfunctions in stitching function");
goto err2;
@@ -1305,6 +1327,9 @@ int PostScriptFunction::exec(double *stack, int sp0) {
if (sp + 1 >= psStackSize) {
goto underflow;
}
+ if (stack[sp] == 0) {
+ goto invalidArg;
+ }
stack[sp + 1] = stack[sp + 1] / stack[sp];
++sp;
break;
@@ -1371,7 +1396,11 @@ int PostScriptFunction::exec(double *stack, int sp0) {
if (sp + 1 >= psStackSize) {
goto underflow;
}
- stack[sp + 1] = (int)stack[sp + 1] / (int)stack[sp];
+ k = (int)stack[sp];
+ if (k == 0) {
+ goto invalidArg;
+ }
+ stack[sp + 1] = (int)stack[sp + 1] / k;
++sp;
break;
case psOpIndex:
@@ -1417,7 +1446,11 @@ int PostScriptFunction::exec(double *stack, int sp0) {
if (sp + 1 >= psStackSize) {
goto underflow;
}
- stack[sp + 1] = (int)stack[sp + 1] % (int)stack[sp];
+ k = (int)stack[sp];
+ if (k == 0) {
+ goto invalidArg;
+ }
+ stack[sp + 1] = (int)stack[sp + 1] % k;
++sp;
break;
case psOpMul:
@@ -1468,22 +1501,24 @@ int PostScriptFunction::exec(double *stack, int sp0) {
if (nn < 0) {
goto invalidArg;
}
- if (sp + nn > psStackSize) {
- goto underflow;
- }
- if (k >= 0) {
- k %= nn;
- } else {
- k = -k % nn;
- if (k) {
- k = nn - k;
+ if (nn > 0) {
+ if (sp + nn > psStackSize) {
+ goto underflow;
+ }
+ if (k >= 0) {
+ k %= nn;
+ } else {
+ k = -k % nn;
+ if (k) {
+ k = nn - k;
+ }
+ }
+ for (i = 0; i < nn; ++i) {
+ tmp[i] = stack[sp + i];
+ }
+ for (i = 0; i < nn; ++i) {
+ stack[sp + i] = tmp[(i + k) % nn];
}
- }
- for (i = 0; i < nn; ++i) {
- tmp[i] = stack[sp + i];
- }
- for (i = 0; i < nn; ++i) {
- stack[sp + i] = tmp[(i + k) % nn];
}
break;
case psOpRound:
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h
index 5cf45169a49..bf1f25e51cc 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Function.h
@@ -38,8 +38,11 @@ public:
virtual ~Function();
- // Construct a function. Returns NULL if unsuccessful.
- static Function *parse(Object *funcObj, int recursion = 0);
+ // Construct a function, with [expectedInputs] inputs and
+ // [expectedOutputs] outputs. [expectedOutputs] can be -1 to
+ // indicate unknown. Returns NULL if unsuccessful.
+ static Function *parse(Object *funcObj, int expectedInputs,
+ int expectedOutputs, int recursion = 0);
// Initialize the entries common to all function types.
GBool init(Dict *dict);
@@ -86,9 +89,9 @@ protected:
class IdentityFunction: public Function {
public:
- IdentityFunction();
+ IdentityFunction(int nInputs);
virtual ~IdentityFunction();
- virtual Function *copy() { return new IdentityFunction(); }
+ virtual Function *copy() { return new IdentityFunction(m); }
virtual int getType() { return -1; }
virtual void transform(double *in, double *out);
virtual GBool isOk() { return gTrue; }
@@ -173,7 +176,8 @@ private:
class StitchingFunction: public Function {
public:
- StitchingFunction(Object *funcObj, Dict *dict, int recursion);
+ StitchingFunction(Object *funcObj, Dict *dict, int expectedInputs,
+ int expectedOutputs, int recursion);
virtual ~StitchingFunction();
virtual Function *copy() { return new StitchingFunction(this); }
virtual int getType() { return 3; }
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
index 5d34eb9f9ab..7a0c9c6a9a5 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
@@ -919,12 +919,24 @@ void Gfx::opSetFlat(Object args[], int numArgs) {
}
void Gfx::opSetLineJoin(Object args[], int numArgs) {
- state->setLineJoin(args[0].getInt());
+ int lineJoin;
+
+ lineJoin = args[0].getInt();
+ if (lineJoin < 0 || lineJoin > 2) {
+ lineJoin = 0;
+ }
+ state->setLineJoin(lineJoin);
out->updateLineJoin(state);
}
void Gfx::opSetLineCap(Object args[], int numArgs) {
- state->setLineCap(args[0].getInt());
+ int lineCap;
+
+ lineCap = args[0].getInt();
+ if (lineCap < 0 || lineCap > 2) {
+ lineCap = 0;
+ }
+ state->setLineCap(lineCap);
out->updateLineCap(state);
}
@@ -1041,17 +1053,17 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
// fill/stroke overprint, overprint mode
if ((haveFillOP = (obj1.dictLookup("op", &obj2)->isBool()))) {
- if (!state->getInCachedT3Char()) {
+ if (!state->getIgnoreColorOps()) {
state->setFillOverprint(obj2.getBool());
out->updateFillOverprint(state);
} else {
- error(errSyntaxWarning, getPos(),
- "Ignoring overprint setting in cached Type 3 character");
+ error(errSyntaxWarning, getPos(), "Ignoring overprint setting"
+ " in uncolored Type 3 char or tiling pattern");
}
}
obj2.free();
if (obj1.dictLookup("OP", &obj2)->isBool()) {
- if (!state->getInCachedT3Char()) {
+ if (!state->getIgnoreColorOps()) {
state->setStrokeOverprint(obj2.getBool());
out->updateStrokeOverprint(state);
if (!haveFillOP) {
@@ -1059,18 +1071,18 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
out->updateFillOverprint(state);
}
} else {
- error(errSyntaxWarning, getPos(),
- "Ignoring overprint setting in cached Type 3 character");
+ error(errSyntaxWarning, getPos(), "Ignoring overprint setting"
+ " in uncolored Type 3 char or tiling pattern");
}
}
obj2.free();
if (obj1.dictLookup("OPM", &obj2)->isInt()) {
- if (!state->getInCachedT3Char()) {
+ if (!state->getIgnoreColorOps()) {
state->setOverprintMode(obj2.getInt());
out->updateOverprintMode(state);
} else {
- error(errSyntaxWarning, getPos(),
- "Ignoring overprint setting in cached Type 3 character");
+ error(errSyntaxWarning, getPos(), "Ignoring overprint setting"
+ " in uncolored Type 3 char or tiling pattern");
}
}
obj2.free();
@@ -1088,7 +1100,7 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
obj1.dictLookup("TR", &obj2);
}
if (!obj2.isNull()) {
- if (!state->getInCachedT3Char()) {
+ if (!state->getIgnoreColorOps()) {
if (obj2.isName("Default") ||
obj2.isName("Identity")) {
funcs[0] = funcs[1] = funcs[2] = funcs[3] = NULL;
@@ -1097,7 +1109,7 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
} else if (obj2.isArray() && obj2.arrayGetLength() == 4) {
for (i = 0; i < 4; ++i) {
obj2.arrayGet(i, &obj3);
- funcs[i] = Function::parse(&obj3);
+ funcs[i] = Function::parse(&obj3, 1, 1);
obj3.free();
if (!funcs[i]) {
break;
@@ -1108,7 +1120,7 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
out->updateTransfer(state);
}
} else if (obj2.isName() || obj2.isDict() || obj2.isStream()) {
- if ((funcs[0] = Function::parse(&obj2))) {
+ if ((funcs[0] = Function::parse(&obj2, 1, 1))) {
funcs[1] = funcs[2] = funcs[3] = NULL;
state->setTransfer(funcs);
out->updateTransfer(state);
@@ -1118,8 +1130,8 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
"Invalid transfer function in ExtGState");
}
} else {
- error(errSyntaxWarning, getPos(),
- "Ignoring transfer function setting in cached Type 3 character");
+ error(errSyntaxWarning, getPos(), "Ignoring transfer function setting"
+ " in uncolored Type 3 char or tiling pattern");
}
}
obj2.free();
@@ -1129,9 +1141,14 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
if (obj2.isName("None")) {
out->clearSoftMask(state);
} else if (obj2.isDict()) {
- if (obj2.dictLookup("S", &obj3)->isName("Alpha")) {
+ obj2.dictLookup("S", &obj3);
+ if (obj3.isName("Alpha")) {
alpha = gTrue;
- } else { // "Luminosity"
+ } else if (obj3.isName("Luminosity")) {
+ alpha = gFalse;
+ } else {
+ error(errSyntaxError, getPos(),
+ "Missing S (subtype) entry in soft mask");
alpha = gFalse;
}
obj3.free();
@@ -1141,9 +1158,7 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
obj3.isName("Identity")) {
funcs[0] = NULL;
} else {
- funcs[0] = Function::parse(&obj3);
- if (funcs[0]->getInputSize() != 1 ||
- funcs[0]->getOutputSize() != 1) {
+ if (!(funcs[0] = Function::parse(&obj3, 1, 1))) {
error(errSyntaxError, getPos(),
"Invalid transfer function in soft mask in ExtGState");
delete funcs[0];
@@ -1290,9 +1305,9 @@ void Gfx::doSoftMask(Object *str, Object *strRef, GBool alpha,
void Gfx::opSetRenderingIntent(Object args[], int numArgs) {
GfxRenderingIntent ri;
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring rendering intent setting in cached Type 3 character");
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring rendering intent setting"
+ " in uncolored Type 3 char or tiling pattern");
return;
}
ri = parseRenderingIntent(args[0].getName());
@@ -1320,9 +1335,9 @@ GfxRenderingIntent Gfx::parseRenderingIntent(const char *name) {
void Gfx::opSetFillGray(Object args[], int numArgs) {
GfxColor color;
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring color setting in cached Type 3 character");
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring color setting"
+ " in uncolored Type 3 char or tiling pattern");
return;
}
state->setFillPattern(NULL);
@@ -1336,9 +1351,9 @@ void Gfx::opSetFillGray(Object args[], int numArgs) {
void Gfx::opSetStrokeGray(Object args[], int numArgs) {
GfxColor color;
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring color setting in cached Type 3 character");
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring color setting"
+ " in uncolored Type 3 char or tiling pattern");
return;
}
state->setStrokePattern(NULL);
@@ -1353,9 +1368,9 @@ void Gfx::opSetFillCMYKColor(Object args[], int numArgs) {
GfxColor color;
int i;
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring color setting in cached Type 3 character");
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring color setting"
+ " in uncolored Type 3 char or tiling pattern");
return;
}
state->setFillPattern(NULL);
@@ -1372,9 +1387,9 @@ void Gfx::opSetStrokeCMYKColor(Object args[], int numArgs) {
GfxColor color;
int i;
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring color setting in cached Type 3 character");
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring color setting"
+ " in uncolored Type 3 char or tiling pattern");
return;
}
state->setStrokePattern(NULL);
@@ -1391,9 +1406,9 @@ void Gfx::opSetFillRGBColor(Object args[], int numArgs) {
GfxColor color;
int i;
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring color setting in cached Type 3 character");
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring color setting"
+ " in uncolored Type 3 char or tiling pattern");
return;
}
state->setFillPattern(NULL);
@@ -1410,9 +1425,9 @@ void Gfx::opSetStrokeRGBColor(Object args[], int numArgs) {
GfxColor color;
int i;
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring color setting in cached Type 3 character");
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring color setting"
+ " in uncolored Type 3 char or tiling pattern");
return;
}
state->setStrokePattern(NULL);
@@ -1430,9 +1445,9 @@ void Gfx::opSetFillColorSpace(Object args[], int numArgs) {
GfxColorSpace *colorSpace;
GfxColor color;
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring color space setting in cached Type 3 character");
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring color space setting"
+ " in uncolored Type 3 char or tiling pattern");
return;
}
state->setFillPattern(NULL);
@@ -1461,9 +1476,9 @@ void Gfx::opSetStrokeColorSpace(Object args[], int numArgs) {
GfxColorSpace *colorSpace;
GfxColor color;
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring color space setting in cached Type 3 character");
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring color space setting"
+ " in uncolored Type 3 char or tiling pattern");
return;
}
state->setStrokePattern(NULL);
@@ -1491,9 +1506,9 @@ void Gfx::opSetFillColor(Object args[], int numArgs) {
GfxColor color;
int i;
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring color setting in cached Type 3 character");
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring color setting"
+ " in uncolored Type 3 char or tiling pattern");
return;
}
if (numArgs != state->getFillColorSpace()->getNComps()) {
@@ -1531,9 +1546,9 @@ void Gfx::opSetFillColorN(Object args[], int numArgs) {
GfxPattern *pattern;
int i;
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring color setting in cached Type 3 character");
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring color setting"
+ " in uncolored Type 3 char or tiling pattern");
return;
}
if (state->getFillColorSpace()->getMode() == csPattern) {
@@ -1585,9 +1600,9 @@ void Gfx::opSetStrokeColorN(Object args[], int numArgs) {
GfxPattern *pattern;
int i;
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring color setting in cached Type 3 character");
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring color setting"
+ " in uncolored Type 3 char or tiling pattern");
return;
}
if (state->getStrokeColorSpace()->getMode() == csPattern) {
@@ -2068,6 +2083,7 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
state->setStrokeColor(state->getFillColor());
out->updateFillColor(state);
out->updateStrokeColor(state);
+ state->setIgnoreColorOps(gTrue);
} else {
state->setFillColorSpace(GfxColorSpace::create(csDeviceGray));
out->updateFillColorSpace(state);
@@ -2223,6 +2239,7 @@ void Gfx::doShadingPatternFill(GfxShadingPattern *sPat,
if (stroke) {
state->clipToStrokePath();
out->clipToStrokePath(state);
+ state->setFillOverprint(state->getStrokeOverprint());
} else if (!text) {
state->clip();
if (eoFill) {
@@ -2241,6 +2258,7 @@ void Gfx::doShadingPatternFill(GfxShadingPattern *sPat,
det = ctm[0] * ctm[3] - ctm[1] * ctm[2];
if (fabs(det) <= 1e-10) {
error(errSyntaxError, getPos(), "Singular matrix in shading pattern fill");
+ restoreStateStack(savedState);
return;
}
det = 1 / det;
@@ -2338,9 +2356,9 @@ void Gfx::opShFill(Object args[], int numArgs) {
GfxState *savedState;
double xMin, yMin, xMax, yMax;
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring shaded fill in cached Type 3 character");
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring shaded fill"
+ " in uncolored Type 3 char or tiling pattern");
return;
}
@@ -4123,7 +4141,7 @@ void Gfx::opXObject(Object args[], int numArgs) {
ocState = ocSaved;
}
-void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
+GBool Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
Dict *dict, *maskDict;
int width, height;
int bits, maskBits;
@@ -4145,7 +4163,7 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
// check for optional content
if (!ocState && !inlineImg) {
- return;
+ return gTrue;
}
// get info from the stream
@@ -4309,6 +4327,11 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
if (!colorSpace) {
goto err1;
}
+ if (colorSpace->getMode() == csPattern) {
+ error(errSyntaxError, getPos(), "Image with a Pattern color space");
+ delete colorSpace;
+ goto err1;
+ }
dict->lookup("Decode", &obj1);
if (obj1.isNull()) {
obj1.free();
@@ -4365,6 +4388,12 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
}
maskHeight = obj1.getInt();
obj1.free();
+ if (maskWidth <= 0 || maskHeight <= 0) {
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
+ goto err1;
+ }
maskDict->lookup("BitsPerComponent", &obj1);
if (obj1.isNull()) {
obj1.free();
@@ -4378,6 +4407,12 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
}
maskBits = obj1.getInt();
obj1.free();
+ if (maskBits < 1 || maskBits > 16) {
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
+ goto err1;
+ }
maskDict->lookup("ColorSpace", &obj1);
if (obj1.isNull()) {
obj1.free();
@@ -4501,6 +4536,12 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
}
maskHeight = obj1.getInt();
obj1.free();
+ if (maskWidth <= 0 || maskHeight <= 0) {
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
+ goto err2;
+ }
maskDict->lookup("ImageMask", &obj1);
if (obj1.isNull()) {
obj1.free();
@@ -4534,10 +4575,10 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
}
// if drawing is disabled, skip over inline image data
- if (state->getInCachedT3Char() || !ocState) {
- if (state->getInCachedT3Char()) {
- error(errSyntaxWarning, getPos(),
- "Ignoring image in cached Type 3 character");
+ if (state->getIgnoreColorOps() || !ocState) {
+ if (state->getIgnoreColorOps()) {
+ error(errSyntaxWarning, getPos(), "Ignoring image"
+ " in uncolored Type 3 char or tiling pattern");
}
if (inlineImg) {
str->reset();
@@ -4582,7 +4623,7 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
}
opCounter += i;
- return;
+ return gTrue;
err2:
obj1.free();
@@ -4594,6 +4635,8 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
state->setRenderingIntent(riSaved);
out->updateRenderingIntent(state);
}
+
+ return gFalse;
}
void Gfx::doForm(Object *strRef, Object *str) {
@@ -4826,11 +4869,12 @@ void Gfx::opBeginImage(Object args[], int numArgs) {
// display the image
if (str) {
- doImage(NULL, str, gTrue);
+ if (!doImage(NULL, str, gTrue)) {
+ delete str;
// if we have the stream length, skip to end-of-stream and then
// skip 'EI' in the original stream
- if (haveLength) {
+ } else if (haveLength) {
while ((c1 = str->getChar()) != EOF) ;
delete str;
str = parser->getStream();
@@ -4935,7 +4979,7 @@ void Gfx::opSetCharWidth(Object args[], int numArgs) {
}
void Gfx::opSetCacheDevice(Object args[], int numArgs) {
- state->setInCachedT3Char(gTrue);
+ state->setIgnoreColorOps(gTrue);
out->type3D1(state, args[0].getNum(), args[1].getNum(),
args[2].getNum(), args[3].getNum(),
args[4].getNum(), args[5].getNum());
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
index 9d175825f97..2159eaaf2e9 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
@@ -330,7 +330,7 @@ private:
// XObject operators
void opXObject(Object args[], int numArgs);
- void doImage(Object *ref, Stream *str, GBool inlineImg);
+ GBool doImage(Object *ref, Stream *str, GBool inlineImg);
void doForm(Object *strRef, Object *str);
// in-line image operators
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
index 640cf81db02..b10c81779ff 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
@@ -164,7 +164,8 @@ GfxFontLoc::~GfxFontLoc() {
// GfxFont
//------------------------------------------------------------------------
-GfxFont *GfxFont::makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict) {
+GfxFont *GfxFont::makeFont(XRef *xref, const char *tagA,
+ Ref idA, Dict *fontDict) {
GString *nameA;
Ref embFontIDA;
GfxFontType typeA;
@@ -197,7 +198,7 @@ GfxFont *GfxFont::makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict) {
return font;
}
-GfxFont::GfxFont(char *tagA, Ref idA, GString *nameA,
+GfxFont::GfxFont(const char *tagA, Ref idA, GString *nameA,
GfxFontType typeA, Ref embFontIDA) {
ok = gFalse;
tag = new GString(tagA);
@@ -541,6 +542,7 @@ CharCodeToUnicode *GfxFont::readToUnicodeCMap(Dict *fontDict, int nBits,
GfxFontLoc *GfxFont::locateFont(XRef *xref, GBool ps) {
GfxFontLoc *fontLoc;
SysFontType sysFontType;
+ FoFiIdentifierType fft;
GString *path, *base14Name, *substName;
PSFontParam16 *psFont16;
Object refObj, embFontObj;
@@ -635,32 +637,43 @@ GfxFontLoc *GfxFont::locateFont(XRef *xref, GBool ps) {
//----- system font
if (name && (path = globalParams->findSystemFontFile(name, &sysFontType,
&fontNum))) {
+ fontLoc = new GfxFontLoc();
+ fontLoc->locType = gfxFontLocExternal;
+ fontLoc->path = path;
+ fontLoc->fontNum = fontNum;
if (isCIDFont()) {
if (sysFontType == sysFontTTF || sysFontType == sysFontTTC) {
- fontLoc = new GfxFontLoc();
- fontLoc->locType = gfxFontLocExternal;
fontLoc->fontType = fontCIDType2;
- fontLoc->path = path;
- fontLoc->fontNum = fontNum;
return fontLoc;
+ } else if (sysFontType == sysFontOTF) {
+ fft = FoFiIdentifier::identifyFile(fontLoc->path->getCString());
+ if (fft == fofiIdOpenTypeCFFCID) {
+ fontLoc->fontType = fontCIDType0COT;
+ return fontLoc;
+ } else if (fft == fofiIdTrueType) {
+ fontLoc->fontType = fontCIDType2;
+ return fontLoc;
+ }
}
} else {
if (sysFontType == sysFontTTF || sysFontType == sysFontTTC) {
- fontLoc = new GfxFontLoc();
- fontLoc->locType = gfxFontLocExternal;
fontLoc->fontType = fontTrueType;
- fontLoc->path = path;
- fontLoc->fontNum = fontNum;
return fontLoc;
} else if (sysFontType == sysFontPFA || sysFontType == sysFontPFB) {
- fontLoc = new GfxFontLoc();
- fontLoc->locType = gfxFontLocExternal;
fontLoc->fontType = fontType1;
- fontLoc->path = path;
return fontLoc;
+ } else if (sysFontType == sysFontOTF) {
+ fft = FoFiIdentifier::identifyFile(fontLoc->path->getCString());
+ if (fft == fofiIdOpenTypeCFF8Bit) {
+ fontLoc->fontType = fontType1COT;
+ return fontLoc;
+ } else if (fft == fofiIdTrueType) {
+ fontLoc->fontType = fontTrueTypeOT;
+ return fontLoc;
+ }
}
}
- delete path;
+ delete fontLoc;
}
if (!isCIDFont()) {
@@ -863,7 +876,7 @@ char *GfxFont::readEmbFontFile(XRef *xref, int *len) {
// Gfx8BitFont
//------------------------------------------------------------------------
-Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
+Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
GfxFontType typeA, Ref embFontIDA, Dict *fontDict):
GfxFont(tagA, idA, nameA, typeA, embFontIDA)
{
@@ -1490,6 +1503,33 @@ int *Gfx8BitFont::getCodeToGIDMap(FoFiTrueType *ff) {
return map;
}
+int *Gfx8BitFont::getCodeToGIDMap(FoFiType1C *ff) {
+ int *map;
+ GHash *nameToGID;
+ int i, gid;
+
+ map = (int *)gmallocn(256, sizeof(int));
+ for (i = 0; i < 256; ++i) {
+ map[i] = 0;
+ }
+
+ nameToGID = ff->getNameToGIDMap();
+ for (i = 0; i < 256; ++i) {
+ if (!enc[i]) {
+ continue;
+ }
+ gid = nameToGID->lookupInt(enc[i]);
+ if (gid < 0 || gid >= 65536) {
+ continue;
+ }
+ map[i] = gid;
+ }
+
+ delete nameToGID;
+
+ return map;
+}
+
Dict *Gfx8BitFont::getCharProcs() {
return charProcs.isDict() ? charProcs.getDict() : (Dict *)NULL;
}
@@ -1575,7 +1615,7 @@ GBool Gfx8BitFont::problematicForUnicode() {
// GfxCIDFont
//------------------------------------------------------------------------
-GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
+GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
GfxFontType typeA, Ref embFontIDA, Dict *fontDict):
GfxFont(tagA, idA, nameA, typeA, embFontIDA)
{
@@ -2001,6 +2041,13 @@ GString *GfxCIDFont::getCollection() {
return cMap ? cMap->getCollection() : (GString *)NULL;
}
+double GfxCIDFont::getWidth(CID cid) {
+ double w;
+
+ getHorizontalMetrics(cid, &w);
+ return w;
+}
+
GBool GfxCIDFont::problematicForUnicode() {
GString *nameLC;
GBool symbolic;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
index b2d8637a46d..3b63fa69fe0 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
@@ -26,6 +26,7 @@ class Dict;
class CMap;
class CharCodeToUnicode;
class FoFiTrueType;
+class FoFiType1C;
struct GfxFontCIDWidths;
struct Base14FontMapEntry;
class FNVHash;
@@ -131,9 +132,10 @@ class GfxFont {
public:
// Build a GfxFont object.
- static GfxFont *makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict);
+ static GfxFont *makeFont(XRef *xref, const char *tagA,
+ Ref idA, Dict *fontDict);
- GfxFont(char *tagA, Ref idA, GString *nameA,
+ GfxFont(const char *tagA, Ref idA, GString *nameA,
GfxFontType typeA, Ref embFontIDA);
virtual ~GfxFont();
@@ -243,7 +245,7 @@ protected:
class Gfx8BitFont: public GfxFont {
public:
- Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
+ Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
GfxFontType typeA, Ref embFontIDA, Dict *fontDict);
virtual ~Gfx8BitFont();
@@ -274,6 +276,10 @@ public:
// (This is only useful for TrueType fonts.)
int *getCodeToGIDMap(FoFiTrueType *ff);
+ // Return a char code-to-GID mapping for the provided font file.
+ // (This is only useful for Type1C fonts.)
+ int *getCodeToGIDMap(FoFiType1C *ff);
+
// Return the Type 3 CharProc dictionary, or NULL if none.
Dict *getCharProcs();
@@ -311,7 +317,7 @@ private:
class GfxCIDFont: public GfxFont {
public:
- GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
+ GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GString *nameA,
GfxFontType typeA, Ref embFontIDA, Dict *fontDict);
virtual ~GfxCIDFont();
@@ -331,6 +337,9 @@ public:
// Get the collection name (<registry>-<ordering>).
GString *getCollection();
+ // Return the horizontal width for <cid>.
+ double getWidth(CID cid);
+
// Return the CID-to-GID mapping table. These should only be called
// if type is fontCIDType2.
int *getCIDToGID() { return cidToGID; }
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
index 9a43608c2fe..60b5f577054 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
@@ -1281,7 +1281,7 @@ GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr,
}
obj1.free();
arr->get(3, &obj1);
- if (!(funcA = Function::parse(&obj1))) {
+ if (!(funcA = Function::parse(&obj1, 1, altA->getNComps()))) {
goto err4;
}
obj1.free();
@@ -1476,7 +1476,7 @@ GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr,
}
obj1.free();
arr->get(3, &obj1);
- if (!(funcA = Function::parse(&obj1))) {
+ if (!(funcA = Function::parse(&obj1, nCompsA, altA->getNComps()))) {
goto err4;
}
obj1.free();
@@ -2117,14 +2117,14 @@ GfxFunctionShading *GfxFunctionShading::parse(Dict *dict
}
for (i = 0; i < nFuncsA; ++i) {
obj1.arrayGet(i, &obj2);
- if (!(funcsA[i] = Function::parse(&obj2))) {
+ if (!(funcsA[i] = Function::parse(&obj2, 2, 1))) {
goto err2;
}
obj2.free();
}
} else {
nFuncsA = 1;
- if (!(funcsA[0] = Function::parse(&obj1))) {
+ if (!(funcsA[0] = Function::parse(&obj1, 2, -1))) {
goto err1;
}
}
@@ -2137,6 +2137,16 @@ GfxFunctionShading *GfxFunctionShading::parse(Dict *dict
delete shading;
return NULL;
}
+
+ for (i = 0; i < shading->nFuncs; ++i) {
+ if (shading->funcs[i]->getOutputSize()
+ != shading->getColorSpace()->getNComps()) {
+ error(errSyntaxError, -1, "Invalid function in shading dictionary");
+ delete shading;
+ return NULL;
+ }
+ }
+
return shading;
err2:
@@ -2274,7 +2284,7 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict
}
for (i = 0; i < nFuncsA; ++i) {
obj1.arrayGet(i, &obj2);
- if (!(funcsA[i] = Function::parse(&obj2))) {
+ if (!(funcsA[i] = Function::parse(&obj2, 1, 1))) {
obj1.free();
obj2.free();
goto err1;
@@ -2283,7 +2293,7 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict
}
} else {
nFuncsA = 1;
- if (!(funcsA[0] = Function::parse(&obj1))) {
+ if (!(funcsA[0] = Function::parse(&obj1, 1, -1))) {
obj1.free();
goto err1;
}
@@ -2307,6 +2317,16 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict
delete shading;
return NULL;
}
+
+ for (i = 0; i < shading->nFuncs; ++i) {
+ if (shading->funcs[i]->getOutputSize()
+ != shading->getColorSpace()->getNComps()) {
+ error(errSyntaxError, -1, "Invalid function in shading dictionary");
+ delete shading;
+ return NULL;
+ }
+ }
+
return shading;
err1:
@@ -2446,7 +2466,7 @@ GfxRadialShading *GfxRadialShading::parse(Dict *dict
}
for (i = 0; i < nFuncsA; ++i) {
obj1.arrayGet(i, &obj2);
- if (!(funcsA[i] = Function::parse(&obj2))) {
+ if (!(funcsA[i] = Function::parse(&obj2, 1, 1))) {
obj1.free();
obj2.free();
goto err1;
@@ -2455,7 +2475,7 @@ GfxRadialShading *GfxRadialShading::parse(Dict *dict
}
} else {
nFuncsA = 1;
- if (!(funcsA[0] = Function::parse(&obj1))) {
+ if (!(funcsA[0] = Function::parse(&obj1, 1, -1))) {
obj1.free();
goto err1;
}
@@ -2479,6 +2499,16 @@ GfxRadialShading *GfxRadialShading::parse(Dict *dict
delete shading;
return NULL;
}
+
+ for (i = 0; i < shading->nFuncs; ++i) {
+ if (shading->funcs[i]->getOutputSize()
+ != shading->getColorSpace()->getNComps()) {
+ error(errSyntaxError, -1, "Invalid function in shading dictionary");
+ delete shading;
+ return NULL;
+ }
+ }
+
return shading;
err1:
@@ -2719,7 +2749,7 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(
}
for (i = 0; i < nFuncsA; ++i) {
obj1.arrayGet(i, &obj2);
- if (!(funcsA[i] = Function::parse(&obj2))) {
+ if (!(funcsA[i] = Function::parse(&obj2, 1, 1))) {
obj1.free();
obj2.free();
goto err1;
@@ -2728,7 +2758,7 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(
}
} else {
nFuncsA = 1;
- if (!(funcsA[0] = Function::parse(&obj1))) {
+ if (!(funcsA[0] = Function::parse(&obj1, 1, -1))) {
obj1.free();
goto err1;
}
@@ -2832,6 +2862,16 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(
delete shading;
return NULL;
}
+
+ for (i = 0; i < shading->nFuncs; ++i) {
+ if (shading->funcs[i]->getOutputSize()
+ != shading->getColorSpace()->getNComps()) {
+ error(errSyntaxError, -1, "Invalid function in shading dictionary");
+ delete shading;
+ return NULL;
+ }
+ }
+
return shading;
err2:
@@ -3017,7 +3057,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict,
}
for (i = 0; i < nFuncsA; ++i) {
obj1.arrayGet(i, &obj2);
- if (!(funcsA[i] = Function::parse(&obj2))) {
+ if (!(funcsA[i] = Function::parse(&obj2, 1, 1))) {
obj1.free();
obj2.free();
goto err1;
@@ -3026,7 +3066,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict,
}
} else {
nFuncsA = 1;
- if (!(funcsA[0] = Function::parse(&obj1))) {
+ if (!(funcsA[0] = Function::parse(&obj1, 1, -1))) {
obj1.free();
goto err1;
}
@@ -3044,6 +3084,12 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict,
if (!bitBuf->getBits(flagBits, &flag)) {
break;
}
+ flag &= 3;
+ if (flag != 0 && nPatchesA == 0) {
+ error(errSyntaxError, -1, "Invalid patch in patch mesh shading");
+ delete bitBuf;
+ goto err1;
+ }
if (typeA == 6) {
switch (flag) {
case 0: nPts = 12; nColors = 4; break;
@@ -3445,6 +3491,16 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict,
delete shading;
return NULL;
}
+
+ for (i = 0; i < shading->nFuncs; ++i) {
+ if (shading->funcs[i]->getOutputSize()
+ != shading->getColorSpace()->getNComps()) {
+ error(errSyntaxError, -1, "Invalid function in shading dictionary");
+ delete shading;
+ return NULL;
+ }
+ }
+
return shading;
err2:
@@ -4122,7 +4178,7 @@ GfxState::GfxState(double hDPIA, double vDPIA, PDFRectangle *pageBox,
clipXMax = pageWidth;
clipYMax = pageHeight;
- inCachedT3Char = gFalse;
+ ignoreColorOps = gFalse;
saved = NULL;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
index 8e5d3b0b7a5..50507040fed 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
@@ -1183,7 +1183,7 @@ public:
void getUserClipBBox(double *xMin, double *yMin, double *xMax, double *yMax);
double getLineX() { return lineX; }
double getLineY() { return lineY; }
- GBool getInCachedT3Char() { return inCachedT3Char; }
+ GBool getIgnoreColorOps() { return ignoreColorOps; }
// Is there a current point/path?
GBool isCurPt() { return path->isCurPt(); }
@@ -1280,8 +1280,9 @@ public:
void textShift(double tx, double ty);
void shift(double dx, double dy);
- // Cached Type 3 char status.
- void setInCachedT3Char(GBool in) { inCachedT3Char = in; }
+ // Ignore color operators (in cached/uncolored Type 3 chars, and
+ // uncolored tiling patterns). Cached Type 3 char status.
+ void setIgnoreColorOps(GBool ignore) { ignoreColorOps = ignore; }
// Push/pop GfxState on/off stack.
GfxState *save();
@@ -1344,7 +1345,9 @@ private:
double clipXMin, clipYMin, // bounding box for clip region
clipXMax, clipYMax;
- GBool inCachedT3Char; // in a cached (uncolored) Type 3 char
+ GBool ignoreColorOps; // ignore color ops (in cached/uncolored
+ // Type 3 chars, and uncolored tiling
+ // patterns)
GfxState *saved; // next GfxState on stack
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
index 2205a621322..56bfba8e3cc 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
@@ -17,13 +17,18 @@
#include <string.h>
#include <stdio.h>
+#include <stdarg.h>
#include <ctype.h>
+#include <time.h>
#ifdef _WIN32
# include <shlobj.h>
#endif
#if HAVE_PAPER_H
#include <paper.h>
#endif
+#if HAVE_FONTCONFIG
+# include <fontconfig/fontconfig.h>
+#endif
#include "gmem.h"
#include "gmempp.h"
#include "GString.h"
@@ -91,14 +96,14 @@ static struct {
{"Courier-BoldOblique", "n022024l.pfb", "courbi.ttf", "Courier", "Courier Bold Oblique", "Courier-Bold", 0.212557},
{"Courier-Oblique", "n022023l.pfb", "couri.ttf", "Courier", "Courier Oblique", "Courier", 0.212557},
{"Helvetica", "n019003l.pfb", "arial.ttf", "Helvetica", "Helvetica", NULL, 0},
- {"Helvetica-Bold", "n019004l.pfb", "arialbd.ttf", "Helvetica", "Helvetica-Bold", NULL, 0},
+ {"Helvetica-Bold", "n019004l.pfb", "arialbd.ttf", "Helvetica", "Helvetica Bold", NULL, 0},
{"Helvetica-BoldOblique", "n019024l.pfb", "arialbi.ttf", "Helvetica", "Helvetica Bold Oblique", "Helvetica-Bold", 0.212557},
{"Helvetica-Oblique", "n019023l.pfb", "ariali.ttf", "Helvetica", "Helvetica Oblique", "Helvetica", 0.212557},
{"Symbol", "s050000l.pfb", NULL, "Symbol", "Symbol", NULL, 0},
- {"Times-Bold", "n021004l.pfb", "timesbd.ttf", "Times", "Times-Bold", NULL, 0},
- {"Times-BoldItalic", "n021024l.pfb", "timesbi.ttf", "Times", "Times-BoldItalic", NULL, 0},
- {"Times-Italic", "n021023l.pfb", "timesi.ttf", "Times", "Times-Italic", NULL, 0},
- {"Times-Roman", "n021003l.pfb", "times.ttf", "Times", "Times-Roman", NULL, 0},
+ {"Times-Bold", "n021004l.pfb", "timesbd.ttf", "Times", "Times Bold", NULL, 0},
+ {"Times-BoldItalic", "n021024l.pfb", "timesbi.ttf", "Times", "Times Bold Italic", NULL, 0},
+ {"Times-Italic", "n021023l.pfb", "timesi.ttf", "Times", "Times Italic", NULL, 0},
+ {"Times-Roman", "n021003l.pfb", "times.ttf", "Times", "Times Roman", NULL, 0},
{"ZapfDingbats", "d050000l.pfb", NULL, "ZapfDingbats", "Zapf Dingbats", NULL, 0},
{NULL}
};
@@ -226,6 +231,10 @@ public:
void scanWindowsFonts(char *winFontDir);
#endif
+#if HAVE_FONTCONFIG
+ void scanFontconfigFonts();
+#endif
+
private:
#ifdef _WIN32
@@ -458,6 +467,8 @@ SysFontInfo *SysFontList::makeWindowsFont(char *name, int fontNum,
if (!strcasecmp(path + strlen(path) - 4, ".ttc")) {
type = sysFontTTC;
+ } else if (!strcasecmp(path + strlen(path) - 4, ".otf")) {
+ type = sysFontOTF;
} else {
type = sysFontTTF;
}
@@ -465,6 +476,109 @@ SysFontInfo *SysFontList::makeWindowsFont(char *name, int fontNum,
}
#endif
+#if HAVE_FONTCONFIG
+void SysFontList::scanFontconfigFonts() {
+ FcPattern *pattern;
+ FcObjectSet *objSet;
+ FcFontSet *fontSet;
+ char *family, *file, *styleLang, *style;
+ GString *family2;
+ SysFontType type;
+ GBool bold, italic;
+ char c;
+ int fontNum, i, j, n;
+
+ FcInit();
+
+ pattern = FcPatternBuild(NULL,
+ FC_OUTLINE, FcTypeBool, FcTrue,
+ FC_SCALABLE, FcTypeBool, FcTrue,
+ NULL);
+ objSet = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_STYLELANG,
+ FC_FILE, FC_INDEX, NULL);
+ fontSet = FcFontList(NULL, pattern, objSet);
+ FcPatternDestroy(pattern);
+ FcObjectSetDestroy(objSet);
+
+ if (fontSet) {
+ for (i = 0; i < fontSet->nfont; ++i) {
+
+ //--- font file, font type
+ if (FcPatternGetString(fontSet->fonts[i], FC_FILE, 0,
+ (FcChar8 **)&file)
+ != FcResultMatch) {
+ continue;
+ }
+ n = (int)strlen(file);
+ if (n > 4 && !strcasecmp(file + n - 4, ".pfa")) {
+ type = sysFontPFA;
+ } else if (n > 4 && !strcasecmp(file + n - 4, ".pfb")) {
+ type = sysFontPFB;
+ } else if (n > 4 && !strcasecmp(file + n - 4, ".ttf")) {
+ type = sysFontTTF;
+ } else if (n > 4 && !strcasecmp(file + n - 4, ".otf")) {
+ type = sysFontOTF;
+ } else {
+ continue;
+ }
+
+ //--- font number
+ if (FcPatternGetInteger(fontSet->fonts[i], FC_INDEX, 0, &fontNum)
+ != FcResultMatch) {
+ fontNum = 0;
+ }
+
+ //--- font family
+ if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0,
+ (FcChar8 **)&family)
+ != FcResultMatch) {
+ continue;
+ }
+
+ //----- normalize the font name
+ family2 = new GString(family);
+ j = 0;
+ while (j < family2->getLength()) {
+ c = family2->getChar(j);
+ if (c == ' ' || c == ',' || c == '-') {
+ family2->del(j);
+ } else {
+ ++j;
+ }
+ }
+
+ //--- font style
+ style = NULL;
+ for (j = 0;
+ FcPatternGetString(fontSet->fonts[i], FC_STYLELANG, j,
+ (FcChar8 **)&styleLang)
+ == FcResultMatch;
+ ++j) {
+ if (!strcmp(styleLang, "en")) {
+ if (FcPatternGetString(fontSet->fonts[i], FC_STYLE, j,
+ (FcChar8 **)&style)
+ != FcResultMatch) {
+ style = NULL;
+ }
+ break;
+ }
+ ++j;
+ }
+ bold = style && strstr(style, "Bold") != NULL;
+ italic = style && (strstr(style, "Italic") != NULL ||
+ strstr(style, "Oblique") != NULL);
+
+ fonts->append(new SysFontInfo(family2, bold, italic,
+ new GString(file), type, fontNum));
+ }
+
+ FcFontSetDestroy(fontSet);
+ }
+
+ FcFini();
+}
+#endif // HAVE_FONTCONFIG
+
//------------------------------------------------------------------------
// KeyBinding
//------------------------------------------------------------------------
@@ -619,7 +733,10 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
textKeepTinyChars = gTrue;
initialZoom = new GString("125");
defaultFitZoom = 0;
+ initialDisplayMode = new GString("continuous");
+ initialToolbarState = gTrue;
initialSidebarState = gTrue;
+ initialSelectMode = new GString("linear");
maxTileWidth = 1500;
maxTileHeight = 1500;
tileCacheSize = 10;
@@ -644,6 +761,7 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
paperColor = new GString("#ffffff");
matteColor = new GString("#808080");
fullScreenMatteColor = new GString("#000000");
+ reverseVideoInvertImages = gFalse;
launchCommand = NULL;
movieCommand = NULL;
defaultPrinter = NULL;
@@ -657,6 +775,7 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
tabStateFile = appendToPath(getHomeDir(), ".xpdf.tab-state");
printCommands = gFalse;
errQuiet = gFalse;
+ debugLogFile = NULL;
cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
unicodeToUnicodeCache =
@@ -787,6 +906,9 @@ void GlobalParams::createDefaultKeyBindings() {
xpdfKeyContextAny, "newWindow"));
keyBindings->append(new KeyBinding('w', xpdfKeyModCtrl,
xpdfKeyContextAny, "closeTabOrQuit"));
+ keyBindings->append(new KeyBinding('l', xpdfKeyModCtrl,
+ xpdfKeyContextAny,
+ "toggleFullScreenMode"));
keyBindings->append(new KeyBinding('q', xpdfKeyModCtrl,
xpdfKeyContextAny, "quit"));
keyBindings->append(new KeyBinding(xpdfKeyCodeTab, xpdfKeyModCtrl,
@@ -1022,9 +1144,18 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
parseString("initialZoom", &initialZoom, tokens, fileName, line);
} else if (!cmd->cmp("defaultFitZoom")) {
parseInteger("defaultFitZoom", &defaultFitZoom, tokens, fileName, line);
+ } else if (!cmd->cmp("initialDisplayMode")) {
+ parseString("initialDisplayMode", &initialDisplayMode,
+ tokens, fileName, line);
+ } else if (!cmd->cmp("initialToolbarState")) {
+ parseYesNo("initialToolbarState", &initialToolbarState,
+ tokens, fileName, line);
} else if (!cmd->cmp("initialSidebarState")) {
parseYesNo("initialSidebarState", &initialSidebarState,
tokens, fileName, line);
+ } else if (!cmd->cmp("initialSelectMode")) {
+ parseString("initialSelectMode", &initialSelectMode,
+ tokens, fileName, line);
} else if (!cmd->cmp("maxTileWidth")) {
parseInteger("maxTileWidth", &maxTileWidth, tokens, fileName, line);
} else if (!cmd->cmp("maxTileHeight")) {
@@ -1086,6 +1217,9 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
} else if (!cmd->cmp("fullScreenMatteColor")) {
parseString("fullScreenMatteColor", &fullScreenMatteColor,
tokens, fileName, line);
+ } else if (!cmd->cmp("reverseVideoInvertImages")) {
+ parseYesNo("reverseVideoInvertImages", &reverseVideoInvertImages,
+ tokens, fileName, line);
} else if (!cmd->cmp("launchCommand")) {
parseString("launchCommand", &launchCommand, tokens, fileName, line);
} else if (!cmd->cmp("movieCommand")) {
@@ -1118,6 +1252,8 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
parseYesNo("printCommands", &printCommands, tokens, fileName, line);
} else if (!cmd->cmp("errQuiet")) {
parseYesNo("errQuiet", &errQuiet, tokens, fileName, line);
+ } else if (!cmd->cmp("debugLogFile")) {
+ parseString("debugLogFile", &debugLogFile, tokens, fileName, line);
} else {
error(errConfig, -1, "Unknown config file command '{0:t}' ({1:t}:{2:d})",
cmd, fileName, line);
@@ -1862,6 +1998,8 @@ GlobalParams::~GlobalParams() {
deleteGList(psResidentFontsCC, PSFontParam16);
delete textEncoding;
delete initialZoom;
+ delete initialDisplayMode;
+ delete initialSelectMode;
if (paperColor) {
delete paperColor;
}
@@ -1943,6 +2081,7 @@ static void getWinFontDir(char *winFontDir) {
}
}
}
+ FreeLibrary(shell32Lib);
}
// if something went wrong, or we're on a Terminal Server, try using
// %SYSTEMROOT%\Fonts
@@ -1958,6 +2097,40 @@ static void getWinFontDir(char *winFontDir) {
}
#endif
+#ifdef __APPLE__
+// Apple dfonts and ttc fonts seem to randomly and interchangeably use
+// space and hyphen, and sometimes drop the separator entirely.
+static GBool macFontNameMatches(GString *name1, const char *name2) {
+ const char *p1, *p2;
+ char c1, c2;
+
+ p1 = name1->getCString();
+ p2 = name2;
+ while (*p1 && *p2) {
+ c1 = *p1;
+ c2 = *p2;
+ if (c2 == ' ') {
+ // * space or hyphen matches a space in the pattern
+ // * separators can also be dropped, in which case we move to
+ // the next char in the pattern
+ if (c1 == ' ' || c1 == '-') {
+ ++p1;
+ }
+ } else {
+ if (c1 != c2) {
+ return gFalse;
+ }
+ ++p1;
+ }
+ ++p2;
+ }
+ if (*p1 || *p2) {
+ return gFalse;
+ }
+ return gTrue;
+}
+#endif
+
void GlobalParams::setupBaseFonts(const char *dir) {
GString *fontName;
GString *fileName;
@@ -2036,8 +2209,8 @@ void GlobalParams::setupBaseFonts(const char *dir) {
}
if (dfontFontNames) {
for (k = 0; k < dfontFontNames->getLength(); ++k) {
- if (!((GString *)dfontFontNames->get(k))
- ->cmp(displayFontTab[i].macFontName)) {
+ if (macFontNameMatches((GString *)dfontFontNames->get(k),
+ displayFontTab[i].macFontName)) {
fontNum = k;
found = gTrue;
break;
@@ -2114,6 +2287,9 @@ void GlobalParams::setupBaseFonts(const char *dir) {
sysFonts->scanWindowsFonts(winFontDir);
}
#endif
+#if HAVE_FONTCONFIG
+ sysFonts->scanFontconfigFonts();
+#endif
}
//------------------------------------------------------------------------
@@ -2653,6 +2829,24 @@ int GlobalParams::getDefaultFitZoom() {
return z;
}
+GString *GlobalParams::getInitialDisplayMode() {
+ GString *s;
+
+ lockGlobalParams;
+ s = initialDisplayMode->copy();
+ unlockGlobalParams;
+ return s;
+}
+
+GBool GlobalParams::getInitialToolbarState() {
+ GBool state;
+
+ lockGlobalParams;
+ state = initialToolbarState;
+ unlockGlobalParams;
+ return state;
+}
+
GBool GlobalParams::getInitialSidebarState() {
GBool state;
@@ -2662,6 +2856,15 @@ GBool GlobalParams::getInitialSidebarState() {
return state;
}
+GString *GlobalParams::getInitialSelectMode() {
+ GString *s;
+
+ lockGlobalParams;
+ s = initialSelectMode->copy();
+ unlockGlobalParams;
+ return s;
+}
+
int GlobalParams::getMaxTileWidth() {
int w;
@@ -2872,6 +3075,15 @@ GString *GlobalParams::getFullScreenMatteColor() {
return s;
}
+GBool GlobalParams::getReverseVideoInvertImages() {
+ GBool invert;
+
+ lockGlobalParams;
+ invert = reverseVideoInvertImages;
+ unlockGlobalParams;
+ return invert;
+}
+
GString *GlobalParams::getDefaultPrinter() {
GString *s;
@@ -2998,6 +3210,51 @@ GBool GlobalParams::getErrQuiet() {
return errQuiet;
}
+GString *GlobalParams::getDebugLogFile() {
+ return debugLogFile;
+}
+
+void GlobalParams::debugLogPrintf(char *fmt, ...) {
+ GString *path;
+ FILE *f;
+ GBool needClose;
+ time_t t;
+ struct tm tm;
+ va_list args;
+
+ if (!(path = getDebugLogFile())) {
+ return;
+ }
+ needClose = gFalse;
+ if (!path->cmp("-")) {
+ f = stdout;
+ } else if (!path->cmp("+")) {
+ f = stderr;
+ } else {
+ f = fopen(path->getCString(), "a");
+ needClose = gTrue;
+ }
+ if (!f) {
+ return;
+ }
+ t = time(NULL);
+#ifdef _WIN32
+ localtime_s(&tm, &t);
+#else
+ localtime_r(&t, &tm);
+#endif
+ fprintf(f, "[%04d-%02d-%02d %02d:%02d:%02d] ",
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+ va_start(args, fmt);
+ vfprintf(f, fmt, args);
+ va_end(args);
+ fflush(f);
+ if (needClose) {
+ fclose(f);
+ }
+}
+
CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) {
GString *fileName;
CharCodeToUnicode *ctu;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
index 066b420dfa8..ed1fed3152d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
@@ -55,7 +55,8 @@ enum SysFontType {
sysFontPFA,
sysFontPFB,
sysFontTTF,
- sysFontTTC
+ sysFontTTC,
+ sysFontOTF
};
//------------------------------------------------------------------------
@@ -283,7 +284,10 @@ public:
GBool getTextKeepTinyChars();
GString *getInitialZoom();
int getDefaultFitZoom();
+ GString *getInitialDisplayMode();
+ GBool getInitialToolbarState();
GBool getInitialSidebarState();
+ GString *getInitialSelectMode();
int getMaxTileWidth();
int getMaxTileHeight();
int getTileCacheSize();
@@ -308,6 +312,7 @@ public:
GString *getPaperColor();
GString *getMatteColor();
GString *getFullScreenMatteColor();
+ GBool getReverseVideoInvertImages();
GString *getLaunchCommand() { return launchCommand; }
GString *getMovieCommand() { return movieCommand; }
GString *getDefaultPrinter();
@@ -322,6 +327,8 @@ public:
GString *getTabStateFile();
GBool getPrintCommands();
GBool getErrQuiet();
+ GString *getDebugLogFile();
+ void debugLogPrintf(char *fmt, ...);
CharCodeToUnicode *getCIDToUnicode(GString *collection);
CharCodeToUnicode *getUnicodeToUnicode(GString *fontName);
@@ -509,8 +516,13 @@ private:
GString *initialZoom; // initial zoom level
int defaultFitZoom; // default zoom factor if initialZoom is
// 'page' or 'width'.
+ GString *initialDisplayMode; // initial display mode (single,
+ // continuous, etc.)
+ GBool initialToolbarState; // initial toolbar state - open (true)
+ // or closed (false)
GBool initialSidebarState; // initial sidebar state - open (true)
// or closed (false)
+ GString *initialSelectMode; // initial selection mode (block or linear)
int maxTileWidth; // maximum rasterization tile width
int maxTileHeight; // maximum rasterization tile height
int tileCacheSize; // number of rasterization tiles in cache
@@ -536,6 +548,7 @@ private:
GString *paperColor; // paper (page background) color
GString *matteColor; // matte (background outside of page) color
GString *fullScreenMatteColor; // matte color in full-screen mode
+ GBool reverseVideoInvertImages; // invert images in reverse video mode
GString *launchCommand; // command executed for 'launch' links
GString *movieCommand; // command executed for movie annotations
GString *defaultPrinter; // default printer (for interactive printing
@@ -551,6 +564,7 @@ private:
GString *tabStateFile; // path for the tab state save file
GBool printCommands; // print the drawing commands
GBool errQuiet; // suppress error messages?
+ GString *debugLogFile; // path for debug log file
CharCodeToUnicodeCache *cidToUnicodeCache;
CharCodeToUnicodeCache *unicodeToUnicodeCache;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
index d6cbc24680d..036f1116c01 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
@@ -34,9 +34,11 @@
#include "GList.h"
#include "SplashBitmap.h"
#include "PDFDoc.h"
+#include "GfxFont.h"
#include "TextOutputDev.h"
#include "SplashOutputDev.h"
#include "ErrorCodes.h"
+#include "WebFont.h"
#include "HTMLGen.h"
#ifdef _WIN32
@@ -62,11 +64,14 @@ static FontStyleTagInfo fontStyleTags[] = {
{"CondensedBold", 13, gTrue, gFalse},
{"CondensedLight", 14, gFalse, gFalse},
{"SemiBold", 8, gTrue, gFalse},
+ {"BoldItalicMT", 12, gTrue, gTrue},
{"BoldItalic", 10, gTrue, gTrue},
{"Bold_Italic", 11, gTrue, gTrue},
{"BoldOblique", 11, gTrue, gTrue},
{"Bold_Oblique", 12, gTrue, gTrue},
+ {"BoldMT", 6, gTrue, gFalse},
{"Bold", 4, gTrue, gFalse},
+ {"ItalicMT", 8, gFalse, gTrue},
{"Italic", 6, gFalse, gTrue},
{"Oblique", 7, gFalse, gTrue},
{"Light", 5, gFalse, gFalse},
@@ -171,6 +176,26 @@ static const char *vertAlignNames[] = {
//------------------------------------------------------------------------
+class HTMLGenFontDefn {
+public:
+
+ HTMLGenFontDefn(Ref fontIDA, GString *fontFaceA, GString *fontSpecA,
+ double scaleA)
+ : fontID(fontIDA), fontFace(fontFaceA), fontSpec(fontSpecA)
+ , scale(scaleA), used(gFalse) {}
+ ~HTMLGenFontDefn() { delete fontFace; delete fontSpec; }
+ GBool match(Ref fontIDA)
+ { return fontIDA.num == fontID.num && fontIDA.gen == fontID.gen; }
+
+ Ref fontID;
+ GString *fontFace; // NULL for substituted fonts
+ GString *fontSpec;
+ double scale;
+ GBool used; // set when used (per page)
+};
+
+//------------------------------------------------------------------------
+
//------------------------------------------------------------------------
@@ -184,6 +209,7 @@ HTMLGen::HTMLGen(double backgroundResolutionA) {
zoom = 1.0;
drawInvisibleText = gTrue;
allTextInvisible = gFalse;
+ extractFontFiles = gFalse;
// set up the TextOutputDev
textOutControl.mode = textOutReadingOrder;
@@ -196,16 +222,27 @@ HTMLGen::HTMLGen(double backgroundResolutionA) {
// set up the SplashOutputDev
paperColor[0] = paperColor[1] = paperColor[2] = 0xff;
splashOut = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor);
+
+ fontDefns = NULL;
}
HTMLGen::~HTMLGen() {
delete textOut;
delete splashOut;
+ if (fontDefns) {
+ deleteGList(fontDefns, HTMLGenFontDefn);
+ }
}
void HTMLGen::startDoc(PDFDoc *docA) {
doc = docA;
splashOut->startDoc(doc->getXRef());
+
+ if (fontDefns) {
+ deleteGList(fontDefns, HTMLGenFontDefn);
+ }
+ fontDefns = new GList();
+ nextFontFaceIdx = 0;
}
static inline int pr(int (*writeFunc)(void *stream, const char *data, int size),
@@ -240,7 +277,7 @@ static void pngWriteFunc(png_structp png, png_bytep data, png_size_t size) {
}
int HTMLGen::convertPage(
- int pg, const char *pngURL,
+ int pg, const char *pngURL, const char *htmlDir,
int (*writeHTML)(void *stream, const char *data, int size),
void *htmlStream,
int (*writePNG)(void *stream, const char *data, int size),
@@ -257,6 +294,7 @@ int HTMLGen::convertPage(
TextColumn *col;
TextParagraph *par;
TextLine *line;
+ HTMLGenFontDefn *fontDefn;
GString *s;
double base;
int primaryDir, spanDir;
@@ -269,7 +307,7 @@ int HTMLGen::convertPage(
0, gFalse, gTrue, gFalse);
bitmap = splashOut->getBitmap();
if (!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
- NULL, NULL, NULL)) ||
+ NULL, NULL, NULL)) ||
!(pngInfo = png_create_info_struct(png))) {
return errFileIO;
}
@@ -314,11 +352,19 @@ int HTMLGen::convertPage(
pr(writeHTML, htmlStream, ".txt { white-space:nowrap; }\n");
fonts = text->getFonts();
fontScales = (double *)gmallocn(fonts->getLength(), sizeof(double));
+ for (i = 0; i < fontDefns->getLength(); ++i) {
+ fontDefn = (HTMLGenFontDefn *)fontDefns->get(i);
+ fontDefn->used = gFalse;
+ }
for (i = 0; i < fonts->getLength(); ++i) {
font = (TextFontInfo *)fonts->get(i);
- s = getFontDefn(font, &fontScales[i]);
- pf(writeHTML, htmlStream, "#f{0:d} {{ {1:t} }}\n", i, s);
- delete s;
+ fontDefn = getFontDefn(font, htmlDir);
+ if (!fontDefn->used && fontDefn->fontFace) {
+ pr(writeHTML, htmlStream, fontDefn->fontFace->getCString());
+ }
+ pf(writeHTML, htmlStream, "#f{0:d} {{ {1:t} }}\n", i, fontDefn->fontSpec);
+ fontScales[i] = fontDefn->scale;
+ fontDefn->used = gTrue;
}
pr(writeHTML, htmlStream, "</style>\n");
pr(writeHTML, htmlStream, "</head>\n");
@@ -592,7 +638,112 @@ void HTMLGen::appendUTF8(Unicode u, GString *s) {
}
}
-GString *HTMLGen::getFontDefn(TextFontInfo *font, double *scale) {
+HTMLGenFontDefn *HTMLGen::getFontDefn(TextFontInfo *font,
+ const char *htmlDir) {
+ Ref id;
+ HTMLGenFontDefn *fontDefn;
+ int i;
+
+ // check the existing font defns
+ id = font->getFontID();
+ if (id.num >= 0) {
+ for (i = 0; i < fontDefns->getLength(); ++i) {
+ fontDefn = (HTMLGenFontDefn *)fontDefns->get(i);
+ if (fontDefn->match(id)) {
+ return fontDefn;
+ }
+ }
+ }
+
+ // try to extract a font file
+ if (!extractFontFiles ||
+ !(fontDefn = getFontFile(font, htmlDir))) {
+
+ // get a substitute font
+ fontDefn = getSubstituteFont(font);
+ }
+
+ fontDefns->append(fontDefn);
+ return fontDefn;
+}
+
+HTMLGenFontDefn *HTMLGen::getFontFile(TextFontInfo *font,
+ const char *htmlDir) {
+ Ref id;
+ HTMLGenFontDefn *fontDefn;
+ Object fontObj;
+ GfxFont *gfxFont;
+ WebFont *webFont;
+ GString *fontFile, *fontPath, *fontFace, *fontSpec;
+ const char *family, *weight, *style;
+ double scale;
+
+ id = font->getFontID();
+ if (id.num < 0) {
+ return NULL;
+ }
+
+ doc->getXRef()->fetch(id.num, id.gen, &fontObj);
+ if (!fontObj.isDict()) {
+ fontObj.free();
+ return NULL;
+ }
+
+ gfxFont = GfxFont::makeFont(doc->getXRef(), "F", id, fontObj.getDict());
+ webFont = new WebFont(gfxFont, doc->getXRef());
+ fontDefn = NULL;
+
+ if (webFont->canWriteTTF()) {
+ fontFile = GString::format("{0:d}.ttf", nextFontFaceIdx);
+ fontPath = GString::format("{0:s}/{1:t}", htmlDir, fontFile);
+ if (webFont->writeTTF(fontPath->getCString())) {
+ fontFace = GString::format("@font-face {{ font-family: ff{0:d}; src: url(\"{1:t}\"); }}\n",
+ nextFontFaceIdx, fontFile);
+ getFontDetails(font, &family, &weight, &style, &scale);
+ fontSpec = GString::format("font-family:ff{0:d},{1:s}; font-weight:{2:s}; font-style:{3:s};",
+ nextFontFaceIdx, family, weight, style);
+ ++nextFontFaceIdx;
+ fontDefn = new HTMLGenFontDefn(id, fontFace, fontSpec, 1.0);
+ }
+ delete fontPath;
+ delete fontFile;
+
+ } else if (webFont->canWriteOTF()) {
+ fontFile = GString::format("{0:d}.otf", nextFontFaceIdx);
+ fontPath = GString::format("{0:s}/{1:t}", htmlDir, fontFile);
+ if (webFont->writeOTF(fontPath->getCString())) {
+ fontFace = GString::format("@font-face {{ font-family: ff{0:d}; src: url(\"{1:t}\"); }}\n",
+ nextFontFaceIdx, fontFile);
+ getFontDetails(font, &family, &weight, &style, &scale);
+ fontSpec = GString::format("font-family:ff{0:d},{1:s}; font-weight:{2:s}; font-style:{3:s};",
+ nextFontFaceIdx, family, weight, style);
+ fontDefn = new HTMLGenFontDefn(id, fontFace, fontSpec, 1.0);
+ }
+ delete fontPath;
+ delete fontFile;
+ }
+
+ delete webFont;
+ delete gfxFont;
+ fontObj.free();
+
+ return fontDefn;
+}
+
+HTMLGenFontDefn *HTMLGen::getSubstituteFont(TextFontInfo *font) {
+ const char *family, *weight, *style;
+ double scale;
+ GString *fontSpec;
+
+ getFontDetails(font, &family, &weight, &style, &scale);
+ fontSpec = GString::format("font-family:{0:s}; font-weight:{1:s}; font-style:{2:s};",
+ family, weight, style);
+ return new HTMLGenFontDefn(font->getFontID(), NULL, fontSpec, scale);
+}
+
+void HTMLGen::getFontDetails(TextFontInfo *font, const char **family,
+ const char **weight, const char **style,
+ double *scale) {
GString *fontName;
char *fontName2;
FontStyleTagInfo *fst;
@@ -666,11 +817,7 @@ GString *HTMLGen::getFontDefn(TextFontInfo *font, double *scale) {
}
}
- // generate the CSS markup
- return GString::format("font-family:{0:s}; font-weight:{1:s}; font-style:{2:s};",
- fixedWidth ? "monospace"
- : serif ? "serif"
- : "sans-serif",
- bold ? "bold" : "normal",
- italic ? "italic" : "normal");
+ *family = fixedWidth ? "monospace" : serif ? "serif" : "sans-serif";
+ *weight = bold ? "bold" : "normal";
+ *style = italic ? "italic" : "normal";
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
index e870d8ef842..d09eea3f266 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
@@ -20,6 +20,7 @@ class PDFDoc;
class TextOutputDev;
class TextFontInfo;
class SplashOutputDev;
+class HTMLGenFontDefn;
//------------------------------------------------------------------------
@@ -46,8 +47,11 @@ public:
void setAllTextInvisible(GBool allTextInvisibleA)
{ allTextInvisible = allTextInvisibleA; }
+ void setExtractFontFiles(GBool extractFontFilesA)
+ { extractFontFiles = extractFontFilesA; }
+
void startDoc(PDFDoc *docA);
- int convertPage(int pg, const char *pngURL,
+ int convertPage(int pg, const char *pngURL, const char *htmlDir,
int (*writeHTML)(void *stream, const char *data, int size),
void *htmlStream,
int (*writePNG)(void *stream, const char *data, int size),
@@ -61,20 +65,29 @@ private:
int primaryDir, int spanDir,
double base, GBool dropCapLine, GString *s);
void appendUTF8(Unicode u, GString *s);
- GString *getFontDefn(TextFontInfo *font, double *scale);
+ HTMLGenFontDefn *getFontDefn(TextFontInfo *font, const char *htmlDir);
+ HTMLGenFontDefn *getFontFile(TextFontInfo *font, const char *htmlDir);
+ HTMLGenFontDefn *getSubstituteFont(TextFontInfo *font);
+ void getFontDetails(TextFontInfo *font, const char **family,
+ const char **weight, const char **style,
+ double *scale);
double backgroundResolution;
double zoom;
GBool drawInvisibleText;
GBool allTextInvisible;
+ GBool extractFontFiles;
PDFDoc *doc;
TextOutputDev *textOut;
SplashOutputDev *splashOut;
- GList *fonts;
+ GList *fonts; // [TextFontInfo]
double *fontScales;
+ GList *fontDefns; // [HTMLGenFontDefn]
+ int nextFontFaceIdx;
+
GBool ok;
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
index d3c9b6f8c4d..fcb9d6d0e3a 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
@@ -838,6 +838,9 @@ void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
} else {
y0 = 0;
}
+ if (y > INT_MAX - bitmap->h) {
+ return;
+ }
if (y + bitmap->h > h) {
y1 = h - y;
} else {
@@ -1202,10 +1205,13 @@ Stream *JBIG2Stream::copy() {
}
void JBIG2Stream::reset() {
- // read the globals stream
+ GList *t;
+
+ segments = new GList();
globalSegments = new GList();
+
+ // read the globals stream
if (globalsStream.isStream()) {
- segments = globalSegments;
curStr = globalsStream.getStream();
curStr->reset();
arithDecoder->setStream(curStr);
@@ -1213,10 +1219,13 @@ void JBIG2Stream::reset() {
mmrDecoder->setStream(curStr);
readSegments();
curStr->close();
+ // swap the newly read segments list into globalSegments
+ t = segments;
+ segments = globalSegments;
+ globalSegments = t;
}
// read the main stream
- segments = new GList();
curStr = str;
curStr->reset();
arithDecoder->setStream(curStr);
@@ -1280,7 +1289,8 @@ int JBIG2Stream::getBlock(char *blk, int size) {
return n;
}
-GString *JBIG2Stream::getPSFilter(int psLevel, const char *indent) {
+GString *JBIG2Stream::getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream) {
return NULL;
}
@@ -1506,7 +1516,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
Guint symHeight, symWidth, totalWidth, x, symID;
int dh, dw, refAggNum, refDX, refDY, bmSize;
GBool ex;
- int run, cnt;
+ int run, prevRun, cnt;
Guint i, j, k;
symWidths = NULL;
@@ -1853,12 +1863,21 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
// exported symbol list
i = j = 0;
ex = gFalse;
+ prevRun = 1;
while (i < numInputSyms + numNewSyms) {
if (huff) {
huffDecoder->decodeInt(&run, huffTableA);
} else {
arithDecoder->decodeInt(&run, iaexStats);
}
+ if (run == 0 && prevRun == 0) {
+ // this avoids infinite loops with damaged files (consecutive
+ // zero runs are never useful)
+ error(errSyntaxError, getPos(),
+ "Invalid exported symbol list in JBIG2 symbol dictionary");
+ delete symbolDict;
+ goto syntaxError;
+ }
if (i + run > numInputSyms + numNewSyms ||
(ex && j + run > numExSyms)) {
error(errSyntaxError, getPos(),
@@ -1874,6 +1893,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
i += run;
}
ex = !ex;
+ prevRun = run;
}
if (j != numExSyms) {
error(errSyntaxError, getPos(), "Too few symbols in JBIG2 symbol dictionary");
@@ -2143,18 +2163,23 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
runLengthTab[i].val = i;
runLengthTab[i].prefixLen = huffDecoder->readBits(4);
runLengthTab[i].rangeLen = 0;
+ runLengthTab[i].prefix = 0;
}
runLengthTab[32].val = 0x103;
runLengthTab[32].prefixLen = huffDecoder->readBits(4);
runLengthTab[32].rangeLen = 2;
+ runLengthTab[32].prefix = 0;
runLengthTab[33].val = 0x203;
runLengthTab[33].prefixLen = huffDecoder->readBits(4);
runLengthTab[33].rangeLen = 3;
+ runLengthTab[33].prefix = 0;
runLengthTab[34].val = 0x20b;
runLengthTab[34].prefixLen = huffDecoder->readBits(4);
runLengthTab[34].rangeLen = 7;
+ runLengthTab[34].prefix = 0;
runLengthTab[35].prefixLen = 0;
runLengthTab[35].rangeLen = jbig2HuffmanEOT;
+ runLengthTab[35].prefix = 0;
huffDecoder->buildTable(runLengthTab, 35);
symCodeTab = (JBIG2HuffmanTable *)gmallocn(numSyms + 1,
sizeof(JBIG2HuffmanTable));
@@ -2170,6 +2195,12 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
symCodeTab[i++].prefixLen = 0;
}
} else if (j > 0x100) {
+ if (i == 0) {
+ error(errSyntaxError, getPos(), "Invalid code in JBIG2 text region");
+ gfree(syms);
+ gfree(symCodeTab);
+ return;
+ }
for (j -= 0x100; j && i < numSyms; --j) {
symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
++i;
@@ -2226,8 +2257,8 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
codeTableError:
error(errSyntaxError, getPos(), "Missing code table in JBIG2 text region");
- gfree(codeTables);
- delete syms;
+ delete codeTables;
+ gfree(syms);
return;
eofError:
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
index 17181d72038..7aa4d9d8edb 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
@@ -42,7 +42,8 @@ public:
virtual int getChar();
virtual int lookChar();
virtual int getBlock(char *blk, int size);
- virtual GString *getPSFilter(int psLevel, const char *indent);
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
private:
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
index 79a7c51eda9..a5dd6f0db0e 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
@@ -414,18 +414,17 @@ void JPXStream::fillReadBuf() {
if (curY >= (img.ySize >> reduction)) {
return;
}
- tileIdx = ((curY - img.yTileOffsetR) / img.yTileSizeR) * img.nXTiles
- + (curX - img.xTileOffsetR) / img.xTileSizeR;
+ tileIdx = (((curY << reduction) - img.yTileOffset) / img.yTileSize)
+ * img.nXTiles
+ + ((curX << reduction) - img.xTileOffset) / img.xTileSize;
#if 1 //~ ignore the palette, assume the PDF ColorSpace object is valid
tileComp = &img.tiles[tileIdx].tileComps[curComp];
#else
tileComp = &img.tiles[tileIdx].tileComps[havePalette ? 0 : curComp];
#endif
- //~ can curX/curY be less than x/yTileOffsetR?
- //~ if yes, we need to use tx = max(0, ....)
- tx = jpxFloorDiv((curX - img.xTileOffsetR) % img.xTileSizeR,
+ tx = jpxFloorDiv(curX - jpxCeilDivPow2(img.tiles[tileIdx].x0, reduction),
tileComp->hSep);
- ty = jpxFloorDiv((curY - img.yTileOffsetR) % img.yTileSizeR,
+ ty = jpxFloorDiv(curY - jpxCeilDivPow2(img.tiles[tileIdx].y0, reduction),
tileComp->vSep);
pix = (int)tileComp->data[ty * tileComp->w + tx];
pixBits = tileComp->prec;
@@ -463,7 +462,8 @@ void JPXStream::fillReadBuf() {
} while (readBufLen < 8);
}
-GString *JPXStream::getPSFilter(int psLevel, const char *indent) {
+GString *JPXStream::getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream) {
return NULL;
}
@@ -960,10 +960,6 @@ JPXDecodeResult JPXStream::readCodestream(Guint len) {
img.ySizeR = jpxCeilDivPow2(img.ySize, reduction);
img.xOffsetR = jpxCeilDivPow2(img.xOffset, reduction);
img.yOffsetR = jpxCeilDivPow2(img.yOffset, reduction);
- img.xTileSizeR = jpxCeilDivPow2(img.xTileSize, reduction);
- img.yTileSizeR = jpxCeilDivPow2(img.yTileSize, reduction);
- img.xTileOffsetR = jpxCeilDivPow2(img.xTileOffset, reduction);
- img.yTileOffsetR = jpxCeilDivPow2(img.yTileOffset, reduction);
img.nXTiles = (img.xSize - img.xTileOffset + img.xTileSize - 1)
/ img.xTileSize;
img.nYTiles = (img.ySize - img.yTileOffset + img.yTileSize - 1)
@@ -1449,8 +1445,7 @@ JPXDecodeResult JPXStream::readCodestream(Guint len) {
ok = gTrue;
while (1) {
if (!readTilePart()) {
- ok = gFalse;
- break;
+ return jpxDecodeFatalError;
}
if (!readMarkerHdr(&segType, &segLen)) {
error(errSyntaxError, getPos(), "Error in JPX codestream");
@@ -1913,6 +1908,7 @@ GBool JPXStream::readTilePart() {
tile->res = 0;
tile->precinct = 0;
tile->layer = 0;
+ tile->done = gFalse;
tile->maxNDecompLevels = 0;
for (comp = 0; comp < img.nComps; ++comp) {
tileComp = &tile->tileComps[comp];
@@ -1925,8 +1921,15 @@ GBool JPXStream::readTilePart() {
tileComp->y1 = jpxCeilDiv(tile->y1, tileComp->vSep);
tileComp->cbW = 1 << tileComp->codeBlockW;
tileComp->cbH = 1 << tileComp->codeBlockH;
- tileComp->w = jpxCeilDivPow2(tileComp->x1 - tileComp->x0, reduction);
- tileComp->h = jpxCeilDivPow2(tileComp->y1 - tileComp->y0, reduction);
+ tileComp->w = jpxCeilDivPow2(tileComp->x1, reduction)
+ - jpxCeilDivPow2(tileComp->x0, reduction);
+ tileComp->h = jpxCeilDivPow2(tileComp->y1, reduction)
+ - jpxCeilDivPow2(tileComp->y0, reduction);
+ if (tileComp->w == 0 || tileComp->h == 0) {
+ error(errSyntaxError, getPos(),
+ "Invalid tile size or sample separation in JPX stream");
+ return gFalse;
+ }
tileComp->data = (int *)gmallocn(tileComp->w * tileComp->h, sizeof(int));
if (tileComp->x1 - tileComp->x0 > tileComp->y1 - tileComp->y0) {
n = tileComp->x1 - tileComp->x0;
@@ -1942,13 +1945,20 @@ GBool JPXStream::readTilePart() {
resLevel->y0 = jpxCeilDivPow2(tileComp->y0, k);
resLevel->x1 = jpxCeilDivPow2(tileComp->x1, k);
resLevel->y1 = jpxCeilDivPow2(tileComp->y1, k);
+ // the JPEG 2000 spec says that packets for empty res levels
+ // should all be present in the codestream (B.6, B.9, B.10),
+ // but it appears that encoders drop packets if the res level
+ // AND the subbands are all completely empty
+ resLevel->empty = resLevel->x0 == resLevel->x1 ||
+ resLevel->y0 == resLevel->y1;
if (r == 0) {
resLevel->bx0[0] = resLevel->x0;
resLevel->by0[0] = resLevel->y0;
resLevel->bx1[0] = resLevel->x1;
resLevel->by1[0] = resLevel->y1;
- resLevel->empty = resLevel->bx0[0] == resLevel->bx1[0] ||
- resLevel->by0[0] == resLevel->by1[0];
+ resLevel->empty = resLevel->empty &&
+ (resLevel->bx0[0] == resLevel->bx1[0] ||
+ resLevel->by0[0] == resLevel->by1[0]);
} else {
resLevel->bx0[0] = jpxCeilDivPow2(tileComp->x0 - (1 << (k-1)), k);
resLevel->by0[0] = resLevel->y0;
@@ -1962,7 +1972,8 @@ GBool JPXStream::readTilePart() {
resLevel->by0[2] = jpxCeilDivPow2(tileComp->y0 - (1 << (k-1)), k);
resLevel->bx1[2] = jpxCeilDivPow2(tileComp->x1 - (1 << (k-1)), k);
resLevel->by1[2] = jpxCeilDivPow2(tileComp->y1 - (1 << (k-1)), k);
- resLevel->empty = (resLevel->bx0[0] == resLevel->bx1[0] ||
+ resLevel->empty = resLevel->empty &&
+ (resLevel->bx0[0] == resLevel->bx1[0] ||
resLevel->by0[0] == resLevel->by1[0]) &&
(resLevel->bx0[1] == resLevel->bx1[1] ||
resLevel->by0[1] == resLevel->by1[1]) &&
@@ -2117,6 +2128,12 @@ 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 (tilePartToEOC) {
@@ -2373,6 +2390,7 @@ GBool JPXStream::readTilePartData(Guint tileIdx,
tile->res = 0;
if (++tile->layer == tile->nLayers) {
tile->layer = 0;
+ tile->done = gTrue;
}
}
}
@@ -2385,6 +2403,7 @@ GBool JPXStream::readTilePartData(Guint tileIdx,
tile->layer = 0;
if (++tile->res == tile->maxNDecompLevels + 1) {
tile->res = 0;
+ tile->done = gTrue;
}
}
}
@@ -2398,6 +2417,7 @@ GBool JPXStream::readTilePartData(Guint tileIdx,
tile->comp = 0;
if (++tile->res == tile->maxNDecompLevels + 1) {
tile->res = 0;
+ tile->done = gTrue;
}
}
}
@@ -2411,6 +2431,7 @@ GBool JPXStream::readTilePartData(Guint tileIdx,
tile->res = 0;
if (++tile->comp == img.nComps) {
tile->comp = 0;
+ tile->done = gTrue;
}
}
}
@@ -2424,6 +2445,7 @@ GBool JPXStream::readTilePartData(Guint tileIdx,
tile->res = 0;
if (++tile->comp == img.nComps) {
tile->comp = 0;
+ tile->done = gTrue;
}
}
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
index f1a66f5310d..bc5eac4f5ee 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
@@ -230,10 +230,11 @@ struct JPXTile {
// in any component in this tile
//----- progression order loop counters
- Guint comp; // component
- Guint res; // resolution level
- Guint precinct; // precinct
- Guint layer; // layer
+ Guint comp; // component
+ Guint res; // resolution level
+ Guint precinct; // precinct
+ Guint layer; // layer
+ GBool done; // set when this tile is done
//----- tile part info
Guint nextTilePart; // next expected tile-part
@@ -253,9 +254,6 @@ struct JPXImage {
yTileOffset;
Guint xSizeR, ySizeR; // size of reference grid >> reduction
Guint xOffsetR, yOffsetR; // image offset >> reduction
- Guint xTileSizeR, yTileSizeR; // size of tiles >> reduction
- Guint xTileOffsetR, // offset of first tile >> reduction
- yTileOffsetR;
Guint nComps; // number of components
//----- computed
@@ -287,7 +285,8 @@ public:
virtual void close();
virtual int getChar();
virtual int lookChar();
- virtual GString *getPSFilter(int psLevel, const char *indent);
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
virtual void getImageParams(int *bitsPerComponent,
StreamColorSpaceMode *csMode);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc
index 05e9df9f24c..6ff75b0b621 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc
@@ -112,7 +112,7 @@ int Lexer::lookChar() {
Object *Lexer::getObj(Object *obj) {
char *p;
int c, c2;
- GBool comment, neg, doubleMinus, done;
+ GBool comment, neg, doubleMinus, done, invalid;
int numParen;
int xi;
double xf, scale;
@@ -343,6 +343,7 @@ Object *Lexer::getObj(Object *obj) {
p = tokBuf;
n = 0;
s = NULL;
+ invalid = gFalse;
while ((c = lookChar()) != EOF && !specialChars[c]) {
getChar();
if (c == '#') {
@@ -370,6 +371,9 @@ Object *Lexer::getObj(Object *obj) {
goto notEscChar;
}
getChar();
+ if (c == 0) {
+ invalid = gTrue;
+ }
}
notEscChar:
// the PDF spec claims that names are limited to 127 chars, but
@@ -385,7 +389,13 @@ Object *Lexer::getObj(Object *obj) {
s->append((char)c);
}
}
- if (n < tokBufSize) {
+ if (invalid) {
+ error(errSyntaxError, getPos(), "Null character in name");
+ obj->initError();
+ if (s) {
+ delete s;
+ }
+ } else if (n < tokBufSize) {
*p = '\0';
obj->initName(tokBuf);
} else {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
index 70919f48947..09b5b99759a 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
@@ -39,7 +39,7 @@
PDFCore::PDFCore(SplashColorMode colorMode, int bitmapRowPad,
GBool reverseVideo, SplashColorPtr paperColor) {
- GString *initialZoom;
+ GString *initialZoom, *initialDisplayMode;
int z, i;
doc = NULL;
@@ -81,6 +81,19 @@ PDFCore::PDFCore(SplashColorMode colorMode, int bitmapRowPad,
state->setZoom(z);
}
delete initialZoom;
+ initialDisplayMode = globalParams->getInitialDisplayMode();
+ if (!initialDisplayMode->cmp("single")) {
+ state->setDisplayMode(displaySingle);
+ } else if (!initialDisplayMode->cmp("sideBySideSingle")) {
+ state->setDisplayMode(displaySideBySideSingle);
+ } else if (!initialDisplayMode->cmp("sideBySideContinuous")) {
+ state->setDisplayMode(displaySideBySideContinuous);
+ } else if (!initialDisplayMode->cmp("horizontalContinuous")) {
+ state->setDisplayMode(displayHorizontalContinuous);
+ } else {
+ state->setDisplayMode(displayContinuous);
+ }
+ delete initialDisplayMode;
selectMode = selectModeBlock;
selectPage = 0;
@@ -615,8 +628,8 @@ void PDFCore::scrollRight(int nCols) {
scrollTo(state->getScrollX() + nCols, state->getScrollY());
}
-void PDFCore::scrollUp(int nLines) {
- scrollTo(state->getScrollX(), state->getScrollY() - nLines);
+void PDFCore::scrollUp(int nLines, GBool snapToPage) {
+ scrollTo(state->getScrollX(), state->getScrollY() - nLines, snapToPage);
}
void PDFCore::scrollUpPrevPage(int nLines) {
@@ -624,12 +637,12 @@ void PDFCore::scrollUpPrevPage(int nLines) {
state->getScrollY() == 0) {
gotoPrevPage(1, gFalse, gTrue);
} else {
- scrollUp(nLines);
+ scrollUp(nLines, gTrue);
}
}
-void PDFCore::scrollDown(int nLines) {
- scrollTo(state->getScrollX(), state->getScrollY() + nLines);
+void PDFCore::scrollDown(int nLines, GBool snapToPage) {
+ scrollTo(state->getScrollX(), state->getScrollY() + nLines, snapToPage);
}
void PDFCore::scrollDownNextPage(int nLines) {
@@ -643,7 +656,7 @@ void PDFCore::scrollDownNextPage(int nLines) {
scrollDown(nLines);
}
} else {
- scrollDown(nLines);
+ scrollDown(nLines, gTrue);
}
}
@@ -655,9 +668,35 @@ void PDFCore::scrollPageDown() {
scrollDownNextPage(state->getWinH());
}
-void PDFCore::scrollTo(int x, int y) {
+void PDFCore::scrollTo(int x, int y, GBool snapToPage) {
+ int next, topPage, topPageY, sy, dy;
+
startUpdate();
state->setScrollPosition(state->getScrollPage(), x, y);
+
+ if (snapToPage) {
+ if (state->getDisplayMode() == displayContinuous ||
+ state->getDisplayMode() == displaySideBySideContinuous) {
+ next = state->getDisplayMode() == displaySideBySideContinuous ? 2 : 1;
+ topPage = tileMap->getFirstPage();
+ topPageY = tileMap->getPageTopY(topPage);
+ sy = state->getScrollY();
+ dy = sy - topPageY;
+ // note: dy can be negative here if the inter-page gap is at the
+ // top of the window
+ if (-16 < dy && dy < 16) {
+ state->setScrollPosition(state->getScrollPage(), x, topPageY);
+ } else if (topPage + next <= doc->getNumPages()) {
+ topPage += next;
+ topPageY = tileMap->getPageTopY(topPage);
+ dy = sy - topPageY;
+ if (-16 < dy && dy < 0) {
+ state->setScrollPosition(state->getScrollPage(), x, topPageY);
+ }
+ }
+ }
+ }
+
finishUpdate(gTrue, gTrue);
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h
index 0fa089ff949..510c01a1a76 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h
@@ -135,13 +135,13 @@ public:
virtual GBool goBackward();
virtual void scrollLeft(int nCols = 16);
virtual void scrollRight(int nCols = 16);
- virtual void scrollUp(int nLines = 16);
+ virtual void scrollUp(int nLines = 16, GBool snapToPage = gFalse);
virtual void scrollUpPrevPage(int nLines = 16);
- virtual void scrollDown(int nLines = 16);
+ virtual void scrollDown(int nLines = 16, GBool snapToPage = gFalse);
virtual void scrollDownNextPage(int nLines = 16);
virtual void scrollPageUp();
virtual void scrollPageDown();
- virtual void scrollTo(int x, int y);
+ virtual void scrollTo(int x, int y, GBool snapToPage = gFalse);
virtual void scrollToLeftEdge();
virtual void scrollToRightEdge();
virtual void scrollToTopEdge();
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
index 8bc14eb47ad..a130b164f91 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
@@ -46,6 +46,15 @@
#define headerSearchSize 1024 // read this many bytes at beginning of
// file to look for '%PDF'
+// Avoid sharing files with child processes on Windows, where sharing
+// can cause problems.
+#ifdef _WIN32
+# define fopenReadMode "rbN"
+# define wfopenReadMode L"rbN"
+#else
+# define fopenReadMode "rb"
+#endif
+
//------------------------------------------------------------------------
// PDFDoc
//------------------------------------------------------------------------
@@ -75,18 +84,18 @@ PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
// try to open file
fileName2 = NULL;
#ifdef VMS
- if (!(file = fopen(fileName1->getCString(), "rb", "ctx=stm"))) {
+ if (!(file = fopen(fileName1->getCString(), fopenReadMode, "ctx=stm"))) {
error(errIO, -1, "Couldn't open file '{0:t}'", fileName1);
errCode = errOpenFile;
return;
}
#else
- if (!(file = fopen(fileName1->getCString(), "rb"))) {
+ if (!(file = fopen(fileName1->getCString(), fopenReadMode))) {
fileName2 = fileName->copy();
fileName2->lowerCase();
- if (!(file = fopen(fileName2->getCString(), "rb"))) {
+ if (!(file = fopen(fileName2->getCString(), fopenReadMode))) {
fileName2->upperCase();
- if (!(file = fopen(fileName2->getCString(), "rb"))) {
+ if (!(file = fopen(fileName2->getCString(), fopenReadMode))) {
error(errIO, -1, "Couldn't open file '{0:t}'", fileName);
delete fileName2;
errCode = errOpenFile;
@@ -127,9 +136,9 @@ PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GString *ownerPassword,
version.dwOSVersionInfoSize = sizeof(version);
GetVersionEx(&version);
if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- file = _wfopen(fileNameU, L"rb");
+ file = _wfopen(fileNameU, wfopenReadMode);
} else {
- file = fopen(fileName->getCString(), "rb");
+ file = fopen(fileName->getCString(), fopenReadMode);
}
if (!file) {
error(errIO, -1, "Couldn't open file '{0:t}'", fileName);
@@ -181,18 +190,17 @@ PDFDoc::PDFDoc(char *fileNameA, GString *ownerPassword,
version.dwOSVersionInfoSize = sizeof(version);
GetVersionEx(&version);
if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- file = _wfopen(fileNameU, L"rb");
+ file = _wfopen(fileNameU, wfopenReadMode);
} else {
#endif /* 0 */
- file = fopen(fileName->getCString(), "rb");
+ file = fopen(fileName->getCString(), fopenReadMode);
#if 0
}
#endif /* 0 */
-
#elif defined(VMS)
- file = fopen(fileName->getCString(), "rb", "ctx=stm");
+ file = fopen(fileName->getCString(), fopenReadMode, "ctx=stm");
#else
- file = fopen(fileName->getCString(), "rb");
+ file = fopen(fileName->getCString(), fopenReadMode);
#endif
if (!file) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDocEncoding.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDocEncoding.cc
index c4eef7c24b8..8258395b543 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDocEncoding.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDocEncoding.cc
@@ -6,6 +6,7 @@
//
//========================================================================
+#include <aconf.h>
#include "gmempp.h"
#include "PDFDocEncoding.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
index 15a2a233990..f39a72e9015 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
@@ -77,6 +77,7 @@ static const char *prolog[] = {
" put",
" } for",
"~123ngs",
+ "/bdef { bind def } bind def",
"/pdfSetup {",
" /pdfDuplex exch def",
" /setpagedevice where {",
@@ -393,9 +394,9 @@ static const char *prolog[] = {
"/f { fCol fill } def",
"/f* { fCol eofill } def",
"% clipping operators",
- "/W { clip newpath } def",
- "/W* { eoclip newpath } def",
- "/Ws { strokepath clip newpath } def",
+ "/W { clip newpath } bdef",
+ "/W* { eoclip newpath } bdef",
+ "/Ws { strokepath clip newpath } bdef",
"% text state operators",
"/Tc { /pdfCharSpacing exch def } def",
"/Tf { dup /pdfFontSize exch def",
@@ -985,7 +986,9 @@ public:
{ return (bufIdx >= bufSize && !fillBuf()) ? EOF : buf[bufIdx++]; }
virtual int lookChar()
{ return (bufIdx >= bufSize && !fillBuf()) ? EOF : buf[bufIdx]; }
- virtual GString *getPSFilter(int psLevel, const char *indent) { return NULL; }
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream)
+ { return NULL; }
virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
virtual GBool isEncoder() { return gTrue; }
@@ -1084,7 +1087,9 @@ public:
{ return (bufIdx >= width && !fillBuf()) ? EOF : buf[bufIdx++]; }
virtual int lookChar()
{ return (bufIdx >= width && !fillBuf()) ? EOF : buf[bufIdx]; }
- virtual GString *getPSFilter(int psLevel, const char *indent) { return NULL; }
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream)
+ { return NULL; }
virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
virtual GBool isEncoder() { return gTrue; }
@@ -1167,7 +1172,9 @@ public:
{ return (bufIdx >= bufSize && !fillBuf()) ? EOF : buf[bufIdx++]; }
virtual int lookChar()
{ return (bufIdx >= bufSize && !fillBuf()) ? EOF : buf[bufIdx]; }
- virtual GString *getPSFilter(int psLevel, const char *indent) { return NULL; }
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream)
+ { return NULL; }
virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
virtual GBool isEncoder() { return gTrue; }
@@ -3841,7 +3848,7 @@ void PSOutputDev::setupImage(Ref id, Stream *str, GBool mask,
useLZW = useRLE = gFalse;
useCompressed = gFalse;
} else {
- s = str->getPSFilter(level < psLevel3 ? 2 : 3, "");
+ s = str->getPSFilter(level < psLevel3 ? 2 : 3, "", gTrue);
if (s) {
useLZW = useRLE = gFalse;
useCompressed = gTrue;
@@ -4191,7 +4198,13 @@ GBool PSOutputDev::checkPageSlice(Page *page, double hDPI, double vDPI,
}
sliceX = sliceY = 0;
sliceW = (int)((box.x2 - box.x1) * hDPI2 / 72.0);
+ if (sliceW == 0) {
+ sliceW = 1;
+ }
sliceH = (int)((box.y2 - box.y1) * vDPI2 / 72.0);
+ if (sliceH == 0) {
+ sliceH = 1;
+ }
}
nStripes = (int)ceil(((double)sliceW * (double)sliceH) /
(double)globalParams->getPSRasterSliceSize());
@@ -5223,6 +5236,7 @@ void PSOutputDev::tilingPatternFillL2(GfxState *state, Gfx *gfx,
// set the pattern
if (paintType == 2) {
+ writePS("fCol\n");
writePS("currentcolor ");
}
writePSFmt("xpdfTile{0:d} setpattern\n", numTilingPatterns);
@@ -6315,7 +6329,7 @@ void PSOutputDev::doImageL2(Object *ref, GfxState *state,
useASCII = gFalse;
} else {
s = str->getPSFilter(level < psLevel2 ? 1 : level < psLevel3 ? 2 : 3,
- " ");
+ " ", !inlineImg);
if ((colorMap && (colorMap->getColorSpace()->getMode() == csDeviceN ||
level == psLevel2Gray || level == psLevel3Gray)) ||
inlineImg || !s) {
@@ -6790,7 +6804,7 @@ void PSOutputDev::doImageL3(Object *ref, GfxState *state,
maskUseCompressed = gFalse;
maskUseASCII = gFalse;
} else {
- s = maskStr->getPSFilter(3, " ");
+ s = maskStr->getPSFilter(3, " ", !inlineImg);
if (!s) {
if (globalParams->getPSLZW()) {
maskUseLZW = gTrue;
@@ -7018,7 +7032,7 @@ void PSOutputDev::doImageL3(Object *ref, GfxState *state,
useCompressed = gFalse;
useASCII = gFalse;
} else {
- s = str->getPSFilter(3, " ");
+ s = str->getPSFilter(3, " ", !inlineImg);
if ((colorMap && level == psLevel3Gray) || inlineImg || !s) {
if (globalParams->getPSLZW()) {
useLZW = gTrue;
@@ -7557,19 +7571,13 @@ GString *PSOutputDev::createDeviceNTintFunc(GfxDeviceNColorSpace *cs) {
}
obj1.free();
sepCSObj.arrayGet(3, &funcObj);
- if (!(func = Function::parse(&funcObj))) {
+ if (!(func = Function::parse(&funcObj, 1, 4))) {
funcObj.free();
sepCSObj.free();
colorants.free();
return NULL;
}
funcObj.free();
- if (func->getInputSize() != 1 || func->getOutputSize() != 4) {
- delete func;
- sepCSObj.free();
- colorants.free();
- return NULL;
- }
sepIn = 1;
func->transform(&sepIn, cmyk[i]);
delete func;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
index df2e2b289cc..187ef5657b5 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
@@ -28,6 +28,7 @@
#include "BuiltinFont.h"
#include "BuiltinFontTables.h"
#include "FoFiTrueType.h"
+#include "FoFiType1C.h"
#include "JPXStream.h"
#include "SplashBitmap.h"
#include "SplashGlyphBitmap.h"
@@ -498,6 +499,7 @@ public:
int cacheAssoc; // cache associativity (glyphs per set)
Guchar *cacheData; // glyph pixmap cache
T3FontCacheTag *cacheTags; // cache tags, i.e., char codes
+ GBool inUse; // set while this T3 font is in active use
};
T3FontCache::T3FontCache(Ref *fontIDA, double m11A, double m12A,
@@ -539,6 +541,7 @@ T3FontCache::T3FontCache(Ref *fontIDA, double m11A, double m12A,
for (i = 0; i < cacheSets * cacheAssoc; ++i) {
cacheTags[i].mru = (Gushort)(i & (cacheAssoc - 1));
}
+ inUse = gFalse;
}
T3FontCache::~T3FontCache() {
@@ -615,8 +618,8 @@ SplashOutputDev::SplashOutputDev(SplashColorMode colorModeA,
xref = NULL;
bitmap = new SplashBitmap(1, 1, bitmapRowPad, colorMode,
- colorMode != splashModeMono1, bitmapTopDown);
- splash = new Splash(bitmap, vectorAntialias, &screenParams);
+ colorMode != splashModeMono1, bitmapTopDown, NULL);
+ splash = new Splash(bitmap, vectorAntialias, NULL, &screenParams);
splash->setMinLineWidth(globalParams->getMinLineWidth());
splash->setStrokeAdjust(
mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
@@ -761,9 +764,10 @@ void SplashOutputDev::startPage(int pageNum, GfxState *state) {
bitmap = NULL;
}
bitmap = new SplashBitmap(w, h, bitmapRowPad, colorMode,
- colorMode != splashModeMono1, bitmapTopDown);
+ colorMode != splashModeMono1, bitmapTopDown,
+ NULL);
}
- splash = new Splash(bitmap, vectorAntialias, &screenParams);
+ splash = new Splash(bitmap, vectorAntialias, NULL, &screenParams);
splash->setMinLineWidth(globalParams->getMinLineWidth());
splash->setEnablePathSimplification(
globalParams->getEnablePathSimplification());
@@ -804,6 +808,7 @@ void SplashOutputDev::startPage(int pageNum, GfxState *state) {
splash->setStrokeAdjust(
mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
splash->clear(paperColor, 0);
+ reverseVideoInvertImages = globalParams->getReverseVideoInvertImages();
if (startPageCbk) {
(*startPageCbk)(startPageCbkData);
}
@@ -1149,6 +1154,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
SplashFontFile *fontFile;
int fontNum;
FoFiTrueType *ff;
+ FoFiType1C *ffT1C;
Ref embRef;
Object refObj, strObj;
#if LOAD_FONTS_FROM_MEM
@@ -1166,9 +1172,9 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
double fsx, fsy, w, fontScaleMin, fontScaleAvg, fontScale;
Gushort ww;
SplashCoord mat[4];
- char *name;
+ char *name, *start;
Unicode uBuf[8];
- int substIdx, n, code, cmap, cmapPlatform, cmapEncoding, i;
+ int substIdx, n, code, cmap, cmapPlatform, cmapEncoding, length, i;
needFontUpdate = gFalse;
font = NULL;
@@ -1306,6 +1312,17 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
}
break;
case fontType1C:
+#if LOAD_FONTS_FROM_MEM
+ if ((ffT1C = FoFiType1C::make(fontBuf->getCString(),
+ fontBuf->getLength()))) {
+#else
+ if ((ffT1C = FoFiType1C::load(fileName->getCString()))) {
+#endif
+ codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ffT1C);
+ delete ffT1C;
+ } else {
+ codeToGID = NULL;
+ }
if (!(fontFile = fontEngine->loadType1CFont(
id,
#if LOAD_FONTS_FROM_MEM
@@ -1314,6 +1331,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
fileName->getCString(),
fileName == tmpFileName,
#endif
+ codeToGID,
(const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
gfxFont->getName() ? gfxFont->getName()->getCString()
@@ -1323,6 +1341,21 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
}
break;
case fontType1COT:
+ codeToGID = NULL;
+#if LOAD_FONTS_FROM_MEM
+ if ((ff = FoFiTrueType::make(fontBuf->getCString(), fontBuf->getLength(),
+ fontNum, gTrue))) {
+#else
+ if ((ff = FoFiTrueType::load(fileName->getCString(),
+ fontNum, gTrue))) {
+#endif
+ if (ff->getCFFBlock(&start, &length) &&
+ (ffT1C = FoFiType1C::make(start, length))) {
+ codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ffT1C);
+ delete ffT1C;
+ }
+ delete ff;
+ }
if (!(fontFile = fontEngine->loadOpenTypeT1CFont(
id,
#if LOAD_FONTS_FROM_MEM
@@ -1331,6 +1364,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
fileName->getCString(),
fileName == tmpFileName,
#endif
+ codeToGID,
(const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
gfxFont->getName() ? gfxFont->getName()->getCString()
@@ -1559,6 +1593,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
break;
default:
// this shouldn't happen
+ delete fontLoc;
goto err2;
}
@@ -1593,8 +1628,8 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
(name[0] >= 'a' && name[0] <= 'z') ||
(name[0] >= '0' && name[0] <= '9'))) {
w = ((Gfx8BitFont *)gfxFont)->getWidth((Guchar)code);
- builtinFontSubst[substIdx]->widths->getWidth(name, &ww);
- if (w > 0.01 && ww > 10) {
+ if (builtinFontSubst[substIdx]->widths->getWidth(name, &ww) &&
+ w > 0.01 && ww > 10) {
w /= ww * 0.001;
if (w < fontScaleMin) {
fontScaleMin = w;
@@ -1780,7 +1815,10 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
// check for an excessively large tile size
tileSize = tileW * tileH;
- if (tileSize > 1000000 || tileSize < 0) {
+ if (tileXMax - tileXMin + 0.5 > (double)INT_MAX ||
+ tileYMax - tileYMin + 0.5 > (double)INT_MAX ||
+ tileW > INT_MAX / tileH ||
+ tileSize > 1000000) {
mat1[0] = mat[0];
mat1[1] = mat[1];
mat1[2] = mat[2];
@@ -1932,8 +1970,10 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
origBitmap = bitmap;
origSplash = splash;
bitmap = tileBitmap = new SplashBitmap(tileW, tileH, bitmapRowPad,
- colorMode, gTrue, bitmapTopDown);
- splash = new Splash(bitmap, vectorAntialias, origSplash->getScreen());
+ colorMode, gTrue, bitmapTopDown,
+ origBitmap);
+ splash = new Splash(bitmap, vectorAntialias,
+ origSplash->getImageCache(), origSplash->getScreen());
for (i = 0; i < splashMaxColorComps; ++i) {
color[i] = 0;
}
@@ -2085,7 +2125,7 @@ GBool SplashOutputDev::axialShadedFill(GfxState *state,
bitmapWidth = ixMax - ixMin;
bitmapHeight = iyMax - iyMin;
tBitmap = new SplashBitmap(bitmapWidth, bitmapHeight, 1,
- srcMode, gTrue, gTrue);
+ srcMode, gTrue, gTrue, bitmap);
memset(tBitmap->getAlphaPtr(), 0, (size_t)bitmapWidth * bitmapHeight);
nComps = splashColorModeNComps[srcMode];
@@ -2403,7 +2443,7 @@ GBool SplashOutputDev::radialShadedFill(GfxState *state,
bitmapWidth = ixMax - ixMin;
bitmapHeight = iyMax - iyMin;
tBitmap = new SplashBitmap(bitmapWidth, bitmapHeight, 1,
- srcMode, gTrue, gTrue);
+ srcMode, gTrue, gTrue, bitmap);
memset(tBitmap->getAlphaPtr(), 0, tBitmap->getAlphaRowSize() * bitmapHeight);
nComps = splashColorModeNComps[srcMode];
@@ -2908,12 +2948,25 @@ GBool SplashOutputDev::beginType3Char(GfxState *state, double x, double y,
if (i >= nT3Fonts) {
// create new entry in the font cache
- if (nT3Fonts == splashOutT3FontCacheSize) {
- delete t3FontCache[nT3Fonts - 1];
+ if (nT3Fonts < splashOutT3FontCacheSize) {
+ for (j = nT3Fonts; j > 0; --j) {
+ t3FontCache[j] = t3FontCache[j - 1];
+ }
+ } else {
+ for (j = nT3Fonts - 1; j >= 0; --j) {
+ if (!t3FontCache[j]->inUse) {
+ break;
+ }
+ }
+ if (j < 0) {
+ error(errSyntaxError, -1, "Type 3 fonts nested too deeply");
+ return gTrue;
+ }
+ delete t3FontCache[j];
--nT3Fonts;
- }
- for (j = nT3Fonts; j > 0; --j) {
- t3FontCache[j] = t3FontCache[j - 1];
+ for (; j > 0; --j) {
+ t3FontCache[j] = t3FontCache[j - 1];
+ }
}
++nT3Fonts;
bbox = gfxFont->getFontBBox();
@@ -2985,6 +3038,8 @@ GBool SplashOutputDev::beginType3Char(GfxState *state, double x, double y,
}
}
+ t3Font->inUse = gTrue;
+
// push a new Type 3 glyph record
t3gs = new T3GlyphStack();
t3gs->next = t3GlyphStack;
@@ -3021,6 +3076,7 @@ void SplashOutputDev::endType3Char(GfxState *state) {
}
t3gs = t3GlyphStack;
t3GlyphStack = t3gs->next;
+ t3gs->cache->inUse = gFalse;
delete t3gs;
}
@@ -3131,16 +3187,19 @@ void SplashOutputDev::type3D1(GfxState *state, double wx, double wy,
if (colorMode == splashModeMono1) {
colorMode = splashModeMono1;
bitmap = new SplashBitmap(t3Font->glyphW, t3Font->glyphH, 1,
- splashModeMono1, gFalse);
- splash = new Splash(bitmap, gFalse, t3GlyphStack->origSplash->getScreen());
+ splashModeMono1, gFalse, gTrue, bitmap);
+ splash = new Splash(bitmap, gFalse,
+ t3GlyphStack->origSplash->getImageCache(),
+ t3GlyphStack->origSplash->getScreen());
color[0] = 0;
splash->clear(color);
color[0] = 0xff;
} else {
colorMode = splashModeMono8;
bitmap = new SplashBitmap(t3Font->glyphW, t3Font->glyphH, 1,
- splashModeMono8, gFalse);
+ splashModeMono8, gFalse, gTrue, bitmap);
splash = new Splash(bitmap, vectorAntialias,
+ t3GlyphStack->origSplash->getImageCache(),
t3GlyphStack->origSplash->getScreen());
color[0] = 0x00;
splash->clear(color);
@@ -3214,6 +3273,7 @@ void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
double *ctm;
SplashCoord mat[6];
SplashOutImageMaskData imgMaskData;
+ GString *imgTag;
if (state->getFillColorSpace()->isNonMarking()) {
return;
@@ -3239,8 +3299,11 @@ void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
imgMaskData.height = height;
imgMaskData.y = 0;
- splash->fillImageMask(&imageMaskSrc, &imgMaskData, width, height, mat,
+ imgTag = makeImageTag(ref);
+ splash->fillImageMask(imgTag,
+ &imageMaskSrc, &imgMaskData, width, height, mat,
t3GlyphStack != NULL, interpolate);
+
if (inlineImg) {
while (imgMaskData.y < height) {
imgMaskData.imgStr->getLine();
@@ -3248,6 +3311,7 @@ void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
}
}
+ delete imgTag;
delete imgMaskData.imgStr;
str->close();
}
@@ -3264,6 +3328,7 @@ void SplashOutputDev::setSoftMaskFromImageMask(GfxState *state,
SplashBitmap *maskBitmap;
Splash *maskSplash;
SplashColor maskColor;
+ GString *imgTag;
ctm = state->getCTM();
mat[0] = ctm[0];
@@ -3280,8 +3345,8 @@ void SplashOutputDev::setSoftMaskFromImageMask(GfxState *state,
imgMaskData.height = height;
imgMaskData.y = 0;
maskBitmap = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
- 1, splashModeMono8, gFalse);
- maskSplash = new Splash(maskBitmap, gTrue);
+ 1, splashModeMono8, gFalse, gTrue, bitmap);
+ maskSplash = new Splash(maskBitmap, gTrue, splash->getImageCache());
maskSplash->setStrokeAdjust(
mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
maskSplash->setEnablePathSimplification(
@@ -3289,8 +3354,10 @@ void SplashOutputDev::setSoftMaskFromImageMask(GfxState *state,
clearMaskRegion(state, maskSplash, 0, 0, 1, 1);
maskColor[0] = 0xff;
maskSplash->setFillPattern(new SplashSolidColor(maskColor));
- maskSplash->fillImageMask(&imageMaskSrc, &imgMaskData,
+ imgTag = makeImageTag(ref);
+ maskSplash->fillImageMask(imgTag, &imageMaskSrc, &imgMaskData,
width, height, mat, gFalse, interpolate);
+ delete imgTag;
delete imgMaskData.imgStr;
str->close();
delete maskSplash;
@@ -3304,6 +3371,7 @@ struct SplashOutImageData {
SplashColorPtr lookup;
int *maskColors;
SplashColorMode colorMode;
+ GBool invert;
int width, height, y;
};
@@ -3312,7 +3380,7 @@ GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr colorLine,
SplashOutImageData *imgData = (SplashOutImageData *)data;
Guchar *p;
SplashColorPtr q, col;
- int x;
+ int n, x;
if (imgData->y == imgData->height ||
!(p = imgData->imgStr->getLine())) {
@@ -3371,6 +3439,13 @@ GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr colorLine,
}
}
+ if (imgData->invert) {
+ n = imgData->width * splashColorModeNComps[imgData->colorMode];
+ for (x = 0, p = colorLine; x < n; ++x, ++p) {
+ *p ^= 0xff;
+ }
+ }
+
++imgData->y;
return gTrue;
}
@@ -3381,7 +3456,7 @@ GBool SplashOutputDev::alphaImageSrc(void *data, SplashColorPtr colorLine,
Guchar *p0, *p, *aq;
SplashColorPtr q, col;
Guchar alpha;
- int nComps, x, i;
+ int nComps, x, n, i;
if (imgData->y == imgData->height ||
!(p0 = imgData->imgStr->getLine())) {
@@ -3455,6 +3530,13 @@ GBool SplashOutputDev::alphaImageSrc(void *data, SplashColorPtr colorLine,
*aq++ = alpha;
}
+ if (imgData->invert) {
+ n = imgData->width * splashColorModeNComps[imgData->colorMode];
+ for (x = 0, p = colorLine; x < n; ++x, ++p) {
+ *p ^= 0xff;
+ }
+ }
+
++imgData->y;
return gTrue;
}
@@ -3470,6 +3552,7 @@ void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
SplashOutImageData imgData;
SplashColorMode srcMode;
SplashImageSource src;
+ GString *imgTag;
GfxGray gray;
GfxRGB rgb;
#if SPLASH_CMYK
@@ -3500,6 +3583,7 @@ void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
imgData.ri = state->getRenderingIntent();
imgData.maskColors = maskColors;
imgData.colorMode = colorMode;
+ imgData.invert = reverseVideo && reverseVideoInvertImages;
imgData.width = width;
imgData.height = height;
imgData.y = 0;
@@ -3559,7 +3643,9 @@ void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
srcMode = colorMode;
}
src = maskColors ? &alphaImageSrc : &imageSrc;
- splash->drawImage(src, &imgData, srcMode, maskColors ? gTrue : gFalse,
+ imgTag = makeImageTag(ref);
+ splash->drawImage(imgTag,
+ src, &imgData, srcMode, maskColors ? gTrue : gFalse,
width, height, mat, interpolate);
if (inlineImg) {
while (imgData.y < height) {
@@ -3568,6 +3654,7 @@ void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
}
}
+ delete imgTag;
gfree(imgData.lookup);
delete imgData.imgStr;
str->close();
@@ -3580,6 +3667,7 @@ struct SplashOutMaskedImageData {
SplashBitmap *mask;
SplashColorPtr lookup;
SplashColorMode colorMode;
+ GBool invert;
int width, height, y;
};
@@ -3591,7 +3679,7 @@ GBool SplashOutputDev::maskedImageSrc(void *data, SplashColorPtr colorLine,
static Guchar bitToByte[2] = {0x00, 0xff};
Guchar *maskPtr;
int maskShift;
- int x;
+ int n, x;
if (imgData->y == imgData->height ||
!(p = imgData->imgStr->getLine())) {
@@ -3672,6 +3760,13 @@ GBool SplashOutputDev::maskedImageSrc(void *data, SplashColorPtr colorLine,
}
}
+ if (imgData->invert) {
+ n = imgData->width * splashColorModeNComps[imgData->colorMode];
+ for (x = 0, p = colorLine; x < n; ++x, ++p) {
+ *p ^= 0xff;
+ }
+ }
+
++imgData->y;
return gTrue;
}
@@ -3692,6 +3787,7 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
SplashColorMode srcMode;
SplashBitmap *maskBitmap;
Splash *maskSplash;
+ GString *imgTag;
SplashColor maskColor;
GfxGray gray;
GfxRGB rgb;
@@ -3741,8 +3837,9 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
imgMaskData.width = maskWidth;
imgMaskData.height = maskHeight;
imgMaskData.y = 0;
- maskBitmap = new SplashBitmap(width, height, 1, splashModeMono1, gFalse);
- maskSplash = new Splash(maskBitmap, gFalse);
+ maskBitmap = new SplashBitmap(width, height, 1, splashModeMono1,
+ gFalse, gTrue, bitmap);
+ maskSplash = new Splash(maskBitmap, gFalse, splash->getImageCache());
maskSplash->setStrokeAdjust(
mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
maskSplash->setEnablePathSimplification(
@@ -3752,7 +3849,7 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
maskColor[0] = 0xff;
maskSplash->setFillPattern(new SplashSolidColor(maskColor));
// use "glyph mode" here to get the correct scaled size
- maskSplash->fillImageMask(&imageMaskSrc, &imgMaskData,
+ maskSplash->fillImageMask(NULL, &imageMaskSrc, &imgMaskData,
maskWidth, maskHeight, mat, gTrue, interpolate);
delete imgMaskData.imgStr;
maskStr->close();
@@ -3775,6 +3872,7 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
imgData.ri = state->getRenderingIntent();
imgData.mask = maskBitmap;
imgData.colorMode = colorMode;
+ imgData.invert = reverseVideo && reverseVideoInvertImages;
imgData.width = width;
imgData.height = height;
imgData.y = 0;
@@ -3833,9 +3931,12 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
} else {
srcMode = colorMode;
}
- splash->drawImage(&maskedImageSrc, &imgData, srcMode, gTrue,
+ imgTag = makeImageTag(ref);
+ splash->drawImage(imgTag,
+ &maskedImageSrc, &imgData, srcMode, gTrue,
width, height, mat, interpolate);
+ delete imgTag;
delete maskBitmap;
gfree(imgData.lookup);
delete imgData.imgStr;
@@ -3850,6 +3951,7 @@ struct SplashOutSoftMaskMatteImageData {
GfxRenderingIntent ri;
Guchar matte[gfxColorMaxComps];
SplashColorMode colorMode;
+ GBool invert;
int width, height, y;
};
@@ -3866,7 +3968,7 @@ GBool SplashOutputDev::softMaskMatteImageSrc(void *data,
GfxCMYK cmyk;
#endif
Guchar alpha;
- int nComps, x;
+ int nComps, n, x;
if (imgData->y == imgData->height ||
!(p = imgData->imgStr->getLine()) ||
@@ -3938,6 +4040,13 @@ GBool SplashOutputDev::softMaskMatteImageSrc(void *data,
*aq++ = alpha;
}
+ if (imgData->invert) {
+ n = imgData->width * splashColorModeNComps[imgData->colorMode];
+ for (x = 0, p = colorLine; x < n; ++x, ++p) {
+ *p ^= 0xff;
+ }
+ }
+
++imgData->y;
return gTrue;
}
@@ -3955,6 +4064,7 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
SplashOutImageData imgData;
SplashOutImageData imgMaskData;
SplashOutSoftMaskMatteImageData matteImgData;
+ GString *imgTag;
SplashColorMode srcMode;
SplashBitmap *maskBitmap;
Splash *maskSplash;
@@ -4044,11 +4154,14 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
n = 1 << 8;
}
matteImgData.colorMode = colorMode;
+ matteImgData.invert = reverseVideo && reverseVideoInvertImages;
matteImgData.width = width;
matteImgData.height = height;
matteImgData.y = 0;
- splash->drawImage(&softMaskMatteImageSrc, &matteImgData,
+ imgTag = makeImageTag(ref);
+ splash->drawImage(imgTag, &softMaskMatteImageSrc, &matteImgData,
srcMode, gTrue, width, height, mat, interpolate);
+ delete imgTag;
delete matteImgData.maskStr;
delete matteImgData.imgStr;
maskStr->close();
@@ -4069,6 +4182,7 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
imgMaskData.ri = state->getRenderingIntent();
imgMaskData.maskColors = NULL;
imgMaskData.colorMode = splashModeMono8;
+ imgMaskData.invert = gFalse;
imgMaskData.width = maskWidth;
imgMaskData.height = maskHeight;
imgMaskData.y = 0;
@@ -4080,14 +4194,16 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
imgMaskData.lookup[i] = colToByte(gray);
}
maskBitmap = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
- 1, splashModeMono8, gFalse);
- maskSplash = new Splash(maskBitmap, vectorAntialias);
+ 1, splashModeMono8, gFalse, gTrue, bitmap);
+ maskSplash = new Splash(maskBitmap, vectorAntialias,
+ splash->getImageCache());
maskSplash->setStrokeAdjust(
mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
maskSplash->setEnablePathSimplification(
globalParams->getEnablePathSimplification());
clearMaskRegion(state, maskSplash, 0, 0, 1, 1);
- maskSplash->drawImage(&imageSrc, &imgMaskData, splashModeMono8, gFalse,
+ maskSplash->drawImage(NULL,
+ &imageSrc, &imgMaskData, splashModeMono8, gFalse,
maskWidth, maskHeight, mat, interpolate);
delete imgMaskData.imgStr;
maskStr->close();
@@ -4105,6 +4221,7 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
imgData.ri = state->getRenderingIntent();
imgData.maskColors = NULL;
imgData.colorMode = colorMode;
+ imgData.invert = reverseVideo && reverseVideoInvertImages;
imgData.width = width;
imgData.height = height;
imgData.y = 0;
@@ -4156,10 +4273,13 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
}
}
- splash->drawImage(&imageSrc, &imgData, srcMode, gFalse, width, height, mat,
+ imgTag = makeImageTag(ref);
+ splash->drawImage(imgTag,
+ &imageSrc, &imgData, srcMode, gFalse, width, height, mat,
interpolate);
splash->setSoftMask(NULL);
+ delete imgTag;
gfree(imgData.lookup);
delete imgData.imgStr;
@@ -4168,12 +4288,21 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
}
}
+GString *SplashOutputDev::makeImageTag(Object *ref) {
+ if (!ref || !ref->isRef()) {
+ return NULL;
+ }
+ return GString::format("{0:d}_{1:d}", ref->getRefNum(), ref->getRefGen());
+}
+
void SplashOutputDev::reduceImageResolution(Stream *str, double *ctm,
int *width, int *height) {
double sw, sh;
int reduction;
if (str->getKind() == strJPX &&
+ *width >= 256 &&
+ *height >= 256 &&
*width * *height > 10000000) {
sw = (double)*width / (fabs(ctm[0]) + fabs(ctm[1]));
sh = (double)*height / (fabs(ctm[2]) + fabs(ctm[3]));
@@ -4396,8 +4525,9 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
// create the temporary bitmap
bitmap = new SplashBitmap(w, h, bitmapRowPad, colorMode, gTrue,
- bitmapTopDown);
+ bitmapTopDown, transpGroup->origBitmap);
splash = new Splash(bitmap, vectorAntialias,
+ transpGroup->origSplash->getImageCache(),
transpGroup->origSplash->getScreen());
splash->setMinLineWidth(globalParams->getMinLineWidth());
splash->setStrokeAdjust(
@@ -4415,11 +4545,12 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
}
if (!isolated &&
transpGroup->origBitmap->getAlphaPtr() &&
- transpGroup->origSplash->getInNonIsolatedGroup()) {
+ transpGroup->origSplash->getInNonIsolatedGroup() &&
+ colorMode != splashModeMono1) {
// when drawing a non-isolated group into another non-isolated group,
// compute a backdrop bitmap with corrected alpha values
backdropBitmap = new SplashBitmap(w, h, bitmapRowPad, colorMode, gTrue,
- bitmapTopDown);
+ bitmapTopDown, transpGroup->origBitmap);
transpGroup->origSplash->blitCorrectedAlpha(backdropBitmap,
tx, ty, 0, 0, w, h);
transpGroup->backdropBitmap = backdropBitmap;
@@ -4521,6 +4652,7 @@ void SplashOutputDev::setSoftMask(GfxState *state, double *bbox,
//~ space is given
if (transpGroupStack->blendingColorSpace) {
tSplash = new Splash(tBitmap, vectorAntialias,
+ transpGroupStack->origSplash->getImageCache(),
transpGroupStack->origSplash->getScreen());
tSplash->setStrokeAdjust(
mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
@@ -4578,7 +4710,7 @@ void SplashOutputDev::setSoftMask(GfxState *state, double *bbox,
}
softMask = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
- 1, splashModeMono8, gFalse);
+ 1, splashModeMono8, gFalse, gTrue, bitmap);
memset(softMask->getDataPtr(), (int)(backdrop2 * 255.0 + 0.5),
softMask->getRowSize() * softMask->getHeight());
if (tx < softMask->getWidth() && ty < softMask->getHeight()) {
@@ -4660,7 +4792,7 @@ SplashBitmap *SplashOutputDev::takeBitmap() {
ret = bitmap;
bitmap = new SplashBitmap(1, 1, bitmapRowPad, colorMode,
- colorMode != splashModeMono1, bitmapTopDown);
+ colorMode != splashModeMono1, bitmapTopDown, NULL);
return ret;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
index 12e8831a905..2215f883d32 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
@@ -279,6 +279,7 @@ private:
static GBool softMaskMatteImageSrc(void *data,
SplashColorPtr colorLine,
Guchar *alphaLine);
+ GString *makeImageTag(Object *ref);
void reduceImageResolution(Stream *str, double *mat,
int *width, int *height);
void clearMaskRegion(GfxState *state,
@@ -295,6 +296,7 @@ private:
GBool allowAntialias;
GBool vectorAntialias;
GBool reverseVideo; // reverse video mode
+ GBool reverseVideoInvertImages;
SplashColor paperColor; // paper color
SplashScreenParams screenParams;
GBool skipHorizText;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
index 4e9a2dc2ff4..a7c13c9eab3 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
@@ -121,7 +121,8 @@ Guint Stream::discardChars(Guint n) {
return count;
}
-GString *Stream::getPSFilter(int psLevel, const char *indent) {
+GString *Stream::getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream) {
return new GString();
}
@@ -132,15 +133,15 @@ Stream *Stream::addFilters(Object *dict, int recursion) {
int i;
str = this;
- dict->dictLookup("Filter", &obj);
+ dict->dictLookup("Filter", &obj, recursion);
if (obj.isNull()) {
obj.free();
- dict->dictLookup("F", &obj);
+ dict->dictLookup("F", &obj, recursion);
}
- dict->dictLookup("DecodeParms", &params);
+ dict->dictLookup("DecodeParms", &params, recursion);
if (params.isNull()) {
params.free();
- dict->dictLookup("DP", &params);
+ dict->dictLookup("DP", &params, recursion);
}
if (obj.isName()) {
str = makeFilter(obj.getName(), str, &params, recursion);
@@ -1096,13 +1097,14 @@ int ASCIIHexStream::lookChar() {
return buf;
}
-GString *ASCIIHexStream::getPSFilter(int psLevel, const char *indent) {
+GString *ASCIIHexStream::getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream) {
GString *s;
if (psLevel < 2) {
return NULL;
}
- if (!(s = str->getPSFilter(psLevel, indent))) {
+ if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
return NULL;
}
s->append(indent)->append("/ASCIIHexDecode filter\n");
@@ -1181,13 +1183,14 @@ int ASCII85Stream::lookChar() {
return b[index];
}
-GString *ASCII85Stream::getPSFilter(int psLevel, const char *indent) {
+GString *ASCII85Stream::getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream) {
GString *s;
if (psLevel < 2) {
return NULL;
}
- if (!(s = str->getPSFilter(psLevel, indent))) {
+ if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
return NULL;
}
s->append(indent)->append("/ASCII85Decode filter\n");
@@ -1408,13 +1411,14 @@ int LZWStream::getCode() {
return code;
}
-GString *LZWStream::getPSFilter(int psLevel, const char *indent) {
+GString *LZWStream::getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream) {
GString *s;
if (psLevel < 2 || pred) {
return NULL;
}
- if (!(s = str->getPSFilter(psLevel, indent))) {
+ if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
return NULL;
}
s->append(indent)->append("<< ");
@@ -1474,13 +1478,14 @@ int RunLengthStream::getBlock(char *blk, int size) {
return n;
}
-GString *RunLengthStream::getPSFilter(int psLevel, const char *indent) {
+GString *RunLengthStream::getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream) {
GString *s;
if (psLevel < 2) {
return NULL;
}
- if (!(s = str->getPSFilter(psLevel, indent))) {
+ if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
return NULL;
}
s->append(indent)->append("/RunLengthDecode filter\n");
@@ -2012,7 +2017,7 @@ GBool CCITTFaxStream::readRow() {
lookBits(1);
eatBits(1);
}
- if (encoding >= 0) {
+ if (encoding > 0) {
for (i = 0; i < 4; ++i) {
code1 = lookBits(12);
if (code1 != 0x001) {
@@ -2260,14 +2265,15 @@ short CCITTFaxStream::lookBits(int n) {
return (short)((inputBuf >> (inputBits - n)) & (0xffffffff >> (32 - n)));
}
-GString *CCITTFaxStream::getPSFilter(int psLevel, const char *indent) {
+GString *CCITTFaxStream::getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream) {
GString *s;
char s1[50];
if (psLevel < 2) {
return NULL;
}
- if (!(s = str->getPSFilter(psLevel, indent))) {
+ if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
return NULL;
}
s->append(indent)->append("<< ");
@@ -2384,6 +2390,11 @@ void DCTStream::reset() {
jpeg_start_decompress(&decomp);
}
+GBool DCTStream::checkSequentialInterleaved() {
+ //~ this is unimplemented
+ return gTrue;
+}
+
void DCTStream::close() {
// we don't call jpeg_finish_decompress() here because it will report
// an error if the full image wasn't read
@@ -2754,6 +2765,28 @@ void DCTStream::reset() {
}
}
+GBool DCTStream::checkSequentialInterleaved() {
+ GBool headerOk;
+
+ str->reset();
+
+ progressive = interleaved = gFalse;
+ width = height = 0;
+ numComps = 0;
+ numQuantTables = 0;
+ numDCHuffTables = 0;
+ numACHuffTables = 0;
+ gotJFIFMarker = gFalse;
+ gotAdobeMarker = gFalse;
+ restartInterval = 0;
+
+ headerOk = readHeader(gTrue);
+
+ FilterStream::close();
+
+ return headerOk && !progressive && interleaved;
+}
+
void DCTStream::close() {
int i;
@@ -3755,7 +3788,7 @@ int DCTStream::readBit() {
GBool DCTStream::readHeader(GBool frame) {
GBool doScan;
- int n;
+ int n, i;
int c = 0;
// read headers
@@ -3850,6 +3883,13 @@ GBool DCTStream::readHeader(GBool frame) {
}
}
+ for (i = 0; i < numComps; ++i) {
+ if (compInfo[i].quantTable >= numQuantTables) {
+ error(errSyntaxError, getPos(), "Invalid DCT quant table selector");
+ return gFalse;
+ }
+ }
+
return gTrue;
}
@@ -3878,8 +3918,14 @@ GBool DCTStream::readBaselineSOF() {
compInfo[i].hSample = (c >> 4) & 0x0f;
compInfo[i].vSample = c & 0x0f;
compInfo[i].quantTable = str->getChar();
- if (compInfo[i].hSample < 1 || compInfo[i].hSample > 4 ||
- compInfo[i].vSample < 1 || compInfo[i].vSample > 4) {
+ // a sampling factor of 3 is allowed by the spec, but requires
+ // messy upsampling, and appears not to be used in practice
+ if (!(compInfo[i].hSample == 1 ||
+ compInfo[i].hSample == 2 ||
+ compInfo[i].hSample == 4) ||
+ !(compInfo[i].vSample == 1 ||
+ compInfo[i].vSample == 2 ||
+ compInfo[i].vSample == 4)) {
error(errSyntaxError, getPos(), "Bad DCT sampling factor");
return gFalse;
}
@@ -3917,8 +3963,14 @@ GBool DCTStream::readProgressiveSOF() {
compInfo[i].hSample = (c >> 4) & 0x0f;
compInfo[i].vSample = c & 0x0f;
compInfo[i].quantTable = str->getChar();
- if (compInfo[i].hSample < 1 || compInfo[i].hSample > 4 ||
- compInfo[i].vSample < 1 || compInfo[i].vSample > 4) {
+ // a sampling factor of 3 is allowed by the spec, but requires
+ // messy upsampling, and appears not to be used in practice
+ if (!(compInfo[i].hSample == 1 ||
+ compInfo[i].hSample == 2 ||
+ compInfo[i].hSample == 4) ||
+ !(compInfo[i].vSample == 1 ||
+ compInfo[i].vSample == 2 ||
+ compInfo[i].vSample == 4)) {
error(errSyntaxError, getPos(), "Bad DCT sampling factor");
return gFalse;
}
@@ -4182,13 +4234,19 @@ int DCTStream::read16() {
#endif // HAVE_JPEGLIB
-GString *DCTStream::getPSFilter(int psLevel, const char *indent) {
+GString *DCTStream::getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream) {
GString *s;
if (psLevel < 2) {
return NULL;
}
- if (!(s = str->getPSFilter(psLevel, indent))) {
+ if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
+ return NULL;
+ }
+ if (okToReadStream && !checkSequentialInterleaved()) {
+ // PostScript does not allow progressive or interleaved JPEG
+ delete s;
return NULL;
}
s->append(indent)->append("<< >> /DCTDecode filter\n");
@@ -4982,13 +5040,14 @@ int FlateStream::getBlock(char *blk, int size) {
return n;
}
-GString *FlateStream::getPSFilter(int psLevel, const char *indent) {
+GString *FlateStream::getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream) {
GString *s;
if (psLevel < 3 || pred) {
return NULL;
}
- if (!(s = str->getPSFilter(psLevel, indent))) {
+ if (!(s = str->getPSFilter(psLevel, indent, okToReadStream))) {
return NULL;
}
s->append(indent)->append("<< >> /FlateDecode filter\n");
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
index c25d46b2cd7..38a8dd3497c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
@@ -117,7 +117,8 @@ public:
virtual void setPos(GFileOffset pos, int dir = 0) = 0;
// Get PostScript command for the filter(s).
- virtual GString *getPSFilter(int psLevel, const char *indent);
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream);
// Does this stream type potentially contain non-printable chars?
virtual GBool isBinary(GBool last = gTrue) = 0;
@@ -422,7 +423,8 @@ public:
virtual int getChar()
{ int c = lookChar(); buf = EOF; return c; }
virtual int lookChar();
- virtual GString *getPSFilter(int psLevel, const char *indent);
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
private:
@@ -446,7 +448,8 @@ public:
virtual int getChar()
{ int ch = lookChar(); ++index; return ch; }
virtual int lookChar();
- virtual GString *getPSFilter(int psLevel, const char *indent);
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
private:
@@ -474,7 +477,8 @@ public:
virtual int lookChar();
virtual int getRawChar();
virtual int getBlock(char *blk, int size);
- virtual GString *getPSFilter(int psLevel, const char *indent);
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
private:
@@ -520,7 +524,8 @@ public:
virtual int lookChar()
{ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
virtual int getBlock(char *blk, int size);
- virtual GString *getPSFilter(int psLevel, const char *indent);
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
private:
@@ -552,7 +557,8 @@ public:
virtual int getChar();
virtual int lookChar();
virtual int getBlock(char *blk, int size);
- virtual GString *getPSFilter(int psLevel, const char *indent);
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
private:
@@ -650,12 +656,15 @@ public:
virtual int getChar();
virtual int lookChar();
virtual int getBlock(char *blk, int size);
- virtual GString *getPSFilter(int psLevel, const char *indent);
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
Stream *getRawStream() { return str; }
private:
+ GBool checkSequentialInterleaved();
+
#if HAVE_JPEGLIB
int colorXform; // color transform: -1 = unspecified
@@ -785,7 +794,8 @@ public:
virtual int lookChar();
virtual int getRawChar();
virtual int getBlock(char *blk, int size);
- virtual GString *getPSFilter(int psLevel, const char *indent);
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream);
virtual GBool isBinary(GBool last = gTrue);
private:
@@ -840,7 +850,8 @@ public:
virtual int getChar() { return EOF; }
virtual int lookChar() { return EOF; }
virtual int getBlock(char *blk, int size) { return 0; }
- virtual GString *getPSFilter(int psLevel, const char *indent)
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream)
{ return NULL; }
virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
};
@@ -859,7 +870,8 @@ public:
virtual void reset();
virtual int getChar();
virtual int lookChar();
- virtual GString *getPSFilter(int psLevel, const char *indent)
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream)
{ return NULL; }
virtual GBool isBinary(GBool last = gTrue);
@@ -885,7 +897,8 @@ public:
virtual void reset();
virtual int getChar();
virtual int lookChar();
- virtual GString *getPSFilter(int psLevel, const char *indent)
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream)
{ return NULL; }
virtual GBool isBinary(GBool last = gTrue);
virtual GBool isEncoder() { return gTrue; }
@@ -912,7 +925,8 @@ public:
{ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
virtual int lookChar()
{ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
- virtual GString *getPSFilter(int psLevel, const char *indent)
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream)
{ return NULL; }
virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
virtual GBool isEncoder() { return gTrue; }
@@ -944,7 +958,8 @@ public:
{ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
virtual int lookChar()
{ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
- virtual GString *getPSFilter(int psLevel, const char *indent)
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream)
{ return NULL; }
virtual GBool isBinary(GBool last = gTrue) { return gFalse; }
virtual GBool isEncoder() { return gTrue; }
@@ -976,7 +991,8 @@ public:
{ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
virtual int lookChar()
{ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); }
- virtual GString *getPSFilter(int psLevel, const char *indent)
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream)
{ return NULL; }
virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
virtual GBool isEncoder() { return gTrue; }
@@ -1012,7 +1028,8 @@ public:
virtual void reset();
virtual int getChar();
virtual int lookChar();
- virtual GString *getPSFilter(int psLevel, const char *indent)
+ virtual GString *getPSFilter(int psLevel, const char *indent,
+ GBool okToReadStream)
{ return NULL; }
virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
virtual GBool isEncoder() { return gTrue; }
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
index 9c226af3f31..4f594384915 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
@@ -16,6 +16,7 @@
#include <stdlib.h>
#include <stddef.h>
#include <math.h>
+#include <limits.h>
#include <ctype.h>
#ifdef _WIN32
#include <fcntl.h> // for O_BINARY
@@ -111,7 +112,7 @@
// In simple layout mode, lines are broken at gaps larger than this
// value multiplied by font size.
-#define simpleLayoutGapThreshold 0.4
+#define simpleLayoutGapThreshold 0.7
// Table cells (TextColumns) are allowed to overlap by this much
// in table layout mode (as a fraction of cell width or height).
@@ -407,19 +408,52 @@ void TextBlock::updateBounds(int childIdx) {
}
//------------------------------------------------------------------------
-// TextGap
+// TextGaps
//------------------------------------------------------------------------
-class TextGap {
+struct TextGap {
+ double x; // center of gap: x for vertical gaps,
+ // y for horizontal gaps
+ double w; // width/height of gap
+};
+
+class TextGaps {
public:
- TextGap(double aXY, double aW): xy(aXY), w(aW) {}
+ TextGaps();
+ ~TextGaps();
+ void addGap(double x, double w);
+ int getLength() { return length; }
+ double getX(int idx) { return gaps[idx].x; }
+ double getW(int idx) { return gaps[idx].w; }
- double xy; // center of gap: x for vertical gaps,
- // y for horizontal gaps
- double w; // width of gap
+private:
+
+ int length;
+ int size;
+ TextGap *gaps;
};
+TextGaps::TextGaps() {
+ length = 0;
+ size = 16;
+ gaps = (TextGap *)gmallocn(size, sizeof(TextGap));
+}
+
+TextGaps::~TextGaps() {
+ gfree(gaps);
+}
+
+void TextGaps::addGap(double x, double w) {
+ if (length == size) {
+ size *= 2;
+ gaps = (TextGap *)greallocn(gaps, size, sizeof(TextGap));
+ }
+ gaps[length].x = x;
+ gaps[length].w = w;
+ ++length;
+}
+
//------------------------------------------------------------------------
// TextSuperLine
//------------------------------------------------------------------------
@@ -508,6 +542,10 @@ TextOutputControl::TextOutputControl() {
discardInvisibleText = gFalse;
discardClippedText = gFalse;
insertBOM = gFalse;
+ marginLeft = 0;
+ marginRight = 0;
+ marginTop = 0;
+ marginBottom = 0;
}
@@ -1136,9 +1174,11 @@ void TextPage::updateFont(GfxState *state) {
if (name && name[0] == 'm' && name[1] == '\0') {
mCode = code;
}
- if (letterCode < 0 && name && name[1] == '\0' &&
+ if (letterCode < 0 &&
+ name &&
((name[0] >= 'A' && name[0] <= 'Z') ||
- (name[0] >= 'a' && name[0] <= 'z'))) {
+ (name[0] >= 'a' && name[0] <= 'z')) &&
+ name[1] == '\0') {
letterCode = code;
}
if (anyCode < 0 && name &&
@@ -1239,9 +1279,12 @@ void TextPage::addChar(GfxState *state, double x, double y,
// throw away chars that aren't inside the page bounds
// (and also do a sanity check on the character size)
state->transform(x, y, &x1, &y1);
- if (x1 + w1 < 0 || x1 > pageWidth ||
- y1 + h1 < 0 || y1 > pageHeight ||
- w1 > pageWidth || h1 > pageHeight) {
+ if (x1 + w1 < control.marginLeft ||
+ x1 > pageWidth - control.marginRight ||
+ y1 + h1 < control.marginTop ||
+ y1 > pageHeight - control.marginBottom ||
+ w1 > pageWidth ||
+ h1 > pageHeight) {
charPos += nBytes;
return;
}
@@ -1876,8 +1919,9 @@ void TextPage::writeRaw(void *outputStream,
if (fabs(ch2->yMin - ch->yMin) > rawModeLineDelta * ch->fontSize ||
ch2->xMin - ch->xMax < -rawModeCharOverlap * ch->fontSize) {
s->append(eol, eolLen);
- } else if (ch2->xMin - ch->xMax >
- rawModeWordSpacing * ch->fontSize) {
+ } else if (ch->spaceAfter ||
+ ch2->xMin - ch->xMax >
+ rawModeWordSpacing * ch->fontSize) {
s->append(space, spaceLen);
}
break;
@@ -1885,8 +1929,9 @@ void TextPage::writeRaw(void *outputStream,
if (fabs(ch->xMax - ch2->xMax) > rawModeLineDelta * ch->fontSize ||
ch2->yMin - ch->yMax < -rawModeCharOverlap * ch->fontSize) {
s->append(eol, eolLen);
- } else if (ch2->yMin - ch->yMax >
- rawModeWordSpacing * ch->fontSize) {
+ } else if (ch->spaceAfter ||
+ ch2->yMin - ch->yMax >
+ rawModeWordSpacing * ch->fontSize) {
s->append(space, spaceLen);
}
break;
@@ -1894,8 +1939,9 @@ void TextPage::writeRaw(void *outputStream,
if (fabs(ch->yMax - ch2->yMax) > rawModeLineDelta * ch->fontSize ||
ch->xMin - ch2->xMax < -rawModeCharOverlap * ch->fontSize) {
s->append(eol, eolLen);
- } else if (ch->xMin - ch2->xMax >
- rawModeWordSpacing * ch->fontSize) {
+ } else if (ch->spaceAfter ||
+ ch->xMin - ch2->xMax >
+ rawModeWordSpacing * ch->fontSize) {
s->append(space, spaceLen);
}
break;
@@ -1903,8 +1949,9 @@ void TextPage::writeRaw(void *outputStream,
if (fabs(ch2->xMin - ch->xMin) > rawModeLineDelta * ch->fontSize ||
ch->yMin - ch2->yMax < -rawModeCharOverlap * ch->fontSize) {
s->append(eol, eolLen);
- } else if (ch->yMin - ch2->yMax >
- rawModeWordSpacing * ch->fontSize) {
+ } else if (ch->spaceAfter ||
+ ch->yMin - ch2->yMax >
+ rawModeWordSpacing * ch->fontSize) {
s->append(space, spaceLen);
}
break;
@@ -2693,12 +2740,11 @@ TextBlock *TextPage::splitChars(GList *charsA) {
TextBlock *TextPage::split(GList *charsA, int rot) {
TextBlock *blk;
GList *chars2, *chars3;
- GList *horizGaps, *vertGaps;
- TextGap *gap;
+ TextGaps *horizGaps, *vertGaps;
TextChar *ch;
double xMin, yMin, xMax, yMax, avgFontSize;
double horizGapSize, vertGapSize, minHorizChunkWidth, minVertChunkWidth;
- double nLines, vertGapThreshold, minChunk;
+ double gap, nLines, vertGapThreshold, minChunk;
double largeCharSize;
double x0, x1, y0, y1;
int nHorizGaps, nVertGaps, nLargeChars;
@@ -2707,8 +2753,8 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
//----- find all horizontal and vertical gaps
- horizGaps = new GList();
- vertGaps = new GList();
+ horizGaps = new TextGaps();
+ vertGaps = new TextGaps();
findGaps(charsA, rot, &xMin, &yMin, &xMax, &yMax, &avgFontSize,
horizGaps, vertGaps);
@@ -2716,16 +2762,16 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
horizGapSize = 0;
for (i = 0; i < horizGaps->getLength(); ++i) {
- gap = (TextGap *)horizGaps->get(i);
- if (gap->w > horizGapSize) {
- horizGapSize = gap->w;
+ gap = horizGaps->getW(i);
+ if (gap > horizGapSize) {
+ horizGapSize = gap;
}
}
vertGapSize = 0;
for (i = 0; i < vertGaps->getLength(); ++i) {
- gap = (TextGap *)vertGaps->get(i);
- if (gap->w > vertGapSize) {
- vertGapSize = gap->w;
+ gap = vertGaps->getW(i);
+ if (gap > vertGapSize) {
+ vertGapSize = gap;
}
}
@@ -2736,14 +2782,14 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
if (horizGaps->getLength() > 0) {
y0 = yMin;
for (i = 0; i < horizGaps->getLength(); ++i) {
- gap = (TextGap *)horizGaps->get(i);
- if (gap->w > horizGapSize - splitGapSlack * avgFontSize) {
+ gap = horizGaps->getW(i);
+ if (gap > horizGapSize - splitGapSlack * avgFontSize) {
++nHorizGaps;
- y1 = gap->xy - 0.5 * gap->w;
+ y1 = horizGaps->getX(i) - 0.5 * gap;
if (y1 - y0 < minHorizChunkWidth) {
minHorizChunkWidth = y1 - y0;
}
- y0 = y1 + gap->w;
+ y0 = y1 + gap;
}
}
y1 = yMax;
@@ -2756,14 +2802,14 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
if (vertGaps->getLength() > 0) {
x0 = xMin;
for (i = 0; i < vertGaps->getLength(); ++i) {
- gap = (TextGap *)vertGaps->get(i);
- if (gap->w > vertGapSize - splitGapSlack * avgFontSize) {
+ gap = vertGaps->getW(i);
+ if (gap > vertGapSize - splitGapSlack * avgFontSize) {
++nVertGaps;
- x1 = gap->xy - 0.5 * gap->w;
+ x1 = vertGaps->getX(i) - 0.5 * gap;
if (x1 - x0 < minVertChunkWidth) {
minVertChunkWidth = x1 - x0;
}
- x0 = x1 + gap->w;
+ x0 = x1 + gap;
}
}
x1 = xMax;
@@ -2881,9 +2927,8 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
printf("vert split xMin=%g yMin=%g xMax=%g yMax=%g small=%d\n",
xMin, pageHeight - yMax, xMax, pageHeight - yMin, smallSplit);
for (i = 0; i < vertGaps->getLength(); ++i) {
- gap = (TextGap *)vertGaps->get(i);
- if (gap->w > vertGapSize - splitGapSlack * avgFontSize) {
- printf(" x=%g\n", gap->xy);
+ if (vertGaps->getW(i) > vertGapSize - splitGapSlack * avgFontSize) {
+ printf(" x=%g\n", vertGaps->getX(i));
}
}
#endif
@@ -2891,9 +2936,8 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
blk->smallSplit = smallSplit;
x0 = xMin - 1;
for (i = 0; i < vertGaps->getLength(); ++i) {
- gap = (TextGap *)vertGaps->get(i);
- if (gap->w > vertGapSize - splitGapSlack * avgFontSize) {
- x1 = gap->xy;
+ if (vertGaps->getW(i) > vertGapSize - splitGapSlack * avgFontSize) {
+ x1 = vertGaps->getX(i);
chars2 = getChars(charsA, x0, yMin - 1, x1, yMax + 1);
blk->addChild(split(chars2, rot));
delete chars2;
@@ -2910,9 +2954,8 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
printf("horiz split xMin=%g yMin=%g xMax=%g yMax=%g small=%d\n",
xMin, pageHeight - yMax, xMax, pageHeight - yMin, smallSplit);
for (i = 0; i < horizGaps->getLength(); ++i) {
- gap = (TextGap *)horizGaps->get(i);
- if (gap->w > horizGapSize - splitGapSlack * avgFontSize) {
- printf(" y=%g\n", pageHeight - gap->xy);
+ if (horizGaps->getW(i) > horizGapSize - splitGapSlack * avgFontSize) {
+ printf(" y=%g\n", pageHeight - horizGaps->getX(i));
}
}
#endif
@@ -2920,9 +2963,8 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
blk->smallSplit = smallSplit;
y0 = yMin - 1;
for (i = 0; i < horizGaps->getLength(); ++i) {
- gap = (TextGap *)horizGaps->get(i);
- if (gap->w > horizGapSize - splitGapSlack * avgFontSize) {
- y1 = gap->xy;
+ if (horizGaps->getW(i) > horizGapSize - splitGapSlack * avgFontSize) {
+ y1 = horizGaps->getX(i);
chars2 = getChars(charsA, xMin - 1, y0, xMax + 1, y1);
blk->addChild(split(chars2, rot));
delete chars2;
@@ -2966,8 +3008,8 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
}
}
- deleteGList(horizGaps, TextGap);
- deleteGList(vertGaps, TextGap);
+ delete horizGaps;
+ delete vertGaps;
tagBlock(blk);
@@ -3001,11 +3043,12 @@ void TextPage::findGaps(GList *charsA, int rot,
double *xMinOut, double *yMinOut,
double *xMaxOut, double *yMaxOut,
double *avgFontSizeOut,
- GList *horizGaps, GList *vertGaps) {
+ TextGaps *horizGaps, TextGaps *vertGaps) {
TextChar *ch;
- int *horizProfile, *vertProfile;
+ char *horizProfile, *vertProfile;
double xMin, yMin, xMax, yMax, w;
- double minFontSize, avgFontSize, splitPrecision, ascentAdjust, descentAdjust;
+ double minFontSize, avgFontSize, splitPrecision, invSplitPrecision;
+ double ascentAdjust, descentAdjust;
int xMinI, yMinI, xMaxI, yMaxI, xMinI2, yMinI2, xMaxI2, yMaxI2;
int start, x, y, i;
@@ -3037,6 +3080,7 @@ void TextPage::findGaps(GList *charsA, int rot,
if (splitPrecision < minSplitPrecision) {
splitPrecision = minSplitPrecision;
}
+ invSplitPrecision = 1 / splitPrecision;
*xMinOut = xMin;
*yMinOut = yMin;
*xMaxOut = xMax;
@@ -3045,59 +3089,65 @@ void TextPage::findGaps(GList *charsA, int rot,
//----- compute the horizontal and vertical profiles
+ if (xMin * invSplitPrecision < 0.5 * INT_MIN ||
+ xMax * invSplitPrecision > 0.5 * INT_MAX ||
+ yMin * invSplitPrecision < 0.5 * INT_MIN ||
+ xMax * invSplitPrecision > 0.5 * INT_MAX) {
+ return;
+ }
// add some slack to the array bounds to avoid floating point
// precision problems
- xMinI = (int)floor(xMin / splitPrecision) - 1;
- yMinI = (int)floor(yMin / splitPrecision) - 1;
- xMaxI = (int)floor(xMax / splitPrecision) + 1;
- yMaxI = (int)floor(yMax / splitPrecision) + 1;
- horizProfile = (int *)gmallocn(yMaxI - yMinI + 1, sizeof(int));
- vertProfile = (int *)gmallocn(xMaxI - xMinI + 1, sizeof(int));
- memset(horizProfile, 0, (yMaxI - yMinI + 1) * sizeof(int));
- memset(vertProfile, 0, (xMaxI - xMinI + 1) * sizeof(int));
+ xMinI = (int)floor(xMin * invSplitPrecision) - 1;
+ yMinI = (int)floor(yMin * invSplitPrecision) - 1;
+ xMaxI = (int)floor(xMax * invSplitPrecision) + 1;
+ yMaxI = (int)floor(yMax * invSplitPrecision) + 1;
+ horizProfile = (char *)gmalloc(yMaxI - yMinI + 1);
+ vertProfile = (char *)gmalloc(xMaxI - xMinI + 1);
+ memset(horizProfile, 0, yMaxI - yMinI + 1);
+ memset(vertProfile, 0, xMaxI - xMinI + 1);
for (i = 0; i < charsA->getLength(); ++i) {
ch = (TextChar *)charsA->get(i);
// yMinI2 and yMaxI2 are adjusted to allow for slightly overlapping lines
switch (rot) {
case 0:
default:
- xMinI2 = (int)floor(ch->xMin / splitPrecision);
- xMaxI2 = (int)floor(ch->xMax / splitPrecision);
+ xMinI2 = (int)floor(ch->xMin * invSplitPrecision);
+ xMaxI2 = (int)floor(ch->xMax * invSplitPrecision);
ascentAdjust = ascentAdjustFactor * (ch->yMax - ch->yMin);
- yMinI2 = (int)floor((ch->yMin + ascentAdjust) / splitPrecision);
+ yMinI2 = (int)floor((ch->yMin + ascentAdjust) * invSplitPrecision);
descentAdjust = descentAdjustFactor * (ch->yMax - ch->yMin);
- yMaxI2 = (int)floor((ch->yMax - descentAdjust) / splitPrecision);
+ yMaxI2 = (int)floor((ch->yMax - descentAdjust) * invSplitPrecision);
break;
case 1:
descentAdjust = descentAdjustFactor * (ch->xMax - ch->xMin);
- xMinI2 = (int)floor((ch->xMin + descentAdjust) / splitPrecision);
+ xMinI2 = (int)floor((ch->xMin + descentAdjust) * invSplitPrecision);
ascentAdjust = ascentAdjustFactor * (ch->xMax - ch->xMin);
- xMaxI2 = (int)floor((ch->xMax - ascentAdjust) / splitPrecision);
- yMinI2 = (int)floor(ch->yMin / splitPrecision);
- yMaxI2 = (int)floor(ch->yMax / splitPrecision);
+ xMaxI2 = (int)floor((ch->xMax - ascentAdjust) * invSplitPrecision);
+ yMinI2 = (int)floor(ch->yMin * invSplitPrecision);
+ yMaxI2 = (int)floor(ch->yMax * invSplitPrecision);
break;
case 2:
- xMinI2 = (int)floor(ch->xMin / splitPrecision);
- xMaxI2 = (int)floor(ch->xMax / splitPrecision);
+ xMinI2 = (int)floor(ch->xMin * invSplitPrecision);
+ xMaxI2 = (int)floor(ch->xMax * invSplitPrecision);
descentAdjust = descentAdjustFactor * (ch->yMax - ch->yMin);
- yMinI2 = (int)floor((ch->yMin + descentAdjust) / splitPrecision);
+ yMinI2 = (int)floor((ch->yMin + descentAdjust) * invSplitPrecision);
ascentAdjust = ascentAdjustFactor * (ch->yMax - ch->yMin);
- yMaxI2 = (int)floor((ch->yMax - ascentAdjust) / splitPrecision);
+ yMaxI2 = (int)floor((ch->yMax - ascentAdjust) * invSplitPrecision);
break;
case 3:
ascentAdjust = ascentAdjustFactor * (ch->xMax - ch->xMin);
- xMinI2 = (int)floor((ch->xMin + ascentAdjust) / splitPrecision);
+ xMinI2 = (int)floor((ch->xMin + ascentAdjust) * invSplitPrecision);
descentAdjust = descentAdjustFactor * (ch->xMax - ch->xMin);
- xMaxI2 = (int)floor((ch->xMax - descentAdjust) / splitPrecision);
- yMinI2 = (int)floor(ch->yMin / splitPrecision);
- yMaxI2 = (int)floor(ch->yMax / splitPrecision);
+ xMaxI2 = (int)floor((ch->xMax - descentAdjust) * invSplitPrecision);
+ yMinI2 = (int)floor(ch->yMin * invSplitPrecision);
+ yMaxI2 = (int)floor(ch->yMax * invSplitPrecision);
break;
}
for (y = yMinI2; y <= yMaxI2; ++y) {
- ++horizProfile[y - yMinI];
+ horizProfile[y - yMinI] = 1;
}
for (x = xMinI2; x <= xMaxI2; ++x) {
- ++vertProfile[x - xMinI];
+ vertProfile[x - xMinI] = 1;
}
}
@@ -3112,8 +3162,7 @@ void TextPage::findGaps(GList *charsA, int rot,
} else {
if (horizProfile[y + 1 - yMinI]) {
w = (y - start) * splitPrecision;
- horizGaps->append(new TextGap((start + 1) * splitPrecision + 0.5 * w,
- w));
+ horizGaps->addGap((start + 1) * splitPrecision + 0.5 * w, w);
}
}
}
@@ -3129,8 +3178,7 @@ void TextPage::findGaps(GList *charsA, int rot,
} else {
if (vertProfile[x + 1 - xMinI]) {
w = (x - start) * splitPrecision;
- vertGaps->append(new TextGap((start + 1) * splitPrecision + 0.5 * w,
- w));
+ vertGaps->addGap((start + 1) * splitPrecision + 0.5 * w, w);
}
}
}
@@ -3818,18 +3866,27 @@ double TextPage::computeWordSpacingThreshold(GList *charsA, int rot) {
minGap = 0;
}
- // if spacing is nearly uniform (minGap is close to maxGap), use the
- // SpGap/AdjGap values if available, otherwise assume it's a single
- // word (technically it could be either "ABC" or "A B C", but it's
- // essentially impossible to tell)
+ // if spacing is nearly uniform (minGap is close to maxGap), there
+ // are three cases:
+ // (1) if the SpGap and AdjGap values are both available and
+ // sensible, use them
+ // (2) if only the SpGap values are available, meaning that every
+ // character in the line had a space after it, split after every
+ // character
+ // (3) otherwise assume it's a single word (technically it could be
+ // either "ABC" or "A B C", but it's essentially impossible to
+ // tell)
if (maxGap - minGap < uniformSpacing * avgFontSize) {
- if (minAdjGap <= maxAdjGap &&
- minSpGap <= maxSpGap &&
- minSpGap - maxAdjGap > 0.01) {
- return 0.5 * (maxAdjGap + minSpGap);
- } else {
- return maxGap + 1;
+ if (minSpGap <= maxSpGap) {
+ if (minAdjGap <= maxAdjGap &&
+ minSpGap - maxAdjGap > 0.01) {
+ return 0.5 * (maxAdjGap + minSpGap);
+ } else if (minAdjGap > maxAdjGap &&
+ maxSpGap - minSpGap < uniformSpacing * avgFontSize) {
+ return minSpGap - 1;
+ }
}
+ return maxGap + 1;
// if there is some variation in spacing, but it's small, assume
// there are some inter-word spaces
@@ -4033,8 +4090,8 @@ void TextPage::assignSimpleLayoutPositions(GList *superLines,
UnicodeMap *uMap) {
GList *lines;
TextLine *line0, *line1;
- double xMin;
- int px, sp, i, j;
+ double xMin, xMax;
+ int px, px2, sp, i, j;
// build a list of lines and sort by x
lines = new GList();
@@ -4048,21 +4105,25 @@ void TextPage::assignSimpleLayoutPositions(GList *superLines,
for (i = 0; i < lines->getLength(); ++i) {
line0 = (TextLine *)lines->get(i);
computeLinePhysWidth(line0, uMap);
- line0->px = (int)((line0->xMin - xMin) / (0.5 * line0->fontSize));
+ px = 0;
+ xMax = xMin;
for (j = 0; j < i; ++j) {
line1 = (TextLine *)lines->get(j);
if (line0->xMin > line1->xMax) {
- sp = (int)((line0->xMin - line1->xMax) /
- (0.5 * line0->fontSize) + 0.5);
- if (sp < 1) {
- sp = 1;
+ if (line1->xMax > xMax) {
+ xMax = line1->xMax;
}
- px = line1->px + line1->pw + sp;
- if (px > line0->px) {
- line0->px = px;
+ px2 = line1->px + line1->pw;
+ if (px2 > px) {
+ px = px2;
}
}
}
+ sp = (int)((line0->xMin - xMax) / (0.5 * line0->fontSize) + 0.5);
+ if (sp < 1 && xMax > xMin) {
+ sp = 1;
+ }
+ line0->px = px + sp;
}
delete lines;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
index 0884ace6b6b..0f00cf5ae7b 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
@@ -26,6 +26,7 @@ class UnicodeRemapping;
class TextBlock;
class TextChar;
+class TextGaps;
class TextLink;
class TextPage;
@@ -69,6 +70,10 @@ public:
GBool discardClippedText; // discard all clipped characters
GBool insertBOM; // insert a Unicode BOM at the start of
// the text output
+ double marginLeft, // characters outside the margins are
+ marginRight, // discarded
+ marginTop,
+ marginBottom;
};
//------------------------------------------------------------------------
@@ -502,7 +507,7 @@ private:
double *xMinOut, double *yMinOut,
double *xMaxOut, double *yMaxOut,
double *avgFontSizeOut,
- GList *horizGaps, GList *vertGaps);
+ TextGaps *horizGaps, TextGaps *vertGaps);
void tagBlock(TextBlock *blk);
void insertLargeChars(GList *largeChars, TextBlock *blk);
void insertLargeCharsInFirstLeaf(GList *largeChars, TextBlock *blk);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc
index 431c639a020..70128a4a47f 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc
@@ -67,7 +67,7 @@ SplashBitmap *TileCompositor::getBitmap(GBool *finished) {
}
bitmap = new SplashBitmap(state->getWinW(), state->getWinH(),
state->getBitmapRowPad(), state->getColorMode(),
- gFalse);
+ gFalse, gTrue, NULL);
}
clearBitmap();
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
index 6db67738d70..d1a5aea2963 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
@@ -592,6 +592,11 @@ GBool TileMap::cvtWindowToDev(int xw, int yw,
offsetY = 0;
}
*pg = findContinuousPage(yw - offsetY + state->getScrollY());
+ if (*pg < 1 || *pg > state->getDoc()->getNumPages()) {
+ *pg = 0;
+ *xd = *yd = 0;
+ return gFalse;
+ }
pageW1 = pageW[*pg - 1];
pageH1 = pageH[*pg - 1];
if (maxW < state->getWinW()) {
@@ -655,6 +660,11 @@ GBool TileMap::cvtWindowToDev(int xw, int yw,
offsetY = 0;
}
*pg = findSideBySideContinuousPage(yw - offsetY + state->getScrollY());
+ if (*pg < 1 || *pg > state->getDoc()->getNumPages()) {
+ *pg = 0;
+ *xd = *yd = 0;
+ return gFalse;
+ }
pageW1 = pageW[*pg - 1];
pageH1 = pageH[*pg - 1];
if (*pg + 1 <= state->getDoc()->getNumPages()) {
@@ -693,6 +703,11 @@ GBool TileMap::cvtWindowToDev(int xw, int yw,
offsetX = 0;
}
*pg = findHorizContinuousPage(xw - offsetX + state->getScrollX());
+ if (*pg < 1 || *pg > state->getDoc()->getNumPages()) {
+ *pg = 0;
+ *xd = *yd = 0;
+ return gFalse;
+ }
pageW1 = pageW[*pg - 1];
pageH1 = pageH[*pg - 1];
if (maxH < state->getWinH()) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.cc
index 637d36b6d58..9ee01425094 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.cc
@@ -6,6 +6,7 @@
//
//========================================================================
+#include <aconf.h>
#include "UTF8.h"
int mapUTF8(Unicode u, char *buf, int bufSize) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc
new file mode 100644
index 00000000000..95f0e983a31
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.cc
@@ -0,0 +1,384 @@
+//========================================================================
+//
+// WebFont.cc
+//
+// Copyright 2019 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include "gmem.h"
+#include "gmempp.h"
+#include "GHash.h"
+#include "FoFiTrueType.h"
+#include "FoFiType1C.h"
+#include "CharCodeToUnicode.h"
+#include "WebFont.h"
+
+WebFont::WebFont(GfxFont *gfxFontA, XRef *xref) {
+ GfxFontType type;
+
+ gfxFont = gfxFontA;
+ fontBuf = NULL;
+ ffTrueType = NULL;
+ ffType1C = NULL;
+ isOpenType = gFalse;
+
+ type = gfxFont->getType();
+ if (type == fontTrueType ||
+ type == fontTrueTypeOT ||
+ type == fontCIDType2 ||
+ type == fontCIDType2OT) {
+ if ((fontBuf = gfxFont->readEmbFontFile(xref, &fontLength))) {
+ ffTrueType = FoFiTrueType::make(fontBuf, fontLength, 0);
+ }
+ } else if (type == fontType1C ||
+ type == fontCIDType0C) {
+ if ((fontBuf = gfxFont->readEmbFontFile(xref, &fontLength))) {
+ ffType1C = FoFiType1C::make(fontBuf, fontLength);
+ }
+ } else if (type == fontType1COT ||
+ type == fontCIDType0COT) {
+ if ((fontBuf = gfxFont->readEmbFontFile(xref, &fontLength))) {
+ isOpenType = gTrue;
+ }
+ }
+}
+
+WebFont::~WebFont() {
+ delete ffTrueType;
+ delete ffType1C;
+ gfree(fontBuf);
+}
+
+GBool WebFont::canWriteTTF() {
+ return ffTrueType != NULL;
+}
+
+GBool WebFont::canWriteOTF() {
+ return ffType1C || isOpenType;
+}
+
+static void writeToFile(void *stream, const char *data, int len) {
+ fwrite(data, 1, len, (FILE *)stream);
+}
+
+GBool WebFont::writeTTF(const char *fontFilePath) {
+ FILE *out;
+ int *codeToGID;
+ Guchar *cmapTable;
+ GBool freeCodeToGID;
+ int nCodes, cmapTableLength;
+
+ if (!ffTrueType) {
+ return gFalse;
+ }
+ if (gfxFont->isCIDFont()) {
+ codeToGID = ((GfxCIDFont *)gfxFont)->getCIDToGID();
+ nCodes = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+ if (!codeToGID) {
+ nCodes = ffTrueType->getNumGlyphs();
+ }
+ freeCodeToGID = gFalse;
+ } else {
+ codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ffTrueType);
+ nCodes = 256;
+ freeCodeToGID = gTrue;
+ }
+ cmapTable = makeUnicodeCmapTable(codeToGID, nCodes, &cmapTableLength);
+ if (freeCodeToGID) {
+ gfree(codeToGID);
+ }
+ if (!cmapTable) {
+ return gFalse;
+ }
+ if (!(out = fopen(fontFilePath, "wb"))) {
+ gfree(cmapTable);
+ return gFalse;
+ }
+ ffTrueType->writeTTF(writeToFile, out, NULL, NULL,
+ cmapTable, cmapTableLength);
+ fclose(out);
+ gfree(cmapTable);
+ return gTrue;
+}
+
+GBool WebFont::writeOTF(const char *fontFilePath) {
+ int *codeToGID;
+ Gushort *widths;
+ Guchar *cmapTable;
+ FILE *out;
+ int nCodes, nWidths, cmapTableLength;
+
+ if (ffType1C) {
+ if (gfxFont->getType() == fontType1C) {
+ codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ffType1C);
+ if (!(cmapTable = makeUnicodeCmapTable(codeToGID, 256,
+ &cmapTableLength))) {
+ gfree(codeToGID);
+ return gFalse;
+ }
+ widths = makeType1CWidths(codeToGID, 256, &nWidths);
+ gfree(codeToGID);
+ } else { // fontCIDType0C
+ codeToGID = ffType1C->getCIDToGIDMap(&nCodes);
+ if (!(cmapTable = makeUnicodeCmapTable(codeToGID, nCodes,
+ &cmapTableLength))) {
+ gfree(codeToGID);
+ return gFalse;
+ }
+ widths = makeCIDType0CWidths(codeToGID, nCodes, &nWidths);
+ gfree(codeToGID);
+ }
+ if (!(out = fopen(fontFilePath, "wb"))) {
+ gfree(cmapTable);
+ gfree(widths);
+ return gFalse;
+ }
+ ffType1C->convertToOpenType(writeToFile, out,
+ nWidths, widths,
+ cmapTable, cmapTableLength);
+ fclose(out);
+ gfree(cmapTable);
+ gfree(widths);
+
+ } else if (isOpenType) {
+ if (!(out = fopen(fontFilePath, "wb"))) {
+ return gFalse;
+ }
+ if (fwrite(fontBuf, 1, fontLength, out) != (Guint)fontLength) {
+ fclose(out);
+ return gFalse;
+ }
+ fclose(out);
+
+ } else {
+ return gFalse;
+ }
+
+ return gTrue;
+}
+
+Gushort *WebFont::makeType1CWidths(int *codeToGID, int nCodes,
+ int *nWidths) {
+ Gushort *widths;
+ Gushort width;
+ int widthsLen, gid, i;
+
+ widthsLen = ffType1C->getNumGlyphs();
+ widths = (Gushort *)gmallocn(widthsLen, sizeof(Gushort));
+ for (i = 0; i < widthsLen; ++i) {
+ widths[i] = 0;
+ }
+ for (i = 0; i < nCodes; ++i) {
+ gid = codeToGID[i];
+ if (gid < 0 || gid >= widthsLen) {
+ continue;
+ }
+ width = (Gushort)(((Gfx8BitFont *)gfxFont)->getWidth((Guchar)i)
+ * 1000 + 0.5);
+ if (width == 0) {
+ continue;
+ }
+ widths[gid] = width;
+ }
+ *nWidths = widthsLen;
+ return widths;
+}
+
+Gushort *WebFont::makeCIDType0CWidths(int *codeToGID, int nCodes,
+ int *nWidths) {
+ Gushort *widths;
+ Gushort width;
+ int widthsLen, gid, i;
+
+ widthsLen = ffType1C->getNumGlyphs();
+ widths = (Gushort *)gmallocn(widthsLen, sizeof(Gushort));
+ for (i = 0 ; i < widthsLen; ++i) {
+ widths[i] = 0;
+ }
+ for (i = 0; i < nCodes; ++i) {
+ gid = codeToGID[i];
+ if (gid < 0 || gid >= widthsLen) {
+ continue;
+ }
+ width = (Gushort)(((GfxCIDFont *)gfxFont)->getWidth((CID)i)
+ * 1000 + 0.5);
+ if (width == 0) {
+ continue;
+ }
+ widths[gid] = width;
+ }
+ *nWidths = widthsLen;
+ return widths;
+}
+
+Guchar *WebFont::makeUnicodeCmapTable(int *codeToGID, int nCodes,
+ int *unicodeCmapLength) {
+ int *unicodeToGID;
+ Guchar *cmapTable;
+ int unicodeToGIDLength, nMappings, len;
+ int nSegs, searchRange, entrySelector, rangeShift;
+ int glyphIdOffset, idRangeOffset;
+ int start, end, c, i;
+
+ if (!(unicodeToGID = makeUnicodeToGID(codeToGID, nCodes,
+ &unicodeToGIDLength))) {
+ return NULL;
+ }
+
+ // count the valid code-to-glyph mappings, and the sequences of
+ // consecutive valid mappings
+ // (note: char code 65535 is used to mark the end of table)
+ nMappings = 0;
+ nSegs = 1; // count the last segment, mapping 65535
+ for (c = 0; c < unicodeToGIDLength && c <= 65534; ++c) {
+ if (unicodeToGID[c]) {
+ ++nMappings;
+ if (c == 0 || !unicodeToGID[c-1]) {
+ ++nSegs;
+ }
+ }
+ }
+
+ i = 1;
+ entrySelector = 0;
+ while (2 * i <= nSegs) {
+ i *= 2;
+ ++entrySelector;
+ }
+ searchRange = 1 << (entrySelector + 1);
+ rangeShift = 2 * nSegs - searchRange;
+
+ len = 28 + nSegs * 8 + nMappings * 2;
+ cmapTable = (Guchar *)gmalloc(len);
+
+ // header
+ cmapTable[ 0] = 0x00; // table version
+ cmapTable[ 1] = 0x00;
+ cmapTable[ 2] = 0x00; // number of cmaps
+ cmapTable[ 3] = 0x01;
+ cmapTable[ 4] = 0x00; // platform[0]
+ cmapTable[ 5] = 0x03;
+ cmapTable[ 6] = 0x00; // encoding[0]
+ cmapTable[ 7] = 0x01;
+ cmapTable[ 8] = 0x00; // offset[0]
+ cmapTable[ 9] = 0x00;
+ cmapTable[10] = 0x00;
+ cmapTable[11] = 0x0c;
+
+ // table info
+ cmapTable[12] = 0x00; // cmap format
+ cmapTable[13] = 0x04;
+ cmapTable[14] = (Guchar)((len - 12) >> 8); // cmap length
+ cmapTable[15] = (Guchar)(len - 12);
+ cmapTable[16] = 0x00; // cmap version
+ cmapTable[17] = 0x00;
+ cmapTable[18] = (Guchar)(nSegs >> 7); // segCountX2
+ cmapTable[19] = (Guchar)(nSegs << 1);
+ cmapTable[20] = (Guchar)(searchRange >> 8); // searchRange
+ cmapTable[21] = (Guchar)searchRange;
+ cmapTable[22] = (Guchar)(entrySelector >> 8); // entrySelector
+ cmapTable[23] = (Guchar)entrySelector;
+ cmapTable[24] = (Guchar)(rangeShift >> 8); // rangeShift
+ cmapTable[25] = (Guchar)rangeShift;
+ cmapTable[26 + nSegs*2 ] = 0; // reservedPad
+ cmapTable[26 + nSegs*2 + 1] = 0;
+
+ i = 0;
+ glyphIdOffset = 28 + nSegs*8;
+ for (c = 0; c < unicodeToGIDLength && c <= 65534; ++c) {
+ if (unicodeToGID[c]) {
+ if (c == 0 || !unicodeToGID[c-1]) {
+ start = c;
+ cmapTable[28 + nSegs*2 + i*2 ] = (Guchar)(start >> 8);
+ cmapTable[28 + nSegs*2 + i*2 + 1] = (Guchar)start;
+ cmapTable[28 + nSegs*4 + i*2 ] = (Guchar)0; // idDelta
+ cmapTable[28 + nSegs*4 + i*2 + 1] = (Guchar)0;
+ idRangeOffset = glyphIdOffset - (28 + nSegs*6 + i*2);
+ cmapTable[28 + nSegs*6 + i*2 ] = (Guchar)(idRangeOffset >> 8);
+ cmapTable[28 + nSegs*6 + i*2 + 1] = (Guchar)idRangeOffset;
+ }
+ if (c == 65534 || !unicodeToGID[c+1]) {
+ end = c;
+ cmapTable[26 + i*2 ] = (Guchar)(end >> 8);
+ cmapTable[26 + i*2 + 1] = (Guchar)end;
+ ++i;
+ }
+ cmapTable[glyphIdOffset++] = (Guchar)(unicodeToGID[c] >> 8);
+ cmapTable[glyphIdOffset++] = (Guchar)unicodeToGID[c];
+ }
+ }
+
+ // last segment maps code 65535 to GID 0
+ cmapTable[26 + i*2 ] = (Guchar)0xff; // end
+ cmapTable[26 + i*2 + 1] = (Guchar)0xff;
+ cmapTable[28 + nSegs*2 + i*2 ] = (Guchar)0xff; // start
+ cmapTable[28 + nSegs*2 + i*2 + 1] = (Guchar)0xff;
+ cmapTable[28 + nSegs*4 + i*2 ] = (Guchar)0; // idDelta
+ cmapTable[28 + nSegs*4 + i*2 + 1] = (Guchar)1;
+ cmapTable[28 + nSegs*6 + i*2 ] = (Guchar)0; // idRangeOffset
+ cmapTable[28 + nSegs*6 + i*2 + 1] = (Guchar)0;
+
+ gfree(unicodeToGID);
+
+ *unicodeCmapLength = len;
+ return cmapTable;
+}
+
+int *WebFont::makeUnicodeToGID(int *codeToGID, int nCodes,
+ int *unicodeToGIDLength) {
+ int *unicodeToGID;
+ CharCodeToUnicode *ctu;
+ Unicode u[2];
+ int len, size, newSize, uLen, c, gid;
+
+ if (gfxFont->isCIDFont()) {
+ if (!(ctu = ((GfxCIDFont *)gfxFont)->getToUnicode())) {
+ return NULL;
+ }
+ } else {
+ ctu = ((Gfx8BitFont *)gfxFont)->getToUnicode();
+ }
+
+ len = 0;
+ size = 256;
+ unicodeToGID = (int *)gmallocn(size, sizeof(int));
+ memset(unicodeToGID, 0, size * sizeof(int));
+ for (c = 0; c < nCodes; ++c) {
+ gid = codeToGID ? codeToGID[c] : c;
+ if (gid < 0 || gid >= 65536) {
+ continue;
+ }
+ uLen = ctu->mapToUnicode(c, u, 2);
+ if (uLen != 1) {
+ continue;
+ }
+ if (u[0] >= 65536) { // sanity check
+ continue;
+ }
+ if ((int)u[0] >= size) {
+ newSize = 2 * size;
+ while ((int)u[0] >= newSize) {
+ newSize *= 2;
+ }
+ unicodeToGID = (int *)greallocn(unicodeToGID, newSize, sizeof(int));
+ memset(unicodeToGID + size, 0, (newSize - size) * sizeof(int));
+ size = newSize;
+ }
+ unicodeToGID[u[0]] = gid;
+ if ((int)u[0] >= len) {
+ len = u[0] + 1;
+ }
+ }
+
+ ctu->decRefCnt();
+
+ *unicodeToGIDLength = len;
+ return unicodeToGID;
+}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h b/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h
new file mode 100644
index 00000000000..a967e2e490a
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/WebFont.h
@@ -0,0 +1,69 @@
+//========================================================================
+//
+// WebFont.h
+//
+// Modify/convert embedded PDF fonts to a form usable by web browsers.
+//
+// Copyright 2019 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef WEBFONT_H
+#define WEBFONT_H
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include "gtypes.h"
+#include "GfxFont.h"
+
+class FoFiTrueType;
+class FoFiType1C;
+class XRef;
+
+//------------------------------------------------------------------------
+
+class WebFont {
+public:
+
+ WebFont(GfxFont *gfxFontA, XRef *xref);
+
+ ~WebFont();
+
+ // Returns true if the font is, or can be converted to, a TrueType
+ // font.
+ GBool canWriteTTF();
+
+ // Returns true if the font is, or can be converted to, an OpenType
+ // font.
+ GBool canWriteOTF();
+
+ // Write a TrueType (.ttf) file to [fontFilePath]. This can only be
+ // called if canWriteTTF() returns true. Returns true on success.
+ GBool writeTTF(const char *fontFilePath);
+
+ // Write an OpenType (.otf) file to [fontFilePath]. This can only
+ // be called if canWriteOTF() returns true. Returns true on
+ // success.
+ GBool writeOTF(const char *fontFilePath);
+
+private:
+
+ Gushort *makeType1CWidths(int *codeToGID, int nCodes, int *nWidths);
+ Gushort *makeCIDType0CWidths(int *codeToGID, int nCodes, int *nWidths);
+ Guchar *makeUnicodeCmapTable(int *codeToGID, int nCodes,
+ int *unicodeCmapLength);
+ int *makeUnicodeToGID(int *codeToGID, int nCodes, int *unicodeToGIDLength);
+
+ GfxFont *gfxFont;
+ char *fontBuf;
+ int fontLength;
+ FoFiTrueType *ffTrueType;
+ FoFiType1C *ffType1C;
+ GBool isOpenType;
+};
+
+#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc
index 18534401946..3b88270c798 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc
@@ -25,6 +25,7 @@
#include "GfxFont.h"
#include "Zoox.h"
#include "PDF417Barcode.h"
+#include "UTF8.h"
#include "XFAForm.h"
#ifdef _WIN32
@@ -446,7 +447,7 @@ XFAForm *XFAForm::load(PDFDoc *docA, Catalog *catalog,
fullNameIdx = new GHash();
xfaForm->scanNode(tmpl, name, fullName, gFalse, NULL,
nameCount, nameIdx, fullNameCount, fullNameIdx,
- catalog);
+ NULL, catalog);
delete nameCount;
delete nameIdx;
delete fullNameCount;
@@ -504,11 +505,6 @@ XFAForm::~XFAForm() {
gfree(pageOffsetY);
}
-//~ need to handle exclGroup
-//~ - fields in an exclGroup may/must(?) not have names
-//~ - each field has an items element with the the value when that
-//~ field is selected
-
// Scan <elem>. Constructs the node's name and full name. If <elem>
// is a field, creates an XFAFormField; else scans <elem>'s children.
void XFAForm::scanNode(ZxElement *elem,
@@ -516,7 +512,7 @@ void XFAForm::scanNode(ZxElement *elem,
GBool inPageSet, XFATableInfo *tableInfo,
GHash *nameCount, GHash *nameIdx,
GHash *fullNameCount, GHash *fullNameIdx,
- Catalog *catalog) {
+ GString *exclGroupName, Catalog *catalog) {
ZxAttr *attr;
GString *name, *fullName, *namePart, *fullNamePart;
GHash *childNameCount, *childNameIdx, *childFullNameCount, *childFullNameIdx;
@@ -575,7 +571,8 @@ void XFAForm::scanNode(ZxElement *elem,
}
if (elem->isElement("field")) {
- scanField(elem, name, fullName, inPageSet, tableInfo, colSpan, catalog);
+ scanField(elem, name, fullName, exclGroupName,
+ inPageSet, tableInfo, colSpan, catalog);
} else {
scanNonField(elem, name, fullName, inPageSet, tableInfo, colSpan,
childNameCount, childNameIdx,
@@ -652,7 +649,7 @@ void XFAForm::scanFullNames(ZxElement *elem, GHash *fullNameCount) {
}
void XFAForm::scanField(ZxElement *elem, GString *name, GString *fullName,
- GBool inPageSet,
+ GString *exclGroupName, GBool inPageSet,
XFATableInfo *tableInfo, int colSpan,
Catalog *catalog) {
double xSubOffset, ySubOffset, columnWidth, rowHeight;
@@ -679,6 +676,8 @@ void XFAForm::scanField(ZxElement *elem, GString *name, GString *fullName,
}
fields->append(new XFAFormField(this, elem, name->copy(), fullName->copy(),
+ exclGroupName ? exclGroupName->copy()
+ : (GString *)NULL,
curPageNum, curXOffset, curYOffset,
columnWidth, rowHeight));
@@ -699,6 +698,7 @@ void XFAForm::scanNonField(ZxElement *elem, GString *name, GString *fullName,
ZxNode *child;
ZxAttr *attr;
PDFRectangle *box;
+ GString *exclGroupName;
double xSubOffset, ySubOffset;
int savedPageNum;
@@ -744,7 +744,8 @@ void XFAForm::scanNonField(ZxElement *elem, GString *name, GString *fullName,
curXOffset += xSubOffset;
curYOffset += ySubOffset;
- } else if (elem->isElement("area")) {
+ } else if (elem->isElement("area") ||
+ elem->isElement("exclGroup")) {
xSubOffset = XFAFormField::getMeasurement(elem->findAttr("x"), 0);
ySubOffset = XFAFormField::getMeasurement(elem->findAttr("y"), 0);
curXOffset += xSubOffset;
@@ -780,11 +781,17 @@ void XFAForm::scanNonField(ZxElement *elem, GString *name, GString *fullName,
}
}
+ if (elem->isElement("exclGroup")) {
+ exclGroupName = name;
+ } else {
+ exclGroupName = NULL;
+ }
+
for (child = elem->getFirstChild(); child; child = child->getNextChild()) {
if (child->isElement()) {
scanNode((ZxElement *)child, name, fullName, inPageSet,
newTableInfo, nameCount, nameIdx, fullNameCount, fullNameIdx,
- catalog);
+ exclGroupName, catalog);
}
}
@@ -871,12 +878,14 @@ FormField *XFAForm::getField(int idx) {
XFAFormField::XFAFormField(XFAForm *xfaFormA, ZxElement *xmlA,
GString *nameA, GString *fullNameA,
+ GString *exclGroupNameA,
int pageNumA, double xOffsetA, double yOffsetA,
double columnWidthA, double rowHeightA) {
xfaForm = xfaFormA;
xml = xmlA;
name = nameA;
fullName = fullNameA;
+ exclGroupName = exclGroupNameA;
pageNum = pageNumA;
xOffset = xOffsetA;
yOffset = yOffsetA;
@@ -887,6 +896,9 @@ XFAFormField::XFAFormField(XFAForm *xfaFormA, ZxElement *xmlA,
XFAFormField::~XFAFormField() {
delete name;
delete fullName;
+ if (exclGroupName) {
+ delete exclGroupName;
+ }
}
int XFAFormField::getPageNum() {
@@ -943,7 +955,9 @@ Unicode *XFAFormField::getValue(int *length) {
s = getFieldValue("text");
break;
} else if (node->isElement("checkButton")) {
- s = getFieldValue("integer");
+ if (!(s = getFieldValue("integer"))) {
+ s = getFieldValue("text");
+ }
break;
} else if (node->isElement("barcode")) {
s = getFieldValue("text");
@@ -1921,6 +1935,22 @@ GString *XFAFormField::getFieldValue(const char *valueChildType) {
}
}
}
+ if (exclGroupName) {
+ p = exclGroupName->getCString();
+ if (xfaForm->xml->getRoot() && !strncmp(p, "form.", 5)) {
+ if ((datasets =
+ xfaForm->xml->getRoot()->findFirstChildElement("xfa:datasets")) &&
+ (data = datasets->findFirstChildElement("xfa:data"))) {
+ elem = findFieldInDatasets(data, p + 5);
+ if (elem &&
+ elem->getFirstChild() &&
+ elem->getFirstChild()->isCharData() &&
+ ((ZxCharData *)elem->getFirstChild())->getData()->getLength() > 0) {
+ return ((ZxCharData *)elem->getFirstChild())->getData();
+ }
+ }
+ }
+ }
// check the <form> element
p = fullName->getCString();
@@ -1955,7 +1985,9 @@ GString *XFAFormField::getFieldValue(const char *valueChildType) {
ZxElement *XFAFormField::findFieldInDatasets(ZxElement *elem, char *partName) {
ZxNode *node;
+ ZxElement *result;
GString *nodeName;
+ char *next;
int curIdx, idx, n;
curIdx = 0;
@@ -1976,11 +2008,21 @@ ZxElement *XFAFormField::findFieldInDatasets(ZxElement *elem, char *partName) {
if (!partName[n]) {
return (ZxElement *)node;
} else if (partName[n] == '.') {
- return findFieldInDatasets((ZxElement *)node, partName + n + 1);
+ if ((result = findFieldInDatasets((ZxElement *)node,
+ partName + n + 1))) {
+ return result;
+ }
+ break;
}
}
}
}
+
+ // search for an "ancestor match"
+ if ((next = strchr(partName, '.'))) {
+ return findFieldInDatasets(elem, next + 1);
+ }
+
return NULL;
}
@@ -2054,14 +2096,26 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
double x, double y, double w, double h,
GBool whiteBackground,
GfxFontDict *fontDict, GString *appearBuf) {
+ GString *text2;
GfxFont *font;
const char *fontTag;
GString *s;
+ Unicode u;
double yTop, xx, yy, tw, charWidth, lineHeight;
double ascent, descent, rectX, rectY, rectW, rectH, blkH;
int nLines, line, i, j, k, c, rectI;
- //~ deal with Unicode text (is it UTF-8?)
+ // convert UTF-8 to Latin1
+ //~ this currently drops all non-Latin1 characters
+ text2 = new GString();
+ i = 0;
+ while (getUTF8(text, &i, &u)) {
+ if (u <= 0xff) {
+ text2->append((char)u);
+ } else {
+ text2->append('?');
+ }
+ }
// find the font
if ((font = findFont(fontDict, fontName, bold, italic))) {
@@ -2093,8 +2147,8 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
if (vAlign == xfaVAlignBottom || vAlign == xfaVAlignMiddle) {
nLines = 0;
i = 0;
- while (i < text->getLength()) {
- getNextLine(text, i, font, fontSize, w, &j, &tw, &k);
+ while (i < text2->getLength()) {
+ getNextLine(text2, i, font, fontSize, w, &j, &tw, &k);
++nLines;
i = k;
}
@@ -2114,9 +2168,9 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
// write a series of lines of text
line = 0;
i = 0;
- while (i < text->getLength()) {
+ while (i < text2->getLength()) {
- getNextLine(text, i, font, fontSize, w, &j, &tw, &k);
+ getNextLine(text2, i, font, fontSize, w, &j, &tw, &k);
if (tw > rectW) {
rectW = tw;
}
@@ -2140,7 +2194,7 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
appearBuf->appendf("1 0 0 1 {0:.4f} {1:.4f} Tm\n", xx, yy);
appearBuf->append('(');
for (; i < j; ++i) {
- c = text->getChar(i) & 0xff;
+ c = text2->getChar(i) & 0xff;
if (c == '(' || c == ')' || c == '\\') {
appearBuf->append('\\');
appearBuf->append((char)c);
@@ -2172,13 +2226,13 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
xx = x;
break;
case xfaHAlignCenter:
- xx = x + (int)(0.5 * (combCells - text->getLength())) * tw;
+ xx = x + (int)(0.5 * (combCells - text2->getLength())) * tw;
break;
case xfaHAlignRight:
- xx = x + w - text->getLength() * tw;
+ xx = x + w - text2->getLength() * tw;
break;
}
- rectW = text->getLength() * tw;
+ rectW = text2->getLength() * tw;
switch (vAlign) {
case xfaVAlignTop:
default:
@@ -2195,8 +2249,8 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
rectH = ascent - descent;
// write the text string
- for (i = 0; i < text->getLength(); ++i) {
- c = text->getChar(i) & 0xff;
+ for (i = 0; i < text2->getLength(); ++i) {
+ c = text2->getChar(i) & 0xff;
if (font && !font->isCIDFont()) {
charWidth = fontSize * ((Gfx8BitFont *)font)->getWidth((Guchar)c);
appearBuf->appendf("1 0 0 1 {0:.4f} {1:.4f} Tm\n",
@@ -2223,12 +2277,12 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
// compute string width
if (font && !font->isCIDFont()) {
tw = 0;
- for (i = 0; i < text->getLength(); ++i) {
- tw += ((Gfx8BitFont *)font)->getWidth(text->getChar(i));
+ for (i = 0; i < text2->getLength(); ++i) {
+ tw += ((Gfx8BitFont *)font)->getWidth(text2->getChar(i));
}
} else {
// otherwise, make a crude estimate
- tw = text->getLength() * 0.5;
+ tw = text2->getLength() * 0.5;
}
tw *= fontSize;
rectW = tw;
@@ -2264,8 +2318,8 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
// write the text string
appearBuf->append('(');
- for (i = 0; i < text->getLength(); ++i) {
- c = text->getChar(i) & 0xff;
+ for (i = 0; i < text2->getLength(); ++i) {
+ c = text2->getChar(i) & 0xff;
if (c == '(' || c == ')' || c == '\\') {
appearBuf->append('\\');
appearBuf->append((char)c);
@@ -2304,6 +2358,8 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
appearBuf->insert(rectI, s);
delete s;
}
+
+ delete text2;
}
// Searches <fontDict> for a font matching(<fontName>, <bold>,
@@ -2734,7 +2790,7 @@ GString *XFAFormField::pictureFormatDateTime(GString *value, GString *picture) {
u <<= 4;
if (c >= '0' && c <= '9') {
u += c - '0';
- } else if (c >= 'a' && c <= 'F') {
+ } else if (c >= 'a' && c <= 'f') {
u += c - 'a' + 10;
} else if (c >= 'A' && c <= 'F') {
u += c - 'A' + 10;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h
index 8e0b363386a..2f56e728a98 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h
@@ -63,11 +63,11 @@ private:
GBool inPageSet, XFATableInfo *tableInfo,
GHash *nameCount, GHash *nameIdx,
GHash *fullNameCount, GHash *fullNameIdx,
- Catalog *catalog);
+ GString *exclGroupName, Catalog *catalog);
void scanNames(ZxElement *elem, GHash *nameCount);
void scanFullNames(ZxElement *elem, GHash *fullNameCount);
void scanField(ZxElement *elem, GString *name, GString *fullName,
- GBool inPageSet,
+ GString *exclGroupName, GBool inPageSet,
XFATableInfo *tableInfo, int colSpan,
Catalog *catalog);
void scanNonField(ZxElement *elem, GString *name, GString *fullName,
@@ -102,7 +102,7 @@ class XFAFormField: public FormField {
public:
XFAFormField(XFAForm *xfaFormA, ZxElement *xmlA,
- GString *nameA, GString *fullNameA,
+ GString *nameA, GString *fullNameA, GString *exclGroupNameA,
int pageNumA, double xOffsetA, double yOffsetA,
double columnWidthA, double rowHeightA);
@@ -166,6 +166,7 @@ private:
ZxElement *xml;
GString *name;
GString *fullName;
+ GString *exclGroupName;
int pageNum;
double xOffset, yOffset;
double columnWidth; // column width, if this field is in a
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/config.h b/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
index f5c566e9696..3dbed2ae93c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
@@ -14,14 +14,14 @@
//------------------------------------------------------------------------
// xpdf version
-#define xpdfVersion "4.01.01"
-#define xpdfVersionNum 4.01
+#define xpdfVersion "4.02"
+#define xpdfVersionNum 4.02
#define xpdfMajorVersion 4
-#define xpdfMinorVersion 1
-#define xpdfUpdateVersion 1
+#define xpdfMinorVersion 2
+#define xpdfUpdateVersion 0
#define xpdfMajorVersionStr "4"
-#define xpdfMinorVersionStr "1"
-#define xpdfUpdateVersionStr "1"
+#define xpdfMinorVersionStr "2"
+#define xpdfUpdateVersionStr "0"
// supported PDF version
#define supportedPDFVersionStr "2.0"
@@ -31,7 +31,7 @@
#define xpdfCopyright "Copyright 1996-2019 Glyph & Cog, LLC"
// Windows resource file stuff
-#define winxpdfVersion "WinXpdf 4.01.01"
+#define winxpdfVersion "WinXpdf 4.02"
#define xpdfCopyrightAmp "Copyright 1996-2019 Glyph && Cog, LLC"
//------------------------------------------------------------------------
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
index 7df38cc11d7..22298b138c5 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
@@ -159,11 +159,11 @@ int main(int argc, char *argv[]) {
// scan the fonts
if (showFontLoc || showFontLocPS) {
- printf("name type emb sub uni prob object ID location\n");
- printf("------------------------------------ ----------------- --- --- --- ---- --------- --------\n");
+ printf("name type emb sub uni prob object ID location\n");
+ printf("---------------------------------------------- ----------------- --- --- --- ---- --------- --------\n");
} else {
- printf("name type emb sub uni prob object ID\n");
- printf("------------------------------------ ----------------- --- --- --- ---- ---------\n");
+ printf("name type emb sub uni prob object ID\n");
+ printf("---------------------------------------------- ----------------- --- --- --- ---- ---------\n");
}
fonts = NULL;
fontsLen = fontsSize = 0;
@@ -302,7 +302,7 @@ static void scanFonts(Dict *resDict, PDFDoc *doc) {
resDict->lookupNF("ExtGState", &gsDict1);
if (checkObject(&gsDict1, &gsDict2) && gsDict2.isDict()) {
for (i = 0; i < gsDict2.dictGetLength(); ++i) {
- gsDict1.dictGetValNF(i, &gs1);
+ gsDict2.dictGetValNF(i, &gs1);
if (checkObject(&gs1, &gs2) && gs2.isDict()) {
gs2.dictLookupNF("SMask", &smask1);
if (checkObject(&smask1, &smask2) && smask2.isDict()) {
@@ -375,7 +375,7 @@ static void scanFont(GfxFont *font, PDFDoc *doc) {
}
// print the font info
- printf("%-36s %-17s %-3s %-3s %-3s %-4s",
+ printf("%-46s %-17s %-3s %-3s %-3s %-4s",
name ? name->getCString() : "[none]",
fontTypeNames[font->getType()],
emb ? "yes" : "no",
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
index b458202effb..29095509bed 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
@@ -171,6 +171,7 @@ int main(int argc, char *argv[]) {
htmlGen->setZoom(zoom);
htmlGen->setDrawInvisibleText(!skipInvisible);
htmlGen->setAllTextInvisible(allInvisible);
+ htmlGen->setExtractFontFiles(gTrue);
htmlGen->startDoc(doc);
// convert the pages
@@ -191,7 +192,7 @@ int main(int argc, char *argv[]) {
goto err2;
}
pngURL = GString::format("page{0:d}.png", pg);
- err = htmlGen->convertPage(pg, pngURL->getCString(),
+ err = htmlGen->convertPage(pg, pngURL->getCString(), htmlDir,
&writeToFile, htmlFile,
&writeToFile, pngFile);
delete pngURL;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
index 720066d32a8..64a0087c7d3 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
@@ -352,6 +352,7 @@ static void writePNGData(png_structp png, SplashBitmap *bitmap) {
+
static void finishPNG(png_structp *png, png_infop *pngInfo) {
if (setjmp(png_jmpbuf(*png))) {
exit(2);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
index 0496c6442ff..aa74fb68612 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
@@ -50,6 +50,10 @@ static char textEncName[128] = "";
static char textEOL[16] = "";
static GBool noPageBreaks = gFalse;
static GBool insertBOM = gFalse;
+static double marginLeft = 0;
+static double marginRight = 0;
+static double marginTop = 0;
+static double marginBottom = 0;
static char ownerPassword[33] = "\001";
static char userPassword[33] = "\001";
static GBool quiet = gFalse;
@@ -88,6 +92,14 @@ static ArgDesc argDesc[] = {
"don't insert page breaks between pages"},
{"-bom", argFlag, &insertBOM, 0,
"insert a Unicode BOM at the start of the text file"},
+ {"-marginl", argFP, &marginLeft, 0,
+ "left page margin"},
+ {"-marginr", argFP, &marginRight, 0,
+ "right page margin"},
+ {"-margint", argFP, &marginTop, 0,
+ "top page margin"},
+ {"-marginb", argFP, &marginBottom, 0,
+ "bottom page margin"},
{"-opw", argString, ownerPassword, sizeof(ownerPassword),
"owner password (for encrypted files)"},
{"-upw", argString, userPassword, sizeof(userPassword),
@@ -247,6 +259,10 @@ int main(int argc, char *argv[]) {
textOutControl.clipText = clipText;
textOutControl.discardDiagonalText = discardDiag;
textOutControl.insertBOM = insertBOM;
+ textOutControl.marginLeft = marginLeft;
+ textOutControl.marginRight = marginRight;
+ textOutControl.marginTop = marginTop;
+ textOutControl.marginBottom = marginBottom;
textOut = new TextOutputDev(textFileName->getCString(), &textOutControl,
gFalse);
if (textOut->isOk()) {