summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2017-08-13 07:14:48 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2017-08-13 07:14:48 +0000
commit4b4995cda35627e06c43e25ecbe07c1bc1859bb5 (patch)
tree143ed02a389bab62f44043a54cbc70f69e312e2f /Build/source/libs/xpdf
parent00d00899c484b81967558f43c4fe4a896ffdf610 (diff)
xpdf 4.00
git-svn-id: svn://tug.org/texlive/trunk@45031 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/xpdf')
-rw-r--r--Build/source/libs/xpdf/ChangeLog6
-rw-r--r--Build/source/libs/xpdf/Makefile.am1
-rw-r--r--Build/source/libs/xpdf/Makefile.in6
-rw-r--r--Build/source/libs/xpdf/TLpatches/ChangeLog8
-rw-r--r--Build/source/libs/xpdf/TLpatches/TL-Changes8
-rw-r--r--Build/source/libs/xpdf/TLpatches/patch-10-exclude-body-of-Page_getDefaultCTM23
-rw-r--r--Build/source/libs/xpdf/TLpatches/patch-20-skip-reading-config-file60
-rw-r--r--Build/source/libs/xpdf/TLpatches/patch-22-exclude-openTempFile34
-rw-r--r--Build/source/libs/xpdf/TLpatches/patch-30-include-strings_h15
-rw-r--r--Build/source/libs/xpdf/TLpatches/patch-40-W32TeX29
-rw-r--r--Build/source/libs/xpdf/TLpatches/patch-41-W32TeX177
-rw-r--r--Build/source/libs/xpdf/TLpatches/patch-bunched176
-rwxr-xr-xBuild/source/libs/xpdf/configure20
-rw-r--r--Build/source/libs/xpdf/version.ac2
-rw-r--r--Build/source/libs/xpdf/xpdf-foolabs/README2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/ANNOUNCE34
-rw-r--r--Build/source/libs/xpdf/xpdf-src/CHANGES133
-rw-r--r--Build/source/libs/xpdf/xpdf-src/CMakeLists.txt41
-rw-r--r--Build/source/libs/xpdf/xpdf-src/INSTALL242
-rw-r--r--Build/source/libs/xpdf/xpdf-src/Makefile.in134
-rw-r--r--Build/source/libs/xpdf/xpdf-src/README94
-rw-r--r--Build/source/libs/xpdf/xpdf-src/aclocal.m4274
-rw-r--r--Build/source/libs/xpdf/xpdf-src/aconf-dj.h73
-rw-r--r--Build/source/libs/xpdf/xpdf-src/aconf-win32.h112
-rw-r--r--Build/source/libs/xpdf/xpdf-src/aconf.h.in107
-rw-r--r--Build/source/libs/xpdf/xpdf-src/aconf2.h2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/cmake-config.txt290
-rwxr-xr-xBuild/source/libs/xpdf/xpdf-src/configure9386
-rw-r--r--Build/source/libs/xpdf/xpdf-src/configure.in398
-rwxr-xr-xBuild/source/libs/xpdf/xpdf-src/dj_make.bat91
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.110
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat10
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdffonts.114
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat33
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfimages.138
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat55
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.112
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat12
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.136
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat41
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftopng.115
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.117
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat16
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftops.124
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat36
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftotext.126
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat60
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/sample-xpdfrc2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/xpdf.11005
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat884
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.5409
-rw-r--r--Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat467
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/CMakeLists.txt26
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc149
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc831
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h30
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/Makefile.dep0
-rw-r--r--Build/source/libs/xpdf/xpdf-src/fofi/Makefile.in71
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/CMakeLists.txt27
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.cc3
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h59
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/GHash.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/GList.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/GMutex.h55
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/GString.cc19
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/Makefile.dep0
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/Makefile.in71
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/gfile.cc216
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/gfile.h64
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/gmem.cc67
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/gmem.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/gmempp.cc23
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/gmempp.h48
-rw-r--r--Build/source/libs/xpdf/xpdf-src/goo/parseargs.c13
-rw-r--r--Build/source/libs/xpdf/xpdf-src/misc/hello.pdfbin917 -> 0 bytes
-rw-r--r--Build/source/libs/xpdf/xpdf-src/misc/xpdf.dt28
-rwxr-xr-xBuild/source/libs/xpdf/xpdf-src/ms_make.bat134
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt47
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/Makefile.dep0
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/Makefile.in93
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/Splash.cc1957
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/Splash.h26
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashClip.cc153
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashClip.h24
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.cc45
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.cc53
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.h10
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.cc36
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.h16
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFont.cc9
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFont.h13
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc32
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h12
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.cc16
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.h24
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h194
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashPath.cc27
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashPath.h10
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.h16
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc47
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashState.h9
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashTypes.h10
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc377
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.h54
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.cc929
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.h61
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc626
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h35
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc312
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h13
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Array.h12
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFontTables.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt228
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc22
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc314
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h22
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc177
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h8
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CoreOutputDev.cc61
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/CoreOutputDev.h61
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc96
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h10
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h12
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.cc223
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.h173
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc8
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Error.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/FontEncodingTables.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Form.cc70
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Form.h13
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc25
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc687
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h28
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc565
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h33
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc215
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h137
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc701
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h135
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc436
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h18
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc208
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h25
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc88
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc88
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc53
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.h6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Makefile.dep0
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Makefile.in687
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc21
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Object.h14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc42
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc3
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc3
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h8
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc2723
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h324
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc47
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h9
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PDFDocEncoding.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc2786
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h130
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc1
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc34
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Page.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc53
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h3
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc25
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc355
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h38
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc1852
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h38
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc1396
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h107
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc1556
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h147
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TextString.cc95
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.cc562
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.h78
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc447
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.h77
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc1614
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h243
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.cc182
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.h84
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc25
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMapTables.h3
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc2
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc2115
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h59
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XPDFApp.cc447
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XPDFApp.h114
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.cc1680
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.h253
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XPDFTree.cc951
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XPDFTree.h46
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XPDFTreeP.h88
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XPDFViewer.cc3582
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XPDFViewer.h357
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc109
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h24
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XpdfPluginAPI.cc262
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/XpdfPluginAPI.h341
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc231
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h30
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/about-text.h24
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/about.xbm6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/backArrow.xbm6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/backArrowDis.xbm6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/config.h22
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/dblLeftArrow.xbm6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/dblLeftArrowDis.xbm6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/dblRightArrow.xbm6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/dblRightArrowDis.xbm6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/find.xbm6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/findDis.xbm6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/forwardArrow.xbm6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/forwardArrowDis.xbm6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/leftArrow.xbm5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/leftArrowDis.xbm5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc19
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc12
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc14
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc108
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc54
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc42
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc21
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/print.xbm6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/printDis.xbm6
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/rightArrow.xbm5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/rightArrowDis.xbm5
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/xpdf.cc334
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/xpdfIcon.xpm62
260 files changed, 24255 insertions, 30553 deletions
diff --git a/Build/source/libs/xpdf/ChangeLog b/Build/source/libs/xpdf/ChangeLog
index d8345036d99..0acdf955a83 100644
--- a/Build/source/libs/xpdf/ChangeLog
+++ b/Build/source/libs/xpdf/ChangeLog
@@ -1,3 +1,9 @@
+2017-08-13 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * Import xpdf-4.00.
+ * Makefile.am, version.ac: Adjust.
+ * xpdf-foolabs: Remove.
+
2017-03-27 Karl Berry <karl@freefriends.org>
* Makefile.am (EXTRA_DIST): TLpatches not Tlpatches.
diff --git a/Build/source/libs/xpdf/Makefile.am b/Build/source/libs/xpdf/Makefile.am
index f5005923108..1e42d919a07 100644
--- a/Build/source/libs/xpdf/Makefile.am
+++ b/Build/source/libs/xpdf/Makefile.am
@@ -112,6 +112,7 @@ xpdf_libxpdf_a_sources = \
@XPDF_TREE@/xpdf/Stream.cc \
@XPDF_TREE@/xpdf/TextString.cc \
@XPDF_TREE@/xpdf/UnicodeMap.cc \
+ @XPDF_TREE@/xpdf/UTF8.cc \
@XPDF_TREE@/xpdf/XFAForm.cc \
@XPDF_TREE@/xpdf/XRef.cc \
@XPDF_TREE@/xpdf/Zoox.cc
diff --git a/Build/source/libs/xpdf/Makefile.in b/Build/source/libs/xpdf/Makefile.in
index a149fdcc561..05537d910c7 100644
--- a/Build/source/libs/xpdf/Makefile.in
+++ b/Build/source/libs/xpdf/Makefile.in
@@ -160,6 +160,7 @@ am__objects_3 = @XPDF_TREE@/xpdf/AcroForm.$(OBJEXT) \
@XPDF_TREE@/xpdf/Stream.$(OBJEXT) \
@XPDF_TREE@/xpdf/TextString.$(OBJEXT) \
@XPDF_TREE@/xpdf/UnicodeMap.$(OBJEXT) \
+ @XPDF_TREE@/xpdf/UTF8.$(OBJEXT) \
@XPDF_TREE@/xpdf/XFAForm.$(OBJEXT) \
@XPDF_TREE@/xpdf/XRef.$(OBJEXT) \
@XPDF_TREE@/xpdf/Zoox.$(OBJEXT)
@@ -472,6 +473,7 @@ xpdf_libxpdf_a_sources = \
@XPDF_TREE@/xpdf/Stream.cc \
@XPDF_TREE@/xpdf/TextString.cc \
@XPDF_TREE@/xpdf/UnicodeMap.cc \
+ @XPDF_TREE@/xpdf/UTF8.cc \
@XPDF_TREE@/xpdf/XFAForm.cc \
@XPDF_TREE@/xpdf/XRef.cc \
@XPDF_TREE@/xpdf/Zoox.cc
@@ -677,6 +679,9 @@ clean-noinstLIBRARIES:
@XPDF_TREE@/xpdf/UnicodeMap.$(OBJEXT): \
@XPDF_TREE@/xpdf/$(am__dirstamp) \
@XPDF_TREE@/xpdf/$(DEPDIR)/$(am__dirstamp)
+@XPDF_TREE@/xpdf/UTF8.$(OBJEXT): \
+ @XPDF_TREE@/xpdf/$(am__dirstamp) \
+ @XPDF_TREE@/xpdf/$(DEPDIR)/$(am__dirstamp)
@XPDF_TREE@/xpdf/XFAForm.$(OBJEXT): @XPDF_TREE@/xpdf/$(am__dirstamp) \
@XPDF_TREE@/xpdf/$(DEPDIR)/$(am__dirstamp)
@XPDF_TREE@/xpdf/XRef.$(OBJEXT): @XPDF_TREE@/xpdf/$(am__dirstamp) \
@@ -748,6 +753,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@@XPDF_TREE@/xpdf/$(DEPDIR)/Stream.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@XPDF_TREE@/xpdf/$(DEPDIR)/TextString.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@XPDF_TREE@/xpdf/$(DEPDIR)/UnicodeMap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@@XPDF_TREE@/xpdf/$(DEPDIR)/UTF8.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@XPDF_TREE@/xpdf/$(DEPDIR)/XFAForm.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@XPDF_TREE@/xpdf/$(DEPDIR)/XRef.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@@XPDF_TREE@/xpdf/$(DEPDIR)/Zoox.Po@am__quote@
diff --git a/Build/source/libs/xpdf/TLpatches/ChangeLog b/Build/source/libs/xpdf/TLpatches/ChangeLog
index f00ad4df94c..67389ffa67a 100644
--- a/Build/source/libs/xpdf/TLpatches/ChangeLog
+++ b/Build/source/libs/xpdf/TLpatches/ChangeLog
@@ -1,3 +1,11 @@
+2017-08-13 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ Imported xpdf-4.00 source tree:
+ http://www.xpdfreader.com/download.html
+ xpdf-4.00.tar.gz
+ * patch-bunched: Added patch-10, patch-20, patch-22, patch-30,
+ patch-40, and patch-41 by Peter, for simplicity.
+
2015-05-09 Peter Breitenlohner <peb@mppmu.mpg.de>
* patch-41-W32TeX: On Windows use USERPROFILE instead of HOME.
diff --git a/Build/source/libs/xpdf/TLpatches/TL-Changes b/Build/source/libs/xpdf/TLpatches/TL-Changes
index 16c6b27b495..cab5d4eaeaa 100644
--- a/Build/source/libs/xpdf/TLpatches/TL-Changes
+++ b/Build/source/libs/xpdf/TLpatches/TL-Changes
@@ -1,6 +1,6 @@
-Changes applied to the xpdf-3.04/ tree as obtained from:
- ftp://ftp.foolabs.com/pub/xpdf/
+Changes applied to the xpdf-4.00/ tree as obtained from:
+ http://www.xpdfreader.com/download.html
Removed:
- install-sh
-
+ aconf.h.in
+ xpdf-qt/
diff --git a/Build/source/libs/xpdf/TLpatches/patch-10-exclude-body-of-Page_getDefaultCTM b/Build/source/libs/xpdf/TLpatches/patch-10-exclude-body-of-Page_getDefaultCTM
deleted file mode 100644
index da4d8519c31..00000000000
--- a/Build/source/libs/xpdf/TLpatches/patch-10-exclude-body-of-Page_getDefaultCTM
+++ /dev/null
@@ -1,23 +0,0 @@
- Enable compilation with -DPDF_PARSER_ONLY
-
-diff -ur -N xpdf-3.04.orig/xpdf/Page.cc xpdf-3.04/xpdf/Page.cc
---- xpdf-3.04.orig/xpdf/Page.cc 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/xpdf/Page.cc 2014-05-30 19:57:46.000000000 +0200
-@@ -468,9 +468,9 @@
- delete links;
- }
-
--#ifndef PDF_PARSER_ONLY
- void Page::getDefaultCTM(double *ctm, double hDPI, double vDPI,
- int rotate, GBool useMediaBox, GBool upsideDown) {
-+#ifndef PDF_PARSER_ONLY
- GfxState *state;
- int i;
-
-@@ -487,5 +487,5 @@
- ctm[i] = state->getCTM()[i];
- }
- delete state;
--}
- #endif
-+}
diff --git a/Build/source/libs/xpdf/TLpatches/patch-20-skip-reading-config-file b/Build/source/libs/xpdf/TLpatches/patch-20-skip-reading-config-file
deleted file mode 100644
index 5c20dccdd72..00000000000
--- a/Build/source/libs/xpdf/TLpatches/patch-20-skip-reading-config-file
+++ /dev/null
@@ -1,60 +0,0 @@
- Patches for pdfTeX / luaTeX / XeTeX
-
- Declare GlobalParams constructor with a default config file argument
- and skip reading a config file.
-
- from:
- Han The Thanh <thanh@pdftex.org>
- Peter Breitenlohner <tex-live@tug.org>
-
-diff -ur -N xpdf-3.04.orig/xpdf/GlobalParams.cc xpdf-3.04/xpdf/GlobalParams.cc
---- xpdf-3.04.orig/xpdf/GlobalParams.cc 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/xpdf/GlobalParams.cc 2014-05-30 19:29:23.000000000 +0200
-@@ -5,6 +5,9 @@
- // Copyright 2001-2003 Glyph & Cog, LLC
- //
- //========================================================================
-+// Modified for TeX Live by Peter Breitenlohner <tex-live@tug.org>
-+// See top-level ChangeLog for a list of all modifications
-+//========================================================================
-
- #include <aconf.h>
-
-@@ -812,6 +815,7 @@
- f = NULL;
- fileName = NULL;
- if (cfgFileName && cfgFileName[0]) {
-+#ifndef PDF_PARSER_ONLY
- fileName = new GString(cfgFileName);
- if (!(f = fopen(fileName->getCString(), "r"))) {
- delete fileName;
-@@ -844,6 +848,7 @@
- parseFile(fileName, f);
- delete fileName;
- fclose(f);
-+#endif /* !PDF_PARSER_ONLY */
- }
- }
-
-diff -ur -N xpdf-3.04.orig/xpdf/GlobalParams.h xpdf-3.04/xpdf/GlobalParams.h
---- xpdf-3.04.orig/xpdf/GlobalParams.h 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/xpdf/GlobalParams.h 2014-05-30 19:29:23.000000000 +0200
-@@ -5,6 +5,9 @@
- // Copyright 2001-2003 Glyph & Cog, LLC
- //
- //========================================================================
-+// Modified for TeX Live by Peter Breitenlohner <tex-live@tug.org>
-+// See top-level ChangeLog for a list of all modifications
-+//========================================================================
-
- #ifndef GLOBALPARAMS_H
- #define GLOBALPARAMS_H
-@@ -173,7 +176,7 @@
-
- // Initialize the global parameters by attempting to read a config
- // file.
-- GlobalParams(const char *cfgFileName);
-+ GlobalParams(const char *cfgFileName = NULL);
-
- ~GlobalParams();
-
diff --git a/Build/source/libs/xpdf/TLpatches/patch-22-exclude-openTempFile b/Build/source/libs/xpdf/TLpatches/patch-22-exclude-openTempFile
deleted file mode 100644
index be04bd4042d..00000000000
--- a/Build/source/libs/xpdf/TLpatches/patch-22-exclude-openTempFile
+++ /dev/null
@@ -1,34 +0,0 @@
- Patches for pdfTeX / luaTeX / XeTeX
-
- from:
- Han The Thanh <thanh@pdftex.org>
-
-diff -ur -N xpdf-3.04.orig/goo/gfile.cc xpdf-3.04/goo/gfile.cc
---- xpdf-3.04.orig/goo/gfile.cc 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/goo/gfile.cc 2014-05-30 19:42:41.000000000 +0200
-@@ -7,6 +7,9 @@
- // Copyright 1996-2003 Glyph & Cog, LLC
- //
- //========================================================================
-+// Modified for TeX Live by Peter Breitenlohner <tex-live@tug.org>
-+// See top-level ChangeLog for a list of all modifications
-+//========================================================================
-
- #include <aconf.h>
-
-@@ -441,6 +444,7 @@
- #endif
- }
-
-+#ifndef PDF_PARSER_ONLY
- GBool openTempFile(GString **name, FILE **f,
- const char *mode, const char *ext) {
- #if defined(_WIN32)
-@@ -551,6 +555,7 @@
- return gTrue;
- #endif
- }
-+#endif
-
- GBool createDir(char *path, int mode) {
- #ifdef _WIN32
diff --git a/Build/source/libs/xpdf/TLpatches/patch-30-include-strings_h b/Build/source/libs/xpdf/TLpatches/patch-30-include-strings_h
deleted file mode 100644
index f9b694650b1..00000000000
--- a/Build/source/libs/xpdf/TLpatches/patch-30-include-strings_h
+++ /dev/null
@@ -1,15 +0,0 @@
- The Posix manpage says strcasecmp() is declared in <strings.h>
- and this indeed required for AIX 4.3 and xlc.
-
-diff -ur -N xpdf-3.04.orig/xpdf/GlobalParams.cc xpdf-3.04/xpdf/GlobalParams.cc
---- xpdf-3.04.orig/xpdf/GlobalParams.cc 2014-05-30 19:29:23.000000000 +0200
-+++ xpdf-3.04/xpdf/GlobalParams.cc 2014-05-30 19:47:44.000000000 +0200
-@@ -54,6 +54,8 @@
- #ifdef _WIN32
- # define strcasecmp stricmp
- # define strncasecmp strnicmp
-+#else
-+# include <strings.h>
- #endif
-
- #if MULTITHREADED
diff --git a/Build/source/libs/xpdf/TLpatches/patch-40-W32TeX b/Build/source/libs/xpdf/TLpatches/patch-40-W32TeX
deleted file mode 100644
index 53a431f334a..00000000000
--- a/Build/source/libs/xpdf/TLpatches/patch-40-W32TeX
+++ /dev/null
@@ -1,29 +0,0 @@
- WIN32TeX uses MSVC 5.0 with the kpathsea headers and library.
-
-diff -ur -N xpdf-3.04.orig/xpdf/GlobalParams.cc xpdf-3.04/xpdf/GlobalParams.cc
---- xpdf-3.04.orig/xpdf/GlobalParams.cc 2014-05-30 19:47:44.000000000 +0200
-+++ xpdf-3.04/xpdf/GlobalParams.cc 2014-05-30 19:52:04.000000000 +0200
-@@ -52,6 +52,8 @@
- #include "GlobalParams.h"
-
- #ifdef _WIN32
-+# undef strcasecmp
-+# undef strncasecmp
- # define strcasecmp stricmp
- # define strncasecmp strnicmp
- #else
-diff -ur -N xpdf-3.04.orig/xpdf/config.h xpdf-3.04/xpdf/config.h
---- xpdf-3.04.orig/xpdf/config.h 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/xpdf/config.h 2014-05-30 19:52:04.000000000 +0200
-@@ -78,11 +78,6 @@
- // popen
- //------------------------------------------------------------------------
-
--#if defined(_MSC_VER) || defined(__BORLANDC__)
--#define popen _popen
--#define pclose _pclose
--#endif
--
- #if defined(VMS) || defined(VMCMS) || defined(DOS) || defined(OS2) || defined(__EMX__) || defined(_WIN32) || defined(__DJGPP__) || defined(MACOS)
- #define POPEN_READ_MODE "rb"
- #else
diff --git a/Build/source/libs/xpdf/TLpatches/patch-41-W32TeX b/Build/source/libs/xpdf/TLpatches/patch-41-W32TeX
deleted file mode 100644
index 28efb4219f3..00000000000
--- a/Build/source/libs/xpdf/TLpatches/patch-41-W32TeX
+++ /dev/null
@@ -1,177 +0,0 @@
-diff -ur -N xpdf-3.04.orig/goo/gfile.cc xpdf-3.04/goo/gfile.cc
---- xpdf-3.04.orig/goo/gfile.cc 2014-05-30 19:42:41.000000000 +0200
-+++ xpdf-3.04/goo/gfile.cc 2015-05-09 15:49:36.000000000 +0200
-@@ -55,7 +55,11 @@
- char *s;
- GString *ret;
-
-+#ifdef _WIN32
-+ if ((s = getenv("USERPROFILE")))
-+#else
- if ((s = getenv("HOME")))
-+#endif
- ret = new GString(s);
- else
- ret = new GString(".");
-@@ -559,7 +563,7 @@
-
- GBool createDir(char *path, int mode) {
- #ifdef _WIN32
-- return !mkdir(path);
-+ return !_mkdir(path);
- #else
- return !mkdir(path, mode);
- #endif
-diff -ur -N xpdf-3.04.orig/xpdf/GlobalParams.cc xpdf-3.04/xpdf/GlobalParams.cc
---- xpdf-3.04.orig/xpdf/GlobalParams.cc 2014-05-30 19:52:04.000000000 +0200
-+++ xpdf-3.04/xpdf/GlobalParams.cc 2015-05-07 08:43:30.000000000 +0200
-@@ -16,7 +16,9 @@
- #endif
-
- #ifdef _WIN32
-+# ifndef _WIN32_WINNT
- # define _WIN32_WINNT 0x0500 // for GetSystemWindowsDirectory
-+# endif
- # include <windows.h>
- #endif
- #include <string.h>
-@@ -54,8 +56,8 @@
- #ifdef _WIN32
- # undef strcasecmp
- # undef strncasecmp
--# define strcasecmp stricmp
--# define strncasecmp strnicmp
-+# define strcasecmp _stricmp
-+# define strncasecmp _strnicmp
- #else
- # include <strings.h>
- #endif
-@@ -2138,8 +2140,11 @@
- base14->fontNum,
- displayFontTab[i].obliqueFactor));
- } else {
-+// Do not display unnecessary looking message on W32
-+#ifndef _WIN32
- error(errConfig, -1, "No display font for '{0:s}'",
- displayFontTab[i].name);
-+#endif
- }
- }
- }
-diff -ur -N xpdf-3.04.orig/xpdf/pdfdetach.cc xpdf-3.04/xpdf/pdfdetach.cc
---- xpdf-3.04.orig/xpdf/pdfdetach.cc 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/xpdf/pdfdetach.cc 2015-05-07 08:43:30.000000000 +0200
-@@ -74,6 +74,9 @@
-
- exitCode = 99;
-
-+#ifdef _MSC_VER
-+ (void)kpse_set_program_name(argv[0], NULL);
-+#endif
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if ((doList ? 1 : 0) +
-diff -ur -N xpdf-3.04.orig/xpdf/pdffonts.cc xpdf-3.04/xpdf/pdffonts.cc
---- xpdf-3.04.orig/xpdf/pdffonts.cc 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/xpdf/pdffonts.cc 2015-05-07 08:43:30.000000000 +0200
-@@ -107,6 +107,9 @@
-
- exitCode = 99;
-
-+#ifdef _MSC_VER
-+ (void)kpse_set_program_name(argv[0], NULL);
-+#endif
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (!ok || argc != 2 || printVersion || printHelp) {
-diff -ur -N xpdf-3.04.orig/xpdf/pdfimages.cc xpdf-3.04/xpdf/pdfimages.cc
---- xpdf-3.04.orig/xpdf/pdfimages.cc 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/xpdf/pdfimages.cc 2015-05-07 08:43:30.000000000 +0200
-@@ -76,6 +76,9 @@
-
- exitCode = 99;
-
-+#ifdef _MSC_VER
-+ (void)kpse_set_program_name(argv[0], NULL);
-+#endif
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (!ok || argc != 3 || printVersion || printHelp) {
-diff -ur -N xpdf-3.04.orig/xpdf/pdfinfo.cc xpdf-3.04/xpdf/pdfinfo.cc
---- xpdf-3.04.orig/xpdf/pdfinfo.cc 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/xpdf/pdfinfo.cc 2015-05-07 08:43:30.000000000 +0200
-@@ -100,6 +100,9 @@
-
- exitCode = 99;
-
-+#ifdef _MSC_VER
-+ (void)kpse_set_program_name(argv[0], NULL);
-+#endif
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (!ok || argc != 2 || printVersion || printHelp) {
-diff -ur -N xpdf-3.04.orig/xpdf/pdftohtml.cc xpdf-3.04/xpdf/pdftohtml.cc
---- xpdf-3.04.orig/xpdf/pdftohtml.cc 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/xpdf/pdftohtml.cc 2015-05-07 08:43:30.000000000 +0200
-@@ -86,6 +86,9 @@
-
- exitCode = 99;
-
-+#ifdef _MSC_VER
-+ (void)kpse_set_program_name(argv[0], NULL);
-+#endif
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (!ok || argc != 3 || printVersion || printHelp) {
-diff -ur -N xpdf-3.04.orig/xpdf/pdftopng.cc xpdf-3.04/xpdf/pdftopng.cc
---- xpdf-3.04.orig/xpdf/pdftopng.cc 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/xpdf/pdftopng.cc 2015-05-07 08:43:30.000000000 +0200
-@@ -99,6 +99,9 @@
-
- exitCode = 99;
-
-+#ifdef _MSC_VER
-+ (void)kpse_set_program_name(argv[0], NULL);
-+#endif
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (mono && gray) {
-diff -ur -N xpdf-3.04.orig/xpdf/pdftoppm.cc xpdf-3.04/xpdf/pdftoppm.cc
---- xpdf-3.04.orig/xpdf/pdftoppm.cc 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/xpdf/pdftoppm.cc 2015-05-07 08:43:30.000000000 +0200
-@@ -111,6 +111,9 @@
-
- exitCode = 99;
-
-+#ifdef _MSC_VER
-+ (void)kpse_set_program_name(argv[0], NULL);
-+#endif
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (mono && gray) {
-diff -ur -N xpdf-3.04.orig/xpdf/pdftops.cc xpdf-3.04/xpdf/pdftops.cc
---- xpdf-3.04.orig/xpdf/pdftops.cc 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/xpdf/pdftops.cc 2015-05-07 08:43:30.000000000 +0200
-@@ -168,6 +168,9 @@
-
- exitCode = 99;
-
-+#ifdef _MSC_VER
-+ (void)kpse_set_program_name(argv[0], NULL);
-+#endif
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) {
-diff -ur -N xpdf-3.04.orig/xpdf/pdftotext.cc xpdf-3.04/xpdf/pdftotext.cc
---- xpdf-3.04.orig/xpdf/pdftotext.cc 2014-05-28 20:50:50.000000000 +0200
-+++ xpdf-3.04/xpdf/pdftotext.cc 2015-05-07 08:43:30.000000000 +0200
-@@ -129,6 +129,9 @@
-
- exitCode = 99;
-
-+#ifdef _MSC_VER
-+ (void)kpse_set_program_name(argv[0], NULL);
-+#endif
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) {
diff --git a/Build/source/libs/xpdf/TLpatches/patch-bunched b/Build/source/libs/xpdf/TLpatches/patch-bunched
new file mode 100644
index 00000000000..57d1de7e4b8
--- /dev/null
+++ b/Build/source/libs/xpdf/TLpatches/patch-bunched
@@ -0,0 +1,176 @@
+diff -ur xpdf-4.00.orig/goo/gfile.cc xpdf-4.00/goo/gfile.cc
+--- xpdf-4.00.orig/goo/gfile.cc Wed Aug 09 08:22:50 2017
++++ xpdf-4.00/goo/gfile.cc Sun Aug 13 13:46:03 2017
+@@ -7,6 +7,9 @@
+ // Copyright 1996-2003 Glyph & Cog, LLC
+ //
+ //========================================================================
++// Modified for TeX Live by Peter Breitenlohner <tex-live@tug.org>
++// See top-level ChangeLog for a list of all modifications
++//========================================================================
+
+ #include <aconf.h>
+
+@@ -51,7 +54,11 @@
+ char *s;
+ GString *ret;
+
++#ifdef _WIN32
++ if ((s = getenv("USERPROFILE")))
++#else
+ if ((s = getenv("HOME")))
++#endif
+ ret = new GString(s);
+ else
+ ret = new GString(".");
+@@ -400,6 +407,7 @@
+ #endif
+ }
+
++#ifndef PDF_PARSER_ONLY
+ GBool openTempFile(GString **name, FILE **f,
+ const char *mode, const char *ext) {
+ #if defined(_WIN32)
+@@ -514,10 +522,11 @@
+ return gTrue;
+ #endif
+ }
++#endif
+
+ GBool createDir(char *path, int mode) {
+ #ifdef _WIN32
+- return !mkdir(path);
++ return !_mkdir(path);
+ #else
+ return !mkdir(path, mode);
+ #endif
+diff -ur xpdf-4.00.orig/xpdf/GlobalParams.cc xpdf-4.00/xpdf/GlobalParams.cc
+--- xpdf-4.00.orig/xpdf/GlobalParams.cc Wed Aug 09 08:22:50 2017
++++ xpdf-4.00/xpdf/GlobalParams.cc Sun Aug 13 13:51:37 2017
+@@ -5,6 +5,9 @@
+ // Copyright 2001-2003 Glyph & Cog, LLC
+ //
+ //========================================================================
++// Modified for TeX Live by Peter Breitenlohner <tex-live@tug.org>
++// See top-level ChangeLog for a list of all modifications
++//========================================================================
+
+ #include <aconf.h>
+
+@@ -38,8 +41,12 @@
+ #include "GlobalParams.h"
+
+ #ifdef _WIN32
+-# define strcasecmp stricmp
+-# define strncasecmp strnicmp
++# undef strcasecmp
++# undef strncasecmp
++# define strcasecmp _stricmp
++# define strncasecmp _strnicmp
++#else
++# include <strings.h>
+ #endif
+
+ #if MULTITHREADED
+@@ -677,6 +684,7 @@
+ f = NULL;
+ fileName = NULL;
+ if (cfgFileName && cfgFileName[0]) {
++#ifndef PDF_PARSER_ONLY
+ fileName = new GString(cfgFileName);
+ if (!(f = fopen(fileName->getCString(), "r"))) {
+ delete fileName;
+@@ -709,6 +717,7 @@
+ parseFile(fileName, f);
+ delete fileName;
+ fclose(f);
++#endif /* !PDF_PARSER_ONLY */
+ }
+ }
+
+@@ -2105,8 +2114,11 @@
+ base14->fontNum,
+ displayFontTab[i].obliqueFactor));
+ } else {
++// Do not display unnecessary looking message on W32
++#ifndef _WIN32
+ error(errConfig, -1, "No display font for '{0:s}'",
+ displayFontTab[i].name);
++#endif
+ }
+ }
+ }
+diff -ur xpdf-4.00.orig/xpdf/GlobalParams.h xpdf-4.00/xpdf/GlobalParams.h
+--- xpdf-4.00.orig/xpdf/GlobalParams.h Wed Aug 09 08:22:50 2017
++++ xpdf-4.00/xpdf/GlobalParams.h Sun Aug 13 13:32:19 2017
+@@ -5,6 +5,9 @@
+ // Copyright 2001-2003 Glyph & Cog, LLC
+ //
+ //========================================================================
++// Modified for TeX Live by Peter Breitenlohner <tex-live@tug.org>
++// See top-level ChangeLog for a list of all modifications
++//========================================================================
+
+ #ifndef GLOBALPARAMS_H
+ #define GLOBALPARAMS_H
+@@ -217,7 +220,7 @@
+
+ // Initialize the global parameters by attempting to read a config
+ // file.
+- GlobalParams(const char *cfgFileName);
++ GlobalParams(const char *cfgFileName = NULL);
+
+ ~GlobalParams();
+
+diff -ur xpdf-4.00.orig/xpdf/Page.cc xpdf-4.00/xpdf/Page.cc
+--- xpdf-4.00.orig/xpdf/Page.cc Wed Aug 09 08:22:50 2017
++++ xpdf-4.00/xpdf/Page.cc Sun Aug 13 13:24:07 2017
+@@ -480,9 +480,9 @@
+ delete links;
+ }
+
+-#ifndef PDF_PARSER_ONLY
+ void Page::getDefaultCTM(double *ctm, double hDPI, double vDPI,
+ int rotate, GBool useMediaBox, GBool upsideDown) {
++#ifndef PDF_PARSER_ONLY
+ GfxState *state;
+ int i;
+
+@@ -499,5 +499,5 @@
+ ctm[i] = state->getCTM()[i];
+ }
+ delete state;
+-}
+ #endif
++}
+diff -ur xpdf-4.00.orig/xpdf/XFAForm.cc xpdf-4.00/xpdf/XFAForm.cc
+--- xpdf-4.00.orig/xpdf/XFAForm.cc Wed Aug 09 08:22:50 2017
++++ xpdf-4.00/xpdf/XFAForm.cc Sun Aug 13 14:28:34 2017
+@@ -27,8 +27,10 @@
+ #include "XFAForm.h"
+
+ #ifdef _WIN32
+-# define strcasecmp stricmp
+-# define strncasecmp strnicmp
++# undef strcasecmp
++# undef strncasecmp
++# define strcasecmp _stricmp
++# define strncasecmp _strnicmp
+ #endif
+
+ //------------------------------------------------------------------------
+diff -ur xpdf-4.00.orig/xpdf/config.h xpdf-4.00/xpdf/config.h
+--- xpdf-4.00.orig/xpdf/config.h Wed Aug 09 08:22:50 2017
++++ xpdf-4.00/xpdf/config.h Sun Aug 13 13:42:04 2017
+@@ -78,11 +78,6 @@
+ // popen
+ //------------------------------------------------------------------------
+
+-#if defined(_MSC_VER) || defined(__BORLANDC__)
+-#define popen _popen
+-#define pclose _pclose
+-#endif
+-
+ #if defined(VMS) || defined(VMCMS) || defined(DOS) || defined(OS2) || defined(__EMX__) || defined(_WIN32) || defined(__DJGPP__)
+ #define POPEN_READ_MODE "rb"
+ #else
diff --git a/Build/source/libs/xpdf/configure b/Build/source/libs/xpdf/configure
index 3adbfe0c4e7..a0db6c6cc84 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) 3.04.
+# Generated by GNU Autoconf 2.69 for xpdf (TeX Live) 4.00.
#
# 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='3.04'
-PACKAGE_STRING='xpdf (TeX Live) 3.04'
+PACKAGE_VERSION='4.00'
+PACKAGE_STRING='xpdf (TeX Live) 4.00'
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) 3.04 to adapt to many kinds of systems.
+\`configure' configures xpdf (TeX Live) 4.00 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) 3.04:";;
+ short | recursive ) echo "Configuration of xpdf (TeX Live) 4.00:";;
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 3.04
+xpdf (TeX Live) configure 4.00
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 3.04, which was
+It was created by xpdf (TeX Live) $as_me 4.00, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3790,7 +3790,7 @@ fi
# Define the identity of the package.
PACKAGE='xpdf--tex-live-'
- VERSION='3.04'
+ VERSION='4.00'
# Some tools Automake needs.
@@ -6703,7 +6703,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 3.04, which was
+This file was extended by xpdf (TeX Live) $as_me 4.00, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -6773,7 +6773,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 3.04
+xpdf (TeX Live) config.status 4.00
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 92ef926d85d..71236424efc 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], [3.04])
+m4_define([xpdf_version], [4.00])
diff --git a/Build/source/libs/xpdf/xpdf-foolabs/README b/Build/source/libs/xpdf/xpdf-foolabs/README
deleted file mode 100644
index 95dd725375a..00000000000
--- a/Build/source/libs/xpdf/xpdf-foolabs/README
+++ /dev/null
@@ -1,2 +0,0 @@
-Official patches as obtained from ftp://ftp.foolabs.com/pub/xpdf
-(if any).
diff --git a/Build/source/libs/xpdf/xpdf-src/ANNOUNCE b/Build/source/libs/xpdf/xpdf-src/ANNOUNCE
index d21dd9c1934..3274339e19c 100644
--- a/Build/source/libs/xpdf/xpdf-src/ANNOUNCE
+++ b/Build/source/libs/xpdf/xpdf-src/ANNOUNCE
@@ -1,31 +1,33 @@
-Subject: ANNOUNCE: Xpdf 3.04 - a PDF viewer for X
-
+Subject: ANNOUNCE: Xpdf 4.00 - 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 for X. The Xpdf
-project also includes a PDF text extractor, PDF-to-PostScript
-converter, and various other utilities.
+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 runs under the X Window System on Unix, and OS/2. The non-X
-components (pdftops, pdftotext, etc.) also run on Win32 systems and
-should run on pretty much any system with a decent C++ compiler.
+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.
Major changes:
-* New text extractor.
-* Added the pdftohtml tool.
-* Added the pdftopng tool.
-* New trapezoid-based rasterizer core (for performance).
+* Complete rewrite of the xpdf GUI, using Qt instead of Motif.
+* Multithreaded rasterization in the viewer - pages are now rasterized
+ in a separate thread so that scrolling and other UI activity is not
+ blocked.
+* Added a linear text selection mode.
See the `CHANGES' file for a complete list of changes.
Source (C++ and C) is available, and it should be fairly easy to
-compile for UNIX, OS/2, and Win32.
+compile for Linux and Windows.
More information, source code, and precompiled binaries are on the
-xpdf web page and ftp site:
+xpdf web page:
- http://www.foolabs.com/xpdf/
- ftp://ftp.foolabs.com/pub/xpdf/
+ http://www.xpdfreader.com/
For information on commercial licensing and consulting, please see the
Glyph & Cog web site:
diff --git a/Build/source/libs/xpdf/xpdf-src/CHANGES b/Build/source/libs/xpdf/xpdf-src/CHANGES
index d2228d233b3..5f4461feac3 100644
--- a/Build/source/libs/xpdf/xpdf-src/CHANGES
+++ b/Build/source/libs/xpdf/xpdf-src/CHANGES
@@ -2321,3 +2321,136 @@ When upsampling an image mask or image with a large resulting image
size, do it in stream mode instead of prescaling the whole image
(to avoid running out of memory).
Added infinite loop detection to pdffonts.
+
+4.00 (2017-aug-10)
+------------------
+Complete rewrite of the xpdf GUI, using Qt instead of Motif.
+Multithreaded rasterization in the viewer - pages are now rasterized
+ in a separate thread so that scrolling and other UI activity is not
+ blocked.
+Added a linear text selection mode.
+Limit transparency groups to the clip rectangle (performance
+ optimization).
+Optimized the SplashScreen code, used in 1-bit monochrome mode.
+Added setmode calls to pdftopng, when writing to stdout on Windows.
+ [Thanks to Robert Schroll.]
+Regenerate the appearance stream for an AcroForm field if there is
+ no appearance stream, even if NeedAppearances isn't set.
+When regenerating AcroForm field appearance streams, use a default
+ font (Helvetica) for fields that don't have a valid font.
+When the line width is increased by the minLineWidth setting, force
+ the line join mode to "bevel" to avoid "whiskers" at sharp corners.
+Change the pdftoppm/pdftopng resolution (-r) argument from an integer
+ to floating point.
+Use the FontDescriptor 'CapHeight' value in place of 'Ascent' if it's
+ available.
+OC (optional content) entries in image XObjects were being ignored.
+Added support for preblended soft-masked images.
+Added optional support for using libjpeg to decode DCT (JPEG)
+ streams.
+Transparency groups weren't being composited correctly in mono1 mode.
+Switched to a different IDCT transform in the DCT (JPEG) decoder, to
+ get better accuracy; the new transform is also a bit faster.
+Modified the polygon scan converter to avoid O(n^2) performance, which
+ can get really bad with paths that have extremely large numbers of
+ segments.
+Added the maxTileWidth, maxTileHeight, tileCacheSize, and
+ workerThreads xpdfrc settings.
+Modified PSOutputDev so it doesn't output resources (fonts, etc.) for
+ pages that are rasterized (because they use transparency).
+Added the -alpha flag to pdftopng.
+Handle TrueType fonts with out-of-bounds loca entries.
+Optimize consectutive "q" (gsave) operations in PostScript output.
+Various improvements to the XFA rendering code.
+Added the -nodiag flag to pdftotext.
+Switched to cmake instead of autoconf.
+Look for Widget-type annotations that aren't attached to the
+ AcroForm, and add them to the AcroForm.
+Added the "-z" option to pdftohtml.
+The JPEG 2000 decoder now treats invalid boxes after the image
+ codestream as non-fatal errors.
+Improved the handling of drop caps in pdftohtml.
+Added the "psNeverRasterize" setting.
+Pdftohtml now converts invisible PDF text to transparent HTML text.
+Check for zero-width/height bitmaps in the JBIG2 decoder -- these can
+ happen in corrupted JBIG2 streams.
+Pdfimages was inverting 1-bit monochrome images.
+Added CCITTFaxStream::getBlock() to speed up the CCITTFax decoder.
+Added resolution info to PNG files generated by pdftopng.
+The DCT decoder now ignores non-Adobe APP14 markers (rather than
+ generating an error).
+Regenerate appearance streams for FreeText annotations.
+The TextString class now handles UTF-16LE in addition to UTF-16BE.
+ (UTF-16LE isn't allowed by the PDF spec, but I've seen it used.)
+Added the simple one-column text extraction mode (pdftotext -simple).
+Added a -cmyk option to pdftoppm to write CMYK PAM files.
+Modified pdfinfo to output "static XFA" or "dynamic XFA", rather than
+ just "XFA".
+Added the "drawFormFields" xpdfrc command.
+Various performance optimizations in the rasterizer.
+Fixed the tiling pattern code to avoid stripes between pattern cells,
+ and to honor the TilingType flag.
+Always split axial shadings into 256 slices.
+Handle the case where an optional content block is left open at the
+ end of a page content stream.
+Accept code-to-CID-type CMaps as ToUnicode CMaps (to work around buggy
+ PDF generators).
+Unicode-to-unicode maps weren't working correctly with fonts that have
+ an "Identity" encoding.
+Modify the lexer to interpret "--123.4" as -123.4, "--123" as 0, and
+ "123-45" as "123" to match Adobe's behavior.
+The text extractor now reverses the order of side-by-side columns for
+ right-to-left scripts.
+Worked on right-to-left script support in pdftohtml (still not
+ complete).
+Switched the default display mode to continuous (from single page).
+Added the "-bom" switch to pdftotext.
+Share font objects when multiple font tags point to the same object.
+The transfer function goes before alpha blending in the rasterizer
+ pipeline.
+Added the "-allinvisible" switch to pdftohtml.
+Added overprint mode (OPM) support in Level 3 PostScript output.
+Added support for DeviceN color spaces in Level 3 PostScript output.
+Added the "-userunit" option to pdftops.
+Added the "-raw" and "-list" options to pdfimages.
+Pdfimages now writes PGM files (instead of PPM files) for DeviceGray
+ and CalGray images.
+Added grayscale PostScript output -- added the '-level2gray' and
+ '-level3gray' switches to pdftops.
+Fix up Type 1 fonts when embedding in PostScript.
+Added the "problematic" column to pdffonts output.
+Generate an appearance stream for signature fields in AcroForms.
+Correctly handle line dash patterns with zero-length segments when the
+ line cap is butt or project.
+Added the "strokeAdjust cad" xpdfrc option; fixed some issues with
+ stroke adjustment and projecting line caps.
+Added support for Code128B bar codes in XFA forms.
+Look at both the ON and OFF arrays in the default OCCD (optional
+ content config dict), to work around certain broken PDF files.
+Added support for XFA 'numericEdit' fields.
+Added support for 'picture' formatting in XFA forms.
+Added mouseClickN events (in addition to mousePressN and
+ mouseReleaseN).
+External CID OpenType CFF fonts should map through Unicode (similarly
+ to external CID TrueType fonts).
+Handle axial and radial shadings in SplashOutputDev, in device space.
+Use the PDF 2.0 inline image length field.
+Handle duplicate embedded Type 1 font names in PostScript output.
+Handle the case of a stroked closed path with a dash pattern -- if the
+ dash pattern is "on" at both the start and end of a subpath, it
+ should be joined.
+If the line dash phase is negative, add a multiple of 2x the total
+ dash length.
+Indexed color space indexes should be clipped to [0,hival].
+Fix the handling of the text render mode with Type 3 fonts, in the
+ rasterizer and in PostScript output.
+CID font metrics shouldn't be sorted - the PDF 2.0 spec says that, in
+ the case of duplicate entries, the first entry should be used.
+PSOutputDev now converts tiling patterns to PostScript tiling patterns
+ (in Level 2/3).
+Fixed a security hole in SecurityHandler.cc (uninitialized variables).
+ This vulnerability was discovered by Kushal Shah of Fortinet's
+ FortiGuard Labs.
+Fixed a security hole in Function.cc (write past end of array).
+Fixed a security hole with the use of d0/d1 operators outside of a
+ Type3 CharProc [CVE-2016-9027].
diff --git a/Build/source/libs/xpdf/xpdf-src/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/CMakeLists.txt
new file mode 100644
index 00000000000..a99cd253231
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/CMakeLists.txt
@@ -0,0 +1,41 @@
+#========================================================================
+#
+# cmake-xpdf.txt
+#
+# CMake script for the Xpdf package.
+#
+# Copyright 2015 Glyph & Cog, LLC
+#
+#========================================================================
+
+cmake_minimum_required(VERSION 2.8.8)
+
+project(xpdf)
+
+include(cmake-config.txt)
+
+add_subdirectory(goo)
+add_subdirectory(fofi)
+add_subdirectory(splash)
+add_subdirectory(xpdf)
+add_subdirectory(xpdf-qt)
+
+if (NOT HAVE_FREETYPE_H)
+ message(WARNING "Couldn't find FreeType -- will not build pdftoppm, pdftopng, pdftohtml, or xpdf.")
+endif ()
+
+if (NOT PNG_FOUND)
+ message(WARNING "Couldn't find libpng -- will not build pdftopng or pdftohtml.")
+endif ()
+
+if (NOT QT4_FOUND AND NOT Qt5Widgets_FOUND)
+ message(WARNING "Couldn't find Qt4 or Qt5 -- will not build xpdf.")
+endif ()
+
+if (NOT MULTITHREADED)
+ message(WARNING "Multithreading is disabled -- will not build xpdf.")
+endif ()
+
+if (NOT USE_EXCEPTIONS)
+ message(WARNING "C++ exceptions are disabled -- will not build xpdf.")
+endif ()
diff --git a/Build/source/libs/xpdf/xpdf-src/INSTALL b/Build/source/libs/xpdf/xpdf-src/INSTALL
index fce20fdbfa8..a292b605dc3 100644
--- a/Build/source/libs/xpdf/xpdf-src/INSTALL
+++ b/Build/source/libs/xpdf/xpdf-src/INSTALL
@@ -1,14 +1,14 @@
Xpdf
====
-version 3.04
-2014-may-28
+version 4.00
+2017-aug-10
The Xpdf software and documentation are
-copyright 1996-2014 Glyph & Cog, LLC.
+copyright 1996-2017 Glyph & Cog, LLC.
-Email: derekn@foolabs.com
-WWW: http://www.foolabs.com/xpdf/
+Email: xpdf@xpdfreader.com
+WWW: http://www.xpdfreader.com/
Compiling xpdf
@@ -18,179 +18,157 @@ Xpdf is written in C++ (with a little bit of C). It should work with
any ANSI-compliant C++ and C compilers. The systems and compilers
it's been tested with are listed on the xpdf web page.
-Xpdf requires the Motif (or Lesstif) toolkit.
+Xpdf requires the Qt toolkit. The non-GUI command line tools do not
+use Qt.
The following notes give specific instructions for compiling on
different systems.
-**************
-*** UNIX ***
-**************
+*********************
+*** Linux, OS X ***
+*********************
-* Install FreeType 2 (this is required). WARNING: You must have
- version 2.0.5 or newer. Some older versions of XFree86 ship with an
- older version of FreeType, which means you'll need to explicitly set
- include and library paths to get the correct version:
+* Make sure you have the following installed:
- --with-freetype2-library=PATH
- --with-freetype2-includes=PATH
+ - CMake 2.8.8 or newer
+ - FreeType 2.0.5 or newer
+ - Qt 4.8.x or 5.x (for xpdf only)
+ - libpng (for pdftoppm and pdftohtml)
+ - zlib (for pdftoppm and pdftohtml)
-* If you have Motif (or Lesstif) installed in a non-standard place,
- you can use the following options to tell configure where to find
- it:
+ If Qt isn't found, the GUI viewer (xpdf) won't be built, but the
+ command line tools will still be built.
- --with-Xm-library=PATH
- --with-Xm-includes=PATH
+* Create a build directory. These instructions assume that you create
+ a directory called "build" under the top-level xpdf source
+ directory, but the build directory can be anywhere you like. Create
+ the directory and cd into it:
-* Run the configure script:
+ cd ..../xpdf-X.YY
+ mkdir build
+ cd build
- ./configure
+* Run cmake:
- This should produce a set of makefiles customized for your system.
- The configure script accepts the following options (in addition to
- the usual things accepted by autoconf configure scripts):
+ cmake -DCMAKE_BUILD_TYPE=Release {other options - see below} ..
- --prefix=PREFIX
- Changes the directory where xpdf is installed. The default is
- /usr/local.
+ If your build directory isn't under the source, use the full path to
+ the source directory:
- --enable-a4-paper
- Switches the default paper size for PostScript output (xpdf
- and pdftops) to A4. The default is Letter size.
-
- --enable-no-text-select
- With this option, xpdf will not copy text. (This is only
- useful on closed systems where the user can't get at the PDF
- file directly.)
-
- --enable-opi
- Enables support for generation of OPI (Open Prepress
- Interface) comments with pdftops.
-
- --sysconfdir=DIR
- Look for the system-wide xpdfrc config file in this directory.
- The default is PREFIX/etc.
-
- --with-appdef-dir=DIR
- Use the specified app-defaults directory. The default is
- /usr/lib/X11/app-defaults.
-
- If you need to pass specific options to the C and/or C++ compiler,
- you can set the CFLAGS and/or CXXFLAGS environment variables before
- running the configure script. Any options given that way will be
- added to the CFLAGS/CXXFLAGS used by all of the Xpdf makefiles.
-
-* Type 'make'. This should build the executables:
+ cmake -DCMAKE_BUILD_TYPE=Release {other options} ..../xpdf-X.YY
- xpdf/xpdf
- xpdf/pdftops
- xpdf/pdftotext
- xpdf/pdfinfo
- xpdf/pdffonts
- xpdf/pdfdetach
- xpdf/pdftoppm
- xpdf/pdfimages
+* If cmake doesn't find FreeType, you can set FREETYPE_DIR to point to
+ the FreeType install directory. Add this to the cmake command line:
-* If desired, type 'make install' to install the binaries and man
- pages.
+ -DFREETYPE_DIR=/opt/freetype
-The old Makefile.config and Makefiles are no longer provided or
-supported. If you really want to manually configure Xpdf (which is
-not recommended), the files that need to be created are aconf.h,
-Makefile, goo/Makefile, fofi/Makefile, splash/Makefile, and
-xpdf/Makefile, all of which are generated from the corresponding '.in'
-files.
+ Cmake will look for ${FREETYPE_DIR}/include.
-If you want to run a quick test, there is a tiny PDF file included
-with xpdf, as misc/hello.pdf .
-
-
-**************
-*** OS/2 ***
-**************
+ You can also set the FreeType library location with:
-Xpdf is known to run under OS/2 with the EMX runtime environment and
-XFree86. Using a proper autoconf port you can generate a valid
-configure script version.
+ -DFREETYPE_LIBRARY=/opt/freetype/lib/libfreetype.so
+* If cmake doesn't find Qt, make sure qmake is on your executable
+ search path.
-***************
-*** Win32 ***
-***************
+* To change the xpdf install directory, use:
-The non-X programs (pdftops, pdftotext, pdfinfo, pdffonts, pdfdetach,
-pdfimages, and pdftoppm) will compile with both gcc (from cygwin),
-djgpp (the Delorie port of gcc) and Microsoft Visual C++.
+ -DCMAKE_INSTALL_PREFIX=/opt/xpdf
-With cygwin, the build procedure is the same as for Unix:
+ If you're familiar with autoconf, this is similar to the "--prefix"
+ option.
- * Open a shell.
+* Other configuration options are:
- * ./configure
+ -DSPLASH_CMYK=ON
+ Enable CMYK rasterization support.
- * make
+ -DA4_PAPER=ON
+ Switches the default paper size for PostScript output (xpdf
+ and pdftops) to A4. The default is Letter size.
- * make install
+ -DNO_TEXT_SELECT=ON
+ With this option, xpdf will not copy text. (This is only
+ useful on closed systems where the user can't get at the PDF
+ file directly.)
-It is also possible to build the Xpdf viewer with the cygwin XFree86
-port (thanks to Michael A. Richmond for these instructions):
+ -DOPI_SUPPORT=ON
+ Enables support for generation of OPI (Open Prepress
+ Interface) comments with pdftops.
- * make sure you have the lesstif, XFree86-base, and XFree86-prog
- cygwin packages installed (all from the "XFree86" category)
+ -DMULTITHREADED=0
+ Disables multithreading, which also disables building the GUI
+ viewer (xpdf). This does not affect the command line tools.
+ Disabling multithreading should only be necessary if you're
+ building with a compiler other than gcc, clang, or Microsoft
+ Visual Studio.
- * to build xpdf:
- - cd xpdf-x.yy
- - ./configure
- --with-freetype2-library=/usr/lib
- --with-freetype2-includes=/usr/include/freetype2
- --with-Xm-library=/usr/lib
- --with-Xm-includes=/usr/include
- (all on one line)
- - make
- (this should build xpdf.exe, in addition to the command line
- utilities)
+ -DSYSTEM_XPDFRC="/etc/xpdfrc"
+ Look for a system-wide xpdfrc config file in this directory.
-With djgpp:
+ -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).
- * Open a DOS window.
+ -DCMAKE_C_FLAGS="..."
+ -DCMAKE_CXX_FLAGS="..."
+ Set additional options to pass to the C and/or C++ compilers.
- * ./dj_make
+ -DCMAKE_EXE_LINKER_FLAGS="..."
+ Set additional options to pass to the linker.
- * djgpp is a DOS/Windows port of gcc, available from
- http://www.delorie.com/
+* Build:
-With djgpp, for DOS 6 (instead of Win32):
+ make
- * ./dj_make
+ This will build the executables in the build directory:
- * cd xpdf
+ xpdf/xpdf
+ xpdf/pdftops
+ xpdf/pdftotext
+ xpdf/pdftohtml
+ xpdf/pdfinfo
+ xpdf/pdffonts
+ xpdf/pdfdetach
+ xpdf/pdftoppm
+ xpdf/pdftopng
+ xpdf/pdfimages
+ xpdf-qt/xpdf
- * strip pdftops.exe
+* If desired, install the binaries and man pages:
- * exe2coff pdftops.exe
+ make install
- * copy /B c:\djgpp\bin\cwsdstub.exe+pdftops pdftops.exe
+If you want to run a quick test, there is a tiny PDF file included
+with xpdf, as misc/hello.pdf .
- * upx pdftops.exe
- - if you want compressed executables
- * and similarly for the other executables
+*****************
+*** Windows ***
+*****************
- * cwsdstub.exe comes from djgpp/v2misc/csdpmi5b.zip on any of the
- djgpp ftp mirrors; exe2coff is part of the standard djgpp install
+The Windows build procedure is essentially the same as for Unix. If
+building with cygwin, the procedure is identical to Unix.
- * upx comes from http://upx.sourceforge.net/
+If building with Visual Studio:
-With the Microsoft tools:
+* Make sure you have CMake, FreeType, libpng, and zlib installed.
- * Open a DOS window.
+* You'll need to set the FREETYPE_DIR variable to point to your
+ FreeType installation, CMAKE_INCLUDE_PATH to point to your libpng
+ includes, CMAKE_LIBRARY_PATH to point to your libpng library, and
+ ZLIB_ROOT to point to your zlib installation.
- * Type "cl". If you get the message "Bad command or file name", you
- must run VCVARS32.BAT. (The location of this BAT file can be
- determined with Explorer.)
+ cmake -G "NMake Makefiles"
+ -DCMAKE_BUILD_TYPE=Release
+ -DFREETYPE_DIR="c:/software/freetype"
+ -DCMAKE_INCLUDE_PATH="c:/software/libpng"
+ -DCMAKE_LIBRARY_PATH="c:/software/libpng"
+ -DZLIB_ROOT="c:/software/zlib"
+ ..
- * Type "ms_make"
+* Build:
-The dj_make and ms_make scripts don't build pdftoppm -- you'll need to
-install FreeType 2 before you can compile pdftoppm.
+ nmake
diff --git a/Build/source/libs/xpdf/xpdf-src/Makefile.in b/Build/source/libs/xpdf/xpdf-src/Makefile.in
deleted file mode 100644
index 40f74491d66..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/Makefile.in
+++ /dev/null
@@ -1,134 +0,0 @@
-#========================================================================
-#
-# Main xpdf Makefile.
-#
-# Copyright 1996-2003 Glyph & Cog, LLC
-#
-#========================================================================
-
-SHELL = /bin/sh
-
-DESTDIR =
-
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-srcdir = @srcdir@
-
-INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_DATA = @INSTALL_DATA@
-
-EXE = @EXE@
-
-all:
- cd goo; $(MAKE)
- cd @UP_DIR@fofi; $(MAKE)
- cd @UP_DIR@splash; $(MAKE)
- cd @UP_DIR@xpdf; $(MAKE) @XPDF_TARGET@
-
-all-no-x:
- cd goo; $(MAKE)
- cd @UP_DIR@fofi; $(MAKE)
- cd @UP_DIR@xpdf; $(MAKE) all-no-x
-
-xpdf: dummy
- cd goo; $(MAKE)
- cd @UP_DIR@fofi; $(MAKE)
- cd @UP_DIR@splash; $(MAKE)
- cd @UP_DIR@xpdf; $(MAKE) xpdf$(EXE)
-
-pdftops: dummy
- cd goo; $(MAKE)
- cd @UP_DIR@fofi; $(MAKE)
- cd @UP_DIR@splash; $(MAKE)
- cd @UP_DIR@xpdf; $(MAKE) pdftops$(EXE)
-
-pdftotext: dummy
- cd goo; $(MAKE)
- cd @UP_DIR@fofi; $(MAKE)
- cd @UP_DIR@splash; $(MAKE)
- cd @UP_DIR@xpdf; $(MAKE) pdftotext$(EXE)
-
-pdfinfo:
- cd goo; $(MAKE)
- cd @UP_DIR@fofi; $(MAKE)
- cd @UP_DIR@splash; $(MAKE)
- cd @UP_DIR@xpdf; $(MAKE) pdfinfo$(EXE)
-
-pdffonts:
- cd goo; $(MAKE)
- cd @UP_DIR@fofi; $(MAKE)
- cd @UP_DIR@splash; $(MAKE)
- cd @UP_DIR@xpdf; $(MAKE) pdffonts$(EXE)
-
-pdfdetach:
- cd goo; $(MAKE)
- cd @UP_DIR@fofi; $(MAKE)
- cd @UP_DIR@splash; $(MAKE)
- cd @UP_DIR@xpdf; $(MAKE) pdfdetach$(EXE)
-
-pdftoppm:
- cd goo; $(MAKE)
- cd @UP_DIR@fofi; $(MAKE)
- cd @UP_DIR@splash; $(MAKE)
- cd @UP_DIR@xpdf; $(MAKE) pdftoppm$(EXE)
-
-pdfimages:
- cd goo; $(MAKE)
- cd @UP_DIR@fofi; $(MAKE)
- cd @UP_DIR@splash; $(MAKE)
- cd @UP_DIR@xpdf; $(MAKE) pdfimages$(EXE)
-
-dummy:
-
-install: dummy
- -mkdir -p $(DESTDIR)@bindir@
-@X@ $(INSTALL_PROGRAM) xpdf/xpdf$(EXE) $(DESTDIR)@bindir@/xpdf$(EXE)
- $(INSTALL_PROGRAM) xpdf/pdftops$(EXE) $(DESTDIR)@bindir@/pdftops$(EXE)
- $(INSTALL_PROGRAM) xpdf/pdftotext$(EXE) $(DESTDIR)@bindir@/pdftotext$(EXE)
- $(INSTALL_PROGRAM) xpdf/pdfinfo$(EXE) $(DESTDIR)@bindir@/pdfinfo$(EXE)
- $(INSTALL_PROGRAM) xpdf/pdffonts$(EXE) $(DESTDIR)@bindir@/pdffonts$(EXE)
- $(INSTALL_PROGRAM) xpdf/pdfdetach$(EXE) $(DESTDIR)@bindir@/pdfdetach$(EXE)
-@X@ $(INSTALL_PROGRAM) xpdf/pdftoppm$(EXE) $(DESTDIR)@bindir@/pdftoppm$(EXE)
- $(INSTALL_PROGRAM) xpdf/pdfimages$(EXE) $(DESTDIR)@bindir@/pdfimages$(EXE)
- -mkdir -p $(DESTDIR)@mandir@/man1
-@X@ $(INSTALL_DATA) $(srcdir)/doc/xpdf.1 $(DESTDIR)@mandir@/man1/xpdf.1
- $(INSTALL_DATA) $(srcdir)/doc/pdftops.1 $(DESTDIR)@mandir@/man1/pdftops.1
- $(INSTALL_DATA) $(srcdir)/doc/pdftotext.1 $(DESTDIR)@mandir@/man1/pdftotext.1
- $(INSTALL_DATA) $(srcdir)/doc/pdfinfo.1 $(DESTDIR)@mandir@/man1/pdfinfo.1
- $(INSTALL_DATA) $(srcdir)/doc/pdffonts.1 $(DESTDIR)@mandir@/man1/pdffonts.1
- $(INSTALL_DATA) $(srcdir)/doc/pdfdetach.1 $(DESTDIR)@mandir@/man1/pdfdetach.1
-@X@ $(INSTALL_DATA) $(srcdir)/doc/pdftoppm.1 $(DESTDIR)@mandir@/man1/pdftoppm.1
- $(INSTALL_DATA) $(srcdir)/doc/pdfimages.1 $(DESTDIR)@mandir@/man1/pdfimages.1
- -mkdir -p $(DESTDIR)@mandir@/man5
- $(INSTALL_DATA) $(srcdir)/doc/xpdfrc.5 $(DESTDIR)@mandir@/man5/xpdfrc.5
- -mkdir -p $(DESTDIR)@sysconfdir@
- @if test ! -f $(DESTDIR)@sysconfdir@/xpdfrc; then \
- echo "$(INSTALL_DATA) $(srcdir)/doc/sample-xpdfrc $(DESTDIR)@sysconfdir@/xpdfrc"; \
- $(INSTALL_DATA) $(srcdir)/doc/sample-xpdfrc $(DESTDIR)@sysconfdir@/xpdfrc; \
- else \
- echo "# not overwriting the existing $(DESTDIR)@sysconfdir@/xpdfrc"; \
- fi
-
-clean:
- -cd goo; $(MAKE) clean
- -cd @UP_DIR@fofi; $(MAKE) clean
- -cd @UP_DIR@splash; $(MAKE) clean
- -cd @UP_DIR@xpdf; $(MAKE) clean
-
-distclean: clean
- rm -f config.log config.status config.cache
- rm -f aconf.h
- rm -f Makefile goo/Makefile fofi/Makefile splash/Makefile xpdf/Makefile
- rm -f goo/Makefile.dep fofi/Makefile.dep splash/Makefile.dep xpdf/Makefile.dep
- rm -f goo/Makefile.in.bak fofi/Makefile.in.bak splash/Makefile.in.bak xpdf/Makefile.in.bak
- touch goo/Makefile.dep
- touch fofi/Makefile.dep
- touch splash/Makefile.dep
- touch xpdf/Makefile.dep
-
-depend:
- cd goo; $(MAKE) depend
- cd @UP_DIR@fofi; $(MAKE) depend
- cd @UP_DIR@splash; $(MAKE) depend
- cd @UP_DIR@xpdf; $(MAKE) depend
diff --git a/Build/source/libs/xpdf/xpdf-src/README b/Build/source/libs/xpdf/xpdf-src/README
index 93a1bc54766..6e7f4b0b045 100644
--- a/Build/source/libs/xpdf/xpdf-src/README
+++ b/Build/source/libs/xpdf/xpdf-src/README
@@ -1,17 +1,17 @@
Xpdf
====
-version 3.04
-2014-may-28
+version 4.00
+2017-aug-10
The Xpdf software and documentation are
-copyright 1996-2014 Glyph & Cog, LLC.
+copyright 1996-2017 Glyph & Cog, LLC.
-Email: derekn@foolabs.com
-WWW: http://www.foolabs.com/xpdf/
+Email: xpdf@xpdfreader.com
+WWW: http://www.xpdfreader.com/
The PDF data structures, operators, and specification are
-copyright 1985-2006 Adobe Systems Inc.
+documented in ISO 32000-1:2008.
What is Xpdf?
@@ -23,16 +23,14 @@ the name of Adobe's PDF software.) The Xpdf project also includes a
PDF text extractor, PDF-to-PostScript converter, and various other
utilities.
-Xpdf runs under the X Window System on UNIX and OS/2. The non-X
-components (pdftops, pdftotext, etc.) also run on Windows and Mac OSX
-systems and should run on pretty much any system with a decent C++
-compiler. Xpdf will run on 32-bit and 64-bit machines.
+The Xpdf viewer uses the Qt cross-platform GUI toolkit. The other
+command line utilties do not require Qt.
License & Distribution
----------------------
-Xpdf is licensed under the GNU General Pulbic License (GPL), version 2
+Xpdf is licensed under the GNU General Public License (GPL), version 2
or 3. This means that you can distribute derivatives of Xpdf under
any of the following:
- GPL v2 only
@@ -64,17 +62,13 @@ Cog web site:
Compatibility
-------------
-Xpdf is developed and tested on Linux.
+Xpdf uses the Qt toolkit and runs on Linux, Windows, and OS X -- and
+probably other systems that have a Qt port.
-In addition, it has been compiled by others on Solaris, AIX, HP-UX,
-Digital Unix, Irix, and numerous other Unix implementations, as well
-as OS/2. It should work on pretty much any system which runs X11 and
-has Unix-like libraries. You'll need ANSI C++ and C compilers to
-compile it.
-
-The non-X components of Xpdf (pdftops, pdftotext, pdfinfo, pdffonts,
-pdfdetach, pdftoppm, and pdfimages) can also be compiled on Windows
-and Mac OSX systems. See the Xpdf web page for details.
+The non-GUI command line utilities (pdftops, pdftotext, pdftohtml,
+pdfinfo, pdffonts, pdfdetach, pdftoppm, pdftopng, and pdfimages) run
+on Linux, Windows, and OS X -- and should run on pretty much any
+system with a decent C++ compiler.
If you compile Xpdf for a system not listed on the web page, please
let me know. If you're willing to make your binary available by ftp
@@ -85,20 +79,13 @@ disk space and support reasons).
If you can't get Xpdf to compile on your system, send me email and
I'll try to help.
-Xpdf has been ported to the Acorn, Amiga, BeOS, and EPOC. See the
-Xpdf web page for links.
-
Getting Xpdf
------------
The latest version is available from:
- http://www.foolabs.com/xpdf/
-
-or:
-
- ftp://ftp.foolabs.com/pub/xpdf/
+ http://www.xpdfreader.com/
Source code and several precompiled executables are available.
@@ -114,8 +101,7 @@ To run xpdf, simply type:
xpdf file.pdf
-To generate a PostScript file, hit the "print" button in xpdf, or run
-pdftops:
+To generate a PostScript file, run pdftops:
pdftops file.pdf
@@ -123,9 +109,10 @@ To generate a plain text file, run pdftotext:
pdftotext file.pdf
-There are five additional utilities (which are fully described in
+There are several additional utilities (which are fully described in
their man pages):
+ pdftohtml -- converts a PDF file to HTML
pdfinfo -- dumps a PDF file's Info dictionary (plus some other
useful information)
pdffonts -- lists the fonts used in a PDF file along with various
@@ -134,6 +121,7 @@ their man pages):
PDF file
pdftoppm -- converts a PDF file to a series of PPM/PGM/PBM-format
bitmaps
+ pdftopng -- converts a PDF file to a series of PNG image files
pdfimages -- extracts the images from a PDF file
Command line options and many other details are described in the man
@@ -143,30 +131,6 @@ All of these utilities read an optional configuration file: see the
xpdfrc(5) man page.
-Upgrading from Xpdf 3.02 (and earlier)
---------------------------------------
-
-The font configuration system has been changed. Previous versions
-used mostly separate commands to configure fonts for display and for
-PostScript output. As of 3.03, configuration options that make sense
-for both display and PS output have been unified.
-
-The following xpdfrc commands have been removed:
-* displayFontT1, displayFontTT: replaced with fontFile
-* displayNamedCIDFontT1, displayNamedCIDFontTT: replaced with fontFile
-* displayCIDFontT1, displayCIDFontTT: replaced with fontFileCC
-* psFont: replaced with psResidentFont
-* psNamedFont16: replaced with psResidentFont16
-* psFont16: replaced with psResidentFontCC
-
-See the xpdfrc(5) man page for more information on the new commands.
-
-Pdftops will now embed external 16-bit fonts (configured with the
-fontFileCC command) when the PDF file refers to a non-embedded font.
-It does not do any subsetting (yet), so the resulting PS files will be
-large.
-
-
Compiling Xpdf
--------------
@@ -187,7 +151,8 @@ Third-Party Libraries
Xpdf uses the following libraries:
* FreeType [http://www.freetype.org/]
-* libpng [http://www.libpng.com/pub/png/libpng.html] (used by pdftohtml)
+* libpng [http://www.libpng.com/pub/png/libpng.html] (used by pdftohtml
+ and pdftopng)
* zlib [http://zlib.net/] (used by pdftohtml)
@@ -231,15 +196,20 @@ pdftex project:
References
----------
-Adobe Systems Inc., _PDF Reference, sixth edition: Adobe Portable
-Document Format version 1.7_.
+Adobe Systems Inc., ISO 32000-1:2008, Document Management - Portable
+document format - Part 1: PDF 1.7.
http://www.adobe.com/devnet/pdf/pdf_reference.html
[The manual for PDF version 1.7.]
-Adobe Systems Inc., "Errata for the PDF Reference, sixth edition,
-version 1.7", October 16, 2006.
+Adobe Systems Inc., Adobe Supplement to the ISO 32000, BaseVersion
+1.7, ExtensionLevel 3, June 2008.
+http://www.adobe.com/devnet/pdf/pdf_reference.html
+[Additions to the PDF 1.7 spec.]
+
+Adobe Systems Inc., Adobe Supplement to ISO 32000-1, BaseVersion 1.7,
+ExtensionLevel 5, June 2009.
http://www.adobe.com/devnet/pdf/pdf_reference.html
-[The errata for the PDF 1.7 spec.]
+[Additions to the PDF 1.7 spec.]
Adobe Systems Inc., _PostScript Language Reference_, 3rd ed.
Addison-Wesley, 1999, ISBN 0-201-37922-8.
diff --git a/Build/source/libs/xpdf/xpdf-src/aclocal.m4 b/Build/source/libs/xpdf/xpdf-src/aclocal.m4
deleted file mode 100644
index b3aeea2fda6..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/aclocal.m4
+++ /dev/null
@@ -1,274 +0,0 @@
-# <<< smr.m4 from smr_macros 0.2.4 >>>
-
-dnl ####################### -*- Mode: M4 -*- ###########################
-dnl smr.m4 --
-dnl
-dnl Copyright (C) 1999 Matthew D. Langston <langston@SLAC.Stanford.EDU>
-dnl Copyright (C) 1998 Steve Robbins <stever@cs.mcgill.ca>
-dnl
-dnl This file is free software; you can redistribute it and/or modify it
-dnl under the terms of the GNU General Public License as published by
-dnl the Free Software Foundation; either version 2 of the License, or
-dnl (at your option) any later version.
-dnl
-dnl This file is distributed in the hope that it will be useful, but
-dnl WITHOUT ANY WARRANTY; without even the implied warranty of
-dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-dnl General Public License for more details.
-dnl
-dnl You should have received a copy of the GNU General Public License
-dnl along with this file; if not, write to:
-dnl
-dnl Free Software Foundation, Inc.
-dnl Suite 330
-dnl 59 Temple Place
-dnl Boston, MA 02111-1307, USA.
-dnl ####################################################################
-
-
-dnl NOTE: The macros in this file are extensively documented in the
-dnl accompanying `smr_macros.texi' Texinfo file. Please see the
-dnl Texinfo documentation for the definitive specification of how
-dnl these macros are supposed to work. If the macros work
-dnl differently than the Texinfo documentation says they should,
-dnl then the macros (and not the Texinfo documentation) has the
-dnl bug(s).
-
-dnl This is a convenient macro which translates illegal characters for
-dnl bourne shell variables into legal characters. It has the same
-dnl functionality as sed 'y%./+-:%__p__%'.
-AC_DEFUN([smr_safe_translation], [patsubst(patsubst([$1], [+], [p]), [./-:], [_])])
-
-AC_DEFUN(smr_SWITCH,
-[
- dnl Define convenient aliases for the arguments since there are so
- dnl many of them and I keep confusing myself whenever I have to edit
- dnl this macro.
- pushdef([smr_name], $1)
- pushdef([smr_help_string], $2)
- pushdef([smr_default], $3)
- pushdef([smr_yes_define], $4)
- pushdef([smr_no_define], $5)
-
- dnl Do some sanity checking of the arguments.
- ifelse([regexp(smr_default, [^\(yes\|no\)$])], -1, [AC_MSG_ERROR($0: third arg must be either yes or no)])
-
- dnl Create the help string
- pushdef([smr_lhs], [--ifelse(smr_default, yes, disable, enable)-smr_name])dnl
- pushdef([smr_rhs], [ifelse(smr_default, yes, disable, enable) smr_help_string (default is smr_default)])dnl
-
- dnl Add the option to `configure --help'. We don't need to supply the
- dnl 4th argument to AC_ARG_ENABLE (i.e. the code to set the default
- dnl value) because that is done below by AC_CACHE_CHECK.
- AC_ARG_ENABLE([smr_name],
- AC_HELP_STRING([smr_lhs], [smr_rhs]),
- smr_cv_enable_[]smr_name=$enableval)
-
- dnl We cache the result so that the user doesn't have to remember
- dnl which flags they passed to `configure'.
- AC_CACHE_CHECK([whether to enable smr_help_string],
- smr_cv_enable_[]smr_name,
- smr_cv_enable_[]smr_name=smr_default)
-
- ifelse(smr_yes_define, , , test x"[$]smr_cv_enable_[]smr_name" = xyes && AC_DEFINE(smr_yes_define))
- ifelse(smr_no_define, , , test x"[$]smr_cv_enable_[]smr_name" = xno && AC_DEFINE(smr_no_define))
-
- dnl Sanity check the value assigned to smr_cv_enable_$1 to force it to
- dnl be either `yes' or `no'.
- if test ! x"[$]smr_cv_enable_[]smr_name" = xyes; then
- if test ! x"[$]smr_cv_enable_[]smr_name" = xno; then
- AC_MSG_ERROR([smr_lhs must be either yes or no])
- fi
- fi
-
- popdef([smr_name])
- popdef([smr_help_string])
- popdef([smr_default])
- popdef([smr_yes_define])
- popdef([smr_no_define])
- popdef([smr_lhs])
- popdef([smr_rhs])
-])
-
-
-AC_DEFUN(smr_ARG_WITHLIB,
-[
- dnl Define convenient aliases for the arguments since there are so
- dnl many of them and I keep confusing myself whenever I have to edit
- dnl this macro.
- pushdef([smr_name], $1)
- pushdef([smr_libname], ifelse($2, , smr_name, $2))
- pushdef([smr_help_string], $3)
- pushdef([smr_safe_name], smr_safe_translation(smr_name))
-
- dnl Add the option to `configure --help'. We don't need to supply the
- dnl 4th argument to AC_ARG_WITH (i.e. the code to set the default
- dnl value) because that is done below by AC_CACHE_CHECK.
- AC_ARG_WITH(smr_safe_name-library,
- AC_HELP_STRING([--with-smr_safe_name-library[[=PATH]]],
- [use smr_name library ifelse(smr_help_string, , , (smr_help_string))]),
- smr_cv_with_[]smr_safe_name[]_library=$withval)
-
- dnl We cache the result so that the user doesn't have to remember
- dnl which flags they passed to `configure'.
- AC_CACHE_CHECK([whether to use smr_name library],
- smr_cv_with_[]smr_safe_name[]_library,
- smr_cv_with_[]smr_safe_name[]_library=maybe)
-
-
- case x"[$]smr_cv_with_[]smr_safe_name[]_library" in
- xyes | xmaybe)
- smr_safe_name[]_LIBS="-l[]smr_libname"
- with_[]smr_safe_name=[$]smr_cv_with_[]smr_safe_name[]_library
- ;;
- xno)
- smr_safe_name[]_LIBS=
- with_[]smr_safe_name=no
- ;;
- *)
- if test -f "[$]smr_cv_with_[]smr_safe_name[]_library"; then
- smr_safe_name[]_LIBS=[$]smr_cv_with_[]smr_safe_name[]_library
- elif test -d "[$]smr_cv_with_[]smr_safe_name[]_library"; then
- smr_safe_name[]_LIBS="-L[$]smr_cv_with_[]smr_safe_name[]_library -l[]smr_libname"
- else
- AC_MSG_ERROR([argument must be boolean, file, or directory])
- fi
- with_[]smr_safe_name=yes
- ;;
- esac
-
- popdef([smr_name])
- popdef([smr_libname])
- popdef([smr_help_string])
- popdef([smr_safe_name])
-])
-
-
-AC_DEFUN(smr_ARG_WITHINCLUDES,
-[
- dnl Define convenient aliases for the arguments since there are so
- dnl many of them and I keep confusing myself whenever I have to edit
- dnl this macro.
- pushdef([smr_name], $1)
- pushdef([smr_header], $2)
- pushdef([smr_extra_flags], $3)
- pushdef([smr_safe_name], smr_safe_translation(smr_name))
-
- dnl Add the option to `configure --help'. We don't need to supply the
- dnl 4th argument to AC_ARG_WITH (i.e. the code to set the default
- dnl value) because that is done below by AC_CACHE_CHECK.
- AC_ARG_WITH(smr_safe_name-includes,
- AC_HELP_STRING([--with-smr_safe_name-includes[[=DIR]]],
- [set directory for smr_name headers]),
- smr_cv_with_[]smr_safe_name[]_includes=$withval)
-
- dnl We cache the result so that the user doesn't have to remember
- dnl which flags they passed to `configure'.
- AC_CACHE_CHECK([where to find the smr_name header files],
- smr_cv_with_[]smr_safe_name[]_includes,
- smr_cv_with_[]smr_safe_name[]_includes=)
-
- if test ! x"[$]smr_cv_with_[]smr_safe_name[]_includes" = x; then
- if test -d "[$]smr_cv_with_[]smr_safe_name[]_includes"; then
- smr_safe_name[]_CFLAGS="-I[$]smr_cv_with_[]smr_safe_name[]_includes"
- else
- AC_MSG_ERROR([argument must be a directory])
- fi
- else
- smr_safe_name[]_CFLAGS=
- fi
-
- dnl This bit of logic comes from the autoconf AC_PROG_CC macro. We
- dnl need to put the given include directory into CPPFLAGS temporarily,
- dnl but then restore CPPFLAGS to its old value.
- smr_test_CPPFLAGS="${CPPFLAGS+set}"
- smr_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS [$]smr_safe_name[]_CFLAGS smr_extra_flags"
-
- dnl If the header file smr_header exists, then define
- dnl HAVE_[]smr_header (in all capitals).
- AC_CHECK_HEADERS([smr_header],
- smr_have_[]smr_safe_name[]_header=yes,
- smr_have_[]smr_safe_name[]_header=no)
-
- if test x"$smr_test_CPPFLAGS" = xset; then
- CPPFLAGS=$smr_save_CPPFLAGS
- else
- unset CPPFLAGS
- fi
-
- popdef([smr_name])
- popdef([smr_header])
- popdef([smr_extra_flags])
- popdef([smr_safe_name])
-])
-
-
-AC_DEFUN(smr_CHECK_LIB,
-[
- dnl Define convenient aliases for the arguments since there are so
- dnl many of them and I keep confusing myself whenever I have to edit
- dnl this macro.
- pushdef([smr_name], $1)
- pushdef([smr_libname], ifelse($2, , smr_name, $2))
- pushdef([smr_help_string], $3)
- pushdef([smr_function], $4)
- pushdef([smr_header], $5)
- pushdef([smr_extra_libs], $6)
- pushdef([smr_extra_flags], $7)
- pushdef([smr_prototype], $8)
- pushdef([smr_safe_name], smr_safe_translation(smr_name))
-
- dnl Give the user (via "configure --help") an interface to specify
- dnl whether we should use the library or not, and possibly where we
- dnl should find it.
- smr_ARG_WITHLIB([smr_name], [smr_libname], [smr_help_string])
-
- if test ! x"$with_[]smr_safe_name" = xno; then
-
- # If we got this far, then the user didn't explicitly ask not to use
- # the library.
-
- dnl If the caller of smr_CHECK_LIB specified a header file for this
- dnl library, then give the user (via "configure --help") an
- dnl interface to specify where this header file can be found (if it
- dnl isn't found by the compiler by default).
- ifelse(smr_header, , , [smr_ARG_WITHINCLUDES(smr_name, smr_header, smr_extra_flags)])
-
- # We need only look for the library if the header has been found
- # (or no header is needed).
- if test [$]smr_have_[]smr_safe_name[]_header != no; then
-
- AC_CHECK_LIB(smr_libname,
- smr_function,
- smr_have_[]smr_safe_name[]_library=yes,
- smr_have_[]smr_safe_name[]_library=no,
- [$]smr_safe_name[]_CFLAGS [smr_extra_flags] [$]smr_safe_name[]_LIBS [smr_extra_libs],
- [ifelse(smr_prototype, , , [[#]include <smr_header>])],
- smr_prototype)
- fi
-
- if test x"[$]smr_have_[]smr_safe_name[]_library" = xyes; then
- AC_MSG_RESULT([using smr_name library])
- else
- smr_safe_name[]_LIBS=
- smr_safe_name[]_CFLAGS=
-
- if test x"$with_[]smr_safe_name" = xmaybe; then
- AC_MSG_RESULT([not using smr_name library])
- else
- AC_MSG_WARN([requested smr_name library not found!])
- fi
- fi
- fi
-
- popdef([smr_name])
- popdef([smr_libname])
- popdef([smr_help_string])
- popdef([smr_function])
- popdef([smr_header])
- popdef([smr_extra_libs])
- popdef([smr_extra_flags])
- popdef([smr_prototype])
- popdef([smr_safe_name])
-])
diff --git a/Build/source/libs/xpdf/xpdf-src/aconf-dj.h b/Build/source/libs/xpdf/xpdf-src/aconf-dj.h
deleted file mode 100644
index 4c4beff68d1..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/aconf-dj.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * aconf-dj.h
- *
- * Copyright 2002-2003 Glyph & Cog, LLC
- */
-
-#ifndef ACONF_H
-#define ACONF_H
-
-/*
- * Use A4 paper size instead of Letter for PostScript output.
- */
-#undef A4_PAPER
-
-/*
- * Do not allow text selection.
- */
-#undef NO_TEXT_SELECT
-
-/*
- * Include support for OPI comments.
- */
-#undef OPI_SUPPORT
-
-/*
- * Directory with the Xpdf app-defaults file.
- */
-#undef APPDEFDIR
-
-/*
- * Full path for the system-wide xpdfrc file.
- */
-#undef SYSTEM_XPDFRC
-
-/*
- * Various include files and functions.
- */
-#define HAVE_DIRENT_H 1
-#undef HAVE_SYS_NDIR_H
-#undef HAVE_SYS_DIR_H
-#undef HAVE_NDIR_H
-#undef HAVE_SYS_SELECT_H
-#undef HAVE_SYS_BSDTYPES_H
-#undef HAVE_STRINGS_H
-#undef HAVE_BSTRING_H
-#define HAVE_POPEN 1
-#undef HAVE_MKSTEMP
-#undef SELECT_TAKES_INT
-#define HAVE_STD_SORT 1
-#undef HAVE_FSEEK64
-
-/*
- * This is defined if using libXpm.
- */
-#undef HAVE_X11_XPM_H
-
-/*
- * One of these is defined if using FreeType (version 1 or 2).
- */
-#undef HAVE_FREETYPE_H
-#undef HAVE_FREETYPE_FREETYPE_H
-
-/*
- * This is defined if using FreeType version 2.
- */
-#undef FREETYPE2
-
-/*
- * This is defined if using libpaper.
- */
-#undef HAVE_PAPER_H
-
-#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/aconf-win32.h b/Build/source/libs/xpdf/xpdf-src/aconf-win32.h
deleted file mode 100644
index 67bbb443874..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/aconf-win32.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * aconf-win32.h
- *
- * Copyright 2002-2003 Glyph & Cog, LLC
- */
-
-#ifndef ACONF_H
-#define ACONF_H
-
-#include <aconf2.h>
-
-/*
- * Use A4 paper size instead of Letter for PostScript output.
- */
-#undef A4_PAPER
-
-/*
- * Do not allow text selection.
- */
-#undef NO_TEXT_SELECT
-
-/*
- * Include support for OPI comments.
- */
-#undef OPI_SUPPORT
-
-/*
- * Enable multithreading support.
- */
-#define MULTITHREADED 1
-
-/*
- * Enable C++ exceptions.
- */
-#define USE_EXCEPTIONS 1
-
-/*
- * Use fixed point (instead of floating point) arithmetic.
- */
-#undef USE_FIXEDPOINT
-
-/*
- * Directory with the Xpdf app-defaults file.
- */
-#undef APPDEFDIR
-
-/*
- * Full path for the system-wide xpdfrc file.
- */
-#undef SYSTEM_XPDFRC
-
-/*
- * Various include files and functions.
- */
-#undef HAVE_DIRENT_H
-#undef HAVE_SYS_NDIR_H
-#undef HAVE_SYS_DIR_H
-#undef HAVE_NDIR_H
-#undef HAVE_SYS_SELECT_H
-#undef HAVE_SYS_BSDTYPES_H
-#undef HAVE_STRINGS_H
-#undef HAVE_BSTRING_H
-#undef HAVE_POPEN
-#undef HAVE_MKSTEMP
-#undef HAVE_MKSTEMPS
-#undef SELECT_TAKES_INT
-#define HAVE_STD_SORT 1
-#undef HAVE_FSEEKO
-#undef HAVE_FSEEK64
-#define HAVE_FSEEKI64 1
-#undef _FILE_OFFSET_BITS
-#undef _LARGE_FILES
-#undef _LARGEFILE_SOURCE
-#undef HAVE_XTAPPSETEXITFLAG
-
-/*
- * This is defined if using libXpm.
- */
-#undef HAVE_X11_XPM_H
-
-/*
- * One of these is defined if using FreeType (version 1 or 2).
- */
-#undef HAVE_FREETYPE_H
-#define HAVE_FREETYPE_FREETYPE_H 1
-
-/*
- * This is defined if using FreeType version 2.
- */
-#define FREETYPE2
-
-/*
- * This is defined if using libpaper.
- */
-#undef HAVE_PAPER_H
-
-/*
- * Enable support for loading plugins.
- */
-#undef ENABLE_PLUGINS
-
-/*
- * Defined if the Splash library is avaiable.
- */
-#define HAVE_SPLASH 1
-
-/*
- * Enable support for CMYK output.
- */
-#define SPLASH_CMYK 1
-
-#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/aconf.h.in b/Build/source/libs/xpdf/xpdf-src/aconf.h.in
deleted file mode 100644
index 91a9ce48d62..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/aconf.h.in
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * aconf.h
- *
- * Copyright 2002-2003 Glyph & Cog, LLC
- */
-
-#ifndef ACONF_H
-#define ACONF_H
-
-#include <aconf2.h>
-
-/*
- * Use A4 paper size instead of Letter for PostScript output.
- */
-#undef A4_PAPER
-
-/*
- * Do not allow text selection.
- */
-#undef NO_TEXT_SELECT
-
-/*
- * Include support for OPI comments.
- */
-#undef OPI_SUPPORT
-
-/*
- * Enable multithreading support.
- */
-#undef MULTITHREADED
-
-/*
- * Enable C++ exceptions.
- */
-#undef USE_EXCEPTIONS
-
-/*
- * Use fixed point (instead of floating point) arithmetic.
- */
-#undef USE_FIXEDPOINT
-
-/*
- * Directory with the Xpdf app-defaults file.
- */
-#undef APPDEFDIR
-
-/*
- * Full path for the system-wide xpdfrc file.
- */
-#undef SYSTEM_XPDFRC
-
-/*
- * Various include files and functions.
- */
-#undef HAVE_DIRENT_H
-#undef HAVE_SYS_NDIR_H
-#undef HAVE_SYS_DIR_H
-#undef HAVE_NDIR_H
-#undef HAVE_SYS_SELECT_H
-#undef HAVE_SYS_BSDTYPES_H
-#undef HAVE_STRINGS_H
-#undef HAVE_BSTRING_H
-#undef HAVE_POPEN
-#undef HAVE_MKSTEMP
-#undef HAVE_MKSTEMPS
-#undef SELECT_TAKES_INT
-#undef HAVE_STD_SORT
-#undef HAVE_FSEEKO
-#undef HAVE_FSEEK64
-#undef HAVE_FSEEKI64
-#undef _FILE_OFFSET_BITS
-#undef _LARGE_FILES
-#undef _LARGEFILE_SOURCE
-#undef HAVE_XTAPPSETEXITFLAG
-
-/*
- * This is defined if using libXpm.
- */
-#undef HAVE_X11_XPM_H
-
-/*
- * One of these is defined if using FreeType 2.
- */
-#undef HAVE_FREETYPE_H
-#undef HAVE_FREETYPE_FREETYPE_H
-
-/*
- * This is defined if using libpaper.
- */
-#undef HAVE_PAPER_H
-
-/*
- * Enable support for loading plugins.
- */
-#undef ENABLE_PLUGINS
-
-/*
- * Defined if the Splash library is avaiable.
- */
-#undef HAVE_SPLASH
-
-/*
- * Enable support for CMYK output.
- */
-#undef SPLASH_CMYK
-
-#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/aconf2.h b/Build/source/libs/xpdf/xpdf-src/aconf2.h
index 59a1740ab93..8bef688075d 100644
--- a/Build/source/libs/xpdf/xpdf-src/aconf2.h
+++ b/Build/source/libs/xpdf/xpdf-src/aconf2.h
@@ -15,7 +15,7 @@
/*
* This controls the use of the interface/implementation pragmas.
*/
-#ifdef __GNUC__
+#if defined(__GNUC__) && !defined(__clang__)
#define USE_GCC_PRAGMAS
#endif
/* There is a bug in the version of gcc which ships with MacOS X 10.2 */
diff --git a/Build/source/libs/xpdf/xpdf-src/cmake-config.txt b/Build/source/libs/xpdf/xpdf-src/cmake-config.txt
new file mode 100644
index 00000000000..cbd7b9cd3e3
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/cmake-config.txt
@@ -0,0 +1,290 @@
+#========================================================================
+#
+# cmake-config.txt
+#
+# CMake script to do misc cmake config and platform-specific config.
+#
+# Copyright 2015 Glyph & Cog, LLC
+#
+#========================================================================
+
+include(CheckFunctionExists)
+include(CheckCXXSourceCompiles)
+
+enable_language(CXX)
+
+#--- set default C/C++ compiler flags for Unix
+# and add a 'Profiling' build mode
+if (CMAKE_GENERATOR STREQUAL "Unix Makefiles")
+ if (CYGWIN)
+ set(PIC_FLAG "")
+ else ()
+ set(PIC_FLAG "-fPIC")
+ endif ()
+ set(CMAKE_C_FLAGS_DEBUG "-g -O -Wall ${PIC_FLAG}")
+ set(CMAKE_CXX_FLAGS_DEBUG "-g -O -Wall ${PIC_FLAG}")
+ set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-g -O -Wall ${PIC_FLAG}")
+ set(CMAKE_C_FLAGS_RELEASE "-O3 -Wall ${PIC_FLAG}")
+ set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wall ${PIC_FLAG}")
+ set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-O2 -Wall ${PIC_FLAG}")
+ set(CMAKE_C_FLAGS_PROFILING "-g -pg -O -Wall ${PIC_FLAG}"
+ CACHE STRING "C compiler flags for profiling mode")
+ set(CMAKE_CXX_FLAGS_PROFILING "-g -pg -O -Wall ${PIC_FLAG}"
+ CACHE STRING "C++ compiler flags for profiling mode")
+ set(CMAKE_EXE_LINKER_FLAGS_PROFILING "-g -pg -O -Wall ${PIC_FLAG}"
+ CACHE STRING "linker flags for profiling mode")
+ mark_as_advanced(
+ CMAKE_C_FLAGS_PROFILING
+ CMAKE_CXX_FLAGS_PROFILING
+ CMAKE_EXE_LINKER_FLAGS_PROFILING)
+ set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
+ "Choose build mode - options are: None Debug Release RelWithDebInfo MinSiz
+eRel Profiling")
+endif ()
+
+#--- set default C/C++ compiler flags for Windows
+if (WIN32)
+ foreach (var CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG
+ CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE
+ CMAKE_C_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL
+ CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_RELWITHDEBINFO)
+ # note: this converts /MD to /MT and /MDd to /MTd
+ string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}")
+ endforeach ()
+ set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/NODEFAULTLIB:libcmt ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
+ set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "/NODEFAULTLIB:libcmt ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
+ foreach (var CMAKE_C_FLAGS_DEBUG
+ CMAKE_C_FLAGS_RELEASE
+ CMAKE_C_FLAGS_MINSIZEREL
+ CMAKE_C_FLAGS_RELWITHDEBINFO)
+ set(${var} "${${var}} /D_CRT_SECURE_NO_WARNINGS /wd4290 /wd4996")
+ endforeach ()
+ foreach (var CMAKE_CXX_FLAGS_DEBUG
+ CMAKE_CXX_FLAGS_RELEASE
+ CMAKE_CXX_FLAGS_MINSIZEREL
+ CMAKE_CXX_FLAGS_RELWITHDEBINFO)
+ set(${var} "${${var}} /D_CRT_SECURE_NO_WARNINGS /wd4290 /wd4996 /EHsc")
+ endforeach ()
+endif ()
+
+#--- don't set an rpath
+set(CMAKE_SKIP_RPATH FALSE)
+
+#--- miscellaneous options
+option(A4_PAPER "use A4 (instead of Letter) paper size by default for PostScript output" OFF)
+option(NO_TEXT_SELECT "do not allow text selection" OFF)
+option(OPI_SUPPORT "include support for OPI comments" OFF)
+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(SPLASH_DEVICEN "include support for DeviceN rasterization" OFF)
+if (SPLASH_DEVICEN)
+ set(SPLASH_CMYK ON)
+endif ()
+option(USE_LCMS "enable color management using lcms2" OFF)
+option(HIGHLIGHTED_REGIONS "include support for highlighted regions" OFF)
+option(SYSTEM_XPDFRC "full path for system-wide xpdfrc file" "")
+if (SYSTEM_XPDFRC)
+ set(SYSTEM_XPDFRC_DEFINE "#define SYSTEM_XPDFRC \"${SYSTEM_XPDFRC}\"")
+else ()
+ set(SYSTEM_XPDFRC_DEFINE "/* #undef SYSTEM_XPDFRC */")
+endif ()
+option(XPDFWIDGET_PRINTING "include printing support in XpdfWidget" OFF)
+option(EVAL_MODE "enable evaluation mode" OFF)
+option(BUILDING_XPDFREADER "enable closed source XpdfReader build" OFF)
+
+#--- check for various library functions
+check_function_exists(mkstemp HAVE_MKSTEMP)
+check_function_exists(mkstemps HAVE_MKSTEMPS)
+check_function_exists(popen HAVE_POPEN)
+check_cxx_source_compiles(
+ "#include <algorithm>
+ bool cmp(const int &x, const int &y) { return x < y; }
+ int a[100];
+ int main() { std::sort(a, a+100, &cmp); }"
+ HAVE_STD_SORT)
+
+#--- set up 64-bit file seeks
+check_function_exists(fseeko HAVE_FSEEKO)
+check_function_exists(fseek64 HAVE_FSEEK64)
+check_function_exists(_fseeki64 HAVE_FSEEKI64)
+
+#--- look for FreeType
+# This could use cmake's FindFreetype, except that it would require
+# a newer version of cmake -- because FreeType changed their include
+# paths around. Older versions of FreeType require two separate
+# -I switches (typically ..../include and ..../include/freetype2);
+# while newer versions require just one (typically ..../include/freetype2)
+find_path(FREETYPE_INCLUDE_DIR_ft2build ft2build.h
+ HINTS
+ ${FREETYPE_DIR}
+ PATHS
+ /usr/local/include
+ /usr/local/X11R6/include
+ /usr/local/X11/include
+ /usr/freeware/include
+ PATH_SUFFIXES freetype2 include/freetype2 include
+)
+find_path(FREETYPE_INCLUDE_DIR_freetype freetype.h
+ HINTS
+ ${FREETYPE_DIR}
+ PATHS
+ /usr/local/include
+ /usr/local/X11R6/include
+ /usr/local/X11/include
+ /usr/freeware/include
+ PATH_SUFFIXES freetype2 include/freetype2 include
+)
+find_path(FREETYPE_INCLUDE_DIR_freetype_freetype freetype/freetype.h
+ HINTS
+ ${FREETYPE_DIR}
+ PATHS
+ /usr/local/include
+ /usr/local/X11R6/include
+ /usr/local/X11/include
+ /usr/freeware/include
+ PATH_SUFFIXES freetype2 include/freetype2 include
+)
+find_library(FREETYPE_LIBRARY
+ NAMES freetype libfreetype freetype2 freetype219
+ HINTS
+ ${FREETYPE_DIR}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ /usr/local
+ /usr/local/X11R6
+ /usr/local/X11
+ /usr/freeware
+)
+if (FREETYPE_INCLUDE_DIR_ft2build
+ AND FREETYPE_INCLUDE_DIR_freetype
+ AND (FREETYPE_INCLUDE_DIR_ft2build STREQUAL FREETYPE_INCLUDE_DIR_freetype)
+ AND FREETYPE_LIBRARY)
+ set(FREETYPE_INCLUDE_DIRS "${FREETYPE_INCLUDE_DIR_ft2build}")
+ set(HAVE_FREETYPE_H TRUE)
+ message(STATUS "Found FreeType (new-style includes): ${FREETYPE_LIBRARY}")
+elseif (FREETYPE_INCLUDE_DIR_ft2build
+ AND FREETYPE_INCLUDE_DIR_freetype_freetype
+ AND FREETYPE_LIBRARY)
+ set(FREETYPE_INCLUDE_DIRS
+ "${FREETYPE_INCLUDE_DIR_ft2build};${FREETYPE_INCLUDE_DIR_freetype_freetype}")
+ set(HAVE_FREETYPE_H TRUE)
+ message(STATUS "Found FreeType (old-style includes): ${FREETYPE_LIBRARY}")
+else ()
+ message(STATUS "FreeType not found")
+endif ()
+if (HAVE_FREETYPE_H)
+ set(HAVE_SPLASH TRUE)
+endif ()
+
+#--- look for D-Type
+if (DTYPE_INCLUDE_DIR AND DTYPE_LIBRARY)
+ set(HAVE_DTYPE4_H TRUE)
+ message(STATUS "Found D-Type: ${DTYPE_LIBRARY}")
+endif ()
+
+#--- look for zlib
+find_package(ZLIB)
+
+#--- look for libpng
+find_package(PNG)
+
+#--- look for libjpeg
+find_package(JPEG)
+
+#--- look for libtiff
+find_package(TIFF)
+
+#--- look for lcms2
+if (USE_LCMS)
+ find_path(LCMS_INCLUDE_DIR lcms2.h
+ HINTS
+ ${LCMS_DIR}
+ PATHS
+ /usr/local/include
+ /usr/freeware/include
+ PATH_SUFFIXES include
+ )
+ find_library(LCMS_LIBRARY
+ NAMES lcms2 liblcms2
+ HINTS
+ ${LCMS_DIR}
+ PATHS
+ /usr/local
+ /usr/freeware
+ )
+endif ()
+if (USE_LCMS AND LCMS_INCLUDE_DIR AND LCMS_LIBRARY)
+ set(HAVE_LCMS TRUE)
+ message(STATUS "Found lcms2: ${LCMS_LIBRARY}")
+else ()
+ set(HAVE_LCMS FALSE)
+ message(STATUS "lcms2 not found")
+endif ()
+
+#--- look for Qt
+find_package(Qt5Widgets QUIET)
+if (Qt5Widgets_FOUND)
+ find_package(Qt5PrintSupport)
+else ()
+ find_package(Qt4)
+endif ()
+if(Qt5Widgets_FOUND)
+ message(STATUS "Qt5 found")
+ if (XPDFWIDGET_PRINTING)
+ set(QT_INCLUDES "${Qt5Widgets_INCLUDE_DIRS} ${Qt5PrintSupport_INCLUDE_DIRS}")
+ set(QT_DEFINITIONS "${Qt5Widgets_DEFINITIONS} ${Qt5PrintSupport_DEFINITIONS}")
+ if (APPLE)
+ set(QT_LIBRARIES Qt5::Widgets Qt5::PrintSupport "-framework ApplicationServices")
+ elseif (UNIX)
+ set(QT_LIBRARIES Qt5::Widgets Qt5::PrintSupport cups)
+ else ()
+ set(QT_LIBRARIES Qt5::Widgets Qt5::PrintSupport)
+ endif ()
+ else ()
+ set(QT_INCLUDES "${Qt5Widgets_INCLUDE_DIRS}")
+ set(QT_DEFINITIONS "${Qt5Widgets_DEFINITIONS}")
+ set(QT_LIBRARIES Qt5::Widgets)
+ endif ()
+ if (XPDFWIDGET_PRINTING)
+ if (APPLE)
+ set(EXTRA_QT_LIBRARIES "-framework ApplicationServices")
+ elseif (UNIX)
+ set(EXTRA_QT_LIBRARIES cups)
+ else ()
+ set(EXTRA_QT_LIBRARIES "")
+ endif ()
+ endif ()
+ # remove "-fPIE" here because we added "-fPIC" above
+ string(REPLACE "-fPIE" "" QT_CFLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
+ if (POLICY CMP0020)
+ # do not link to qtmain.lib
+ cmake_policy(SET CMP0020 OLD)
+ endif ()
+elseif(QT4_FOUND)
+ message(STATUS "Qt4 found")
+ if (XPDFWIDGET_PRINTING)
+ if (APPLE)
+ set(EXTRA_QT_LIBRARIES "-framework ApplicationServices")
+ elseif (UNIX)
+ set(EXTRA_QT_LIBRARIES cups)
+ else ()
+ set(EXTRA_QT_LIBRARIES "")
+ endif ()
+ endif ()
+else()
+ message(STATUS "No Qt library found")
+endif()
+
+#--- look for libpaper
+find_library(HAVE_PAPER_H
+ NAMES paper libpaper
+ PATH_SUFFIXES lib64 lib
+)
+
+#--- look for pthreads
+find_package(Threads)
+
+#--- create aconf.h
+configure_file("aconf.h.in" "aconf.h")
diff --git a/Build/source/libs/xpdf/xpdf-src/configure b/Build/source/libs/xpdf/xpdf-src/configure
deleted file mode 100755
index b6cd8bdaec4..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/configure
+++ /dev/null
@@ -1,9386 +0,0 @@
-#! /bin/sh
-# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69.
-#
-#
-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
-#
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='print -r --'
- as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='printf %s\n'
- as_echo_n='printf %s'
-else
- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
- as_echo_n='/usr/ucb/echo -n'
- else
- as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
- as_echo_n_body='eval
- arg=$1;
- case $arg in #(
- *"$as_nl"*)
- expr "X$arg" : "X\\(.*\\)$as_nl";
- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
- esac;
- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
- '
- export as_echo_n_body
- as_echo_n='sh -c $as_echo_n_body as_echo'
- fi
- export as_echo_body
- as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-as_myself=
-case $0 in #((
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there. '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# Use a proper internal environment variable to ensure we don't fall
- # into an infinite loop, continuously re-executing ourselves.
- if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
- _as_can_reexec=no; export _as_can_reexec;
- # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-as_fn_exit 255
- fi
- # We don't want this to propagate to other subprocesses.
- { _as_can_reexec=; unset _as_can_reexec;}
-if test "x$CONFIG_SHELL" = x; then
- as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '\${1+\"\$@\"}'='\"\$@\"'
- setopt NO_GLOB_SUBST
-else
- case \`(set -o) 2>/dev/null\` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-"
- as_required="as_fn_return () { (exit \$1); }
-as_fn_success () { as_fn_return 0; }
-as_fn_failure () { as_fn_return 1; }
-as_fn_ret_success () { return 0; }
-as_fn_ret_failure () { return 1; }
-
-exitcode=0
-as_fn_success || { exitcode=1; echo as_fn_success failed.; }
-as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
-as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
-as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
-
-else
- exitcode=1; echo positional parameters were not saved.
-fi
-test x\$exitcode = x0 || exit 1
-test -x / || exit 1"
- as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
- as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
- eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
- test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
-test \$(( 1 + 1 )) = 2 || exit 1"
- if (eval "$as_required") 2>/dev/null; then :
- as_have_required=yes
-else
- as_have_required=no
-fi
- if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
-
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-as_found=false
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- as_found=:
- case $as_dir in #(
- /*)
- for as_base in sh bash ksh sh5; do
- # Try only shells that exist, to save several forks.
- as_shell=$as_dir/$as_base
- if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
- CONFIG_SHELL=$as_shell as_have_required=yes
- if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
- break 2
-fi
-fi
- done;;
- esac
- as_found=false
-done
-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
- CONFIG_SHELL=$SHELL as_have_required=yes
-fi; }
-IFS=$as_save_IFS
-
-
- if test "x$CONFIG_SHELL" != x; then :
- export CONFIG_SHELL
- # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-exit 255
-fi
-
- if test x$as_have_required = xno; then :
- $as_echo "$0: This script requires a shell more modern than all"
- $as_echo "$0: the shells that I found on your system."
- if test x${ZSH_VERSION+set} = xset ; then
- $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
- $as_echo "$0: be upgraded to zsh 4.3.4 or later."
- else
- $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
-$0: including any error possibly output before this
-$0: message. Then install a modern shell, or manually run
-$0: the script under such a shell if you do have one."
- fi
- exit 1
-fi
-fi
-fi
-SHELL=${CONFIG_SHELL-/bin/sh}
-export SHELL
-# Unset more variables known to interfere with behavior of common tools.
-CLICOLOR_FORCE= GREP_OPTIONS=
-unset CLICOLOR_FORCE GREP_OPTIONS
-
-## --------------------- ##
-## M4sh Shell Functions. ##
-## --------------------- ##
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
- { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
- case $as_dir in #(
- -*) as_dir=./$as_dir;;
- esac
- test -d "$as_dir" || eval $as_mkdir_p || {
- as_dirs=
- while :; do
- case $as_dir in #(
- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
- *) as_qdir=$as_dir;;
- esac
- as_dirs="'$as_qdir' $as_dirs"
- as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- test -d "$as_dir" && break
- done
- test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
- test -f "$1" && test -x "$1"
-} # as_fn_executable_p
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
- eval 'as_fn_append ()
- {
- eval $1+=\$2
- }'
-else
- as_fn_append ()
- {
- eval $1=\$$1\$2
- }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
- eval 'as_fn_arith ()
- {
- as_val=$(( $* ))
- }'
-else
- as_fn_arith ()
- {
- as_val=`expr "$@" || test $? -eq 1`
- }
-fi # as_fn_arith
-
-
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
-as_fn_error ()
-{
- as_status=$1; test $as_status -eq 0 && as_status=1
- if test "$4"; then
- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
- fi
- $as_echo "$as_me: error: $2" >&2
- as_fn_exit $as_status
-} # as_fn_error
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-
- as_lineno_1=$LINENO as_lineno_1a=$LINENO
- as_lineno_2=$LINENO as_lineno_2a=$LINENO
- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
-
- # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
- # already done that, so ensure we don't try to do so again and fall
- # in an infinite loop. This has already happened in practice.
- _as_can_reexec=no; export _as_can_reexec
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
- case `echo 'xy\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- xy) ECHO_C='\c';;
- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
- ECHO_T=' ';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
- if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -pR'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -pR'
- elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
- else
- as_ln_s='cp -pR'
- fi
-else
- as_ln_s='cp -pR'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p='mkdir -p "$as_dir"'
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-test -n "$DJDIR" || exec 7<&0 </dev/null
-exec 6>&1
-
-# Name of the host.
-# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-
-# Identity of this package.
-PACKAGE_NAME=
-PACKAGE_TARNAME=
-PACKAGE_VERSION=
-PACKAGE_STRING=
-PACKAGE_BUGREPORT=
-PACKAGE_URL=
-
-ac_unique_file="xpdf/Gfx.cc"
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-# include <memory.h>
-# endif
-# include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
-ac_subst_vars='LTLIBOBJS
-LIBOBJS
-EXTRA_CFLAGS
-EXTRA_LIBS
-XPDF_TARGET
-X
-libpaper_CFLAGS
-libpaper_LIBS
-libpng_CFLAGS
-libpng_LIBS
-freetype2_CFLAGS
-freetype2_LIBS
-Sgm_CFLAGS
-Sgm_LIBS
-Xm_CFLAGS
-Xm_LIBS
-Xt_CFLAGS
-Xt_LIBS
-Xp_CFLAGS
-Xp_LIBS
-Xext_CFLAGS
-Xext_LIBS
-Xpm_CFLAGS
-Xpm_LIBS
-EGREP
-GREP
-X_EXTRA_LIBS
-X_LIBS
-X_PRE_LIBS
-X_CFLAGS
-CPP
-XMKMF
-UP_DIR
-AR
-LIBPREFIX
-EXE
-RANLIB
-INSTALL_DATA
-INSTALL_SCRIPT
-INSTALL_PROGRAM
-ac_ct_CXX
-CXXFLAGS
-CXX
-OBJEXT
-EXEEXT
-ac_ct_CC
-CPPFLAGS
-LDFLAGS
-CFLAGS
-CC
-target_alias
-host_alias
-build_alias
-LIBS
-ECHO_T
-ECHO_N
-ECHO_C
-DEFS
-mandir
-localedir
-libdir
-psdir
-pdfdir
-dvidir
-htmldir
-infodir
-docdir
-oldincludedir
-includedir
-localstatedir
-sharedstatedir
-sysconfdir
-datadir
-datarootdir
-libexecdir
-sbindir
-bindir
-program_transform_name
-prefix
-exec_prefix
-PACKAGE_URL
-PACKAGE_BUGREPORT
-PACKAGE_STRING
-PACKAGE_VERSION
-PACKAGE_TARNAME
-PACKAGE_NAME
-PATH_SEPARATOR
-SHELL'
-ac_subst_files=''
-ac_user_opts='
-enable_option_checking
-enable_a4_paper
-enable_no_text_select
-enable_opi
-enable_multithreaded
-enable_exceptions
-enable_fixedpoint
-enable_cmyk
-with_appdef_dir
-with_x
-enable_largefile
-with_Xpm_library
-with_Xpm_includes
-with_Xext_library
-with_Xext_includes
-with_Xp_library
-with_Xp_includes
-with_Xt_library
-with_Xt_includes
-with_Xm_library
-with_Xm_includes
-with_Sgm_library
-with_Sgm_includes
-with_freetype2_library
-with_freetype2_includes
-with_libpng_library
-with_libpng_includes
-with_libpaper_library
-with_libpaper_includes
-'
- ac_precious_vars='build_alias
-host_alias
-target_alias
-CC
-CFLAGS
-LDFLAGS
-LIBS
-CPPFLAGS
-CXX
-CXXFLAGS
-CCC
-XMKMF
-CPP'
-
-
-# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
-ac_unrecognized_opts=
-ac_unrecognized_sep=
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-cache_file=/dev/null
-exec_prefix=NONE
-no_create=
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-verbose=
-x_includes=NONE
-x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
-# (The list follows the same order as the GNU Coding Standards.)
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datarootdir='${prefix}/share'
-datadir='${datarootdir}'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE}'
-infodir='${datarootdir}/info'
-htmldir='${docdir}'
-dvidir='${docdir}'
-pdfdir='${docdir}'
-psdir='${docdir}'
-libdir='${exec_prefix}/lib'
-localedir='${datarootdir}/locale'
-mandir='${datarootdir}/man'
-
-ac_prev=
-ac_dashdash=
-for ac_option
-do
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval $ac_prev=\$ac_option
- ac_prev=
- continue
- fi
-
- case $ac_option in
- *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
- *=) ac_optarg= ;;
- *) ac_optarg=yes ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case $ac_dashdash$ac_option in
- --)
- ac_dashdash=yes ;;
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir=$ac_optarg ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build_alias ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build_alias=$ac_optarg ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file=$ac_optarg ;;
-
- --config-cache | -C)
- cache_file=config.cache ;;
-
- -datadir | --datadir | --datadi | --datad)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=*)
- datadir=$ac_optarg ;;
-
- -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
- | --dataroo | --dataro | --datar)
- ac_prev=datarootdir ;;
- -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
- | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
- datarootdir=$ac_optarg ;;
-
- -disable-* | --disable-*)
- ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"enable_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval enable_$ac_useropt=no ;;
-
- -docdir | --docdir | --docdi | --doc | --do)
- ac_prev=docdir ;;
- -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
- docdir=$ac_optarg ;;
-
- -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
- ac_prev=dvidir ;;
- -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
- dvidir=$ac_optarg ;;
-
- -enable-* | --enable-*)
- ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"enable_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval enable_$ac_useropt=\$ac_optarg ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix=$ac_optarg ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he | -h)
- ac_init_help=long ;;
- -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
- ac_init_help=recursive ;;
- -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
- ac_init_help=short ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host_alias ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host_alias=$ac_optarg ;;
-
- -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
- ac_prev=htmldir ;;
- -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
- | --ht=*)
- htmldir=$ac_optarg ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir=$ac_optarg ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir=$ac_optarg ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir=$ac_optarg ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir=$ac_optarg ;;
-
- -localedir | --localedir | --localedi | --localed | --locale)
- ac_prev=localedir ;;
- -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
- localedir=$ac_optarg ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst | --locals)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
- localstatedir=$ac_optarg ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir=$ac_optarg ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c | -n)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir=$ac_optarg ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix=$ac_optarg ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix=$ac_optarg ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix=$ac_optarg ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name=$ac_optarg ;;
-
- -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
- ac_prev=pdfdir ;;
- -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
- pdfdir=$ac_optarg ;;
-
- -psdir | --psdir | --psdi | --psd | --ps)
- ac_prev=psdir ;;
- -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
- psdir=$ac_optarg ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir=$ac_optarg ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir=$ac_optarg ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site=$ac_optarg ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir=$ac_optarg ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir=$ac_optarg ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target_alias ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target_alias=$ac_optarg ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers | -V)
- ac_init_version=: ;;
-
- -with-* | --with-*)
- ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"with_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval with_$ac_useropt=\$ac_optarg ;;
-
- -without-* | --without-*)
- ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
- # Reject names that are not valid shell variable names.
- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: $ac_useropt"
- ac_useropt_orig=$ac_useropt
- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
- case $ac_user_opts in
- *"
-"with_$ac_useropt"
-"*) ;;
- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
- ac_unrecognized_sep=', ';;
- esac
- eval with_$ac_useropt=no ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes=$ac_optarg ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries=$ac_optarg ;;
-
- -*) as_fn_error $? "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information"
- ;;
-
- *=*)
- ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
- # Reject names that are not valid shell variable names.
- case $ac_envvar in #(
- '' | [0-9]* | *[!_$as_cr_alnum]* )
- as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
- esac
- eval $ac_envvar=\$ac_optarg
- export $ac_envvar ;;
-
- *)
- # FIXME: should be removed in autoconf 3.0.
- $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
- expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
- : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- as_fn_error $? "missing argument to $ac_option"
-fi
-
-if test -n "$ac_unrecognized_opts"; then
- case $enable_option_checking in
- no) ;;
- fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
- *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
- esac
-fi
-
-# Check all directory arguments for consistency.
-for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
- datadir sysconfdir sharedstatedir localstatedir includedir \
- oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
-do
- eval ac_val=\$$ac_var
- # Remove trailing slashes.
- case $ac_val in
- */ )
- ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
- eval $ac_var=\$ac_val;;
- esac
- # Be sure to have absolute directory names.
- case $ac_val in
- [\\/$]* | ?:[\\/]* ) continue;;
- NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
- esac
- as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
-done
-
-# There might be people who depend on the old broken behavior: `$host'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
- if test "x$build_alias" = x; then
- cross_compiling=maybe
- elif test "x$build_alias" != "x$host_alias"; then
- cross_compiling=yes
- fi
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
-
-test "$silent" = yes && exec 6>/dev/null
-
-
-ac_pwd=`pwd` && test -n "$ac_pwd" &&
-ac_ls_di=`ls -di .` &&
-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
- as_fn_error $? "working directory cannot be determined"
-test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
- as_fn_error $? "pwd does not report name of working directory"
-
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then the parent directory.
- ac_confdir=`$as_dirname -- "$as_myself" ||
-$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_myself" : 'X\(//\)[^/]' \| \
- X"$as_myself" : 'X\(//\)$' \| \
- X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_myself" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- srcdir=$ac_confdir
- if test ! -r "$srcdir/$ac_unique_file"; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r "$srcdir/$ac_unique_file"; then
- test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
- as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
-fi
-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
-ac_abs_confdir=`(
- cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
- pwd)`
-# When building in place, set srcdir=.
-if test "$ac_abs_confdir" = "$ac_pwd"; then
- srcdir=.
-fi
-# Remove unnecessary trailing slashes from srcdir.
-# Double slashes in file names in object file debugging info
-# mess up M-x gdb in Emacs.
-case $srcdir in
-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
-esac
-for ac_var in $ac_precious_vars; do
- eval ac_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_env_${ac_var}_value=\$${ac_var}
- eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
- eval ac_cv_env_${ac_var}_value=\$${ac_var}
-done
-
-#
-# Report the --help message.
-#
-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 this package to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE. See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
- -h, --help display this help and exit
- --help=short display options specific to this package
- --help=recursive display the short help of all the included packages
- -V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking ...' messages
- --cache-file=FILE cache test results in FILE [disabled]
- -C, --config-cache alias for \`--cache-file=config.cache'
- -n, --no-create do not create output files
- --srcdir=DIR find the sources in DIR [configure dir or \`..']
-
-Installation directories:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
- --bindir=DIR user executables [EPREFIX/bin]
- --sbindir=DIR system admin executables [EPREFIX/sbin]
- --libexecdir=DIR program executables [EPREFIX/libexec]
- --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --libdir=DIR object code libraries [EPREFIX/lib]
- --includedir=DIR C header files [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc [/usr/include]
- --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
- --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
- --infodir=DIR info documentation [DATAROOTDIR/info]
- --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
- --mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
- --htmldir=DIR html documentation [DOCDIR]
- --dvidir=DIR dvi documentation [DOCDIR]
- --pdfdir=DIR pdf documentation [DOCDIR]
- --psdir=DIR ps documentation [DOCDIR]
-_ACEOF
-
- cat <<\_ACEOF
-
-X features:
- --x-includes=DIR X include files are in DIR
- --x-libraries=DIR X library files are in DIR
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
-
- cat <<\_ACEOF
-
-Optional Features:
- --disable-option-checking ignore unrecognized --enable/--with options
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --enable-a4-paper use A4 paper size instead of Letter for PostScript
- output
- --enable-no-text-select do not allow text selection
- --enable-opi include support for OPI comments
- --enable-multithreaded include support for multithreading
- --enable-exceptions use C++ exceptions
- --enable-fixedpoint use fixed point (instead of floating point)
- arithmetic
- --enable-cmyk include support for CMYK rasterization
- --disable-largefile omit support for large files
-
-Optional Packages:
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --with-appdef-dir set app-defaults directory
- --with-x use the X Window System
- --with-Xpm-library=PATH
- use Xpm library (pixmap library - used only for icon)
- --with-Xpm-includes=DIR
- set directory for Xpm headers
- --with-Xext-library=PATH
- use Xext library (Motif library)
- --with-Xext-includes=DIR
- set directory for Xext headers
- --with-Xp-library=PATH
- use Xp library (Motif library)
- --with-Xp-includes=DIR
- set directory for Xp headers
- --with-Xt-library=PATH
- use Xt library (Motif library)
- --with-Xt-includes=DIR
- set directory for Xt headers
- --with-Xm-library=PATH
- use Xm library (Motif library)
- --with-Xm-includes=DIR
- set directory for Xm headers
- --with-Sgm-library=PATH
- use Sgm library (SGI Motif library)
- --with-Sgm-includes=DIR
- set directory for Sgm headers
- --with-freetype2-library=PATH
- use freetype2 library (FreeType2 font rasterizer - version 2.0.5+)
- --with-freetype2-includes=DIR
- set directory for freetype2 headers
- --with-libpng-library=PATH
- use libpng library (PNG library)
- --with-libpng-includes=DIR
- set directory for libpng headers
- --with-libpaper-library=PATH
- use libpaper library (Debian libpaper)
- --with-libpaper-includes=DIR
- set directory for libpaper headers
-
-Some influential environment variables:
- CC C compiler command
- CFLAGS C compiler flags
- LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
- nonstandard directory <lib dir>
- LIBS libraries to pass to the linker, e.g. -l<library>
- CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
- you have headers in a nonstandard directory <include dir>
- CXX C++ compiler command
- CXXFLAGS C++ compiler flags
- XMKMF Path to xmkmf, Makefile generator for X Window System
- CPP C preprocessor
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-Report bugs to the package provider.
-_ACEOF
-ac_status=$?
-fi
-
-if test "$ac_init_help" = "recursive"; then
- # If there are subdirs, report their specific --help.
- for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
- test -d "$ac_dir" ||
- { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
- continue
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
- cd "$ac_dir" || { ac_status=$?; continue; }
- # Check for guested configure.
- if test -f "$ac_srcdir/configure.gnu"; then
- echo &&
- $SHELL "$ac_srcdir/configure.gnu" --help=recursive
- elif test -f "$ac_srcdir/configure"; then
- echo &&
- $SHELL "$ac_srcdir/configure" --help=recursive
- else
- $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
- fi || ac_status=$?
- cd "$ac_pwd" || { ac_status=$?; break; }
- done
-fi
-
-test -n "$ac_init_help" && exit $ac_status
-if $ac_init_version; then
- cat <<\_ACEOF
-configure
-generated by GNU Autoconf 2.69
-
-Copyright (C) 2012 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
-_ACEOF
- exit
-fi
-
-## ------------------------ ##
-## Autoconf initialization. ##
-## ------------------------ ##
-
-# ac_fn_c_try_compile LINENO
-# --------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_compile
-
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext && {
- test "$cross_compiling" = yes ||
- test -x conftest$ac_exeext
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
- # interfere with the next link command; also delete a directory that is
- # left behind by Apple's compiler. We do this before executing the actions.
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_link
-
-# ac_fn_cxx_try_compile LINENO
-# ----------------------------
-# Try to compile conftest.$ac_ext, and return whether this succeeded.
-ac_fn_cxx_try_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext
- if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_cxx_try_compile
-
-# ac_fn_c_try_cpp LINENO
-# ----------------------
-# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_cpp ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { { ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } > conftest.i && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_cpp
-
-# ac_fn_c_check_func LINENO FUNC VAR
-# ----------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_c_check_func ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $2 (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $2 ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_func
-
-# ac_fn_cxx_try_link LINENO
-# -------------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_cxx_try_link ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- rm -f conftest.$ac_objext conftest$ac_exeext
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext && {
- test "$cross_compiling" = yes ||
- test -x conftest$ac_exeext
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
- # interfere with the next link command; also delete a directory that is
- # left behind by Apple's compiler. We do this before executing the actions.
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_cxx_try_link
-
-# ac_fn_cxx_check_func LINENO FUNC VAR
-# ------------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_cxx_check_func ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $2 (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $2 ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_cxx_check_func
-
-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists, giving a warning if it cannot be compiled using
-# the include files in INCLUDES and setting the cache variable VAR
-# accordingly.
-ac_fn_c_check_header_mongrel ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if eval \${$3+:} false; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
- $as_echo_n "(cached) " >&6
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-else
- # Is the header compilable?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
-$as_echo_n "checking $2 usability... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_header_compiler=yes
-else
- ac_header_compiler=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
-$as_echo_n "checking $2 presence... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- ac_header_preproc=yes
-else
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
- yes:no: )
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
- ;;
- no:yes:* )
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
- ;;
-esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- eval "$3=\$ac_header_compiler"
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-fi
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_mongrel
-
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
- { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then :
- ac_retval=0
-else
- $as_echo "$as_me: program exited with status $ac_status" >&5
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=$ac_status
-fi
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
- as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_run
-
-# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists and can be compiled using the include files in
-# INCLUDES, setting the cache variable VAR accordingly.
-ac_fn_c_check_header_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_compile
-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 $as_me, which was
-generated by GNU Autoconf 2.69. Invocation command line was
-
- $ $0 $@
-
-_ACEOF
-exec 5>>config.log
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
-
-/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
-/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
-/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- $as_echo "PATH: $as_dir"
- done
-IFS=$as_save_IFS
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
- for ac_arg
- do
- case $ac_arg in
- -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- continue ;;
- *\'*)
- ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- case $ac_pass in
- 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
- 2)
- as_fn_append ac_configure_args1 " '$ac_arg'"
- if test $ac_must_keep_next = true; then
- ac_must_keep_next=false # Got value, back to normal.
- else
- case $ac_arg in
- *=* | --config-cache | -C | -disable-* | --disable-* \
- | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
- | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
- | -with-* | --with-* | -without-* | --without-* | --x)
- case "$ac_configure_args0 " in
- "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
- esac
- ;;
- -* ) ac_must_keep_next=true ;;
- esac
- fi
- as_fn_append ac_configure_args " '$ac_arg'"
- ;;
- esac
- done
-done
-{ ac_configure_args0=; unset ac_configure_args0;}
-{ ac_configure_args1=; unset ac_configure_args1;}
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log. We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Use '\'' to represent an apostrophe within the trap.
-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
-trap 'exit_status=$?
- # Save into config.log some information that might help in debugging.
- {
- echo
-
- $as_echo "## ---------------- ##
-## Cache variables. ##
-## ---------------- ##"
- echo
- # The following way of writing the cache mishandles newlines in values,
-(
- for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
- *) { eval $ac_var=; unset $ac_var;} ;;
- esac ;;
- esac
- done
- (set) 2>&1 |
- case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- sed -n \
- "s/'\''/'\''\\\\'\'''\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
- ;; #(
- *)
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-)
- echo
-
- $as_echo "## ----------------- ##
-## Output variables. ##
-## ----------------- ##"
- echo
- for ac_var in $ac_subst_vars
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- $as_echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
-
- if test -n "$ac_subst_files"; then
- $as_echo "## ------------------- ##
-## File substitutions. ##
-## ------------------- ##"
- echo
- for ac_var in $ac_subst_files
- do
- eval ac_val=\$$ac_var
- case $ac_val in
- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
- esac
- $as_echo "$ac_var='\''$ac_val'\''"
- done | sort
- echo
- fi
-
- if test -s confdefs.h; then
- $as_echo "## ----------- ##
-## confdefs.h. ##
-## ----------- ##"
- echo
- cat confdefs.h
- echo
- fi
- test "$ac_signal" != 0 &&
- $as_echo "$as_me: caught signal $ac_signal"
- $as_echo "$as_me: exit $exit_status"
- } >&5
- rm -f core *.core core.conftest.* &&
- rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
- exit $exit_status
-' 0
-for ac_signal in 1 2 13 15; do
- trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -f -r conftest* confdefs.h
-
-$as_echo "/* confdefs.h */" > confdefs.h
-
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_URL "$PACKAGE_URL"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer an explicitly selected file to automatically selected ones.
-ac_site_file1=NONE
-ac_site_file2=NONE
-if test -n "$CONFIG_SITE"; then
- # We do not want a PATH search for config.site.
- case $CONFIG_SITE in #((
- -*) ac_site_file1=./$CONFIG_SITE;;
- */*) ac_site_file1=$CONFIG_SITE;;
- *) ac_site_file1=./$CONFIG_SITE;;
- esac
-elif test "x$prefix" != xNONE; then
- ac_site_file1=$prefix/share/config.site
- ac_site_file2=$prefix/etc/config.site
-else
- ac_site_file1=$ac_default_prefix/share/config.site
- ac_site_file2=$ac_default_prefix/etc/config.site
-fi
-for ac_site_file in "$ac_site_file1" "$ac_site_file2"
-do
- test "x$ac_site_file" = xNONE && continue
- if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
-$as_echo "$as_me: loading site script $ac_site_file" >&6;}
- sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file" \
- || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5; }
- fi
-done
-
-if test -r "$cache_file"; then
- # Some versions of bash will fail to source /dev/null (special files
- # actually), so we avoid doing that. DJGPP emulates it as a regular file.
- if test /dev/null != "$cache_file" && test -f "$cache_file"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
-$as_echo "$as_me: loading cache $cache_file" >&6;}
- case $cache_file in
- [\\/]* | ?:[\\/]* ) . "$cache_file";;
- *) . "./$cache_file";;
- esac
- fi
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
-$as_echo "$as_me: creating cache $cache_file" >&6;}
- >$cache_file
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in $ac_precious_vars; do
- eval ac_old_set=\$ac_cv_env_${ac_var}_set
- eval ac_new_set=\$ac_env_${ac_var}_set
- eval ac_old_val=\$ac_cv_env_${ac_var}_value
- eval ac_new_val=\$ac_env_${ac_var}_value
- case $ac_old_set,$ac_new_set in
- set,)
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,set)
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
- ac_cache_corrupted=: ;;
- ,);;
- *)
- if test "x$ac_old_val" != "x$ac_new_val"; then
- # differences in whitespace do not lead to failure.
- ac_old_val_w=`echo x $ac_old_val`
- ac_new_val_w=`echo x $ac_new_val`
- if test "$ac_old_val_w" != "$ac_new_val_w"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
- ac_cache_corrupted=:
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
- eval $ac_var=\$ac_old_val
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
-$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
-$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
- fi;;
- esac
- # Pass precious variables to config.status.
- if test "$ac_new_set" = set; then
- case $ac_new_val in
- *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
- *) ac_arg=$ac_var=$ac_new_val ;;
- esac
- case " $ac_configure_args " in
- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
- *) as_fn_append ac_configure_args " '$ac_arg'" ;;
- esac
- fi
-done
-if $ac_cache_corrupted; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
-fi
-## -------------------- ##
-## Main body of script. ##
-## -------------------- ##
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-ac_config_headers="$ac_config_headers aconf.h"
-
-
-
-# Check whether --enable-a4-paper was given.
-if test "${enable_a4_paper+set}" = set; then :
- enableval=$enable_a4_paper;
-fi
-
-if test "x$enable_a4_paper" = "xyes"; then :
- $as_echo "#define A4_PAPER 1" >>confdefs.h
-
-fi
-
-# Check whether --enable-no-text-select was given.
-if test "${enable_no_text_select+set}" = set; then :
- enableval=$enable_no_text_select;
-fi
-
-if test "x$enable_no_text_select" = "xyes"; then :
- $as_echo "#define NO_TEXT_SELECT 1" >>confdefs.h
-
-fi
-
-# Check whether --enable-opi was given.
-if test "${enable_opi+set}" = set; then :
- enableval=$enable_opi;
-fi
-
-if test "x$enable_opi" = "xyes"; then :
- $as_echo "#define OPI_SUPPORT 1" >>confdefs.h
-
-fi
-
-# Check whether --enable-multithreaded was given.
-if test "${enable_multithreaded+set}" = set; then :
- enableval=$enable_multithreaded;
-fi
-
-if test "x$enable_multithreaded" = "xyes"; then :
- $as_echo "#define MULTITHREADED 1" >>confdefs.h
-
-fi
-
-# Check whether --enable-exceptions was given.
-if test "${enable_exceptions+set}" = set; then :
- enableval=$enable_exceptions;
-fi
-
-if test "x$enable_exceptions" = "xyes"; then :
- $as_echo "#define USE_EXCEPTIONS 1" >>confdefs.h
-
-fi
-
-# Check whether --enable-fixedpoint was given.
-if test "${enable_fixedpoint+set}" = set; then :
- enableval=$enable_fixedpoint;
-fi
-
-if test "x$enable_fixedpoint" = "xyes"; then :
- $as_echo "#define USE_FIXEDPOINT 1" >>confdefs.h
-
-fi
-
-# Check whether --enable-cmyk was given.
-if test "${enable_cmyk+set}" = set; then :
- enableval=$enable_cmyk;
-fi
-
-if test "x$enable_cmyk" = "xyes"; then :
- $as_echo "#define SPLASH_CMYK 1" >>confdefs.h
-
-fi
-
-
-# Check whether --with-appdef-dir was given.
-if test "${with_appdef_dir+set}" = set; then :
- withval=$with_appdef_dir;
-fi
-
-if test "x$with_appdef_dir" != "xno"; then :
- cat >>confdefs.h <<_ACEOF
-#define APPDEFDIR "$with_appdef_dir"
-_ACEOF
-
-fi
-
-if test "$sysconfdir" = '${prefix}/etc'; then
- if test "x$prefix" = xNONE; then
- system_xpdfrc="$ac_default_prefix/etc/xpdfrc"
- else
- system_xpdfrc="$prefix/etc/xpdfrc"
- fi
-else
- system_xpdfrc="$sysconfdir/xpdfrc"
-fi
-cat >>confdefs.h <<_ACEOF
-#define SYSTEM_XPDFRC "$system_xpdfrc"
-_ACEOF
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="${ac_tool_prefix}gcc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="gcc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-else
- CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="${ac_tool_prefix}cc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- fi
-fi
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# != 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
- fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- for ac_prog in cl.exe
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$CC" && break
- done
-fi
-if test -z "$CC"; then
- ac_ct_CC=$CC
- for ac_prog in cl.exe
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$ac_ct_CC" && break
-done
-
- if test "x$ac_ct_CC" = x; then
- CC=""
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CC=$ac_ct_CC
- fi
-fi
-
-fi
-
-
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
-
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
- { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compiler $ac_option >&5") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- sed '10a\
-... rest of stderr output deleted ...
- 10q' conftest.err >conftest.er1
- cat conftest.er1 >&5
- fi
- rm -f conftest.er1 conftest.err
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
-done
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-
-# The possible output files:
-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
-
-ac_rmfiles=
-for ac_file in $ac_files
-do
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
- * ) ac_rmfiles="$ac_rmfiles $ac_file";;
- esac
-done
-rm -f $ac_rmfiles
-
-if { { ac_try="$ac_link_default"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link_default") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile. We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
- ;;
- [ab].out )
- # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
- *.* )
- if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
- then :; else
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- fi
- # We set ac_cv_exeext here because the later test for it is not
- # safe: cross compilers may not add the suffix if given an `-o'
- # argument, so we may need to know it at that point already.
- # Even if this section looks crufty: it has the advantage of
- # actually working.
- break;;
- * )
- break;;
- esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
-else
- ac_file=''
-fi
-if test -z "$ac_file"; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-$as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
-ac_exeext=$ac_cv_exeext
-
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
-if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- break;;
- * ) break;;
- esac
-done
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdio.h>
-int
-main ()
-{
-FILE *f = fopen ("conftest.out", "w");
- return ferror (f) || fclose (f) != 0;
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files="$ac_clean_files conftest.out"
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-if test "$cross_compiling" != yes; then
- { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
- if { ac_try='./conftest$ac_cv_exeext'
- { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then
- cross_compiling=no
- else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5; }
- fi
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
-
-rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
-ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if ${ac_cv_objext+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { { ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compile") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- for ac_file in conftest.o conftest.obj conftest.*; do
- test -f "$ac_file" || continue;
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
- break;;
- esac
-done
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_compiler_gnu=yes
-else
- ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
- GCC=yes
-else
- GCC=
-fi
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_save_c_werror_flag=$ac_c_werror_flag
- ac_c_werror_flag=yes
- ac_cv_prog_cc_g=no
- CFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_g=yes
-else
- CFLAGS=""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
- ac_c_werror_flag=$ac_save_c_werror_flag
- CFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_c_werror_flag=$ac_save_c_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not '\xHH' hex character constants.
- These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std is added to get
- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
- array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std. */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
- inside strings and character constants. */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_c89=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
- test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
- x)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
- xno)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
- *)
- CC="$CC $ac_cv_prog_cc_c89"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5
-$as_echo_n "checking for library containing strerror... " >&6; }
-if ${ac_cv_search_strerror+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char strerror ();
-int
-main ()
-{
-return strerror ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' cposix; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_search_strerror=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if ${ac_cv_search_strerror+:} false; then :
- break
-fi
-done
-if ${ac_cv_search_strerror+:} false; then :
-
-else
- ac_cv_search_strerror=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_strerror" >&5
-$as_echo "$ac_cv_search_strerror" >&6; }
-ac_res=$ac_cv_search_strerror
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
- case $ac_cv_prog_cc_stdc in #(
- no) :
- ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #(
- *) :
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
-$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
-if ${ac_cv_prog_cc_c99+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_prog_cc_c99=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <stdio.h>
-
-// Check varargs macros. These examples are taken from C99 6.10.3.5.
-#define debug(...) fprintf (stderr, __VA_ARGS__)
-#define showlist(...) puts (#__VA_ARGS__)
-#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
-static void
-test_varargs_macros (void)
-{
- int x = 1234;
- int y = 5678;
- debug ("Flag");
- debug ("X = %d\n", x);
- showlist (The first, second, and third items.);
- report (x>y, "x is %d but y is %d", x, y);
-}
-
-// Check long long types.
-#define BIG64 18446744073709551615ull
-#define BIG32 4294967295ul
-#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
-#if !BIG_OK
- your preprocessor is broken;
-#endif
-#if BIG_OK
-#else
- your preprocessor is broken;
-#endif
-static long long int bignum = -9223372036854775807LL;
-static unsigned long long int ubignum = BIG64;
-
-struct incomplete_array
-{
- int datasize;
- double data[];
-};
-
-struct named_init {
- int number;
- const wchar_t *name;
- double average;
-};
-
-typedef const char *ccp;
-
-static inline int
-test_restrict (ccp restrict text)
-{
- // See if C++-style comments work.
- // Iterate through items via the restricted pointer.
- // Also check for declarations in for loops.
- for (unsigned int i = 0; *(text+i) != '\0'; ++i)
- continue;
- return 0;
-}
-
-// Check varargs and va_copy.
-static void
-test_varargs (const char *format, ...)
-{
- va_list args;
- va_start (args, format);
- va_list args_copy;
- va_copy (args_copy, args);
-
- const char *str;
- int number;
- float fnumber;
-
- while (*format)
- {
- switch (*format++)
- {
- case 's': // string
- str = va_arg (args_copy, const char *);
- break;
- case 'd': // int
- number = va_arg (args_copy, int);
- break;
- case 'f': // float
- fnumber = va_arg (args_copy, double);
- break;
- default:
- break;
- }
- }
- va_end (args_copy);
- va_end (args);
-}
-
-int
-main ()
-{
-
- // Check bool.
- _Bool success = false;
-
- // Check restrict.
- if (test_restrict ("String literal") == 0)
- success = true;
- char *restrict newvar = "Another string";
-
- // Check varargs.
- test_varargs ("s, d' f .", "string", 65, 34.234);
- test_varargs_macros ();
-
- // Check flexible array members.
- struct incomplete_array *ia =
- malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
- ia->datasize = 10;
- for (int i = 0; i < ia->datasize; ++i)
- ia->data[i] = i * 1.234;
-
- // Check named initializers.
- struct named_init ni = {
- .number = 34,
- .name = L"Test wide string",
- .average = 543.34343,
- };
-
- ni.number = 58;
-
- int dynamic_array[ni.number];
- dynamic_array[ni.number - 1] = 543;
-
- // work around unused variable warnings
- return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
- || dynamic_array[ni.number - 1] != 543);
-
- ;
- return 0;
-}
-_ACEOF
-for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
-do
- CC="$ac_save_CC $ac_arg"
- if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_c99=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
- test "x$ac_cv_prog_cc_c99" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c99" in
- x)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
- xno)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
- *)
- CC="$CC $ac_cv_prog_cc_c99"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
-$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c99" != xno; then :
- ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_prog_cc_c89=no
-ac_save_CC=$CC
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not '\xHH' hex character constants.
- These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std is added to get
- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
- array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std. */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
- inside strings and character constants. */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_prog_cc_c89=$ac_arg
-fi
-rm -f core conftest.err conftest.$ac_objext
- test "x$ac_cv_prog_cc_c89" != "xno" && break
-done
-rm -f conftest.$ac_ext
-CC=$ac_save_CC
-
-fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
- x)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
- xno)
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
- *)
- CC="$CC $ac_cv_prog_cc_c89"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
- ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
-else
- ac_cv_prog_cc_stdc=no
-fi
-
-fi
- ;;
-esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5
-$as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; }
- if ${ac_cv_prog_cc_stdc+:} false; then :
- $as_echo_n "(cached) " >&6
-fi
-
- case $ac_cv_prog_cc_stdc in #(
- no) :
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;; #(
- '') :
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;; #(
- *) :
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5
-$as_echo "$ac_cv_prog_cc_stdc" >&6; } ;;
-esac
-
-#if test -z "$CXX" -a "$CC" = "gcc"; then
-# CXX="gcc"
-#fi
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-if test -z "$CXX"; then
- if test -n "$CCC"; then
- CXX=$CCC
- else
- if test -n "$ac_tool_prefix"; then
- for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CXX+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$CXX"; then
- ac_cv_prog_CXX="$CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-CXX=$ac_cv_prog_CXX
-if test -n "$CXX"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
-$as_echo "$CXX" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$CXX" && break
- done
-fi
-if test -z "$CXX"; then
- ac_ct_CXX=$CXX
- for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CXX+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_CXX"; then
- ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CXX="$ac_prog"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
-if test -n "$ac_ct_CXX"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
-$as_echo "$ac_ct_CXX" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$ac_ct_CXX" && break
-done
-
- if test "x$ac_ct_CXX" = x; then
- CXX="g++"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- CXX=$ac_ct_CXX
- fi
-fi
-
- fi
-fi
-# Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
-set X $ac_compile
-ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
- { { ac_try="$ac_compiler $ac_option >&5"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_compiler $ac_option >&5") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- sed '10a\
-... rest of stderr output deleted ...
- 10q' conftest.err >conftest.er1
- cat conftest.er1 >&5
- fi
- rm -f conftest.er1 conftest.err
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }
-done
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
-$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
-if ${ac_cv_cxx_compiler_gnu+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_compiler_gnu=yes
-else
- ac_compiler_gnu=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
-$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
-if test $ac_compiler_gnu = yes; then
- GXX=yes
-else
- GXX=
-fi
-ac_test_CXXFLAGS=${CXXFLAGS+set}
-ac_save_CXXFLAGS=$CXXFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
-$as_echo_n "checking whether $CXX accepts -g... " >&6; }
-if ${ac_cv_prog_cxx_g+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_save_cxx_werror_flag=$ac_cxx_werror_flag
- ac_cxx_werror_flag=yes
- ac_cv_prog_cxx_g=no
- CXXFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_cv_prog_cxx_g=yes
-else
- CXXFLAGS=""
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-
-else
- ac_cxx_werror_flag=$ac_save_cxx_werror_flag
- CXXFLAGS="-g"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_cv_prog_cxx_g=yes
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_cxx_werror_flag=$ac_save_cxx_werror_flag
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
-$as_echo "$ac_cv_prog_cxx_g" >&6; }
-if test "$ac_test_CXXFLAGS" = set; then
- CXXFLAGS=$ac_save_CXXFLAGS
-elif test $ac_cv_prog_cxx_g = yes; then
- if test "$GXX" = yes; then
- CXXFLAGS="-g -O2"
- else
- CXXFLAGS="-g"
- fi
-else
- if test "$GXX" = yes; then
- CXXFLAGS="-O2"
- else
- CXXFLAGS=
- fi
-fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-ac_aux_dir=
-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
- if test -f "$ac_dir/install-sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f "$ac_dir/install.sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- elif test -f "$ac_dir/shtool"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/shtool install -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
-fi
-
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
-
-
-# Find a good install program. We prefer a C program (faster),
-# so one script is as good as another. But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AmigaOS /C/install, which installs bootblocks on floppy discs
-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# OS/2's system install, which has a completely different semantic
-# ./install, which can be erroneously created by make from ./install.sh.
-# Reject install programs that cannot install multiple files.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
-$as_echo_n "checking for a BSD-compatible install... " >&6; }
-if test -z "$INSTALL"; then
-if ${ac_cv_path_install+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- # Account for people who put trailing slashes in PATH elements.
-case $as_dir/ in #((
- ./ | .// | /[cC]/* | \
- /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
- ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
- /usr/ucb/* ) ;;
- *)
- # OSF1 and SCO ODT 3.0 have their own names for install.
- # Don't use installbsd from OSF since it installs stuff as root
- # by default.
- for ac_prog in ginstall scoinst install; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
- if test $ac_prog = install &&
- grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # AIX install. It has an incompatible calling convention.
- :
- elif test $ac_prog = install &&
- grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # program-specific install script used by HP pwplus--don't use.
- :
- else
- rm -rf conftest.one conftest.two conftest.dir
- echo one > conftest.one
- echo two > conftest.two
- mkdir conftest.dir
- if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
- test -s conftest.one && test -s conftest.two &&
- test -s conftest.dir/conftest.one &&
- test -s conftest.dir/conftest.two
- then
- ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
- break 3
- fi
- fi
- fi
- done
- done
- ;;
-esac
-
- done
-IFS=$as_save_IFS
-
-rm -rf conftest.one conftest.two conftest.dir
-
-fi
- if test "${ac_cv_path_install+set}" = set; then
- INSTALL=$ac_cv_path_install
- else
- # As a last resort, use the slow shell script. Don't cache a
- # value for INSTALL within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the value is a relative name.
- INSTALL=$ac_install_sh
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
-$as_echo "$INSTALL" >&6; }
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_RANLIB+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
-$as_echo "$RANLIB" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_RANLIB"; then
- ac_ct_RANLIB=$RANLIB
- # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$ac_ct_RANLIB"; then
- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_RANLIB="ranlib"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
-$as_echo "$ac_ct_RANLIB" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
- if test "x$ac_ct_RANLIB" = x; then
- RANLIB=":"
- else
- case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
- RANLIB=$ac_ct_RANLIB
- fi
-else
- RANLIB="$ac_cv_prog_RANLIB"
-fi
-
-
-EXE=""
-LIBPREFIX="lib"
-AR="ar rc"
-UP_DIR=""
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OS/2 (with EMX)" >&5
-$as_echo_n "checking for OS/2 (with EMX)... " >&6; }
-if ${xpdf_cv_sys_os2+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-__EMX__
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- xpdf_cv_sys_os2=yes
-else
- xpdf_cv_sys_os2=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xpdf_cv_sys_os2" >&5
-$as_echo "$xpdf_cv_sys_os2" >&6; }
-if test "$xpdf_cv_sys_os2" = yes; then
- EXE=".exe"
- LIBPREFIX=""
- AR="ar -rc"
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DOS (with DJGPP)" >&5
-$as_echo_n "checking for DOS (with DJGPP)... " >&6; }
-if ${xpdf_cv_sys_dos+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-__DJGPP__
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- xpdf_cv_sys_dos=yes
-else
- xpdf_cv_sys_dos=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xpdf_cv_sys_dos" >&5
-$as_echo "$xpdf_cv_sys_dos" >&6; }
-if test "$xpdf_cv_sys_dos" = yes; then
- EXE=".exe"
- LIBPREFIX="lib"
- AR="ar -rc"
- UP_DIR="../"
-fi
-
-
-
-
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
- if ${ac_cv_prog_CPP+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- # Double quotes because CPP needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
- break
-fi
-
- done
- ac_cv_prog_CPP=$CPP
-
-fi
- CPP=$ac_cv_prog_CPP
-else
- ac_cv_prog_CPP=$CPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5
-$as_echo_n "checking for X... " >&6; }
-
-
-# Check whether --with-x was given.
-if test "${with_x+set}" = set; then :
- withval=$with_x;
-fi
-
-# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
-if test "x$with_x" = xno; then
- # The user explicitly disabled X.
- have_x=disabled
-else
- case $x_includes,$x_libraries in #(
- *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #(
- *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- # One or both of the vars are not set, and there is no cached value.
-ac_x_includes=no ac_x_libraries=no
-rm -f -r conftest.dir
-if mkdir conftest.dir; then
- cd conftest.dir
- cat >Imakefile <<'_ACEOF'
-incroot:
- @echo incroot='${INCROOT}'
-usrlibdir:
- @echo usrlibdir='${USRLIBDIR}'
-libdir:
- @echo libdir='${LIBDIR}'
-_ACEOF
- if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then
- # GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
- for ac_var in incroot usrlibdir libdir; do
- eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`"
- done
- # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
- for ac_extension in a so sl dylib la dll; do
- if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" &&
- test -f "$ac_im_libdir/libX11.$ac_extension"; then
- ac_im_usrlibdir=$ac_im_libdir; break
- fi
- done
- # Screen out bogus values from the imake configuration. They are
- # bogus both because they are the default anyway, and because
- # using them would break gcc on systems where it needs fixed includes.
- case $ac_im_incroot in
- /usr/include) ac_x_includes= ;;
- *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;;
- esac
- case $ac_im_usrlibdir in
- /usr/lib | /usr/lib64 | /lib | /lib64) ;;
- *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;;
- esac
- fi
- cd ..
- rm -f -r conftest.dir
-fi
-
-# Standard set of common directories for X headers.
-# Check X11 before X11Rn because it is often a symlink to the current release.
-ac_x_header_dirs='
-/usr/X11/include
-/usr/X11R7/include
-/usr/X11R6/include
-/usr/X11R5/include
-/usr/X11R4/include
-
-/usr/include/X11
-/usr/include/X11R7
-/usr/include/X11R6
-/usr/include/X11R5
-/usr/include/X11R4
-
-/usr/local/X11/include
-/usr/local/X11R7/include
-/usr/local/X11R6/include
-/usr/local/X11R5/include
-/usr/local/X11R4/include
-
-/usr/local/include/X11
-/usr/local/include/X11R7
-/usr/local/include/X11R6
-/usr/local/include/X11R5
-/usr/local/include/X11R4
-
-/usr/X386/include
-/usr/x386/include
-/usr/XFree86/include/X11
-
-/usr/include
-/usr/local/include
-/usr/unsupported/include
-/usr/athena/include
-/usr/local/x11r5/include
-/usr/lpp/Xamples/include
-
-/usr/openwin/include
-/usr/openwin/share/include'
-
-if test "$ac_x_includes" = no; then
- # Guess where to find include files, by looking for Xlib.h.
- # First, try using that file with no special directory specified.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <X11/Xlib.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- # We can compile using X headers with no special include directory.
-ac_x_includes=
-else
- for ac_dir in $ac_x_header_dirs; do
- if test -r "$ac_dir/X11/Xlib.h"; then
- ac_x_includes=$ac_dir
- break
- fi
-done
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-fi # $ac_x_includes = no
-
-if test "$ac_x_libraries" = no; then
- # Check for the libraries.
- # See if we find them without any special options.
- # Don't add to $LIBS permanently.
- ac_save_LIBS=$LIBS
- LIBS="-lX11 $LIBS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <X11/Xlib.h>
-int
-main ()
-{
-XrmInitialize ()
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- LIBS=$ac_save_LIBS
-# We can link X programs with no special library path.
-ac_x_libraries=
-else
- LIBS=$ac_save_LIBS
-for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g`
-do
- # Don't even attempt the hair of trying to link an X program!
- for ac_extension in a so sl dylib la dll; do
- if test -r "$ac_dir/libX11.$ac_extension"; then
- ac_x_libraries=$ac_dir
- break 2
- fi
- done
-done
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi # $ac_x_libraries = no
-
-case $ac_x_includes,$ac_x_libraries in #(
- no,* | *,no | *\'*)
- # Didn't find X, or a directory has "'" in its name.
- ac_cv_have_x="have_x=no";; #(
- *)
- # Record where we found X for the cache.
- ac_cv_have_x="have_x=yes\
- ac_x_includes='$ac_x_includes'\
- ac_x_libraries='$ac_x_libraries'"
-esac
-fi
-;; #(
- *) have_x=yes;;
- esac
- eval "$ac_cv_have_x"
-fi # $with_x != no
-
-if test "$have_x" != yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5
-$as_echo "$have_x" >&6; }
- no_x=yes
-else
- # If each of the values was on the command line, it overrides each guess.
- test "x$x_includes" = xNONE && x_includes=$ac_x_includes
- test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
- # Update the cache value to reflect the command line values.
- ac_cv_have_x="have_x=yes\
- ac_x_includes='$x_includes'\
- ac_x_libraries='$x_libraries'"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5
-$as_echo "libraries $x_libraries, headers $x_includes" >&6; }
-fi
-
-if test "$no_x" = yes; then
- # Not all programs may use this symbol, but it does not hurt to define it.
-
-$as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h
-
- X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS=
-else
- if test -n "$x_includes"; then
- X_CFLAGS="$X_CFLAGS -I$x_includes"
- fi
-
- # It would also be nice to do this for all -L options, not just this one.
- if test -n "$x_libraries"; then
- X_LIBS="$X_LIBS -L$x_libraries"
- # For Solaris; some versions of Sun CC require a space after -R and
- # others require no space. Words are not sufficient . . . .
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5
-$as_echo_n "checking whether -R must be followed by a space... " >&6; }
- ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries"
- ac_xsave_c_werror_flag=$ac_c_werror_flag
- ac_c_werror_flag=yes
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- X_LIBS="$X_LIBS -R$x_libraries"
-else
- LIBS="$ac_xsave_LIBS -R $x_libraries"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- X_LIBS="$X_LIBS -R $x_libraries"
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither works" >&5
-$as_echo "neither works" >&6; }
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- ac_c_werror_flag=$ac_xsave_c_werror_flag
- LIBS=$ac_xsave_LIBS
- fi
-
- # Check for system-dependent libraries X programs must link with.
- # Do this before checking for the system-independent R6 libraries
- # (-lICE), since we may need -lsocket or whatever for X linking.
-
- if test "$ISC" = yes; then
- X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet"
- else
- # Martyn Johnson says this is needed for Ultrix, if the X
- # libraries were built with DECnet support. And Karl Berry says
- # the Alpha needs dnet_stub (dnet does not exist).
- ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char XOpenDisplay ();
-int
-main ()
-{
-return XOpenDisplay ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5
-$as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; }
-if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldnet $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dnet_ntoa ();
-int
-main ()
-{
-return dnet_ntoa ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dnet_dnet_ntoa=yes
-else
- ac_cv_lib_dnet_dnet_ntoa=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5
-$as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; }
-if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then :
- X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
-fi
-
- if test $ac_cv_lib_dnet_dnet_ntoa = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5
-$as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; }
-if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldnet_stub $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dnet_ntoa ();
-int
-main ()
-{
-return dnet_ntoa ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_dnet_stub_dnet_ntoa=yes
-else
- ac_cv_lib_dnet_stub_dnet_ntoa=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5
-$as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; }
-if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then :
- X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
-fi
-
- fi
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- LIBS="$ac_xsave_LIBS"
-
- # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
- # to get the SysV transport functions.
- # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4)
- # needs -lnsl.
- # The nsl library prevents programs from opening the X display
- # on Irix 5.2, according to T.E. Dickey.
- # The functions gethostbyname, getservbyname, and inet_addr are
- # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking.
- ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
-if test "x$ac_cv_func_gethostbyname" = xyes; then :
-
-fi
-
- if test $ac_cv_func_gethostbyname = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
-$as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
-if ${ac_cv_lib_nsl_gethostbyname+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lnsl $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char gethostbyname ();
-int
-main ()
-{
-return gethostbyname ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_nsl_gethostbyname=yes
-else
- ac_cv_lib_nsl_gethostbyname=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5
-$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; }
-if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then :
- X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
-fi
-
- if test $ac_cv_lib_nsl_gethostbyname = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5
-$as_echo_n "checking for gethostbyname in -lbsd... " >&6; }
-if ${ac_cv_lib_bsd_gethostbyname+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lbsd $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char gethostbyname ();
-int
-main ()
-{
-return gethostbyname ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_bsd_gethostbyname=yes
-else
- ac_cv_lib_bsd_gethostbyname=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5
-$as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; }
-if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then :
- X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd"
-fi
-
- fi
- fi
-
- # lieder@skyler.mavd.honeywell.com says without -lsocket,
- # socket/setsockopt and other routines are undefined under SCO ODT
- # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary
- # on later versions), says Simon Leinen: it contains gethostby*
- # variants that don't use the name server (or something). -lsocket
- # must be given before -lnsl if both are needed. We assume that
- # if connect needs -lnsl, so does gethostbyname.
- ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect"
-if test "x$ac_cv_func_connect" = xyes; then :
-
-fi
-
- if test $ac_cv_func_connect = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5
-$as_echo_n "checking for connect in -lsocket... " >&6; }
-if ${ac_cv_lib_socket_connect+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char connect ();
-int
-main ()
-{
-return connect ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_socket_connect=yes
-else
- ac_cv_lib_socket_connect=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5
-$as_echo "$ac_cv_lib_socket_connect" >&6; }
-if test "x$ac_cv_lib_socket_connect" = xyes; then :
- X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
-fi
-
- fi
-
- # Guillermo Gomez says -lposix is necessary on A/UX.
- ac_fn_c_check_func "$LINENO" "remove" "ac_cv_func_remove"
-if test "x$ac_cv_func_remove" = xyes; then :
-
-fi
-
- if test $ac_cv_func_remove = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5
-$as_echo_n "checking for remove in -lposix... " >&6; }
-if ${ac_cv_lib_posix_remove+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lposix $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char remove ();
-int
-main ()
-{
-return remove ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_posix_remove=yes
-else
- ac_cv_lib_posix_remove=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5
-$as_echo "$ac_cv_lib_posix_remove" >&6; }
-if test "x$ac_cv_lib_posix_remove" = xyes; then :
- X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
-fi
-
- fi
-
- # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
- ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat"
-if test "x$ac_cv_func_shmat" = xyes; then :
-
-fi
-
- if test $ac_cv_func_shmat = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5
-$as_echo_n "checking for shmat in -lipc... " >&6; }
-if ${ac_cv_lib_ipc_shmat+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lipc $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char shmat ();
-int
-main ()
-{
-return shmat ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_ipc_shmat=yes
-else
- ac_cv_lib_ipc_shmat=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5
-$as_echo "$ac_cv_lib_ipc_shmat" >&6; }
-if test "x$ac_cv_lib_ipc_shmat" = xyes; then :
- X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
-fi
-
- fi
- fi
-
- # Check for libraries that X11R6 Xt/Xaw programs need.
- ac_save_LDFLAGS=$LDFLAGS
- test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries"
- # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
- # check for ICE first), but we must link in the order -lSM -lICE or
- # we get undefined symbols. So assume we have SM if we have ICE.
- # These have to be linked with before -lX11, unlike the other
- # libraries we check for below, so use a different variable.
- # John Interrante, Karl Berry
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5
-$as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; }
-if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lICE $X_EXTRA_LIBS $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char IceConnectionNumber ();
-int
-main ()
-{
-return IceConnectionNumber ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_ICE_IceConnectionNumber=yes
-else
- ac_cv_lib_ICE_IceConnectionNumber=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5
-$as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; }
-if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then :
- X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
-fi
-
- LDFLAGS=$ac_save_LDFLAGS
-
-fi
-
-ac_header_dirent=no
-for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
- as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
-$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
-if eval \${$as_ac_Header+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <$ac_hdr>
-
-int
-main ()
-{
-if ((DIR *) 0)
-return 0;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "$as_ac_Header=yes"
-else
- eval "$as_ac_Header=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$as_ac_Header
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
-_ACEOF
-
-ac_header_dirent=$ac_hdr; break
-fi
-
-done
-# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
-if test $ac_header_dirent = dirent.h; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
-$as_echo_n "checking for library containing opendir... " >&6; }
-if ${ac_cv_search_opendir+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char opendir ();
-int
-main ()
-{
-return opendir ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' dir; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_search_opendir=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if ${ac_cv_search_opendir+:} false; then :
- break
-fi
-done
-if ${ac_cv_search_opendir+:} false; then :
-
-else
- ac_cv_search_opendir=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
-$as_echo "$ac_cv_search_opendir" >&6; }
-ac_res=$ac_cv_search_opendir
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
-$as_echo_n "checking for library containing opendir... " >&6; }
-if ${ac_cv_search_opendir+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char opendir ();
-int
-main ()
-{
-return opendir ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' x; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_search_opendir=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if ${ac_cv_search_opendir+:} false; then :
- break
-fi
-done
-if ${ac_cv_search_opendir+:} false; then :
-
-else
- ac_cv_search_opendir=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
-$as_echo "$ac_cv_search_opendir" >&6; }
-ac_res=$ac_cv_search_opendir
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
-fi
-
-
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
-
-ac_fn_cxx_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
-if test "x$ac_cv_func_gethostbyname" = xyes; then :
-
-fi
-
-if test $ac_cv_func_gethostbyname = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5
-$as_echo_n "checking for gethostbyname in -lbsd... " >&6; }
-if ${ac_cv_lib_bsd_gethostbyname+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lbsd $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char gethostbyname ();
-int
-main ()
-{
-return gethostbyname ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
- ac_cv_lib_bsd_gethostbyname=yes
-else
- ac_cv_lib_bsd_gethostbyname=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5
-$as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; }
-if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then :
- X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd"
-fi
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking select() and fd_set in sys/select.h and sys/bsdtypes.h" >&5
-$as_echo_n "checking select() and fd_set in sys/select.h and sys/bsdtypes.h... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <sys/types.h>
-int
-main ()
-{
-fd_set fds;
-select(0, NULL, NULL, NULL, NULL);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- xpdf_ok=yes
-else
- xpdf_ok=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-if test $xpdf_ok = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not needed" >&5
-$as_echo "not needed" >&6; }
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/select.h>
-int
-main ()
-{
-fd_set fds;
-select(0, NULL, NULL, NULL, NULL);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- xpdf_ok=yes
-else
- xpdf_ok=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- if test $xpdf_ok = yes; then
- $as_echo "#define HAVE_SYS_SELECT_H 1" >>confdefs.h
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: need sys/select.h" >&5
-$as_echo "need sys/select.h" >&6; }
- else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/bsdtypes.h>
-int
-main ()
-{
-fd_set fds;
-select(0, NULL, NULL, NULL, NULL);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- xpdf_ok=yes
-else
- xpdf_ok=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- if test $xpdf_ok = yes; then
- $as_echo "#define HAVE_SYS_BSDTYPES_H 1" >>confdefs.h
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: need sys/bsdtypes.h" >&5
-$as_echo "need sys/bsdtypes.h" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: problem" >&5
-$as_echo "problem" >&6; }
- fi
- fi
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking FD_ZERO and strings.h or bstring.h" >&5
-$as_echo_n "checking FD_ZERO and strings.h or bstring.h... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-int
-main ()
-{
-fd_set fds; FD_ZERO(&fds);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- xpdf_ok=yes
-else
- xpdf_ok=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-if test $xpdf_ok = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not needed" >&5
-$as_echo "not needed" >&6; }
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <sys/types.h>
-#include <strings.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-int
-main ()
-{
-fd_set fds; FD_ZERO(&fds);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- xpdf_ok=yes
-else
- xpdf_ok=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- if test $xpdf_ok = yes; then
- $as_echo "#define HAVE_STRINGS_H 1" >>confdefs.h
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: need strings.h" >&5
-$as_echo "need strings.h" >&6; }
- else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <sys/types.h>
-#include <bstring.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-int
-main ()
-{
-fd_set fds; FD_ZERO(&fds);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- xpdf_ok=yes
-else
- xpdf_ok=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- if test $xpdf_ok = yes; then
- $as_echo "#define HAVE_BSTRING_H 1" >>confdefs.h
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: need bstring.h" >&5
-$as_echo "need bstring.h" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: problem" >&5
-$as_echo "problem" >&6; }
- fi
- fi
-fi
-
-for ac_func in rewinddir
-do :
- ac_fn_cxx_check_func "$LINENO" "rewinddir" "ac_cv_func_rewinddir"
-if test "x$ac_cv_func_rewinddir" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_REWINDDIR 1
-_ACEOF
-
-fi
-done
-
-if test $ac_cv_func_rewinddir = no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rewinddir in -lcposix" >&5
-$as_echo_n "checking for rewinddir in -lcposix... " >&6; }
-if ${ac_cv_lib_cposix_rewinddir+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lcposix $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char rewinddir ();
-int
-main ()
-{
-return rewinddir ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
- ac_cv_lib_cposix_rewinddir=yes
-else
- ac_cv_lib_cposix_rewinddir=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cposix_rewinddir" >&5
-$as_echo "$ac_cv_lib_cposix_rewinddir" >&6; }
-if test "x$ac_cv_lib_cposix_rewinddir" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBCPOSIX 1
-_ACEOF
-
- LIBS="-lcposix $LIBS"
-
-fi
-
-fi
-
-for ac_func in popen
-do :
- ac_fn_cxx_check_func "$LINENO" "popen" "ac_cv_func_popen"
-if test "x$ac_cv_func_popen" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_POPEN 1
-_ACEOF
-
-fi
-done
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mkstemp" >&5
-$as_echo_n "checking for mkstemp... " >&6; }
-if ${xpdf_cv_func_mkstemp+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <unistd.h>
-int
-main ()
-{
-mkstemp("foo");
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
- xpdf_cv_func_mkstemp=yes
-else
- xpdf_cv_func_mkstemp=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xpdf_cv_func_mkstemp" >&5
-$as_echo "$xpdf_cv_func_mkstemp" >&6; }
-if test "$xpdf_cv_func_mkstemp" = yes; then
- $as_echo "#define HAVE_MKSTEMP 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mkstemps" >&5
-$as_echo_n "checking for mkstemps... " >&6; }
-if ${xpdf_cv_func_mkstemps+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <unistd.h>
-int
-main ()
-{
-mkstemps("foo", 0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_link "$LINENO"; then :
- xpdf_cv_func_mkstemps=yes
-else
- xpdf_cv_func_mkstemps=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xpdf_cv_func_mkstemps" >&5
-$as_echo "$xpdf_cv_func_mkstemps" >&6; }
-if test "$xpdf_cv_func_mkstemps" = yes; then
- $as_echo "#define HAVE_MKSTEMPS 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether select takes fd_set arguments" >&5
-$as_echo_n "checking whether select takes fd_set arguments... " >&6; }
-if ${xpdf_cv_func_select_arg+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-int
-main ()
-{
-fd_set fds;
-select(1, &fds, &fds, &fds, 0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- xpdf_cv_func_select_arg=yes
-else
- xpdf_cv_func_select_arg=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xpdf_cv_func_select_arg" >&5
-$as_echo "$xpdf_cv_func_select_arg" >&6; }
-if test "$xpdf_cv_func_select_arg" != yes; then
- $as_echo "#define SELECT_TAKES_INT 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::sort" >&5
-$as_echo_n "checking for std::sort... " >&6; }
-if ${xpdf_cv_func_std_sort+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <algorithm>
-struct functor {
- bool operator()(const int &i0, const int &i1) { return i0 < i1; }
-};
-int
-main ()
-{
-int a[100];
-std::sort(a, a+100, functor());
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- xpdf_cv_func_std_sort=yes
-else
- xpdf_cv_func_std_sort=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xpdf_cv_func_std_sort" >&5
-$as_echo "$xpdf_cv_func_std_sort" >&6; }
-if test "$xpdf_cv_func_std_sort" = yes; then
- $as_echo "#define HAVE_STD_SORT 1" >>confdefs.h
-
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-# Check whether --enable-largefile was given.
-if test "${enable_largefile+set}" = set; then :
- enableval=$enable_largefile;
-fi
-
-if test "$enable_largefile" != no; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
-$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
-if ${ac_cv_sys_largefile_CC+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_cv_sys_largefile_CC=no
- if test "$GCC" != yes; then
- ac_save_CC=$CC
- while :; do
- # IRIX 6.2 and later do not support large files by default,
- # so use the C compiler's -n32 option if that helps.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
- if ac_fn_c_try_compile "$LINENO"; then :
- break
-fi
-rm -f core conftest.err conftest.$ac_objext
- CC="$CC -n32"
- if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_largefile_CC=' -n32'; break
-fi
-rm -f core conftest.err conftest.$ac_objext
- break
- done
- CC=$ac_save_CC
- rm -f conftest.$ac_ext
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
-$as_echo "$ac_cv_sys_largefile_CC" >&6; }
- if test "$ac_cv_sys_largefile_CC" != no; then
- CC=$CC$ac_cv_sys_largefile_CC
- fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
-$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
-if ${ac_cv_sys_file_offset_bits+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- while :; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_file_offset_bits=no; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#define _FILE_OFFSET_BITS 64
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_file_offset_bits=64; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_cv_sys_file_offset_bits=unknown
- break
-done
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
-$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
-case $ac_cv_sys_file_offset_bits in #(
- no | unknown) ;;
- *)
-cat >>confdefs.h <<_ACEOF
-#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
-_ACEOF
-;;
-esac
-rm -rf conftest*
- if test $ac_cv_sys_file_offset_bits = unknown; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
-$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
-if ${ac_cv_sys_large_files+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- while :; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_large_files=no; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#define _LARGE_FILES 1
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_sys_large_files=1; break
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_cv_sys_large_files=unknown
- break
-done
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
-$as_echo "$ac_cv_sys_large_files" >&6; }
-case $ac_cv_sys_large_files in #(
- no | unknown) ;;
- *)
-cat >>confdefs.h <<_ACEOF
-#define _LARGE_FILES $ac_cv_sys_large_files
-_ACEOF
-;;
-esac
-rm -rf conftest*
- fi
-
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5
-$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; }
-if ${ac_cv_sys_largefile_source+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- while :; do
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h> /* for off_t */
- #include <stdio.h>
-int
-main ()
-{
-int (*fp) (FILE *, off_t, int) = fseeko;
- return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_sys_largefile_source=no; break
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#define _LARGEFILE_SOURCE 1
-#include <sys/types.h> /* for off_t */
- #include <stdio.h>
-int
-main ()
-{
-int (*fp) (FILE *, off_t, int) = fseeko;
- return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_sys_largefile_source=1; break
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- ac_cv_sys_largefile_source=unknown
- break
-done
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5
-$as_echo "$ac_cv_sys_largefile_source" >&6; }
-case $ac_cv_sys_largefile_source in #(
- no | unknown) ;;
- *)
-cat >>confdefs.h <<_ACEOF
-#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
-_ACEOF
-;;
-esac
-rm -rf conftest*
-
-# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
-# in glibc 2.1.3, but that breaks too many other things.
-# If you want fseeko and ftello with glibc, upgrade to a fixed glibc.
-if test $ac_cv_sys_largefile_source != unknown; then
-
-$as_echo "#define HAVE_FSEEKO 1" >>confdefs.h
-
-fi
-
-for ac_func in fseek64
-do :
- ac_fn_c_check_func "$LINENO" "fseek64" "ac_cv_func_fseek64"
-if test "x$ac_cv_func_fseek64" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_FSEEK64 1
-_ACEOF
- xpdf_cv_func_fseek64=yes
-else
- xpdf_cv_func_fseek64=no
-fi
-done
-
-for ac_func in ftell64
-do :
- ac_fn_c_check_func "$LINENO" "ftell64" "ac_cv_func_ftell64"
-if test "x$ac_cv_func_ftell64" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_FTELL64 1
-_ACEOF
- xpdf_cv_func_ftell64=yes
-else
- xpdf_cv_func_ftell64=no
-fi
-done
-
-if test "$xpdf_cv_func_fseek64" = yes -a "$xpdf_cv_func_ftell64" = yes; then
- $as_echo "#define HAVE_FSEEK64 1" >>confdefs.h
-
-fi
-
-if test -z "$no_x"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if ${ac_cv_path_GREP+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$GREP"; then
- ac_path_GREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in grep ggrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- as_fn_executable_p "$ac_path_GREP" || continue
-# Check for GNU ac_path_GREP and select it if it is found.
- # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'GREP' >> "conftest.nl"
- "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_GREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_GREP="$ac_path_GREP"
- ac_path_GREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_GREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_GREP"; then
- as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_GREP=$GREP
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if ${ac_cv_path_EGREP+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
- then ac_cv_path_EGREP="$GREP -E"
- else
- if test -z "$EGREP"; then
- ac_path_EGREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in egrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- as_fn_executable_p "$ac_path_EGREP" || continue
-# Check for GNU ac_path_EGREP and select it if it is found.
- # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'EGREP' >> "conftest.nl"
- "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_EGREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_EGREP="$ac_path_EGREP"
- ac_path_EGREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_EGREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_EGREP"; then
- as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_EGREP=$EGREP
-fi
-
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_stdc=yes
-else
- ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then :
- :
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
- inttypes.h stdint.h unistd.h
-do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-Xpm-library was given.
-if test "${with_Xpm_library+set}" = set; then :
- withval=$with_Xpm_library; smr_cv_with_Xpm_library=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use Xpm library" >&5
-$as_echo_n "checking whether to use Xpm library... " >&6; }
-if ${smr_cv_with_Xpm_library+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_Xpm_library=maybe
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_Xpm_library" >&5
-$as_echo "$smr_cv_with_Xpm_library" >&6; }
-
-
- case x"$smr_cv_with_Xpm_library" in
- xyes | xmaybe)
- Xpm_LIBS="-lXpm"
- with_Xpm=$smr_cv_with_Xpm_library
- ;;
- xno)
- Xpm_LIBS=
- with_Xpm=no
- ;;
- *)
- if test -f "$smr_cv_with_Xpm_library"; then
- Xpm_LIBS=$smr_cv_with_Xpm_library
- elif test -d "$smr_cv_with_Xpm_library"; then
- Xpm_LIBS="-L$smr_cv_with_Xpm_library -lXpm"
- else
- as_fn_error $? "argument must be boolean, file, or directory" "$LINENO" 5
- fi
- with_Xpm=yes
- ;;
- esac
-
-
-
-
-
-
-
- if test ! x"$with_Xpm" = xno; then
-
- # If we got this far, then the user didn't explicitly ask not to use
- # the library.
-
-
-
-
-
-
-
-
-# Check whether --with-Xpm-includes was given.
-if test "${with_Xpm_includes+set}" = set; then :
- withval=$with_Xpm_includes; smr_cv_with_Xpm_includes=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find the Xpm header files" >&5
-$as_echo_n "checking where to find the Xpm header files... " >&6; }
-if ${smr_cv_with_Xpm_includes+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_Xpm_includes=
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_Xpm_includes" >&5
-$as_echo "$smr_cv_with_Xpm_includes" >&6; }
-
- if test ! x"$smr_cv_with_Xpm_includes" = x; then
- if test -d "$smr_cv_with_Xpm_includes"; then
- Xpm_CFLAGS="-I$smr_cv_with_Xpm_includes"
- else
- as_fn_error $? "argument must be a directory" "$LINENO" 5
- fi
- else
- Xpm_CFLAGS=
- fi
-
- smr_test_CPPFLAGS="${CPPFLAGS+set}"
- smr_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $Xpm_CFLAGS $X_CFLAGS"
-
- for ac_header in X11/xpm.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "X11/xpm.h" "ac_cv_header_X11_xpm_h" "$ac_includes_default"
-if test "x$ac_cv_header_X11_xpm_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_X11_XPM_H 1
-_ACEOF
- smr_have_Xpm_header=yes
-else
- smr_have_Xpm_header=no
-fi
-
-done
-
-
- if test x"$smr_test_CPPFLAGS" = xset; then
- CPPFLAGS=$smr_save_CPPFLAGS
- else
- unset CPPFLAGS
- fi
-
-
-
-
-
-
-
- # We need only look for the library if the header has been found
- # (or no header is needed).
- if test $smr_have_Xpm_header != no; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XpmCreatePixmapFromData in -lXpm" >&5
-$as_echo_n "checking for XpmCreatePixmapFromData in -lXpm... " >&6; }
-if ${ac_cv_lib_Xpm_XpmCreatePixmapFromData+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lXpm $Xpm_CFLAGS $X_CFLAGS $Xpm_LIBS $X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS -lX11 $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char XpmCreatePixmapFromData ();
-int
-main ()
-{
-return XpmCreatePixmapFromData ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_Xpm_XpmCreatePixmapFromData=yes
-else
- ac_cv_lib_Xpm_XpmCreatePixmapFromData=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xpm_XpmCreatePixmapFromData" >&5
-$as_echo "$ac_cv_lib_Xpm_XpmCreatePixmapFromData" >&6; }
-if test "x$ac_cv_lib_Xpm_XpmCreatePixmapFromData" = xyes; then :
- smr_have_Xpm_library=yes
-else
- smr_have_Xpm_library=no
-fi
-
- fi
-
- if test x"$smr_have_Xpm_library" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using Xpm library" >&5
-$as_echo "using Xpm library" >&6; }
- else
- Xpm_LIBS=
- Xpm_CFLAGS=
-
- if test x"$with_Xpm" = xmaybe; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not using Xpm library" >&5
-$as_echo "not using Xpm library" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: requested Xpm library not found!" >&5
-$as_echo "$as_me: WARNING: requested Xpm library not found!" >&2;}
- fi
- fi
- fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-fi
-
-if test -z "$no_x"; then
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-Xext-library was given.
-if test "${with_Xext_library+set}" = set; then :
- withval=$with_Xext_library; smr_cv_with_Xext_library=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use Xext library" >&5
-$as_echo_n "checking whether to use Xext library... " >&6; }
-if ${smr_cv_with_Xext_library+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_Xext_library=maybe
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_Xext_library" >&5
-$as_echo "$smr_cv_with_Xext_library" >&6; }
-
-
- case x"$smr_cv_with_Xext_library" in
- xyes | xmaybe)
- Xext_LIBS="-lXext"
- with_Xext=$smr_cv_with_Xext_library
- ;;
- xno)
- Xext_LIBS=
- with_Xext=no
- ;;
- *)
- if test -f "$smr_cv_with_Xext_library"; then
- Xext_LIBS=$smr_cv_with_Xext_library
- elif test -d "$smr_cv_with_Xext_library"; then
- Xext_LIBS="-L$smr_cv_with_Xext_library -lXext"
- else
- as_fn_error $? "argument must be boolean, file, or directory" "$LINENO" 5
- fi
- with_Xext=yes
- ;;
- esac
-
-
-
-
-
-
-
- if test ! x"$with_Xext" = xno; then
-
- # If we got this far, then the user didn't explicitly ask not to use
- # the library.
-
-
-
-
-
-
-
-
-# Check whether --with-Xext-includes was given.
-if test "${with_Xext_includes+set}" = set; then :
- withval=$with_Xext_includes; smr_cv_with_Xext_includes=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find the Xext header files" >&5
-$as_echo_n "checking where to find the Xext header files... " >&6; }
-if ${smr_cv_with_Xext_includes+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_Xext_includes=
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_Xext_includes" >&5
-$as_echo "$smr_cv_with_Xext_includes" >&6; }
-
- if test ! x"$smr_cv_with_Xext_includes" = x; then
- if test -d "$smr_cv_with_Xext_includes"; then
- Xext_CFLAGS="-I$smr_cv_with_Xext_includes"
- else
- as_fn_error $? "argument must be a directory" "$LINENO" 5
- fi
- else
- Xext_CFLAGS=
- fi
-
- smr_test_CPPFLAGS="${CPPFLAGS+set}"
- smr_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $Xext_CFLAGS $X_CFLAGS"
-
- for ac_header in X11/Xlib.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "X11/Xlib.h" "ac_cv_header_X11_Xlib_h" "$ac_includes_default"
-if test "x$ac_cv_header_X11_Xlib_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_X11_XLIB_H 1
-_ACEOF
- smr_have_Xext_header=yes
-else
- smr_have_Xext_header=no
-fi
-
-done
-
-
- if test x"$smr_test_CPPFLAGS" = xset; then
- CPPFLAGS=$smr_save_CPPFLAGS
- else
- unset CPPFLAGS
- fi
-
-
-
-
-
-
-
- # We need only look for the library if the header has been found
- # (or no header is needed).
- if test $smr_have_Xext_header != no; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XextAddDisplay in -lXext" >&5
-$as_echo_n "checking for XextAddDisplay in -lXext... " >&6; }
-if ${ac_cv_lib_Xext_XextAddDisplay+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lXext $Xext_CFLAGS $X_CFLAGS $Xext_LIBS $X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS -lX11 $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char XextAddDisplay ();
-int
-main ()
-{
-return XextAddDisplay ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_Xext_XextAddDisplay=yes
-else
- ac_cv_lib_Xext_XextAddDisplay=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xext_XextAddDisplay" >&5
-$as_echo "$ac_cv_lib_Xext_XextAddDisplay" >&6; }
-if test "x$ac_cv_lib_Xext_XextAddDisplay" = xyes; then :
- smr_have_Xext_library=yes
-else
- smr_have_Xext_library=no
-fi
-
- fi
-
- if test x"$smr_have_Xext_library" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using Xext library" >&5
-$as_echo "using Xext library" >&6; }
- else
- Xext_LIBS=
- Xext_CFLAGS=
-
- if test x"$with_Xext" = xmaybe; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not using Xext library" >&5
-$as_echo "not using Xext library" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: requested Xext library not found!" >&5
-$as_echo "$as_me: WARNING: requested Xext library not found!" >&2;}
- fi
- fi
- fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-Xp-library was given.
-if test "${with_Xp_library+set}" = set; then :
- withval=$with_Xp_library; smr_cv_with_Xp_library=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use Xp library" >&5
-$as_echo_n "checking whether to use Xp library... " >&6; }
-if ${smr_cv_with_Xp_library+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_Xp_library=maybe
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_Xp_library" >&5
-$as_echo "$smr_cv_with_Xp_library" >&6; }
-
-
- case x"$smr_cv_with_Xp_library" in
- xyes | xmaybe)
- Xp_LIBS="-lXp"
- with_Xp=$smr_cv_with_Xp_library
- ;;
- xno)
- Xp_LIBS=
- with_Xp=no
- ;;
- *)
- if test -f "$smr_cv_with_Xp_library"; then
- Xp_LIBS=$smr_cv_with_Xp_library
- elif test -d "$smr_cv_with_Xp_library"; then
- Xp_LIBS="-L$smr_cv_with_Xp_library -lXp"
- else
- as_fn_error $? "argument must be boolean, file, or directory" "$LINENO" 5
- fi
- with_Xp=yes
- ;;
- esac
-
-
-
-
-
-
-
- if test ! x"$with_Xp" = xno; then
-
- # If we got this far, then the user didn't explicitly ask not to use
- # the library.
-
-
-
-
-
-
-
-
-# Check whether --with-Xp-includes was given.
-if test "${with_Xp_includes+set}" = set; then :
- withval=$with_Xp_includes; smr_cv_with_Xp_includes=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find the Xp header files" >&5
-$as_echo_n "checking where to find the Xp header files... " >&6; }
-if ${smr_cv_with_Xp_includes+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_Xp_includes=
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_Xp_includes" >&5
-$as_echo "$smr_cv_with_Xp_includes" >&6; }
-
- if test ! x"$smr_cv_with_Xp_includes" = x; then
- if test -d "$smr_cv_with_Xp_includes"; then
- Xp_CFLAGS="-I$smr_cv_with_Xp_includes"
- else
- as_fn_error $? "argument must be a directory" "$LINENO" 5
- fi
- else
- Xp_CFLAGS=
- fi
-
- smr_test_CPPFLAGS="${CPPFLAGS+set}"
- smr_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $Xp_CFLAGS $X_CFLAGS"
-
- for ac_header in X11/extensions/Print.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "X11/extensions/Print.h" "ac_cv_header_X11_extensions_Print_h" "$ac_includes_default"
-if test "x$ac_cv_header_X11_extensions_Print_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_X11_EXTENSIONS_PRINT_H 1
-_ACEOF
- smr_have_Xp_header=yes
-else
- smr_have_Xp_header=no
-fi
-
-done
-
-
- if test x"$smr_test_CPPFLAGS" = xset; then
- CPPFLAGS=$smr_save_CPPFLAGS
- else
- unset CPPFLAGS
- fi
-
-
-
-
-
-
-
- # We need only look for the library if the header has been found
- # (or no header is needed).
- if test $smr_have_Xp_header != no; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XpStartPage in -lXp" >&5
-$as_echo_n "checking for XpStartPage in -lXp... " >&6; }
-if ${ac_cv_lib_Xp_XpStartPage+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lXp $Xp_CFLAGS $X_CFLAGS $Xp_LIBS $X_LIBS $X_PRE_LIBS $Xext_LIBS $X_EXTRA_LIBS -lX11 $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char XpStartPage ();
-int
-main ()
-{
-return XpStartPage ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_Xp_XpStartPage=yes
-else
- ac_cv_lib_Xp_XpStartPage=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xp_XpStartPage" >&5
-$as_echo "$ac_cv_lib_Xp_XpStartPage" >&6; }
-if test "x$ac_cv_lib_Xp_XpStartPage" = xyes; then :
- smr_have_Xp_library=yes
-else
- smr_have_Xp_library=no
-fi
-
- fi
-
- if test x"$smr_have_Xp_library" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using Xp library" >&5
-$as_echo "using Xp library" >&6; }
- else
- Xp_LIBS=
- Xp_CFLAGS=
-
- if test x"$with_Xp" = xmaybe; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not using Xp library" >&5
-$as_echo "not using Xp library" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: requested Xp library not found!" >&5
-$as_echo "$as_me: WARNING: requested Xp library not found!" >&2;}
- fi
- fi
- fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-Xt-library was given.
-if test "${with_Xt_library+set}" = set; then :
- withval=$with_Xt_library; smr_cv_with_Xt_library=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use Xt library" >&5
-$as_echo_n "checking whether to use Xt library... " >&6; }
-if ${smr_cv_with_Xt_library+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_Xt_library=maybe
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_Xt_library" >&5
-$as_echo "$smr_cv_with_Xt_library" >&6; }
-
-
- case x"$smr_cv_with_Xt_library" in
- xyes | xmaybe)
- Xt_LIBS="-lXt"
- with_Xt=$smr_cv_with_Xt_library
- ;;
- xno)
- Xt_LIBS=
- with_Xt=no
- ;;
- *)
- if test -f "$smr_cv_with_Xt_library"; then
- Xt_LIBS=$smr_cv_with_Xt_library
- elif test -d "$smr_cv_with_Xt_library"; then
- Xt_LIBS="-L$smr_cv_with_Xt_library -lXt"
- else
- as_fn_error $? "argument must be boolean, file, or directory" "$LINENO" 5
- fi
- with_Xt=yes
- ;;
- esac
-
-
-
-
-
-
-
- if test ! x"$with_Xt" = xno; then
-
- # If we got this far, then the user didn't explicitly ask not to use
- # the library.
-
-
-
-
-
-
-
-
-# Check whether --with-Xt-includes was given.
-if test "${with_Xt_includes+set}" = set; then :
- withval=$with_Xt_includes; smr_cv_with_Xt_includes=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find the Xt header files" >&5
-$as_echo_n "checking where to find the Xt header files... " >&6; }
-if ${smr_cv_with_Xt_includes+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_Xt_includes=
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_Xt_includes" >&5
-$as_echo "$smr_cv_with_Xt_includes" >&6; }
-
- if test ! x"$smr_cv_with_Xt_includes" = x; then
- if test -d "$smr_cv_with_Xt_includes"; then
- Xt_CFLAGS="-I$smr_cv_with_Xt_includes"
- else
- as_fn_error $? "argument must be a directory" "$LINENO" 5
- fi
- else
- Xt_CFLAGS=
- fi
-
- smr_test_CPPFLAGS="${CPPFLAGS+set}"
- smr_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $Xt_CFLAGS $X_CFLAGS"
-
- for ac_header in X11/Intrinsic.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "X11/Intrinsic.h" "ac_cv_header_X11_Intrinsic_h" "$ac_includes_default"
-if test "x$ac_cv_header_X11_Intrinsic_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_X11_INTRINSIC_H 1
-_ACEOF
- smr_have_Xt_header=yes
-else
- smr_have_Xt_header=no
-fi
-
-done
-
-
- if test x"$smr_test_CPPFLAGS" = xset; then
- CPPFLAGS=$smr_save_CPPFLAGS
- else
- unset CPPFLAGS
- fi
-
-
-
-
-
-
-
- # We need only look for the library if the header has been found
- # (or no header is needed).
- if test $smr_have_Xt_header != no; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XtAppInitialize in -lXt" >&5
-$as_echo_n "checking for XtAppInitialize in -lXt... " >&6; }
-if ${ac_cv_lib_Xt_XtAppInitialize+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lXt $Xt_CFLAGS $X_CFLAGS $Xt_LIBS $X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS -lX11 $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char XtAppInitialize ();
-int
-main ()
-{
-return XtAppInitialize ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_Xt_XtAppInitialize=yes
-else
- ac_cv_lib_Xt_XtAppInitialize=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xt_XtAppInitialize" >&5
-$as_echo "$ac_cv_lib_Xt_XtAppInitialize" >&6; }
-if test "x$ac_cv_lib_Xt_XtAppInitialize" = xyes; then :
- smr_have_Xt_library=yes
-else
- smr_have_Xt_library=no
-fi
-
- fi
-
- if test x"$smr_have_Xt_library" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using Xt library" >&5
-$as_echo "using Xt library" >&6; }
- else
- Xt_LIBS=
- Xt_CFLAGS=
-
- if test x"$with_Xt" = xmaybe; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not using Xt library" >&5
-$as_echo "not using Xt library" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: requested Xt library not found!" >&5
-$as_echo "$as_me: WARNING: requested Xt library not found!" >&2;}
- fi
- fi
- fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-Xm-library was given.
-if test "${with_Xm_library+set}" = set; then :
- withval=$with_Xm_library; smr_cv_with_Xm_library=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use Xm library" >&5
-$as_echo_n "checking whether to use Xm library... " >&6; }
-if ${smr_cv_with_Xm_library+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_Xm_library=maybe
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_Xm_library" >&5
-$as_echo "$smr_cv_with_Xm_library" >&6; }
-
-
- case x"$smr_cv_with_Xm_library" in
- xyes | xmaybe)
- Xm_LIBS="-lXm"
- with_Xm=$smr_cv_with_Xm_library
- ;;
- xno)
- Xm_LIBS=
- with_Xm=no
- ;;
- *)
- if test -f "$smr_cv_with_Xm_library"; then
- Xm_LIBS=$smr_cv_with_Xm_library
- elif test -d "$smr_cv_with_Xm_library"; then
- Xm_LIBS="-L$smr_cv_with_Xm_library -lXm"
- else
- as_fn_error $? "argument must be boolean, file, or directory" "$LINENO" 5
- fi
- with_Xm=yes
- ;;
- esac
-
-
-
-
-
-
-
- if test ! x"$with_Xm" = xno; then
-
- # If we got this far, then the user didn't explicitly ask not to use
- # the library.
-
-
-
-
-
-
-
-
-# Check whether --with-Xm-includes was given.
-if test "${with_Xm_includes+set}" = set; then :
- withval=$with_Xm_includes; smr_cv_with_Xm_includes=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find the Xm header files" >&5
-$as_echo_n "checking where to find the Xm header files... " >&6; }
-if ${smr_cv_with_Xm_includes+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_Xm_includes=
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_Xm_includes" >&5
-$as_echo "$smr_cv_with_Xm_includes" >&6; }
-
- if test ! x"$smr_cv_with_Xm_includes" = x; then
- if test -d "$smr_cv_with_Xm_includes"; then
- Xm_CFLAGS="-I$smr_cv_with_Xm_includes"
- else
- as_fn_error $? "argument must be a directory" "$LINENO" 5
- fi
- else
- Xm_CFLAGS=
- fi
-
- smr_test_CPPFLAGS="${CPPFLAGS+set}"
- smr_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $Xm_CFLAGS $X_CFLAGS"
-
- for ac_header in Xm/XmAll.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "Xm/XmAll.h" "ac_cv_header_Xm_XmAll_h" "$ac_includes_default"
-if test "x$ac_cv_header_Xm_XmAll_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_XM_XMALL_H 1
-_ACEOF
- smr_have_Xm_header=yes
-else
- smr_have_Xm_header=no
-fi
-
-done
-
-
- if test x"$smr_test_CPPFLAGS" = xset; then
- CPPFLAGS=$smr_save_CPPFLAGS
- else
- unset CPPFLAGS
- fi
-
-
-
-
-
-
-
- # We need only look for the library if the header has been found
- # (or no header is needed).
- if test $smr_have_Xm_header != no; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XmCreateForm in -lXm" >&5
-$as_echo_n "checking for XmCreateForm in -lXm... " >&6; }
-if ${ac_cv_lib_Xm_XmCreateForm+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lXm $Xm_CFLAGS $X_CFLAGS $Xm_LIBS $Xt_LIBS $X_LIBS $X_PRE_LIBS $Xp_LIBS $Xext_LIBS $X_EXTRA_LIBS -lX11 $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char XmCreateForm ();
-int
-main ()
-{
-return XmCreateForm ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_Xm_XmCreateForm=yes
-else
- ac_cv_lib_Xm_XmCreateForm=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xm_XmCreateForm" >&5
-$as_echo "$ac_cv_lib_Xm_XmCreateForm" >&6; }
-if test "x$ac_cv_lib_Xm_XmCreateForm" = xyes; then :
- smr_have_Xm_library=yes
-else
- smr_have_Xm_library=no
-fi
-
- fi
-
- if test x"$smr_have_Xm_library" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using Xm library" >&5
-$as_echo "using Xm library" >&6; }
- else
- Xm_LIBS=
- Xm_CFLAGS=
-
- if test x"$with_Xm" = xmaybe; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not using Xm library" >&5
-$as_echo "not using Xm library" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: requested Xm library not found!" >&5
-$as_echo "$as_me: WARNING: requested Xm library not found!" >&2;}
- fi
- fi
- fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-Sgm-library was given.
-if test "${with_Sgm_library+set}" = set; then :
- withval=$with_Sgm_library; smr_cv_with_Sgm_library=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use Sgm library" >&5
-$as_echo_n "checking whether to use Sgm library... " >&6; }
-if ${smr_cv_with_Sgm_library+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_Sgm_library=maybe
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_Sgm_library" >&5
-$as_echo "$smr_cv_with_Sgm_library" >&6; }
-
-
- case x"$smr_cv_with_Sgm_library" in
- xyes | xmaybe)
- Sgm_LIBS="-lSgm"
- with_Sgm=$smr_cv_with_Sgm_library
- ;;
- xno)
- Sgm_LIBS=
- with_Sgm=no
- ;;
- *)
- if test -f "$smr_cv_with_Sgm_library"; then
- Sgm_LIBS=$smr_cv_with_Sgm_library
- elif test -d "$smr_cv_with_Sgm_library"; then
- Sgm_LIBS="-L$smr_cv_with_Sgm_library -lSgm"
- else
- as_fn_error $? "argument must be boolean, file, or directory" "$LINENO" 5
- fi
- with_Sgm=yes
- ;;
- esac
-
-
-
-
-
-
-
- if test ! x"$with_Sgm" = xno; then
-
- # If we got this far, then the user didn't explicitly ask not to use
- # the library.
-
-
-
-
-
-
-
-
-# Check whether --with-Sgm-includes was given.
-if test "${with_Sgm_includes+set}" = set; then :
- withval=$with_Sgm_includes; smr_cv_with_Sgm_includes=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find the Sgm header files" >&5
-$as_echo_n "checking where to find the Sgm header files... " >&6; }
-if ${smr_cv_with_Sgm_includes+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_Sgm_includes=
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_Sgm_includes" >&5
-$as_echo "$smr_cv_with_Sgm_includes" >&6; }
-
- if test ! x"$smr_cv_with_Sgm_includes" = x; then
- if test -d "$smr_cv_with_Sgm_includes"; then
- Sgm_CFLAGS="-I$smr_cv_with_Sgm_includes"
- else
- as_fn_error $? "argument must be a directory" "$LINENO" 5
- fi
- else
- Sgm_CFLAGS=
- fi
-
- smr_test_CPPFLAGS="${CPPFLAGS+set}"
- smr_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $Sgm_CFLAGS $X_CFLAGS"
-
- for ac_header in Sgm/HPanedW.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "Sgm/HPanedW.h" "ac_cv_header_Sgm_HPanedW_h" "$ac_includes_default"
-if test "x$ac_cv_header_Sgm_HPanedW_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_SGM_HPANEDW_H 1
-_ACEOF
- smr_have_Sgm_header=yes
-else
- smr_have_Sgm_header=no
-fi
-
-done
-
-
- if test x"$smr_test_CPPFLAGS" = xset; then
- CPPFLAGS=$smr_save_CPPFLAGS
- else
- unset CPPFLAGS
- fi
-
-
-
-
-
-
-
- # We need only look for the library if the header has been found
- # (or no header is needed).
- if test $smr_have_Sgm_header != no; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SgCreateHorzPanedWindow in -lSgm" >&5
-$as_echo_n "checking for SgCreateHorzPanedWindow in -lSgm... " >&6; }
-if ${ac_cv_lib_Sgm_SgCreateHorzPanedWindow+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lSgm $Sgm_CFLAGS $X_CFLAGS $Sgm_LIBS $Xm_LIBS $Xt_LIBS $X_LIBS $X_PRE_LIBS $Xp_LIBS $Xext_LIBS $X_EXTRA_LIBS -lX11 $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char SgCreateHorzPanedWindow ();
-int
-main ()
-{
-return SgCreateHorzPanedWindow ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_Sgm_SgCreateHorzPanedWindow=yes
-else
- ac_cv_lib_Sgm_SgCreateHorzPanedWindow=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Sgm_SgCreateHorzPanedWindow" >&5
-$as_echo "$ac_cv_lib_Sgm_SgCreateHorzPanedWindow" >&6; }
-if test "x$ac_cv_lib_Sgm_SgCreateHorzPanedWindow" = xyes; then :
- smr_have_Sgm_library=yes
-else
- smr_have_Sgm_library=no
-fi
-
- fi
-
- if test x"$smr_have_Sgm_library" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using Sgm library" >&5
-$as_echo "using Sgm library" >&6; }
- else
- Sgm_LIBS=
- Sgm_CFLAGS=
-
- if test x"$with_Sgm" = xmaybe; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not using Sgm library" >&5
-$as_echo "not using Sgm library" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: requested Sgm library not found!" >&5
-$as_echo "$as_me: WARNING: requested Sgm library not found!" >&2;}
- fi
- fi
- fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- if test "x$smr_have_Xt_library" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XtAppSetExitFlag in -lXt" >&5
-$as_echo_n "checking for XtAppSetExitFlag in -lXt... " >&6; }
-if ${ac_cv_lib_Xt_XtAppSetExitFlag+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lXt $Xt_LIBS $X_LIBS $X_PRE_LIBS $Xp_LIBS $Xext_LIBS $X_EXTRA_LIBS -lX11 $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char XtAppSetExitFlag ();
-int
-main ()
-{
-return XtAppSetExitFlag ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_Xt_XtAppSetExitFlag=yes
-else
- ac_cv_lib_Xt_XtAppSetExitFlag=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xt_XtAppSetExitFlag" >&5
-$as_echo "$ac_cv_lib_Xt_XtAppSetExitFlag" >&6; }
-if test "x$ac_cv_lib_Xt_XtAppSetExitFlag" = xyes; then :
- $as_echo "#define HAVE_XTAPPSETEXITFLAG 1" >>confdefs.h
-
-fi
-
- fi
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-freetype2-library was given.
-if test "${with_freetype2_library+set}" = set; then :
- withval=$with_freetype2_library; smr_cv_with_freetype2_library=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use freetype2 library" >&5
-$as_echo_n "checking whether to use freetype2 library... " >&6; }
-if ${smr_cv_with_freetype2_library+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_freetype2_library=maybe
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_freetype2_library" >&5
-$as_echo "$smr_cv_with_freetype2_library" >&6; }
-
-
- case x"$smr_cv_with_freetype2_library" in
- xyes | xmaybe)
- freetype2_LIBS="-lfreetype"
- with_freetype2=$smr_cv_with_freetype2_library
- ;;
- xno)
- freetype2_LIBS=
- with_freetype2=no
- ;;
- *)
- if test -f "$smr_cv_with_freetype2_library"; then
- freetype2_LIBS=$smr_cv_with_freetype2_library
- elif test -d "$smr_cv_with_freetype2_library"; then
- freetype2_LIBS="-L$smr_cv_with_freetype2_library -lfreetype"
- else
- as_fn_error $? "argument must be boolean, file, or directory" "$LINENO" 5
- fi
- with_freetype2=yes
- ;;
- esac
-
-
-
-
-
-
-
- if test ! x"$with_freetype2" = xno; then
-
- # If we got this far, then the user didn't explicitly ask not to use
- # the library.
-
-
-
-
-
-
-
-
-# Check whether --with-freetype2-includes was given.
-if test "${with_freetype2_includes+set}" = set; then :
- withval=$with_freetype2_includes; smr_cv_with_freetype2_includes=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find the freetype2 header files" >&5
-$as_echo_n "checking where to find the freetype2 header files... " >&6; }
-if ${smr_cv_with_freetype2_includes+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_freetype2_includes=
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_freetype2_includes" >&5
-$as_echo "$smr_cv_with_freetype2_includes" >&6; }
-
- if test ! x"$smr_cv_with_freetype2_includes" = x; then
- if test -d "$smr_cv_with_freetype2_includes"; then
- freetype2_CFLAGS="-I$smr_cv_with_freetype2_includes"
- else
- as_fn_error $? "argument must be a directory" "$LINENO" 5
- fi
- else
- freetype2_CFLAGS=
- fi
-
- smr_test_CPPFLAGS="${CPPFLAGS+set}"
- smr_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $freetype2_CFLAGS "
-
- for ac_header in ft2build.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "ft2build.h" "ac_cv_header_ft2build_h" "$ac_includes_default"
-if test "x$ac_cv_header_ft2build_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_FT2BUILD_H 1
-_ACEOF
- smr_have_freetype2_header=yes
-else
- smr_have_freetype2_header=no
-fi
-
-done
-
-
- if test x"$smr_test_CPPFLAGS" = xset; then
- CPPFLAGS=$smr_save_CPPFLAGS
- else
- unset CPPFLAGS
- fi
-
-
-
-
-
-
-
- # We need only look for the library if the header has been found
- # (or no header is needed).
- if test $smr_have_freetype2_header != no; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FT_Get_Name_Index in -lfreetype" >&5
-$as_echo_n "checking for FT_Get_Name_Index in -lfreetype... " >&6; }
-if ${ac_cv_lib_freetype_FT_Get_Name_Index+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lfreetype $freetype2_CFLAGS $freetype2_LIBS -lm $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char FT_Get_Name_Index ();
-int
-main ()
-{
-return FT_Get_Name_Index ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_freetype_FT_Get_Name_Index=yes
-else
- ac_cv_lib_freetype_FT_Get_Name_Index=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_freetype_FT_Get_Name_Index" >&5
-$as_echo "$ac_cv_lib_freetype_FT_Get_Name_Index" >&6; }
-if test "x$ac_cv_lib_freetype_FT_Get_Name_Index" = xyes; then :
- smr_have_freetype2_library=yes
-else
- smr_have_freetype2_library=no
-fi
-
- fi
-
- if test x"$smr_have_freetype2_library" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using freetype2 library" >&5
-$as_echo "using freetype2 library" >&6; }
- else
- freetype2_LIBS=
- freetype2_CFLAGS=
-
- if test x"$with_freetype2" = xmaybe; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not using freetype2 library" >&5
-$as_echo "not using freetype2 library" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: requested freetype2 library not found!" >&5
-$as_echo "$as_me: WARNING: requested freetype2 library not found!" >&2;}
- fi
- fi
- fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-if test "x$smr_have_freetype2_library" = xyes; then
- $as_echo "#define HAVE_FREETYPE_FREETYPE_H 1" >>confdefs.h
-
- $as_echo "#define HAVE_SPLASH 1" >>confdefs.h
-
-fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-libpng-library was given.
-if test "${with_libpng_library+set}" = set; then :
- withval=$with_libpng_library; smr_cv_with_libpng_library=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use libpng library" >&5
-$as_echo_n "checking whether to use libpng library... " >&6; }
-if ${smr_cv_with_libpng_library+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_libpng_library=maybe
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_libpng_library" >&5
-$as_echo "$smr_cv_with_libpng_library" >&6; }
-
-
- case x"$smr_cv_with_libpng_library" in
- xyes | xmaybe)
- libpng_LIBS="-lpng"
- with_libpng=$smr_cv_with_libpng_library
- ;;
- xno)
- libpng_LIBS=
- with_libpng=no
- ;;
- *)
- if test -f "$smr_cv_with_libpng_library"; then
- libpng_LIBS=$smr_cv_with_libpng_library
- elif test -d "$smr_cv_with_libpng_library"; then
- libpng_LIBS="-L$smr_cv_with_libpng_library -lpng"
- else
- as_fn_error $? "argument must be boolean, file, or directory" "$LINENO" 5
- fi
- with_libpng=yes
- ;;
- esac
-
-
-
-
-
-
-
- if test ! x"$with_libpng" = xno; then
-
- # If we got this far, then the user didn't explicitly ask not to use
- # the library.
-
-
-
-
-
-
-
-
-# Check whether --with-libpng-includes was given.
-if test "${with_libpng_includes+set}" = set; then :
- withval=$with_libpng_includes; smr_cv_with_libpng_includes=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find the libpng header files" >&5
-$as_echo_n "checking where to find the libpng header files... " >&6; }
-if ${smr_cv_with_libpng_includes+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_libpng_includes=
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_libpng_includes" >&5
-$as_echo "$smr_cv_with_libpng_includes" >&6; }
-
- if test ! x"$smr_cv_with_libpng_includes" = x; then
- if test -d "$smr_cv_with_libpng_includes"; then
- libpng_CFLAGS="-I$smr_cv_with_libpng_includes"
- else
- as_fn_error $? "argument must be a directory" "$LINENO" 5
- fi
- else
- libpng_CFLAGS=
- fi
-
- smr_test_CPPFLAGS="${CPPFLAGS+set}"
- smr_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $libpng_CFLAGS "
-
- for ac_header in png.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "png.h" "ac_cv_header_png_h" "$ac_includes_default"
-if test "x$ac_cv_header_png_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_PNG_H 1
-_ACEOF
- smr_have_libpng_header=yes
-else
- smr_have_libpng_header=no
-fi
-
-done
-
-
- if test x"$smr_test_CPPFLAGS" = xset; then
- CPPFLAGS=$smr_save_CPPFLAGS
- else
- unset CPPFLAGS
- fi
-
-
-
-
-
-
-
- # We need only look for the library if the header has been found
- # (or no header is needed).
- if test $smr_have_libpng_header != no; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_write_row in -lpng" >&5
-$as_echo_n "checking for png_write_row in -lpng... " >&6; }
-if ${ac_cv_lib_png_png_write_row+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpng $libpng_CFLAGS $libpng_LIBS -lz $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char png_write_row ();
-int
-main ()
-{
-return png_write_row ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_png_png_write_row=yes
-else
- ac_cv_lib_png_png_write_row=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png_png_write_row" >&5
-$as_echo "$ac_cv_lib_png_png_write_row" >&6; }
-if test "x$ac_cv_lib_png_png_write_row" = xyes; then :
- smr_have_libpng_library=yes
-else
- smr_have_libpng_library=no
-fi
-
- fi
-
- if test x"$smr_have_libpng_library" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using libpng library" >&5
-$as_echo "using libpng library" >&6; }
- else
- libpng_LIBS=
- libpng_CFLAGS=
-
- if test x"$with_libpng" = xmaybe; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not using libpng library" >&5
-$as_echo "not using libpng library" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: requested libpng library not found!" >&5
-$as_echo "$as_me: WARNING: requested libpng library not found!" >&2;}
- fi
- fi
- fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# Check whether --with-libpaper-library was given.
-if test "${with_libpaper_library+set}" = set; then :
- withval=$with_libpaper_library; smr_cv_with_libpaper_library=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use libpaper library" >&5
-$as_echo_n "checking whether to use libpaper library... " >&6; }
-if ${smr_cv_with_libpaper_library+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_libpaper_library=maybe
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_libpaper_library" >&5
-$as_echo "$smr_cv_with_libpaper_library" >&6; }
-
-
- case x"$smr_cv_with_libpaper_library" in
- xyes | xmaybe)
- libpaper_LIBS="-lpaper"
- with_libpaper=$smr_cv_with_libpaper_library
- ;;
- xno)
- libpaper_LIBS=
- with_libpaper=no
- ;;
- *)
- if test -f "$smr_cv_with_libpaper_library"; then
- libpaper_LIBS=$smr_cv_with_libpaper_library
- elif test -d "$smr_cv_with_libpaper_library"; then
- libpaper_LIBS="-L$smr_cv_with_libpaper_library -lpaper"
- else
- as_fn_error $? "argument must be boolean, file, or directory" "$LINENO" 5
- fi
- with_libpaper=yes
- ;;
- esac
-
-
-
-
-
-
-
- if test ! x"$with_libpaper" = xno; then
-
- # If we got this far, then the user didn't explicitly ask not to use
- # the library.
-
-
-
-
-
-
-
-
-# Check whether --with-libpaper-includes was given.
-if test "${with_libpaper_includes+set}" = set; then :
- withval=$with_libpaper_includes; smr_cv_with_libpaper_includes=$withval
-fi
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking where to find the libpaper header files" >&5
-$as_echo_n "checking where to find the libpaper header files... " >&6; }
-if ${smr_cv_with_libpaper_includes+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- smr_cv_with_libpaper_includes=
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $smr_cv_with_libpaper_includes" >&5
-$as_echo "$smr_cv_with_libpaper_includes" >&6; }
-
- if test ! x"$smr_cv_with_libpaper_includes" = x; then
- if test -d "$smr_cv_with_libpaper_includes"; then
- libpaper_CFLAGS="-I$smr_cv_with_libpaper_includes"
- else
- as_fn_error $? "argument must be a directory" "$LINENO" 5
- fi
- else
- libpaper_CFLAGS=
- fi
-
- smr_test_CPPFLAGS="${CPPFLAGS+set}"
- smr_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $libpaper_CFLAGS "
-
- for ac_header in paper.h
-do :
- ac_fn_c_check_header_mongrel "$LINENO" "paper.h" "ac_cv_header_paper_h" "$ac_includes_default"
-if test "x$ac_cv_header_paper_h" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_PAPER_H 1
-_ACEOF
- smr_have_libpaper_header=yes
-else
- smr_have_libpaper_header=no
-fi
-
-done
-
-
- if test x"$smr_test_CPPFLAGS" = xset; then
- CPPFLAGS=$smr_save_CPPFLAGS
- else
- unset CPPFLAGS
- fi
-
-
-
-
-
-
-
- # We need only look for the library if the header has been found
- # (or no header is needed).
- if test $smr_have_libpaper_header != no; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for paperinit in -lpaper" >&5
-$as_echo_n "checking for paperinit in -lpaper... " >&6; }
-if ${ac_cv_lib_paper_paperinit+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpaper $libpaper_CFLAGS $libpaper_LIBS $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char paperinit ();
-int
-main ()
-{
-return paperinit ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_paper_paperinit=yes
-else
- ac_cv_lib_paper_paperinit=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_paper_paperinit" >&5
-$as_echo "$ac_cv_lib_paper_paperinit" >&6; }
-if test "x$ac_cv_lib_paper_paperinit" = xyes; then :
- smr_have_libpaper_library=yes
-else
- smr_have_libpaper_library=no
-fi
-
- fi
-
- if test x"$smr_have_libpaper_library" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: using libpaper library" >&5
-$as_echo "using libpaper library" >&6; }
- else
- libpaper_LIBS=
- libpaper_CFLAGS=
-
- if test x"$with_libpaper" = xmaybe; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not using libpaper library" >&5
-$as_echo "not using libpaper library" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: requested libpaper library not found!" >&5
-$as_echo "$as_me: WARNING: requested libpaper library not found!" >&2;}
- fi
- fi
- fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-if test -n "$no_x" -o "x$smr_have_Xm_library" != xyes -o "x$smr_have_freetype2_library" != xyes; then
- X="#"
- XPDF_TARGET="all-no-x"
-else
- X=""
- XPDF_TARGET="all"
-fi
-
-
-
-EXTRA_LIBS=
-EXTRA_CFLAGS=
-
-
-
-ac_config_files="$ac_config_files Makefile goo/Makefile fofi/Makefile splash/Makefile xpdf/Makefile"
-
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems. If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, we kill variables containing newlines.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(
- for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
- eval ac_val=\$$ac_var
- case $ac_val in #(
- *${as_nl}*)
- case $ac_var in #(
- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
- esac
- case $ac_var in #(
- _ | IFS | as_nl) ;; #(
- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
- *) { eval $ac_var=; unset $ac_var;} ;;
- esac ;;
- esac
- done
-
- (set) 2>&1 |
- case $as_nl`(ac_space=' '; set) 2>&1` in #(
- *${as_nl}ac_space=\ *)
- # `set' does not quote correctly, so add quotes: double-quote
- # substitution turns \\\\ into \\, and sed turns \\ into \.
- sed -n \
- "s/'/'\\\\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
- ;; #(
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
- ;;
- esac |
- sort
-) |
- sed '
- /^ac_cv_env_/b end
- t clear
- :clear
- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
- t end
- s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
- :end' >>confcache
-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
- if test -w "$cache_file"; then
- if test "x$cache_file" != "x/dev/null"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
-$as_echo "$as_me: updating cache $cache_file" >&6;}
- if test ! -f "$cache_file" || test -h "$cache_file"; then
- cat confcache >"$cache_file"
- else
- case $cache_file in #(
- */* | ?:*)
- mv -f confcache "$cache_file"$$ &&
- mv -f "$cache_file"$$ "$cache_file" ;; #(
- *)
- mv -f confcache "$cache_file" ;;
- esac
- fi
- fi
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
- fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-DEFS=-DHAVE_CONFIG_H
-
-ac_libobjs=
-ac_ltlibobjs=
-U=
-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
- # 1. Remove the extension, and $U if already installed.
- ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
- ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
- # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
- # will be set to the directory where LIBOBJS objects are built.
- as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
- as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
-
-: "${CONFIG_STATUS=./config.status}"
-ac_write_fail=0
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
-as_write_fail=0
-cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate the current configuration.
-# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-
-SHELL=\${CONFIG_SHELL-$SHELL}
-export SHELL
-_ASEOF
-cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
-## -------------------- ##
-## M4sh Initialization. ##
-## -------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in #(
- *posix*) :
- set -o posix ;; #(
- *) :
- ;;
-esac
-fi
-
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='print -r --'
- as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='printf %s\n'
- as_echo_n='printf %s'
-else
- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
- as_echo_n='/usr/ucb/echo -n'
- else
- as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
- as_echo_n_body='eval
- arg=$1;
- case $arg in #(
- *"$as_nl"*)
- expr "X$arg" : "X\\(.*\\)$as_nl";
- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
- esac;
- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
- '
- export as_echo_n_body
- as_echo_n='sh -c $as_echo_n_body as_echo'
- fi
- export as_echo_body
- as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-as_myself=
-case $0 in #((
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- exit 1
-fi
-
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there. '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
-as_fn_error ()
-{
- as_status=$1; test $as_status -eq 0 && as_status=1
- if test "$4"; then
- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
- fi
- $as_echo "$as_me: error: $2" >&2
- as_fn_exit $as_status
-} # as_fn_error
-
-
-# as_fn_set_status STATUS
-# -----------------------
-# Set $? to STATUS, without forking.
-as_fn_set_status ()
-{
- return $1
-} # as_fn_set_status
-
-# as_fn_exit STATUS
-# -----------------
-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
-as_fn_exit ()
-{
- set +e
- as_fn_set_status $1
- exit $1
-} # as_fn_exit
-
-# as_fn_unset VAR
-# ---------------
-# Portably unset VAR.
-as_fn_unset ()
-{
- { eval $1=; unset $1;}
-}
-as_unset=as_fn_unset
-# as_fn_append VAR VALUE
-# ----------------------
-# Append the text in VALUE to the end of the definition contained in VAR. Take
-# advantage of any shell optimizations that allow amortized linear growth over
-# repeated appends, instead of the typical quadratic growth present in naive
-# implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
- eval 'as_fn_append ()
- {
- eval $1+=\$2
- }'
-else
- as_fn_append ()
- {
- eval $1=\$$1\$2
- }
-fi # as_fn_append
-
-# as_fn_arith ARG...
-# ------------------
-# Perform arithmetic evaluation on the ARGs, and store the result in the
-# global $as_val. Take advantage of shells that can avoid forks. The arguments
-# must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
- eval 'as_fn_arith ()
- {
- as_val=$(( $* ))
- }'
-else
- as_fn_arith ()
- {
- as_val=`expr "$@" || test $? -eq 1`
- }
-fi # as_fn_arith
-
-
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in #(((((
--n*)
- case `echo 'xy\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- xy) ECHO_C='\c';;
- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
- ECHO_T=' ';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
- if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -pR'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -pR'
- elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
- else
- as_ln_s='cp -pR'
- fi
-else
- as_ln_s='cp -pR'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-
-# as_fn_mkdir_p
-# -------------
-# Create "$as_dir" as a directory, including parents if necessary.
-as_fn_mkdir_p ()
-{
-
- case $as_dir in #(
- -*) as_dir=./$as_dir;;
- esac
- test -d "$as_dir" || eval $as_mkdir_p || {
- as_dirs=
- while :; do
- case $as_dir in #(
- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
- *) as_qdir=$as_dir;;
- esac
- as_dirs="'$as_qdir' $as_dirs"
- as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- test -d "$as_dir" && break
- done
- test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
-
-
-} # as_fn_mkdir_p
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p='mkdir -p "$as_dir"'
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
- test -f "$1" && test -x "$1"
-} # as_fn_executable_p
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-exec 6>&1
-## ----------------------------------- ##
-## Main body of $CONFIG_STATUS script. ##
-## ----------------------------------- ##
-_ASEOF
-test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# Save the log message, to keep $0 and so on meaningful, and to
-# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.
-ac_log="
-This file was extended by $as_me, which was
-generated by GNU Autoconf 2.69. Invocation command line was
-
- CONFIG_FILES = $CONFIG_FILES
- CONFIG_HEADERS = $CONFIG_HEADERS
- CONFIG_LINKS = $CONFIG_LINKS
- CONFIG_COMMANDS = $CONFIG_COMMANDS
- $ $0 $@
-
-on `(hostname || uname -n) 2>/dev/null | sed 1q`
-"
-
-_ACEOF
-
-case $ac_config_files in *"
-"*) set x $ac_config_files; shift; ac_config_files=$*;;
-esac
-
-case $ac_config_headers in *"
-"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
-esac
-
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-# Files that config.status was made for.
-config_files="$ac_config_files"
-config_headers="$ac_config_headers"
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-ac_cs_usage="\
-\`$as_me' instantiates files and other configuration actions
-from templates according to the current configuration. Unless the files
-and actions are specified as TAGs, all are instantiated by default.
-
-Usage: $0 [OPTION]... [TAG]...
-
- -h, --help print this help, then exit
- -V, --version print version number and configuration settings, then exit
- --config print configuration, then exit
- -q, --quiet, --silent
- do not print progress messages
- -d, --debug don't remove temporary files
- --recheck update $as_me by reconfiguring in the same conditions
- --file=FILE[:TEMPLATE]
- instantiate the configuration file FILE
- --header=FILE[:TEMPLATE]
- instantiate the configuration header FILE
-
-Configuration files:
-$config_files
-
-Configuration headers:
-$config_headers
-
-Report bugs to the package provider."
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
-ac_cs_version="\\
-config.status
-configured by $0, generated by GNU Autoconf 2.69,
- with options \\"\$ac_cs_config\\"
-
-Copyright (C) 2012 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-
-ac_pwd='$ac_pwd'
-srcdir='$srcdir'
-INSTALL='$INSTALL'
-test -n "\$AWK" || AWK=awk
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# The default lists apply if the user does not specify any file.
-ac_need_defaults=:
-while test $# != 0
-do
- case $1 in
- --*=?*)
- ac_option=`expr "X$1" : 'X\([^=]*\)='`
- ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
- ac_shift=:
- ;;
- --*=)
- ac_option=`expr "X$1" : 'X\([^=]*\)='`
- ac_optarg=
- ac_shift=:
- ;;
- *)
- ac_option=$1
- ac_optarg=$2
- ac_shift=shift
- ;;
- esac
-
- case $ac_option in
- # Handling of the options.
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- ac_cs_recheck=: ;;
- --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
- $as_echo "$ac_cs_version"; exit ;;
- --config | --confi | --conf | --con | --co | --c )
- $as_echo "$ac_cs_config"; exit ;;
- --debug | --debu | --deb | --de | --d | -d )
- debug=: ;;
- --file | --fil | --fi | --f )
- $ac_shift
- case $ac_optarg in
- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
- '') as_fn_error $? "missing file argument" ;;
- esac
- as_fn_append CONFIG_FILES " '$ac_optarg'"
- ac_need_defaults=false;;
- --header | --heade | --head | --hea )
- $ac_shift
- case $ac_optarg in
- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
- esac
- as_fn_append CONFIG_HEADERS " '$ac_optarg'"
- ac_need_defaults=false;;
- --he | --h)
- # Conflict between --help and --header
- as_fn_error $? "ambiguous option: \`$1'
-Try \`$0 --help' for more information.";;
- --help | --hel | -h )
- $as_echo "$ac_cs_usage"; exit ;;
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil | --si | --s)
- ac_cs_silent=: ;;
-
- # This is an error.
- -*) as_fn_error $? "unrecognized option: \`$1'
-Try \`$0 --help' for more information." ;;
-
- *) as_fn_append ac_config_targets " $1"
- ac_need_defaults=false ;;
-
- esac
- shift
-done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
- exec 6>/dev/null
- ac_configure_extra_args="$ac_configure_extra_args --silent"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-if \$ac_cs_recheck; then
- set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
- shift
- \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
- CONFIG_SHELL='$SHELL'
- export CONFIG_SHELL
- exec "\$@"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-exec 5>>config.log
-{
- echo
- sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
- $as_echo "$ac_log"
-} >&5
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-
-# Handling of arguments.
-for ac_config_target in $ac_config_targets
-do
- case $ac_config_target in
- "aconf.h") CONFIG_HEADERS="$CONFIG_HEADERS aconf.h" ;;
- "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
- "goo/Makefile") CONFIG_FILES="$CONFIG_FILES goo/Makefile" ;;
- "fofi/Makefile") CONFIG_FILES="$CONFIG_FILES fofi/Makefile" ;;
- "splash/Makefile") CONFIG_FILES="$CONFIG_FILES splash/Makefile" ;;
- "xpdf/Makefile") CONFIG_FILES="$CONFIG_FILES xpdf/Makefile" ;;
-
- *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
- esac
-done
-
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used. Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
- test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
- test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
-fi
-
-# Have a temporary directory for convenience. Make it in the build tree
-# simply because there is no reason against having it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Hook for its removal unless debugging.
-# Note that there is a small window in which the directory will not be cleaned:
-# after its creation but before its name has been assigned to `$tmp'.
-$debug ||
-{
- tmp= ac_tmp=
- trap 'exit_status=$?
- : "${ac_tmp:=$tmp}"
- { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
-' 0
- trap 'as_fn_exit 1' 1 2 13 15
-}
-# Create a (secure) tmp directory for tmp files.
-
-{
- tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
- test -d "$tmp"
-} ||
-{
- tmp=./conf$$-$RANDOM
- (umask 077 && mkdir "$tmp")
-} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
-ac_tmp=$tmp
-
-# Set up the scripts for CONFIG_FILES section.
-# No need to generate them if there are no CONFIG_FILES.
-# This happens for instance with `./config.status config.h'.
-if test -n "$CONFIG_FILES"; then
-
-
-ac_cr=`echo X | tr X '\015'`
-# On cygwin, bash can eat \r inside `` if the user requested igncr.
-# But we know of no other shell where ac_cr would be empty at this
-# point, so we can use a bashism as a fallback.
-if test "x$ac_cr" = x; then
- eval ac_cr=\$\'\\r\'
-fi
-ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
-if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
- ac_cs_awk_cr='\\r'
-else
- ac_cs_awk_cr=$ac_cr
-fi
-
-echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
-_ACEOF
-
-
-{
- echo "cat >conf$$subs.awk <<_ACEOF" &&
- echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
- echo "_ACEOF"
-} >conf$$subs.sh ||
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
-ac_delim='%!_!# '
-for ac_last_try in false false false false false :; do
- . ./conf$$subs.sh ||
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
-
- ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
- if test $ac_delim_n = $ac_delim_num; then
- break
- elif $ac_last_try; then
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-rm -f conf$$subs.sh
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
-_ACEOF
-sed -n '
-h
-s/^/S["/; s/!.*/"]=/
-p
-g
-s/^[^!]*!//
-:repl
-t repl
-s/'"$ac_delim"'$//
-t delim
-:nl
-h
-s/\(.\{148\}\)..*/\1/
-t more1
-s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
-p
-n
-b repl
-:more1
-s/["\\]/\\&/g; s/^/"/; s/$/"\\/
-p
-g
-s/.\{148\}//
-t nl
-:delim
-h
-s/\(.\{148\}\)..*/\1/
-t more2
-s/["\\]/\\&/g; s/^/"/; s/$/"/
-p
-b
-:more2
-s/["\\]/\\&/g; s/^/"/; s/$/"\\/
-p
-g
-s/.\{148\}//
-t delim
-' <conf$$subs.awk | sed '
-/^[^""]/{
- N
- s/\n//
-}
-' >>$CONFIG_STATUS || ac_write_fail=1
-rm -f conf$$subs.awk
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-_ACAWK
-cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
- for (key in S) S_is_set[key] = 1
- FS = ""
-
-}
-{
- line = $ 0
- nfields = split(line, field, "@")
- substed = 0
- len = length(field[1])
- for (i = 2; i < nfields; i++) {
- key = field[i]
- keylen = length(key)
- if (S_is_set[key]) {
- value = S[key]
- line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
- len += length(value) + length(field[++i])
- substed = 1
- } else
- len += 1 + keylen
- }
-
- print line
-}
-
-_ACAWK
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
- sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
-else
- cat
-fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
- || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
-_ACEOF
-
-# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
-# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
-h
-s///
-s/^/:/
-s/[ ]*$/:/
-s/:\$(srcdir):/:/g
-s/:\${srcdir}:/:/g
-s/:@srcdir@:/:/g
-s/^:*//
-s/:*$//
-x
-s/\(=[ ]*\).*/\1/
-G
-s/\n//
-s/^[^=]*=[ ]*$//
-}'
-fi
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-fi # test -n "$CONFIG_FILES"
-
-# Set up the scripts for CONFIG_HEADERS section.
-# No need to generate them if there are no CONFIG_HEADERS.
-# This happens for instance with `./config.status Makefile'.
-if test -n "$CONFIG_HEADERS"; then
-cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
-BEGIN {
-_ACEOF
-
-# Transform confdefs.h into an awk script `defines.awk', embedded as
-# here-document in config.status, that substitutes the proper values into
-# config.h.in to produce config.h.
-
-# Create a delimiter string that does not exist in confdefs.h, to ease
-# handling of long lines.
-ac_delim='%!_!# '
-for ac_last_try in false false :; do
- ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
- if test -z "$ac_tt"; then
- break
- elif $ac_last_try; then
- as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
- else
- ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
- fi
-done
-
-# For the awk script, D is an array of macro values keyed by name,
-# likewise P contains macro parameters if any. Preserve backslash
-# newline sequences.
-
-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
-sed -n '
-s/.\{148\}/&'"$ac_delim"'/g
-t rset
-:rset
-s/^[ ]*#[ ]*define[ ][ ]*/ /
-t def
-d
-:def
-s/\\$//
-t bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3"/p
-s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
-d
-:bsnl
-s/["\\]/\\&/g
-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
-D["\1"]=" \3\\\\\\n"\\/p
-t cont
-s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
-t cont
-d
-:cont
-n
-s/.\{148\}/&'"$ac_delim"'/g
-t clear
-:clear
-s/\\$//
-t bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/"/p
-d
-:bsnlc
-s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
-b cont
-' <confdefs.h | sed '
-s/'"$ac_delim"'/"\\\
-"/g' >>$CONFIG_STATUS || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
- for (key in D) D_is_set[key] = 1
- FS = ""
-}
-/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
- line = \$ 0
- split(line, arg, " ")
- if (arg[1] == "#") {
- defundef = arg[2]
- mac1 = arg[3]
- } else {
- defundef = substr(arg[1], 2)
- mac1 = arg[2]
- }
- split(mac1, mac2, "(") #)
- macro = mac2[1]
- prefix = substr(line, 1, index(line, defundef) - 1)
- if (D_is_set[macro]) {
- # Preserve the white space surrounding the "#".
- print prefix "define", macro P[macro] D[macro]
- next
- } else {
- # Replace #undef with comments. This is necessary, for example,
- # in the case of _POSIX_SOURCE, which is predefined and required
- # on some systems where configure will not decide to define it.
- if (defundef == "undef") {
- print "/*", prefix defundef, macro, "*/"
- next
- }
- }
-}
-{ print }
-_ACAWK
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
- as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
-fi # test -n "$CONFIG_HEADERS"
-
-
-eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS "
-shift
-for ac_tag
-do
- case $ac_tag in
- :[FHLC]) ac_mode=$ac_tag; continue;;
- esac
- case $ac_mode$ac_tag in
- :[FHL]*:*);;
- :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
- :[FH]-) ac_tag=-:-;;
- :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
- esac
- ac_save_IFS=$IFS
- IFS=:
- set x $ac_tag
- IFS=$ac_save_IFS
- shift
- ac_file=$1
- shift
-
- case $ac_mode in
- :L) ac_source=$1;;
- :[FH])
- ac_file_inputs=
- for ac_f
- do
- case $ac_f in
- -) ac_f="$ac_tmp/stdin";;
- *) # Look for the file first in the build tree, then in the source tree
- # (if the path is not absolute). The absolute path cannot be DOS-style,
- # because $ac_f cannot contain `:'.
- test -f "$ac_f" ||
- case $ac_f in
- [\\/$]*) false;;
- *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
- esac ||
- as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
- esac
- case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
- as_fn_append ac_file_inputs " '$ac_f'"
- done
-
- # Let's still pretend it is `configure' which instantiates (i.e., don't
- # use $as_me), people would be surprised to read:
- # /* config.h. Generated by config.status. */
- configure_input='Generated from '`
- $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
- `' by configure.'
- if test x"$ac_file" != x-; then
- configure_input="$ac_file. $configure_input"
- { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
-$as_echo "$as_me: creating $ac_file" >&6;}
- fi
- # Neutralize special characters interpreted by sed in replacement strings.
- case $configure_input in #(
- *\&* | *\|* | *\\* )
- ac_sed_conf_input=`$as_echo "$configure_input" |
- sed 's/[\\\\&|]/\\\\&/g'`;; #(
- *) ac_sed_conf_input=$configure_input;;
- esac
-
- case $ac_tag in
- *:-:* | *:-) cat >"$ac_tmp/stdin" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
- esac
- ;;
- esac
-
- ac_dir=`$as_dirname -- "$ac_file" ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_file" : 'X\(//\)[^/]' \| \
- X"$ac_file" : 'X\(//\)$' \| \
- X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$ac_file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
- as_dir="$ac_dir"; as_fn_mkdir_p
- ac_builddir=.
-
-case "$ac_dir" in
-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
-*)
- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
- # A ".." for each directory in $ac_dir_suffix.
- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
- case $ac_top_builddir_sub in
- "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
- esac ;;
-esac
-ac_abs_top_builddir=$ac_pwd
-ac_abs_builddir=$ac_pwd$ac_dir_suffix
-# for backward compatibility:
-ac_top_builddir=$ac_top_build_prefix
-
-case $srcdir in
- .) # We are building in place.
- ac_srcdir=.
- ac_top_srcdir=$ac_top_builddir_sub
- ac_abs_top_srcdir=$ac_pwd ;;
- [\\/]* | ?:[\\/]* ) # Absolute name.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir
- ac_abs_top_srcdir=$srcdir ;;
- *) # Relative name.
- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_build_prefix$srcdir
- ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
-esac
-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
-
-
- case $ac_mode in
- :F)
- #
- # CONFIG_FILE
- #
-
- case $INSTALL in
- [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
- *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
- esac
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-# If the template does not know about datarootdir, expand it.
-# FIXME: This hack should be removed a few years after 2.60.
-ac_datarootdir_hack=; ac_datarootdir_seen=
-ac_sed_dataroot='
-/datarootdir/ {
- p
- q
-}
-/@datadir@/p
-/@docdir@/p
-/@infodir@/p
-/@localedir@/p
-/@mandir@/p'
-case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
-*datarootdir*) ac_datarootdir_seen=yes;;
-*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
- ac_datarootdir_hack='
- s&@datadir@&$datadir&g
- s&@docdir@&$docdir&g
- s&@infodir@&$infodir&g
- s&@localedir@&$localedir&g
- s&@mandir@&$mandir&g
- s&\\\${datarootdir}&$datarootdir&g' ;;
-esac
-_ACEOF
-
-# Neutralize VPATH when `$srcdir' = `.'.
-# Shell code in configure.ac might set extrasub.
-# FIXME: do we really want to maintain this feature?
-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_sed_extra="$ac_vpsub
-$extrasub
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-:t
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s|@configure_input@|$ac_sed_conf_input|;t t
-s&@top_builddir@&$ac_top_builddir_sub&;t t
-s&@top_build_prefix@&$ac_top_build_prefix&;t t
-s&@srcdir@&$ac_srcdir&;t t
-s&@abs_srcdir@&$ac_abs_srcdir&;t t
-s&@top_srcdir@&$ac_top_srcdir&;t t
-s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
-s&@builddir@&$ac_builddir&;t t
-s&@abs_builddir@&$ac_abs_builddir&;t t
-s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
-s&@INSTALL@&$ac_INSTALL&;t t
-$ac_datarootdir_hack
-"
-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
- >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
-
-test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
- { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
- { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
- "$ac_tmp/out"`; test -z "$ac_out"; } &&
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined" >&5
-$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined" >&2;}
-
- rm -f "$ac_tmp/stdin"
- case $ac_file in
- -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
- *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
- esac \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
- ;;
- :H)
- #
- # CONFIG_HEADER
- #
- if test x"$ac_file" != x-; then
- {
- $as_echo "/* $configure_input */" \
- && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
- } >"$ac_tmp/config.h" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
- if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
-$as_echo "$as_me: $ac_file is unchanged" >&6;}
- else
- rm -f "$ac_file"
- mv "$ac_tmp/config.h" "$ac_file" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
- fi
- else
- $as_echo "/* $configure_input */" \
- && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
- || as_fn_error $? "could not create -" "$LINENO" 5
- fi
- ;;
-
-
- esac
-
-done # for ac_tag
-
-
-as_fn_exit 0
-_ACEOF
-ac_clean_files=$ac_clean_files_save
-
-test $ac_write_fail = 0 ||
- as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded. So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status. When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
- ac_cs_success=:
- ac_config_status_args=
- test "$silent" = yes &&
- ac_config_status_args="$ac_config_status_args --quiet"
- exec 5>/dev/null
- $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
- exec 5>>config.log
- # Use ||, not &&, to avoid exiting from the if with $? = 1, which
- # would make configure fail if this is the last instruction.
- $ac_cs_success || as_fn_exit 1
-fi
-if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
-fi
-
-
-if test -n "$no_x" -o "x$smr_have_Xm_library" != xyes -o "x$smr_have_freetype2_library" != xyes; then
- if test -n "$no_x"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Couldn't find X" >&5
-$as_echo "$as_me: WARNING: Couldn't find X" >&2;};
- fi
- if test "x$smr_have_Xm_library" != xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Couldn't find Motif" >&5
-$as_echo "$as_me: WARNING: Couldn't find Motif" >&2;};
- fi
- if test "x$smr_have_freetype2_library" != xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Couldn't find FreeType" >&5
-$as_echo "$as_me: WARNING: Couldn't find FreeType" >&2;};
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: -- You will be able to compile pdftops, pdftotext,
- pdfinfo, pdffonts, pdfdetach, and pdfimages, but not xpdf
- or pdftoppm" >&5
-$as_echo "$as_me: WARNING: -- You will be able to compile pdftops, pdftotext,
- pdfinfo, pdffonts, pdfdetach, and pdfimages, but not xpdf
- or pdftoppm" >&2;}
-fi
-
-if test "x$smr_have_libpng_library" != xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Couldn't find libpng -- you will not be able to build pdftohtml or pdftopng" >&5
-$as_echo "$as_me: WARNING: Couldn't find libpng -- you will not be able to build pdftohtml or pdftopng" >&2;}
-fi
diff --git a/Build/source/libs/xpdf/xpdf-src/configure.in b/Build/source/libs/xpdf/xpdf-src/configure.in
deleted file mode 100644
index 47e33fc3ac4..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/configure.in
+++ /dev/null
@@ -1,398 +0,0 @@
-dnl Process this file with autoconf to produce a configure script.
-dnl Copyright 1998-2013 Glyph & Cog, LLC
-
-AC_PREREQ(2.57)
-
-AC_INIT(xpdf/Gfx.cc)
-AC_CONFIG_HEADER(aconf.h)
-
-dnl ##### Optional features.
-
-AC_ARG_ENABLE([a4-paper],
- AS_HELP_STRING([--enable-a4-paper],
- [use A4 paper size instead of Letter for PostScript output]))
-AS_IF([test "x$enable_a4_paper" = "xyes"],
- [AC_DEFINE(A4_PAPER)])
-
-AC_ARG_ENABLE([no-text-select],
- AS_HELP_STRING([--enable-no-text-select],
- [do not allow text selection]))
-AS_IF([test "x$enable_no_text_select" = "xyes"],
- [AC_DEFINE(NO_TEXT_SELECT)])
-
-AC_ARG_ENABLE([opi],
- AS_HELP_STRING([--enable-opi],
- [include support for OPI comments]))
-AS_IF([test "x$enable_opi" = "xyes"],
- [AC_DEFINE(OPI_SUPPORT)])
-
-AC_ARG_ENABLE([multithreaded],
- AS_HELP_STRING([--enable-multithreaded],
- [include support for multithreading]))
-AS_IF([test "x$enable_multithreaded" = "xyes"],
- [AC_DEFINE(MULTITHREADED)])
-
-AC_ARG_ENABLE([exceptions],
- AS_HELP_STRING([--enable-exceptions],
- [use C++ exceptions]))
-AS_IF([test "x$enable_exceptions" = "xyes"],
- [AC_DEFINE(USE_EXCEPTIONS)])
-
-AC_ARG_ENABLE([fixedpoint],
- AS_HELP_STRING([--enable-fixedpoint],
- [use fixed point (instead of floating point) arithmetic]))
-AS_IF([test "x$enable_fixedpoint" = "xyes"],
- [AC_DEFINE(USE_FIXEDPOINT)])
-
-AC_ARG_ENABLE([cmyk],
- AS_HELP_STRING([--enable-cmyk],
- [include support for CMYK rasterization]))
-AS_IF([test "x$enable_cmyk" = "xyes"],
- [AC_DEFINE(SPLASH_CMYK)])
-
-AC_ARG_WITH([appdef-dir],
- AS_HELP_STRING([--with-appdef-dir],
- [set app-defaults directory]))
-AS_IF([test "x$with_appdef_dir" != "xno"],
- [AC_DEFINE_UNQUOTED(APPDEFDIR, "$with_appdef_dir")])
-
-dnl ##### Path to xpdfrc.
-dnl This ugly kludge to get the sysconfdir path is needed because
-dnl autoconf doesn't actually set the prefix variable until later.
-if test "$sysconfdir" = '${prefix}/etc'; then
- if test "x$prefix" = xNONE; then
- system_xpdfrc="$ac_default_prefix/etc/xpdfrc"
- else
- system_xpdfrc="$prefix/etc/xpdfrc"
- fi
-else
- system_xpdfrc="$sysconfdir/xpdfrc"
-fi
-AC_DEFINE_UNQUOTED(SYSTEM_XPDFRC, "$system_xpdfrc")
-
-dnl ##### Checks for programs.
-AC_PROG_CC
-AC_ISC_POSIX
-AC_PROG_CC_STDC
-#if test -z "$CXX" -a "$CC" = "gcc"; then
-# CXX="gcc"
-#fi
-AC_PROG_CXX
-AC_PROG_INSTALL
-AC_PROG_RANLIB
-
-dnl ##### Default values for Unix.
-EXE=""
-LIBPREFIX="lib"
-AR="ar rc"
-UP_DIR=""
-
-dnl ##### Check for OS/2.
-AC_CACHE_CHECK([for OS/2 (with EMX)],
-xpdf_cv_sys_os2,
-[AC_TRY_COMPILE([],
-[__EMX__],
-xpdf_cv_sys_os2=yes, xpdf_cv_sys_os2=no)])
-if test "$xpdf_cv_sys_os2" = yes; then
- EXE=".exe"
- LIBPREFIX=""
- AR="ar -rc"
-fi
-
-dnl ##### Check for DOS (with DJGPP).
-AC_CACHE_CHECK([for DOS (with DJGPP)],
-xpdf_cv_sys_dos,
-[AC_TRY_COMPILE([],
-[__DJGPP__],
-xpdf_cv_sys_dos=yes, xpdf_cv_sys_dos=no)])
-if test "$xpdf_cv_sys_dos" = yes; then
- EXE=".exe"
- LIBPREFIX="lib"
- AR="ar -rc"
- UP_DIR="../"
-fi
-
-dnl ##### Do substitutions.
-AC_SUBST(EXE)
-AC_SUBST(LIBPREFIX)
-AC_SUBST(AR)
-AC_SUBST(UP_DIR)
-
-dnl ##### Checks for header files.
-AC_PATH_XTRA
-AC_HEADER_DIRENT
-
-dnl ##### Switch over to C++. This will make the checks below a little
-dnl ##### bit stricter (requiring function prototypes in include files).
-dnl ##### (99% of xpdf is written in C++.)
-AC_LANG_CPLUSPLUS
-
-dnl ##### Check for extra libraries needed by X. (LynxOS needs this.)
-AC_CHECK_FUNC(gethostbyname)
-if test $ac_cv_func_gethostbyname = no; then
- AC_CHECK_LIB(bsd, gethostbyname, X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd")
-fi
-
-dnl ##### Look for header that defines select() and fd_set.
-AC_MSG_CHECKING([select() and fd_set in sys/select.h and sys/bsdtypes.h])
-AC_TRY_COMPILE([#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <sys/types.h>],
- [fd_set fds;
-select(0, NULL, NULL, NULL, NULL);], xpdf_ok=yes, xpdf_ok=no)
-if test $xpdf_ok = yes; then
- AC_MSG_RESULT([not needed])
-else
- AC_TRY_COMPILE([#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/select.h>],
- [fd_set fds;
-select(0, NULL, NULL, NULL, NULL);], xpdf_ok=yes, xpdf_ok=no)
- if test $xpdf_ok = yes; then
- AC_DEFINE(HAVE_SYS_SELECT_H)
- AC_MSG_RESULT([need sys/select.h])
- else
- AC_TRY_COMPILE([#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/bsdtypes.h>],
- [fd_set fds;
-select(0, NULL, NULL, NULL, NULL);], xpdf_ok=yes, xpdf_ok=no)
- if test $xpdf_ok = yes; then
- AC_DEFINE(HAVE_SYS_BSDTYPES_H)
- AC_MSG_RESULT([need sys/bsdtypes.h])
- else
- AC_MSG_RESULT([problem])
- fi
- fi
-fi
-
-dnl ##### Look for header that defines FD_ZERO.
-AC_MSG_CHECKING([FD_ZERO and strings.h or bstring.h])
-AC_TRY_COMPILE([#include <stdlib.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif],
-[fd_set fds; FD_ZERO(&fds);], xpdf_ok=yes, xpdf_ok=no)
-if test $xpdf_ok = yes; then
- AC_MSG_RESULT([not needed])
-else
- AC_TRY_COMPILE([#include <stdlib.h>
-#include <sys/types.h>
-#include <strings.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif],
- [fd_set fds; FD_ZERO(&fds);], xpdf_ok=yes, xpdf_ok=no)
- if test $xpdf_ok = yes; then
- AC_DEFINE(HAVE_STRINGS_H)
- AC_MSG_RESULT([need strings.h])
- else
- AC_TRY_COMPILE([#include <stdlib.h>
-#include <sys/types.h>
-#include <bstring.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif],
- [fd_set fds; FD_ZERO(&fds);], xpdf_ok=yes, xpdf_ok=no)
- if test $xpdf_ok = yes; then
- AC_DEFINE(HAVE_BSTRING_H)
- AC_MSG_RESULT([need bstring.h])
- else
- AC_MSG_RESULT([problem])
- fi
- fi
-fi
-
-dnl ##### Look for rewinddir.
-AC_CHECK_FUNCS(rewinddir)
-if test $ac_cv_func_rewinddir = no; then
- AC_CHECK_LIB(cposix, rewinddir)
-fi
-
-dnl ##### Checks for library functions.
-AC_CHECK_FUNCS(popen)
-dnl # This should use 'AC_CHECK_FUNCS(mkstemp)' but that fails if
-dnl # the mkstemp exists in the library but isn't declared in the
-dnl # include file (e.g., in cygwin 1.1.2).
-AC_CACHE_CHECK([for mkstemp],
-xpdf_cv_func_mkstemp,
-[AC_TRY_LINK([#include <stdlib.h>
-#include <unistd.h>],
-[mkstemp("foo");],
-xpdf_cv_func_mkstemp=yes, xpdf_cv_func_mkstemp=no)])
-if test "$xpdf_cv_func_mkstemp" = yes; then
- AC_DEFINE(HAVE_MKSTEMP)
-fi
-dnl # Check for mkstemps, just like mkstemp.
-AC_CACHE_CHECK([for mkstemps],
-xpdf_cv_func_mkstemps,
-[AC_TRY_LINK([#include <stdlib.h>
-#include <unistd.h>],
-[mkstemps("foo", 0);],
-xpdf_cv_func_mkstemps=yes, xpdf_cv_func_mkstemps=no)])
-if test "$xpdf_cv_func_mkstemps" = yes; then
- AC_DEFINE(HAVE_MKSTEMPS)
-fi
-
-dnl ##### Check select argument type: on HP-UX before version 10, select
-dnl ##### takes (int *) instead of (fd_set *).
-AC_CACHE_CHECK([whether select takes fd_set arguments],
-xpdf_cv_func_select_arg,
-[AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif],
-[fd_set fds;
-select(1, &fds, &fds, &fds, 0);],
-xpdf_cv_func_select_arg=yes, xpdf_cv_func_select_arg=no)])
-if test "$xpdf_cv_func_select_arg" != yes; then
- AC_DEFINE(SELECT_TAKES_INT)
-fi
-
-dnl ##### Check for std::sort.
-AC_CACHE_CHECK([for std::sort],
-xpdf_cv_func_std_sort,
-[AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM([[#include <algorithm>
-struct functor {
- bool operator()(const int &i0, const int &i1) { return i0 < i1; }
-};]],
- [[int a[100];
-std::sort(a, a+100, functor());]])],
-xpdf_cv_func_std_sort=yes, xpdf_cv_func_std_sort=no)])
-if test "$xpdf_cv_func_std_sort" = yes; then
- AC_DEFINE(HAVE_STD_SORT)
-fi
-
-dnl ##### Back to C for the library tests.
-AC_LANG_C
-
-dnl ##### Check for fseeko/ftello or fseek64/ftell64
-dnl The LARGEFILE and FSEEKO macros have to be called in C, not C++, mode.
-AC_SYS_LARGEFILE
-AC_FUNC_FSEEKO
-AC_CHECK_FUNCS(fseek64, xpdf_cv_func_fseek64=yes, xpdf_cv_func_fseek64=no)
-AC_CHECK_FUNCS(ftell64, xpdf_cv_func_ftell64=yes, xpdf_cv_func_ftell64=no)
-if test "$xpdf_cv_func_fseek64" = yes -a "$xpdf_cv_func_ftell64" = yes; then
- AC_DEFINE(HAVE_FSEEK64)
-fi
-
-dnl ##### Check for libXpm.
-if test -z "$no_x"; then
- smr_CHECK_LIB(Xpm, Xpm, [pixmap library - used only for icon],
- XpmCreatePixmapFromData, X11/xpm.h,
- $X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS -lX11, $X_CFLAGS)
- AC_SUBST(Xpm_LIBS)
- AC_SUBST(Xpm_CFLAGS)
-fi
-
-dnl ##### Check for Motif (libXm).
-if test -z "$no_x"; then
- dnl # XextAddDisplay isn't defined in any header file, so we provide a
- dnl # bogus prototype (so the compiler doesn't complain) and a bogus
- dnl # header file (so the smr macro doesn't break).
- smr_CHECK_LIB(Xext, Xext, [Motif library],
- XextAddDisplay, X11/Xlib.h,
- $X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS -lX11, $X_CFLAGS,
- [int XextAddDisplay();])
- AC_SUBST(Xext_LIBS)
- AC_SUBST(Xext_CFLAGS)
- smr_CHECK_LIB(Xp, Xp, [Motif library],
- XpStartPage, X11/extensions/Print.h,
- $X_LIBS $X_PRE_LIBS $Xext_LIBS $X_EXTRA_LIBS -lX11, $X_CFLAGS)
- AC_SUBST(Xp_LIBS)
- AC_SUBST(Xp_CFLAGS)
- smr_CHECK_LIB(Xt, Xt, [Motif library],
- XtAppInitialize, X11/Intrinsic.h,
- $X_LIBS $X_PRE_LIBS $X_EXTRA_LIBS -lX11, $X_CFLAGS)
- AC_SUBST(Xt_LIBS)
- AC_SUBST(Xt_CFLAGS)
- smr_CHECK_LIB(Xm, Xm, [Motif library],
- XmCreateForm, Xm/XmAll.h,
- $Xt_LIBS $X_LIBS $X_PRE_LIBS $Xp_LIBS $Xext_LIBS $X_EXTRA_LIBS -lX11, $X_CFLAGS)
- AC_SUBST(Xm_LIBS)
- AC_SUBST(Xm_CFLAGS)
- smr_CHECK_LIB(Sgm, Sgm, [SGI Motif library],
- SgCreateHorzPanedWindow, Sgm/HPanedW.h,
- $Xm_LIBS $Xt_LIBS $X_LIBS $X_PRE_LIBS $Xp_LIBS $Xext_LIBS $X_EXTRA_LIBS -lX11, $X_CFLAGS)
- AC_SUBST(Sgm_LIBS)
- AC_SUBST(Sgm_CFLAGS)
-
- dnl # check for XtAppSetExitFlag, which didn't exist prior to X11R6 (?)
- if test "x$smr_have_Xt_library" = xyes; then
- AC_CHECK_LIB(Xt, XtAppSetExitFlag,
- AC_DEFINE(HAVE_XTAPPSETEXITFLAG), ,
- [$Xt_LIBS $X_LIBS $X_PRE_LIBS $Xp_LIBS $Xext_LIBS $X_EXTRA_LIBS -lX11])
- fi
-fi
-
-dnl ##### Check for FreeType 2.x.
-dnl ##### (Note: FT_Get_Name_Index was added in FT 2.0.5, and is
-dnl ##### the reason that Xpdf requires 2.0.5+.)
-smr_CHECK_LIB(freetype2, freetype, [FreeType2 font rasterizer - version 2.0.5+],
- FT_Get_Name_Index, ft2build.h, -lm)
-AC_SUBST(freetype2_LIBS)
-AC_SUBST(freetype2_CFLAGS)
-if test "x$smr_have_freetype2_library" = xyes; then
- AC_DEFINE(HAVE_FREETYPE_FREETYPE_H)
- AC_DEFINE(HAVE_SPLASH)
-fi
-
-dnl ##### Check for libpng.
-smr_CHECK_LIB(libpng, png, [PNG library], png_write_row, png.h, -lz)
-AC_SUBST(libpng_LIBS)
-AC_SUBST(libpng_CFLAGS)
-
-dnl ##### Check for libpaper (Debian).
-smr_CHECK_LIB(libpaper, paper, [Debian libpaper], paperinit, paper.h)
-AC_SUBST(libpaper_LIBS)
-AC_SUBST(libpaper_CFLAGS)
-
-dnl ##### Disable X-specific stuff in top-level Makefile.
-if test -n "$no_x" -o "x$smr_have_Xm_library" != xyes -o "x$smr_have_freetype2_library" != xyes; then
- X="#"
- XPDF_TARGET="all-no-x"
-else
- X=""
- XPDF_TARGET="all"
-fi
-AC_SUBST(X)
-AC_SUBST(XPDF_TARGET)
-
-dnl ##### Extra libraries.
-EXTRA_LIBS=
-EXTRA_CFLAGS=
-AC_SUBST(EXTRA_LIBS)
-AC_SUBST(EXTRA_CFLAGS)
-
-dnl ##### Write the makefiles.
-AC_OUTPUT(Makefile goo/Makefile fofi/Makefile splash/Makefile xpdf/Makefile)
-
-dnl ##### Warn user if X is missing.
-if test -n "$no_x" -o "x$smr_have_Xm_library" != xyes -o "x$smr_have_freetype2_library" != xyes; then
- if test -n "$no_x"; then
- AC_MSG_WARN([Couldn't find X]);
- fi
- if test "x$smr_have_Xm_library" != xyes; then
- AC_MSG_WARN([Couldn't find Motif]);
- fi
- if test "x$smr_have_freetype2_library" != xyes; then
- AC_MSG_WARN([Couldn't find FreeType]);
- fi
- AC_MSG_WARN([-- You will be able to compile pdftops, pdftotext,
- pdfinfo, pdffonts, pdfdetach, and pdfimages, but not xpdf
- or pdftoppm])
-fi
-
-dnl ##### Warn user if libpng is missing.
-if test "x$smr_have_libpng_library" != xyes; then
- AC_MSG_WARN([Couldn't find libpng -- you will not be able to build pdftohtml or pdftopng])
-fi
diff --git a/Build/source/libs/xpdf/xpdf-src/dj_make.bat b/Build/source/libs/xpdf/xpdf-src/dj_make.bat
deleted file mode 100755
index a629e17eda2..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/dj_make.bat
+++ /dev/null
@@ -1,91 +0,0 @@
-set CC=gcc
-set CFLAGS=-g -O2 -I.. -I..\splash -I..\fofi -I..\goo
-set CXX=gpp
-set CXXFLAGS=%CFLAGS%
-set LIBPROG=ar
-
-copy aconf-dj.h aconf.h
-
-cd goo
-%CXX% %CXXFLAGS% -c GHash.cc
-%CXX% %CXXFLAGS% -c GList.cc
-%CXX% %CXXFLAGS% -c GString.cc
-%CXX% %CXXFLAGS% -c gmem.cc
-%CXX% %CXXFLAGS% -c gmempp.cc
-%CXX% %CXXFLAGS% -c gfile.cc
-%CC% %CFLAGS% -c parseargs.c
-del libGoo.a
-%LIBPROG% -rc libGoo.a GHash.o GList.o GString.o gmempp.o gfile.o gmem.o parseargs.o
-
-cd ..\fofi
-%CXX% %CXXFLAGS% -c FoFiBase.cc
-%CXX% %CXXFLAGS% -c FoFiEncodings.cc
-%CXX% %CXXFLAGS% -c FoFiIdentifier.cc
-%CXX% %CXXFLAGS% -c FoFiTrueType.cc
-%CXX% %CXXFLAGS% -c FoFiType1.cc
-%CXX% %CXXFLAGS% -c FoFiType1C.cc
-%LIBPROG% -rc libfofi.a FoFiBase.o FoFiEncodings.o FoFiIdentifier.o FoFiTrueType.o FoFiType1.o FoFiType1C.o
-
-cd ..\xpdf
-del *.o
-%CXX% %CXXFLAGS% -c AcroForm.cc
-%CXX% %CXXFLAGS% -c Annot.cc
-%CXX% %CXXFLAGS% -c Array.cc
-%CXX% %CXXFLAGS% -c BuiltinFont.cc
-%CXX% %CXXFLAGS% -c BuiltinFontTables.cc
-%CXX% %CXXFLAGS% -c CMap.cc
-%CXX% %CXXFLAGS% -c Catalog.cc
-%CXX% %CXXFLAGS% -c CharCodeToUnicode.cc
-%CXX% %CXXFLAGS% -c Decrypt.cc
-%CXX% %CXXFLAGS% -c Dict.cc
-%CXX% %CXXFLAGS% -c Error.cc
-%CXX% %CXXFLAGS% -c FontEncodingTables.cc
-%CXX% %CXXFLAGS% -c Form.cc
-%CXX% %CXXFLAGS% -c Function.cc
-%CXX% %CXXFLAGS% -c Gfx.cc
-%CXX% %CXXFLAGS% -c GfxFont.cc
-%CXX% %CXXFLAGS% -c GfxState.cc
-%CXX% %CXXFLAGS% -c GlobalParams.cc
-%CXX% %CXXFLAGS% -c ImageOutputDev.cc
-%CXX% %CXXFLAGS% -c JArithmeticDecoder.cc
-%CXX% %CXXFLAGS% -c JBIG2Stream.cc
-%CXX% %CXXFLAGS% -c JPXStream.cc
-%CXX% %CXXFLAGS% -c Lexer.cc
-%CXX% %CXXFLAGS% -c Link.cc
-%CXX% %CXXFLAGS% -c NameToCharCode.cc
-%CXX% %CXXFLAGS% -c Object.cc
-%CXX% %CXXFLAGS% -c OptionalContent.cc
-%CXX% %CXXFLAGS% -c Outline.cc
-%CXX% %CXXFLAGS% -c OutputDev.cc
-%CXX% %CXXFLAGS% -c PDFDoc.cc
-%CXX% %CXXFLAGS% -c PDFDocEncoding.cc
-%CXX% %CXXFLAGS% -c PSOutputDev.cc
-%CXX% %CXXFLAGS% -c PSTokenizer.cc
-%CXX% %CXXFLAGS% -c Page.cc
-%CXX% %CXXFLAGS% -c Parser.cc
-%CXX% %CXXFLAGS% -c PreScanOutputDev.cc
-%CXX% %CXXFLAGS% -c SecurityHandler.cc
-%CXX% %CXXFLAGS% -c Stream.cc
-%CXX% %CXXFLAGS% -c TextOutputDev.cc
-%CXX% %CXXFLAGS% -c TextString.cc
-%CXX% %CXXFLAGS% -c UnicodeMap.cc
-%CXX% %CXXFLAGS% -c UnicodeTypeTable.cc
-%CXX% %CXXFLAGS% -c XFAForm.cc
-%CXX% %CXXFLAGS% -c XRef.cc
-%CXX% %CXXFLAGS% -c Zoox.cc
-del libxpdf.a
-%LIBPROG% -rc libxpdf.a *.o
-
-%CXX% %CXXFLAGS% -o pdftops.exe pdftops.cc libxpdf.a ..\fofi\libfofi.a ..\goo\libGoo.a
-
-%CXX% %CXXFLAGS% -o pdftotext.exe pdftotext.cc libxpdf.a ..\fofi\libfofi.a ..\goo\libGoo.a
-
-%CXX% %CXXFLAGS% -o pdfinfo.exe pdfinfo.cc libxpdf.a ..\fofi\libfofi.a ..\goo\libGoo.a
-
-%CXX% %CXXFLAGS% -o pdffonts.exe pdffonts.cc libxpdf.a ..\fofi\libfofi.a ..\goo\libGoo.a
-
-%CXX% %CXXFLAGS% -o pdfdetach.exe pdfdetach.cc libxpdf.a ..\fofi\libfofi.a ..\goo\libGoo.a
-
-%CXX% %CXXFLAGS% -o pdfimages.exe pdfimages.cc libxpdf.a ..\fofi\libfofi.a ..\goo\libGoo.a
-
-cd ..
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1 b/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.1
index b0d9dd31186..0ef891d6bc2 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-2014 Glyph & Cog, LLC
-.TH pdfdetach 1 "28 May 2014"
+.\" Copyright 2013-2017 Glyph & Cog, LLC
+.TH pdfdetach 1 "10 Aug 2017"
.SH NAME
pdfdetach \- Portable Document Format (PDF) document embedded file
-extractor (version 3.04)
+extractor (version 4.00)
.SH SYNOPSIS
.B pdfdetach
[options]
@@ -90,7 +90,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdfinfo software and documentation are copyright 1996-2014 Glyph &
+The pdfinfo software and documentation are copyright 1996-2017 Glyph &
Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
@@ -104,4 +104,4 @@ Cog, LLC.
.BR pdfimages (1),
.BR xpdfrc (5)
.br
-.B http://www.foolabs.com/xpdf/
+.B http://www.xpdfreader.com/
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat
index 8b052e26c55..66c812df6a4 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdfdetach.cat
@@ -1,10 +1,10 @@
-pdfdetach(1) pdfdetach(1)
+pdfdetach(1) General Commands Manual pdfdetach(1)
NAME
pdfdetach - Portable Document Format (PDF) document embedded file
- extractor (version 3.04)
+ extractor (version 4.00)
SYNOPSIS
pdfdetach [options] [PDF-file]
@@ -79,14 +79,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdfinfo software and documentation are copyright 1996-2014 Glyph &
+ The pdfinfo software and documentation are copyright 1996-2017 Glyph &
Cog, LLC.
SEE ALSO
xpdf(1), pdftops(1), pdftotext(1), pdftohtml(1), pdfinfo(1), pdf-
fonts(1), pdftoppm(1), pdftopng(1), pdfimages(1), xpdfrc(5)
- http://www.foolabs.com/xpdf/
+ http://www.xpdfreader.com/
- 28 May 2014 pdfdetach(1)
+ 10 Aug 2017 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 70e1f45fd8a..3812c6b50b7 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-2014 Glyph & Cog, LLC
-.TH pdffonts 1 "28 May 2014"
+.\" Copyright 1999-2017 Glyph & Cog, LLC
+.TH pdffonts 1 "10 Aug 2017"
.SH NAME
pdffonts \- Portable Document Format (PDF) font analyzer (version
-3.04)
+4.00)
.SH SYNOPSIS
.B pdffonts
[options]
@@ -32,6 +32,10 @@ the font type -- see below for details
absence of a ToUnicode map doesn't necessarily mean that the text
can't be converted to Unicode)
.TP
+.B prob
+"X" if this font is likely to be problematic when converting text to
+Unicode
+.TP
.B object ID
the font dictionary object ID (number and generation)
.TP
@@ -143,7 +147,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdffonts software and documentation are copyright 1996-2014 Glyph
+The pdffonts software and documentation are copyright 1996-2017 Glyph
& Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
@@ -157,4 +161,4 @@ The pdffonts software and documentation are copyright 1996-2014 Glyph
.BR pdfimages (1),
.BR xpdfrc (5)
.br
-.B http://www.foolabs.com/xpdf/
+.B http://www.xpdfreader.com/
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat
index 0c10b25253a..c11910b977c 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdffonts.cat
@@ -1,9 +1,9 @@
-pdffonts(1) pdffonts(1)
+pdffonts(1) General Commands Manual pdffonts(1)
NAME
- pdffonts - Portable Document Format (PDF) font analyzer (version 3.04)
+ pdffonts - Portable Document Format (PDF) font analyzer (version 4.00)
SYNOPSIS
pdffonts [options] [PDF-file]
@@ -27,6 +27,9 @@ DESCRIPTION
(the absence of a ToUnicode map doesn't necessarily mean that
the text can't be converted to Unicode)
+ prob "X" if this font is likely to be problematic when converting
+ text to Unicode
+
object ID
the font dictionary object ID (number and generation)
@@ -49,32 +52,32 @@ DESCRIPTION
CONFIGURATION FILE
Pdffonts reads a configuration file at startup. It first tries to find
- the user's private config file, ~/.xpdfrc. If that doesn't exist, it
- looks for a system-wide config file, typically /usr/local/etc/xpdfrc
- (but this location can be changed when pdffonts is built). See the
+ the user's private config file, ~/.xpdfrc. If that doesn't exist, it
+ looks for a system-wide config file, typically /usr/local/etc/xpdfrc
+ (but this location can be changed when pdffonts is built). See the
xpdfrc(5) man page for details.
OPTIONS
- Many of the following options can be set with configuration file com-
+ Many of the following options can be set with configuration file com-
mands. These are listed in square brackets with the description of the
corresponding command line option.
-f number
Specifies the first page to analyze.
- -loc Shows additional information on the location of the font that
- will be used when the PDF file is rasterized (with xpdf,
+ -loc Shows additional information on the location of the font that
+ will be used when the PDF file is rasterized (with xpdf,
pdftoppm, etc.).
- -locPS Shows additional information on the location of the font that
- will be used when the PDF file is converted to PostScript (with
+ -locPS Shows additional information on the location of the font that
+ will be used when the PDF file is converted to PostScript (with
pdftops).
-l number
Specifies the last page to analyze.
-opw password
- Specify the owner password for the PDF file. Providing this
+ Specify the owner password for the PDF file. Providing this
will bypass all security restrictions.
-upw password
@@ -102,14 +105,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdffonts software and documentation are copyright 1996-2014 Glyph &
+ The pdffonts software and documentation are copyright 1996-2017 Glyph &
Cog, LLC.
SEE ALSO
- xpdf(1), pdftops(1), pdftotext(1), pdftohtml(1), pdfinfo(1), pdfde-
+ xpdf(1), pdftops(1), pdftotext(1), pdftohtml(1), pdfinfo(1), pdfde-
tach(1), pdftoppm(1), pdftopng(1), pdfimages(1), xpdfrc(5)
- http://www.foolabs.com/xpdf/
+ http://www.xpdfreader.com/
- 28 May 2014 pdffonts(1)
+ 10 Aug 2017 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 0953ced5636..a220d30b151 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-2014 Glyph & Cog, LLC
-.TH pdfimages 1 "28 May 2014"
+.\" Copyright 1998-2017 Glyph & Cog, LLC
+.TH pdfimages 1 "10 Aug 2017"
.SH NAME
pdfimages \- Portable Document Format (PDF) image extractor
-(version 3.04)
+(version 4.00)
.SH SYNOPSIS
.B pdfimages
[options]
@@ -10,17 +10,18 @@ pdfimages \- Portable Document Format (PDF) image extractor
.SH DESCRIPTION
.B Pdfimages
saves images from a Portable Document Format (PDF) file as Portable
-Pixmap (PPM), Portable Bitmap (PBM), or JPEG files.
+Pixmap (PPM), Portable Graymap (PGM), Portable Bitmap (PBM), or JPEG
+files.
.PP
Pdfimages reads the PDF file, scans one or more pages,
.IR PDF-file ,
-and writes one PPM, PBM, or JPEG file for each image,
+and writes one PPM, PGM, PBM, or JPEG file for each image,
.IR image-root - nnnn . xxx ,
where
.I nnnn
is the image number and
.I xxx
-is the image type (.ppm, .pbm, .jpg).
+is the image type (.ppm, .pgm, .pbm, .jpg).
.PP
NB: pdfimages extracts the raw image data from the PDF file, without
performing any additional transforms. Any rotation, clipping,
@@ -45,10 +46,23 @@ Specifies the first page to scan.
Specifies the last page to scan.
.TP
.B \-j
-Normally, all images are written as PBM (for monochrome images) or PPM
-(for non-monochrome images) files. With this option, images in DCT
-format are saved as JPEG files. All non-DCT images are saved in
-PBM/PPM format as usual.
+Normally, all images are written as PBM (for monochrome images), PGM
+(for grayscale images), or PPM (for color images) files. With this
+option, images in DCT format are saved as JPEG files. All non-DCT
+images are saved in PBM/PGM/PPM format as usual. (Inline images are
+always saved in PBM/PGM/PPM format.)
+.TP
+.B \-raw
+Write all images in PDF-native formats. Most of the formats are not
+standard image formats, so this option is primarily useful as input to
+a tool that generates PDF files. (Inline images are always saved in
+PBM/PGM/PPM format.)
+.TP
+.B \-list
+Write a one-line summary to stdout for each image. The summary
+provides the image file name, the page number, the image width and
+height, the horizontal and vertical resolution (DPI) as drawn, the
+color space type, and the number of bits per component (BPC).
.TP
.BI \-opw " password"
Specify the owner password for the PDF file. Providing this will
@@ -88,7 +102,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdfimages software and documentation are copyright 1998-2014 Glyph
+The pdfimages software and documentation are copyright 1998-2017 Glyph
& Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
@@ -102,4 +116,4 @@ The pdfimages software and documentation are copyright 1998-2014 Glyph
.BR pdftopng (1),
.BR xpdfrc (5)
.br
-.B http://www.foolabs.com/xpdf/
+.B http://www.xpdfreader.com/
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat
index a152e789b64..5f9397b06f2 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdfimages.cat
@@ -1,36 +1,37 @@
-pdfimages(1) pdfimages(1)
+pdfimages(1) General Commands Manual pdfimages(1)
NAME
pdfimages - Portable Document Format (PDF) image extractor (version
- 3.04)
+ 4.00)
SYNOPSIS
pdfimages [options] PDF-file image-root
DESCRIPTION
Pdfimages saves images from a Portable Document Format (PDF) file as
- Portable Pixmap (PPM), Portable Bitmap (PBM), or JPEG files.
+ Portable Pixmap (PPM), Portable Graymap (PGM), Portable Bitmap (PBM),
+ or JPEG files.
- Pdfimages reads the PDF file, scans one or more pages, PDF-file, and
- writes one PPM, PBM, or JPEG file for each image, image-root-nnnn.xxx,
- where nnnn is the image number and xxx is the image type (.ppm, .pbm,
- .jpg).
+ Pdfimages reads the PDF file, scans one or more pages, PDF-file, and
+ writes one PPM, PGM, PBM, or JPEG file for each image, image-root-
+ nnnn.xxx, where nnnn is the image number and xxx is the image type
+ (.ppm, .pgm, .pbm, .jpg).
- NB: pdfimages extracts the raw image data from the PDF file, without
- performing any additional transforms. Any rotation, clipping, color
+ NB: pdfimages extracts the raw image data from the PDF file, without
+ performing any additional transforms. Any rotation, clipping, color
inversion, etc. done by the PDF content stream is ignored.
CONFIGURATION FILE
- Pdfimages reads a configuration file at startup. It first tries to
+ Pdfimages reads a configuration file at startup. It first tries to
find the user's private config file, ~/.xpdfrc. If that doesn't exist,
it looks for a system-wide config file, typically /usr/local/etc/xpdfrc
- (but this location can be changed when pdfimages is built). See the
+ (but this location can be changed when pdfimages is built). See the
xpdfrc(5) man page for details.
OPTIONS
- Many of the following options can be set with configuration file com-
+ Many of the following options can be set with configuration file com-
mands. These are listed in square brackets with the description of the
corresponding command line option.
@@ -40,13 +41,25 @@ OPTIONS
-l number
Specifies the last page to scan.
- -j Normally, all images are written as PBM (for monochrome images)
- or PPM (for non-monochrome images) files. With this option,
- images in DCT format are saved as JPEG files. All non-DCT
- images are saved in PBM/PPM format as usual.
+ -j Normally, all images are written as PBM (for monochrome images),
+ PGM (for grayscale images), or PPM (for color images) files.
+ With this option, images in DCT format are saved as JPEG files.
+ All non-DCT images are saved in PBM/PGM/PPM format as usual.
+ (Inline images are always saved in PBM/PGM/PPM format.)
+
+ -raw Write all images in PDF-native formats. Most of the formats are
+ not standard image formats, so this option is primarily useful
+ as input to a tool that generates PDF files. (Inline images are
+ always saved in PBM/PGM/PPM format.)
+
+ -list Write a one-line summary to stdout for each image. The summary
+ provides the image file name, the page number, the image width
+ and height, the horizontal and vertical resolution (DPI) as
+ drawn, the color space type, and the number of bits per compo-
+ nent (BPC).
-opw password
- Specify the owner password for the PDF file. Providing this
+ Specify the owner password for the PDF file. Providing this
will bypass all security restrictions.
-upw password
@@ -72,14 +85,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdfimages software and documentation are copyright 1998-2014 Glyph
+ The pdfimages software and documentation are copyright 1998-2017 Glyph
& Cog, LLC.
SEE ALSO
- xpdf(1), pdftops(1), pdftotext(1), pdftohtml(1), pdfinfo(1), pdf-
+ xpdf(1), pdftops(1), pdftotext(1), pdftohtml(1), pdfinfo(1), pdf-
fonts(1), pdfdetach(1), pdftoppm(1), pdftopng(1), xpdfrc(5)
- http://www.foolabs.com/xpdf/
+ http://www.xpdfreader.com/
- 28 May 2014 pdfimages(1)
+ 10 Aug 2017 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 5a02353744f..2a3a1d9f645 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-2014 Glyph & Cog, LLC
-.TH pdfinfo 1 "28 May 2014"
+.\" Copyright 1999-2017 Glyph & Cog, LLC
+.TH pdfinfo 1 "10 Aug 2017"
.SH NAME
pdfinfo \- Portable Document Format (PDF) document information
-extractor (version 3.04)
+extractor (version 4.00)
.SH SYNOPSIS
.B pdfinfo
[options]
@@ -45,7 +45,7 @@ In addition, the following information is printed:
tagged (yes/no)
.RE
.RS
-form (AcroForm / XFA / none)
+form (AcroForm / static XFA / dynamic XFA / none)
.RE
.RS
page count
@@ -150,7 +150,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdfinfo software and documentation are copyright 1996-2014 Glyph &
+The pdfinfo software and documentation are copyright 1996-2017 Glyph &
Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
@@ -164,4 +164,4 @@ Cog, LLC.
.BR pdfimages (1),
.BR xpdfrc (5)
.br
-.B http://www.foolabs.com/xpdf/
+.B http://www.xpdfreader.com/
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat
index 8ef2bb21317..4c001beb789 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdfinfo.cat
@@ -1,10 +1,10 @@
-pdfinfo(1) pdfinfo(1)
+pdfinfo(1) General Commands Manual pdfinfo(1)
NAME
pdfinfo - Portable Document Format (PDF) document information extractor
- (version 3.04)
+ (version 4.00)
SYNOPSIS
pdfinfo [options] [PDF-file]
@@ -27,7 +27,7 @@ DESCRIPTION
In addition, the following information is printed:
tagged (yes/no)
- form (AcroForm / XFA / none)
+ form (AcroForm / static XFA / dynamic XFA / none)
page count
encrypted flag (yes/no)
print and copy permissions (if encrypted)
@@ -104,14 +104,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdfinfo software and documentation are copyright 1996-2014 Glyph &
+ The pdfinfo software and documentation are copyright 1996-2017 Glyph &
Cog, LLC.
SEE ALSO
xpdf(1), pdftops(1), pdftotext(1), pdftohtml(1), pdffonts(1), pdfde-
tach(1), pdftoppm(1), pdftopng(1), pdfimages(1), xpdfrc(5)
- http://www.foolabs.com/xpdf/
+ http://www.xpdfreader.com/
- 28 May 2014 pdfinfo(1)
+ 10 Aug 2017 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 a74df55c75a..a6c56177fe6 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-2014 Glyph & Cog, LLC
-.TH pdftohtml 1 "28 May 2014"
+.\" Copyright 1997-2017 Glyph & Cog, LLC
+.TH pdftohtml 1 "10 Aug 2017"
.SH NAME
pdftohtml \- Portable Document Format (PDF) to HTML converter
-(version 3.04)
+(version 4.00)
.SH SYNOPSIS
.B pdftohtml
[options]
@@ -38,9 +38,29 @@ Specifies the first page to convert.
.BI \-l " number"
Specifies the last page to convert.
.TP
-.B \-r
-Specifies the resolution, in DPI, for background images. The default
-is 150 DPI.
+.BI \-z " number"
+Specifies the initial zoom level. The default is 1.0, which means
+72dpi, i.e., 1 point in the PDF file will be 1 pixel in the HTML.
+Using \'-z 1.5', for example, will make the initial view 50% larger.
+.TP
+.BI \-r " number"
+Specifies the resolution, in DPI, for background images. This
+controls the pixel size of the background image files. The initial
+zoom level is controlled by the \'-z' option. Specifying a larger
+\'-r' value will allow the viewer to zoom in farther without upscaling
+artifacts in the background.
+.TP
+.B \-skipinvisible
+Don't draw invisible text. By default, invisible text (commonly used
+in OCR'ed PDF files) is drawn as transparent (alpha=0) HTML text.
+This option tells pdftohtml to discard invisible text entirely.
+.TP
+.B \-allinvisible
+Treat all text as invisible. By default, regular (non-invisible) text
+is not drawn in the background image, and is instead drawn with HTML
+on top of the image. This option tells pdftohtml to include the
+regular text in the background image, and then draw it as transparent
+(alpha=0) HTML text.
.TP
.BI \-opw " password"
Specify the owner password for the PDF file. Providing this will
@@ -89,7 +109,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdftohtml software and documentation are copyright 1996-2014 Glyph
+The pdftohtml software and documentation are copyright 1996-2017 Glyph
& Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
@@ -103,4 +123,4 @@ The pdftohtml software and documentation are copyright 1996-2014 Glyph
.BR pdfimages (1),
.BR xpdfrc (5)
.br
-.B http://www.foolabs.com/xpdf/
+.B http://www.xpdfreader.com/
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat
index ed46c1a4c43..4999a589631 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftohtml.cat
@@ -1,10 +1,10 @@
-pdftohtml(1) pdftohtml(1)
+pdftohtml(1) General Commands Manual pdftohtml(1)
NAME
pdftohtml - Portable Document Format (PDF) to HTML converter (version
- 3.04)
+ 4.00)
SYNOPSIS
pdftohtml [options] PDF-file HTML-dir
@@ -35,11 +35,34 @@ OPTIONS
-l number
Specifies the last page to convert.
- -r Specifies the resolution, in DPI, for background images. The
- default is 150 DPI.
+ -z number
+ Specifies the initial zoom level. The default is 1.0, which
+ means 72dpi, i.e., 1 point in the PDF file will be 1 pixel in
+ the HTML. Using '-z 1.5', for example, will make the initial
+ view 50% larger.
+
+ -r number
+ Specifies the resolution, in DPI, for background images. This
+ controls the pixel size of the background image files. The ini-
+ tial zoom level is controlled by the '-z' option. Specifying a
+ larger '-r' value will allow the viewer to zoom in farther with-
+ out upscaling artifacts in the background.
+
+ -skipinvisible
+ Don't draw invisible text. By default, invisible text (commonly
+ used in OCR'ed PDF files) is drawn as transparent (alpha=0) HTML
+ text. This option tells pdftohtml to discard invisible text
+ entirely.
+
+ -allinvisible
+ Treat all text as invisible. By default, regular (non-invisi-
+ ble) text is not drawn in the background image, and is instead
+ drawn with HTML on top of the image. This option tells pdfto-
+ html to include the regular text in the background image, and
+ then draw it as transparent (alpha=0) HTML text.
-opw password
- Specify the owner password for the PDF file. Providing this
+ Specify the owner password for the PDF file. Providing this
will bypass all security restrictions.
-upw password
@@ -56,7 +79,7 @@ OPTIONS
-h Print usage information. (-help and --help are equivalent.)
BUGS
- Some PDF files contain fonts whose encodings have been mangled beyond
+ Some PDF files contain fonts whose encodings have been mangled beyond
recognition. There is no way (short of OCR) to extract text from these
files.
@@ -74,14 +97,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdftohtml software and documentation are copyright 1996-2014 Glyph
+ The pdftohtml software and documentation are copyright 1996-2017 Glyph
& Cog, LLC.
SEE ALSO
xpdf(1), pdftops(1), pdftotext(1), pdfinfo(1), pdffonts(1), pdfde-
tach(1), pdftoppm(1), pdftopng(1), pdfimages(1), xpdfrc(5)
- http://www.foolabs.com/xpdf/
+ http://www.xpdfreader.com/
- 28 May 2014 pdftohtml(1)
+ 10 Aug 2017 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 6d936537bf8..a75704f0ae7 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 2014 Glyph & Cog, LLC
-.TH pdftopng 1 "28 May 2014"
+.\" Copyright 2017 Glyph & Cog, LLC
+.TH pdftopng 1 "10 Aug 2017"
.SH NAME
pdftopng \- Portable Document Format (PDF) to Portable Network Graphics
-(PNG) converter (version 3.04)
+(PNG) converter (version 4.00)
.SH SYNOPSIS
.B pdftopng
[options]
@@ -51,6 +51,11 @@ Generate a monochrome image (instead of a color image).
.B \-gray
Generate a grayscale image (instead of a color image).
.TP
+.B \-alpha
+Generate an alpha channel in the PNG file. This is only useful with
+PDF files that have been constructed with a transparent background.
+The \-alpha flag cannot be used with \-mono.
+.TP
.BI \-freetype " yes | no"
Enable or disable FreeType (a TrueType / Type 1 font rasterizer).
This defaults to "yes".
@@ -102,7 +107,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdftopng software and documentation are copyright 1996-2014 Glyph
+The pdftopng software and documentation are copyright 1996-2017 Glyph
& Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
@@ -116,4 +121,4 @@ The pdftopng software and documentation are copyright 1996-2014 Glyph
.BR pdfimages (1),
.BR xpdfrc (5)
.br
-.B http://www.foolabs.com/xpdf/
+.B http://www.xpdfreader.com/
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat
index ca1c5ed27bb..c403c7b8926 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftopng.cat
@@ -1,10 +1,10 @@
-pdftopng(1) pdftopng(1)
+pdftopng(1) General Commands Manual pdftopng(1)
NAME
pdftopng - Portable Document Format (PDF) to Portable Network Graphics
- (PNG) converter (version 3.04)
+ (PNG) converter (version 4.00)
SYNOPSIS
pdftopng [options] PDF-file PNG-root
@@ -44,6 +44,10 @@ OPTIONS
-gray Generate a grayscale image (instead of a color image).
+ -alpha Generate an alpha channel in the PNG file. This is only useful
+ with PDF files that have been constructed with a transparent
+ background. The -alpha flag cannot be used with -mono.
+
-freetype yes | no
Enable or disable FreeType (a TrueType / Type 1 font raster-
izer). This defaults to "yes". [config file: enableFreeType]
@@ -83,14 +87,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdftopng software and documentation are copyright 1996-2014 Glyph &
+ The pdftopng software and documentation are copyright 1996-2017 Glyph &
Cog, LLC.
SEE ALSO
xpdf(1), pdftops(1), pdftotext(1), pdftohtml(1), pdfinfo(1), pdf-
fonts(1), pdfdetach(1), pdftoppm(1), pdfimages(1), xpdfrc(5)
- http://www.foolabs.com/xpdf/
+ http://www.xpdfreader.com/
- 28 May 2014 pdftopng(1)
+ 10 Aug 2017 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 4255937ab2a..6eb614024d7 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-2014 Glyph & Cog, LLC
-.TH pdftoppm 1 "28 May 2014"
+.\" Copyright 2005-2017 Glyph & Cog, LLC
+.TH pdftoppm 1 "10 Aug 2017"
.SH NAME
pdftoppm \- Portable Document Format (PDF) to Portable Pixmap (PPM)
-converter (version 3.04)
+converter (version 4.00)
.SH SYNOPSIS
.B pdftoppm
[options]
@@ -48,10 +48,13 @@ Specifies the last page to convert.
Specifies the resolution, in DPI. The default is 150 DPI.
.TP
.B \-mono
-Generate a monochrome PBM file (instead of a color PPM file).
+Generate a monochrome PBM file (instead of an RGB PPM file).
.TP
.B \-gray
-Generate a grayscale PGM file (instead of a color PPM file).
+Generate a grayscale PGM file (instead of an RGB PPM file).
+.TP
+.B \-cmyk
+Generate a CMYK PAM file (instead of an RGB PPM file).
.TP
.BI \-freetype " yes | no"
Enable or disable FreeType (a TrueType / Type 1 font rasterizer).
@@ -104,7 +107,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdftoppm software and documentation are copyright 1996-2014 Glyph
+The pdftoppm software and documentation are copyright 1996-2017 Glyph
& Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
@@ -118,4 +121,4 @@ The pdftoppm software and documentation are copyright 1996-2014 Glyph
.BR pdfimages (1),
.BR xpdfrc (5)
.br
-.B http://www.foolabs.com/xpdf/
+.B http://www.xpdfreader.com/
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat
index bfa37c738b1..86d2e4b0165 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftoppm.cat
@@ -1,10 +1,10 @@
-pdftoppm(1) pdftoppm(1)
+pdftoppm(1) General Commands Manual pdftoppm(1)
NAME
pdftoppm - Portable Document Format (PDF) to Portable Pixmap (PPM) con-
- verter (version 3.04)
+ verter (version 4.00)
SYNOPSIS
pdftoppm [options] PDF-file PPM-root
@@ -41,9 +41,11 @@ OPTIONS
-r number
Specifies the resolution, in DPI. The default is 150 DPI.
- -mono Generate a monochrome PBM file (instead of a color PPM file).
+ -mono Generate a monochrome PBM file (instead of an RGB PPM file).
- -gray Generate a grayscale PGM file (instead of a color PPM file).
+ -gray Generate a grayscale PGM file (instead of an RGB PPM file).
+
+ -cmyk Generate a CMYK PAM file (instead of an RGB PPM file).
-freetype yes | no
Enable or disable FreeType (a TrueType / Type 1 font raster-
@@ -84,14 +86,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdftoppm software and documentation are copyright 1996-2014 Glyph &
+ The pdftoppm software and documentation are copyright 1996-2017 Glyph &
Cog, LLC.
SEE ALSO
xpdf(1), pdftops(1), pdftotext(1), pdftohtml(1), pdfinfo(1), pdf-
fonts(1), pdfdetach(1), pdftopng(1), pdfimages(1), xpdfrc(5)
- http://www.foolabs.com/xpdf/
+ http://www.xpdfreader.com/
- 28 May 2014 pdftoppm(1)
+ 10 Aug 2017 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 d9daf492390..59fb3af9da5 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-2014 Glyph & Cog, LLC
-.TH pdftops 1 "28 May 2014"
+.\" Copyright 1996-2017 Glyph & Cog, LLC
+.TH pdftops 1 "10 Aug 2017"
.SH NAME
pdftops \- Portable Document Format (PDF) to PostScript converter
-(version 3.04)
+(version 4.00)
.SH SYNOPSIS
.B pdftops
[options]
@@ -65,6 +65,11 @@ Generate Level 2 PostScript. Level 2 supports color images and image
compression. This is the default setting.
.RB "[config file: " psLevel ]
.TP
+.B \-level2gray
+Generate grayscale Level 2 PostScript. All colors, including images,
+are converted to grayscale.
+.RB "[config file: " psLevel ]
+.TP
.B \-level2sep
Generate Level 2 separable PostScript. All colors are converted to
CMYK. The PostScript separation convention operators are used to
@@ -76,6 +81,11 @@ Generate Level 3 PostScript. This enables all Level 2 features plus
CID font embedding and masked image generation.
.RB "[config file: " psLevel ]
.TP
+.B \-level3gray
+Generate grayscale Level 3 PostScript. All colors, including images,
+are converted to grayscale.
+.RB "[config file: " psLevel ]
+.TP
.B \-level3Sep
Generate Level 3 separable PostScript. The separation handling is the
same as for \-level2Sep.
@@ -174,6 +184,10 @@ Treat the CropBox as the PDF page size. By default, the MediaBox is
used as the page size.
.RB "[config file: " psUseCropBoxAsPage ]
.TP
+.B \-userunit
+Honor the UserUnit settings on PDF pages when computing page/paper
+size. By default, pdftops ignores UserUnit.
+.TP
.B \-duplex
Set the Duplex pagedevice entry in the PostScript file. This tells
duplex-capable printers to enable duplexing.
@@ -222,7 +236,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdftops software and documentation are copyright 1996-2014 Glyph &
+The pdftops software and documentation are copyright 1996-2017 Glyph &
Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
@@ -236,4 +250,4 @@ Cog, LLC.
.BR pdfimages (1),
.BR xpdfrc (5)
.br
-.B http://www.foolabs.com/xpdf/
+.B http://www.xpdfreader.com/
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat
index 9e119ac30d9..de656d5f8da 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftops.cat
@@ -1,10 +1,10 @@
-pdftops(1) pdftops(1)
+pdftops(1) General Commands Manual pdftops(1)
NAME
pdftops - Portable Document Format (PDF) to PostScript converter (ver-
- sion 3.04)
+ sion 4.00)
SYNOPSIS
pdftops [options] [PDF-file [PS-file]]
@@ -54,16 +54,24 @@ OPTIONS
image compression. This is the default setting. [config file:
psLevel]
+ -level2gray
+ Generate grayscale Level 2 PostScript. All colors, including
+ images, are converted to grayscale. [config file: psLevel]
+
-level2sep
Generate Level 2 separable PostScript. All colors are converted
- to CMYK. The PostScript separation convention operators are
+ to CMYK. The PostScript separation convention operators are
used to handle custom (spot) colors. [config file: psLevel]
-level3
- Generate Level 3 PostScript. This enables all Level 2 features
- plus CID font embedding and masked image generation. [config
+ Generate Level 3 PostScript. This enables all Level 2 features
+ plus CID font embedding and masked image generation. [config
file: psLevel]
+ -level3gray
+ Generate grayscale Level 3 PostScript. All colors, including
+ images, are converted to grayscale. [config file: psLevel]
+
-level3Sep
Generate Level 3 separable PostScript. The separation handling
is the same as for -level2Sep. [config file: psLevel]
@@ -153,13 +161,17 @@ OPTIONS
Treat the CropBox as the PDF page size. By default, the Media-
Box is used as the page size. [config file: psUseCropBoxAsPage]
+ -userunit
+ Honor the UserUnit settings on PDF pages when computing
+ page/paper size. By default, pdftops ignores UserUnit.
+
-duplex
- Set the Duplex pagedevice entry in the PostScript file. This
- tells duplex-capable printers to enable duplexing. [config
+ Set the Duplex pagedevice entry in the PostScript file. This
+ tells duplex-capable printers to enable duplexing. [config
file: psDuplex]
-opw password
- Specify the owner password for the PDF file. Providing this
+ Specify the owner password for the PDF file. Providing this
will bypass all security restrictions.
-upw password
@@ -189,14 +201,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdftops software and documentation are copyright 1996-2014 Glyph &
+ The pdftops software and documentation are copyright 1996-2017 Glyph &
Cog, LLC.
SEE ALSO
- xpdf(1), pdftotext(1), pdftohtml(1), pdfinfo(1), pdffonts(1), pdfde-
+ xpdf(1), pdftotext(1), pdftohtml(1), pdfinfo(1), pdffonts(1), pdfde-
tach(1), pdftoppm(1), pdftopng(1), pdfimages(1), xpdfrc(5)
- http://www.foolabs.com/xpdf/
+ http://www.xpdfreader.com/
- 28 May 2014 pdftops(1)
+ 10 Aug 2017 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 12d75006702..7fef78e742a 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-2014 Glyph & Cog, LLC
-.TH pdftotext 1 "28 May 2014"
+.\" Copyright 1997-2017 Glyph & Cog, LLC
+.TH pdftotext 1 "10 Aug 2017"
.SH NAME
pdftotext \- Portable Document Format (PDF) to text converter
-(version 3.04)
+(version 4.00)
.SH SYNOPSIS
.B pdftotext
[options]
@@ -52,6 +52,13 @@ hyphenation, etc.) and output the text in reading order. If the
option is given, character spacing within each line will be determined
by the specified character pitch.
.TP
+.B \-simple
+Similar to
+.BR \-layout ,
+but optimized for simple one-column pages. This mode will do a better
+job of maintaining horizontal spacing, but it will only work properly
+with a single column of text.
+.TP
.B \-table
Table mode is similar to physical layout mode, but optimized for
tabular data, with the goal of keeping rows and columns aligned (at
@@ -92,6 +99,11 @@ Text which is hidden because of clipping is removed before doing
layout, and then added back in. This can be helpful for tables where
clipped (invisible) text would overlap the next column.
.TP
+.B \-nodiag
+Diagonal text, i.e., text that is not close to one of the 0, 90, 180,
+or 270 degree axes, is discarded. This is useful to skip watermarks
+drawn on top of body text, etc.
+.TP
.BI \-enc " encoding-name"
Sets the encoding to use for text output. The
.I encoding\-name
@@ -109,6 +121,10 @@ Sets the end-of-line convention to use for text output.
Don't insert page breaks (form feed characters) between pages.
.RB "[config file: " textPageBreaks ]
.TP
+.B \-bom
+Insert a Unicode byte order marker (BOM) at the start of the text
+output.
+.TP
.BI \-opw " password"
Specify the owner password for the PDF file. Providing this will
bypass all security restrictions.
@@ -156,7 +172,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The pdftotext software and documentation are copyright 1996-2014 Glyph
+The pdftotext software and documentation are copyright 1996-2017 Glyph
& Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
@@ -170,4 +186,4 @@ The pdftotext software and documentation are copyright 1996-2014 Glyph
.BR pdfimages (1),
.BR xpdfrc (5)
.br
-.B http://www.foolabs.com/xpdf/
+.B http://www.xpdfreader.com/
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat b/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat
index 8217743e28d..ffe7ebc08b1 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/pdftotext.cat
@@ -1,10 +1,10 @@
-pdftotext(1) pdftotext(1)
+pdftotext(1) General Commands Manual pdftotext(1)
NAME
pdftotext - Portable Document Format (PDF) to text converter (version
- 3.04)
+ 4.00)
SYNOPSIS
pdftotext [options] [PDF-file [text-file]]
@@ -41,43 +41,54 @@ OPTIONS
-fixed option is given, character spacing within each line will
be determined by the specified character pitch.
+ -simple
+ Similar to -layout, but optimized for simple one-column pages.
+ This mode will do a better job of maintaining horizontal spac-
+ ing, but it will only work properly with a single column of
+ text.
+
-table Table mode is similar to physical layout mode, but optimized for
- tabular data, with the goal of keeping rows and columns aligned
- (at the expense of inserting extra whitespace). If the -fixed
- option is given, character spacing within each line will be
+ tabular data, with the goal of keeping rows and columns aligned
+ (at the expense of inserting extra whitespace). If the -fixed
+ option is given, character spacing within each line will be
determined by the specified character pitch.
-lineprinter
Line printer mode uses a strict fixed-character-pitch and
- -height layout. That is, the page is broken into a grid, and
- characters are placed into that grid. If the grid spacing is
- too small for the actual characters, the result is extra white-
- space. If the grid spacing is too large, the result is missing
- whitespace. The grid spacing can be specified using the -fixed
- and -linespacing options. If one or both are not given on the
- command line, pdftotext will attempt to compute appropriate
+ -height layout. That is, the page is broken into a grid, and
+ characters are placed into that grid. If the grid spacing is
+ too small for the actual characters, the result is extra white-
+ space. If the grid spacing is too large, the result is missing
+ whitespace. The grid spacing can be specified using the -fixed
+ and -linespacing options. If one or both are not given on the
+ command line, pdftotext will attempt to compute appropriate
value(s).
-raw Keep the text in content stream order. Depending on how the PDF
file was generated, this may or may not be useful.
-fixed number
- Specify the character pitch (character width), in points, for
- physical layout, table, or line printer mode. This is ignored
+ Specify the character pitch (character width), in points, for
+ physical layout, table, or line printer mode. This is ignored
in all other modes.
-linespacing number
- Specify the line spacing, in points, for line printer mode.
+ Specify the line spacing, in points, for line printer mode.
This is ignored in all other modes.
-clip Text which is hidden because of clipping is removed before doing
- layout, and then added back in. This can be helpful for tables
+ layout, and then added back in. This can be helpful for tables
where clipped (invisible) text would overlap the next column.
+ -nodiag
+ Diagonal text, i.e., text that is not close to one of the 0, 90,
+ 180, or 270 degree axes, is discarded. This is useful to skip
+ watermarks drawn on top of body text, etc.
+
-enc encoding-name
- Sets the encoding to use for text output. The encoding-name
- must be defined with the unicodeMap command (see xpdfrc(5)).
- The encoding name is case-sensitive. This defaults to "Latin1"
+ Sets the encoding to use for text output. The encoding-name
+ must be defined with the unicodeMap command (see xpdfrc(5)).
+ The encoding name is case-sensitive. This defaults to "Latin1"
(which is a built-in encoding). [config file: textEncoding]
-eol unix | dos | mac
@@ -85,9 +96,12 @@ OPTIONS
file: textEOL]
-nopgbrk
- Don't insert page breaks (form feed characters) between pages.
+ Don't insert page breaks (form feed characters) between pages.
[config file: textPageBreaks]
+ -bom Insert a Unicode byte order marker (BOM) at the start of the
+ text output.
+
-opw password
Specify the owner password for the PDF file. Providing this
will bypass all security restrictions.
@@ -124,14 +138,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The pdftotext software and documentation are copyright 1996-2014 Glyph
+ The pdftotext software and documentation are copyright 1996-2017 Glyph
& Cog, LLC.
SEE ALSO
xpdf(1), pdftops(1), pdftohtml(1), pdfinfo(1), pdffonts(1), pdfde-
tach(1), pdftoppm(1), pdftopng(1), pdfimages(1), xpdfrc(5)
- http://www.foolabs.com/xpdf/
+ http://www.xpdfreader.com/
- 28 May 2014 pdftotext(1)
+ 10 Aug 2017 pdftotext(1)
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/sample-xpdfrc b/Build/source/libs/xpdf/xpdf-src/doc/sample-xpdfrc
index 0a4234fdf9b..21e6c995b6a 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/sample-xpdfrc
+++ b/Build/source/libs/xpdf/xpdf-src/doc/sample-xpdfrc
@@ -16,7 +16,7 @@
# Also, the Xpdf language support packages each include a set of
# options to be added to the xpdfrc file.
#
-# http://www.foolabs.com/xpdf/
+# http://www.xpdfreader.com/
#
#========================================================================
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1 b/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1
index c34ad7fb787..b463d0fab43 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1
+++ b/Build/source/libs/xpdf/xpdf-src/doc/xpdf.1
@@ -1,20 +1,20 @@
-.\" Copyright 1996-2014 Glyph & Cog, LLC
-.TH xpdf 1 "28 May 2014"
+.\" Copyright 1996-2017 Glyph & Cog, LLC
+.TH xpdf 1 "10 Aug 2017"
.SH NAME
-xpdf \- Portable Document Format (PDF) file viewer for X (version 3.04)
+xpdf \- Portable Document Format (PDF) file viewer (version 4.00)
.SH SYNOPSIS
.B xpdf
[options]
.RI [ PDF-file
-.RI [ page " | +" dest ]]
+.RI [: page " | +" dest "]] ..."
.SH DESCRIPTION
.B Xpdf
is a viewer for Portable Document Format (PDF) files. (These are also
sometimes also called \'Acrobat' files, from the name of Adobe's PDF
-software.) Xpdf runs under the X Window System on UNIX, VMS, and
-OS/2.
+software.) Xpdf uses the Qt GUI toolkit and runs on Unix, OS X, and
+Windows.
.PP
-To run xpdf, simply type:
+To run xpdf, type:
.PP
.RS
xpdf file.pdf
@@ -22,16 +22,26 @@ xpdf file.pdf
.PP
where
.I file.pdf
-is your PDF file. The file name can be followed by a number
-specifying the page which should be displayed first, e.g.:
+is your PDF file. The file name can be followed by a page number to
+be displayed, prefixed with a colon:
.PP
.RS
-xpdf file.pdf 18
+xpdf file.pdf :18
.RE
.PP
-You can also give a named destination, prefixed with \'+' in place of
-the page number. (This is only useful with PDF files that provide
-named destination targets.)
+or by a named destination, prefixed with \'+' (this is only useful
+with PDF files that provide named destination targets):
+.PP
+.RS
+xpdf file.pdf +destinationA
+.RE
+.PP
+If you specify multiple files, they will each be opened in a separate
+tab:
+.PP
+.RS
+xpdf file1.pdf file2.pdf :18 file3.pdf
+.RE
.PP
You can also start xpdf without opening any files:
.PP
@@ -46,66 +56,49 @@ looks for a system-wide config file, typically /usr/local/etc/xpdfrc
.BR xpdfrc (5)
man page for details.
.SH OPTIONS
-Many of the following options can be set with configuration file
-commands or X resources. These are listed in square brackets with the
-description of the corresponding command line option.
+The following command line options are available. All command line
+options must come before any PDF files to be opened.
+.PP
+Many of the options can be set with configuration file commands.
+These are listed in square brackets with the description of the
+corresponding command line option.
.TP
-.BI \-g " geometry"
+.BI \-geometry " geometry"
Set the initial window geometry.
-.RB ( \-geometry
-is equivalent.)
-.RB "[X resource: " xpdf.geometry ]
.TP
.BI \-title " title"
Set the window title. By default, the title will be "xpdf: foo.pdf".
-.RB "[X resource: " xpdf.title ]
-.TP
-.B \-cmap
-Install a private colormap. This is ignored on TrueColor visuals.
-.RB "[X resource: " xpdf.installCmap ]
-.TP
-.BI \-rgb " number"
-Set the size of largest RGB cube xpdf will try to allocate. The
-default is 5 (for a 5x5x5 cube); set to a smaller number to conserve
-color table entries. This is ignored with private colormaps and on
-TrueColor visuals.
-.RB "[X resource: " xpdf.rgbCubeSize ]
.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
do weird things with color. This also causes the paper color to
default to black.
-.RB "[X resource: " xpdf.reverseVideo ]
.TP
.BI \-papercolor " color"
-Set the "paper color", i.e., the background of the page display. This
-will not work too well with PDF files that do things like filling in
-white behind the text.
-.RB "[X resource: " xpdf.paperColor ]
+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 filling in white
+behind the text.
+.RB "[config file: " paperColor ]
.TP
.BI \-mattecolor " color"
Set the matte color, i.e., the color used for background outside the
-actual page area. (There is a separate setting,
-xpdf.fullScreenMatteColor, for full-screen mode.)
-.RB "[X resource: " xpdf.matteColor ]
+actual page area. The color can be #RRGGBB (hexadecimal) or a named
+color.
+.RB "[config file: " matteColor ]
+.TP
+.BI \-fsmattecolor " color"
+Set the matte color for full-screen mode. The color can be #RRGGBB
+(hexadecimal) or a named color.
+.RB "[config file: " fullScreenMatteColor ]
.TP
.BI \-z " zoom"
Set the initial zoom factor. A number specifies a zoom percentage,
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.
-.RB "[config file: " initialZoom "; or X resource: " xpdf.initialZoom ]
-.TP
-.B \-cont
-Start in continuous view mode, i.e., with one vertical scroll bar for
-the whole document.
-.RB "[config file: " continuousView ]
-.TP
-.BI \-freetype " yes | no"
-Enable or disable FreeType (a TrueType / Type 1 font rasterizer).
-This defaults to "yes".
-.RB "[config file: " enableFreeType ]
+.RB "[config file: " initialZoom ]
.TP
.BI \-aa " yes | no"
Enable or disable font anti-aliasing. This defaults to "yes".
@@ -115,32 +108,6 @@ Enable or disable font anti-aliasing. This defaults to "yes".
Enable or disable vector anti-aliasing. This defaults to "yes".
.RB "[config file: " vectorAntialias ]
.TP
-.BI \-ps " PS-file"
-Set the default file name for PostScript output (i.e., the name which
-will appear in the print dialog). This can also be of the form
-\'|command' to pipe the PostScript through a command.
-.RB "[config file: " psFile ]
-.TP
-.BI \-paper " size"
-Set the paper size to one of "letter", "legal", "A4", or "A3". This
-can also be set to "match", which will set the paper size to match the
-size specified in the PDF file.
-.RB "[config file: " psPaperSize ]
-.TP
-.BI \-paperw " size"
-Set the paper width, in points.
-.RB "[config file: " psPaperSize ]
-.TP
-.BI \-paperh " size"
-Set the paper height, in points.
-.RB "[config file: " psPaperSize ]
-.TP
-.B \-level1
-Generate Level 1 PostScript. The resulting PostScript files will be
-significantly larger (if they contain images), but will print on Level
-1 printers. This also converts all images to black and white.
-.RB "[config file: " psLevel ]
-.TP
.BI \-enc " encoding-name"
Sets the encoding to use for text output. The
.I encoding\-name
@@ -149,47 +116,21 @@ must be defined with the unicodeMap command (see
This defaults to "Latin1" (which is a built-in encoding).
.RB "[config file: " textEncoding ]
.TP
-.BI \-eol " unix | dos | mac"
-Sets the end-of-line convention to use for text output.
-.RB "[config file: " textEOL ]
-.TP
-.BI \-opw " password"
-Specify the owner password for the PDF file. Providing this will
-bypass all security restrictions.
-.TP
-.BI \-upw " password"
-Specify the user password for the PDF file.
+.BI \-pw " password"
+Specify the password for the PDF file. This can be either the owner
+password (which will bypass all security restrictions) or the user
+password.
.TP
.B \-fullscreen
Open xpdf in full-screen mode, useful for presentations.
.TP
-.BI \-remote " name"
-Start/contact xpdf remote server with specified name (see the
-.B "REMOTE SERVER MODE"
-section below).
-.TP
-.BI \-exec " command"
-Execute a command (see the
-.B COMMANDS
-section below) in an xpdf remote server window (with \-remote only).
-.TP
-.B \-reload
-Reload xpdf remote server window (with \-remote only).
-.TP
-.B \-raise
-Raise xpdf remote server window (with \-remote only).
-.TP
-.B \-quit
-Kill xpdf remote server (with \-remote only).
+.BI \-display " display"
+Set the X display (only available with X11).
.TP
.B \-cmd
Print commands as they're executed (useful for debugging).
.RB "[config file: " printCommands ]
.TP
-.B \-q
-Don't print any messages or errors.
-.RB "[config file: " errQuiet ]
-.TP
.BI \-cfg " config-file"
Read
.I config-file
@@ -205,439 +146,403 @@ and
.B \-\-help
are equivalent.)
.PP
-Several other standard X options and resources will work as expected:
-.TP
-.BI \-display " display"
-.RB "[X resource: " xpdf.display ]
-.TP
-.BI \-fg " color"
-.RB ( \-foreground
-is equivalent.)
-.RB "[X resource: " xpdf*Foreground ]
-.TP
-.BI \-bg " color"
-.RB ( \-background
-is equivalent.)
-.RB "[X resource: " xpdf*Background ]
-.TP
-.BI \-font " font"
-.RB ( \-fn
-is equivalent.)
-.RB "[X resource: " xpdf*fontList ]
-.PP
-The color and font options only affect the user interface elements,
-not the PDF display (the \'paper').
-.PP
-The following X resources do not have command line option equivalents:
-.TP
-.B xpdf.toolTipEnable
-Enables (if set to true) or disables (if set to false) the tool-tips
-on the toolbar buttons.
-.TP
-.B xpdf.fullScreenMatteColor
-Sets the matte color to be used in full-screen mode. The default
-setting is "black".
.SH CONTROLS
-.SS On-screen controls, at the bottom of the xpdf window
+.SS Tool bar
.TP
-.B "left/right arrow buttons"
-Move to the previous/next page.
-.TP
-.B "double left/right arrow buttons"
-Move backward or forward by ten pages.
-.TP
-.B "dashed left/right arrow buttons"
-Move backward or forward along the history path.
-.TP
-.B "\'Page' entry box"
+.B "\'page' entry box"
Move to a specific page number. Click in the box to activate it, type
the page number, then hit return.
.TP
-.B "zoom popup menu"
-Change the zoom factor (see the description of the \-z option above).
-.TP
-.B "binoculars button"
-Find a text string.
-.TP
-.B "print button"
-Bring up a dialog for generating a PostScript file. The dialog has
-options to set the pages to be printed and the PostScript file name.
-The file name can be \'-' for stdout or \'|command' to pipe the
-PostScript through a command, e.g., \'|lpr'.
-.TP
-.B "\'?' button"
-Bring up the \'about xpdf' window.
-.TP
-.B "link info"
-The space between the \'?' and \'Quit' buttons is used to show the URL
-or external file name when the mouse is over a link.
-.TP
-.B "\'Quit' button"
-Quit xpdf.
-.PP
-.SS Menu
-Pressing the right mouse button will post a popup menu with the
-following commands:
-.TP
-.B "Open..."
-Open a new PDF file via a file requester.
+.B "left/right arrow buttons"
+Go backward or forward along the history path.
.TP
-.B "Open in new window..."
-Create a new window and open a new PDF file via a file requester.
+.B "zoom out/in buttons"
+Zoom out or in (i.e., change magnification) incrementally.
.TP
-.B "Reload"
-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.
+.B "zoom popup menu"
+Change the zoom factor (see the description of the \-z option above).
.TP
-.B "Save as..."
-Save the current file via a file requester.
+.B "fit width button"
+Change the zoom factor to fit the page width to the window width.
.TP
-.B "Continuous view"
-Toggles between single page and continuous view modes.
+.B "fit page button"
+Change the zoom factor to fit the page to the window size.
.TP
-.B "Rotate counterclockwise"
-Rotate the page 90 degrees counterclockwise.
+.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 "Rotate clockwise"
-Rotate the page 90 degrees clockwise. The two rotate commands are
-intended primarily for PDF files where the rotation isn't correctly
-specified in the file.
+.B "\'find' box"
+Find a text string. Click in the box to activate it, type a search
+string, then hit return.
.TP
-.B "Zoom to selection"
-Zoom in to the currently selected rectangle.
+.B "find next button"
+Find the next occurrence of the search string.
.TP
-.B "Close"
-Close the current window. If this is the only open window, the
-document is closed, but the window is left open (i.e., this menu
-command won't quit xpdf).
+.B "find previous button"
+Find the previous occurrence of the search string.
.TP
-.B "Quit"
-Quit xpdf.
+.B "find settings button"
+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
+self-explanatory.
+.PP
+.SS Tab list
+The tab list is on the left, just below the tool bar. It lists all
+open tabs.
+.PP
+.SS Outline/layers/attachments pane
+This pane is on the left, below the tab list. The popup allows you to
+select from outline, layers, or attachments.
+.PP
+The outline is a tree-like structure of bookmarks that allows moving
+within the PDF file. Not all PDF files have outlines.
.PP
-.SS Outline
-If the PDF contains an outline (a.k.a., bookmarks), there will be an
-outline pane on the left side of the window. The width of the outline
-pane is adjustable with a vertical split bar via the knob near its
-bottom end.
+Layers (a.k.a. optional content) allow parts of the PDF content to be
+shown or hidden. Not all PDF files have layers.
+.PP
+Attachments are other files embedded within the PDF file. There is
+a 'save' button for each attached file. Not all PDF files have
+attachments.
.PP
.SS Text selection
Dragging the mouse with the left button held down will highlight an
-arbitrary rectangle. Any text inside this rectangle will be copied to
-the X selection buffer.
+arbitrary rectangle. Selected text can be copied to the clipboard
+(with the edit/copy menu item). On X11, selected text will be
+available in the X selection buffer.
.PP
.SS Links
+When the mouse is over a hyperlink, the link target will be shown in a
+popup near the bottom of the window.
+.PP
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 call an external
-command (see the
-.B WEB BROWSERS
-section below).
+you click \'ok', execute the program. URL links are opened in a
+system-dependent way. (On UNIX, Qt uses the $BROWSER environment
+variable.)
+.PP
+.SS Mouse bindings
+The left mouse button is used to select text (see above).
+.PP
+Clicking on a link with the middle button opens the link in a new tab.
.PP
-.SS Panning
Dragging the mouse with the middle button held down pans the window.
.PP
+The right mouse button opens a popup menu (see
+.BR popupMenuCmd " in " xpdfrc (5)).
+.PP
.SS Key bindings
+This section lists the default key bindings. Bindings can be changed
+using the config file (see
+.BR xpdfrc (5)).
.TP
-.B o
+.B control-o
Open a new PDF file via a file requester.
.TP
-.B r
+.B control-r
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.
.TP
-.B control-L
-Redraw the current page.
-.TP
-.B control-W
-Close the current window.
-.TP
-.B f or control-F
-Find a text string.
+.B control-f
+Find a text string. This sets keyboard focus to the \'find' box.
.TP
.B control-G
Find next occurrence.
.TP
+.B control-C
+Copy selected text to the clipboard.
+.TP
.B control-P
Print.
.TP
-.B n
-Move to the next page. Scrolls to the top of the page, unless scroll
-lock is turned on.
+.BR control-0 " (control-zero)"
+Set the zoom factor to 125%.
.TP
-.B p
-Move to the previous page. Scrolls to the top of the page, unless
-scroll lock is turned on.
+.BR control-+ " (control-plus)"
+Zoom in (increment the zoom factor by 1).
.TP
-.BR <Space> " or " <PageDown> " or " <Next>
-Scroll down on the current page; if already at bottom, move to next
-page.
+.BR control-- " (control-minus)"
+Zoom out (decrement the zoom factor by 1).
.TP
-.BR <Backspace> " or " <Delete> " or " <PageUp> " or " <Previous>
-Scroll up on the current page; if already at top, move to previous
-page.
+.B control-s
+Save PDF via a file requester.
.TP
-.B v
-Move forward along the history path.
+.B control-t
+Open a new tab.
.TP
-.B b
-Move backward along the history path.
+.B control-n
+Open a new window.
.TP
-.B <Home>
-Scroll to top of current page.
+.B 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 window.
.TP
-.B <End>
-Scroll to bottom of current page.
+.B control-q
+Quit.
.TP
-.B control-<Home>
-Scroll to first page of document.
+.B control-<tab>
+Next tab.
.TP
-.B control-<End>
-Scroll to last page of document.
+.B control-shift-<tab>
+Previous tab.
.TP
-.B arrows
-Scroll the current page.
+.B control-?
+Help.
.TP
-.B g
-Activate the page number text field ("goto page").
+.B alt-<left-arrow>
+Go backward along the history path.
.TP
-.B 0
-Set the zoom factor to 125%.
+.B alt-<right-arrow>
+Go forward along the history path.
.TP
-.B +
-Zoom in (increment the zoom factor by 1).
+.B home
+Go to the top left of current page.
.TP
-.B -
-Zoom out (decrement the zoom factor by 1).
+.B control-<home>
+Go to the first page.
+.TP
+.B end
+Go to the bottom right of current page.
+.TP
+.B control-<end>
+Go to the last page.
+.TP
+.BR <space> " or " <PageDown>
+Scroll down on the current page; if already at bottom, move to next
+page.
+.TP
+.BR control-<PageDown> " or " control-<down-arrow>
+Go to the next page. If <ScrollLock> is active, this maintains the
+relative position on the page.
+.TP
+.B <PageUp>
+Scroll up on the current page; if already at top, move to previous
+page.
+.TP
+.BR control-<PageUp> " or " control-<up-arrow>
+Go to the previous page. If <ScrollLock> is active, this maintains
+the relative position on the page.
+.TP
+.B <esc>
+Exit full-screen mode.
+.TP
+.B arrows
+Scroll the current page.
+.TP
+.B g
+Set keyboard focus to the page number entry box.
.TP
.B z
-Set the zoom factor to 'page' (fit page to window).
+Set the zoom factor to \'page' (fit page to window).
.TP
.B w
-Set the zoom factor to 'width' (fit page width to window).
-.TP
-.B alt-F
-Toggle full-screen mode.
-.TP
-.B q
-Quit xpdf.
-.SH "WEB BROWSERS"
-If you want to run xpdf automatically from netscape or mosaic (and
-probably other browsers) when you click on a link to a PDF file, you
-need to edit (or create) the files
-.I .mime.types
-and
-.I .mailcap
-in your home directory. In
-.I .mime.types
-add the line:
-.PP
-.RS
-application/pdf pdf
-.RE
-.PP
-In
-.I .mailcap
-add the lines:
-.PP
-.RS
-# Use xpdf to view PDF files.
-.RE
-.RS
-application/pdf; xpdf \-q %s
-.RE
-.PP
-Make sure that xpdf is on your executable search path.
+Set the zoom factor to \'width' (fit page width to window).
+.SH Full-screen mode
+Xpdf can be placed into full-screen mode via the
+.B \-fullscreen
+command line option, the \'full screen' menu item, or a binding to the
+.B fullScreenMode
+or
+.BR toggleFullScreenMode command .
.PP
-When you click on a URL link in a PDF file, xpdf will execute the
-command specified by the urlCommand config file option, replacing an
-occurrence of \'%s' with the URL. For example, to call netscape with
-the URL, add this line to your config file:
+Entering full-screen mode automatically switches to single-page view
+mode and to the fit-page zoom factor.
.PP
-.RS
-urlCommand "netscape \-remote 'openURL(%s)'"
-.RE
+Full-screen mode can be exited via the default <esc> key binding,
+or via a binding to the
+.B windowMode
+or
+.BR toggleFullScreenMode command .
.SH COMMANDS
-Xpdf's key and mouse bindings are user-configurable, using the bind and
-unbind options in the config file (see
+Xpdf's key and mouse bindings are user-configurable, using the bind
+and unbind commands in the config file (see
.BR xpdfrc (5)).
The bind command allows you to bind a key or mouse button to a
sequence of one or more commands.
-.SS Available Commands
+.PP
The following commands are supported:
.TP
-.BI gotoPage( page )
-Go to the specified page.
+.B about
+Open the \'about' dialog.
.TP
-.BI gotoPageNoScroll( page )
-Go to the specified page, with the current relative scroll position.
+.B blockSelectMode
+Set block selection mode. In this mode, the selection is a simple
+rectangle. Any part of the page can be selected, regardless of the
+content on the page.
.TP
-.BI gotoDest( dest )
-Go to a named destination.
+.B closeSidebar
+Close the sidebar.
.TP
-.B gotoLastPage
-Go to the last page in the PDF file.
+.B closeSidebarMoveResizeWin
+Close the sidebar, resizing the window so that the document size
+doesn't change, and moving the window so that the document stays in
+the same place on the screen.
.TP
-.B gotoLastPageNoScroll
-Go to the last page in the PDF file, with the current relative scroll
-position.
+.B closeSidebarResizeWin
+Close the sidebar, resizing the window so that the document size
+doesn't change.
.TP
-.B nextPage
-Go to the next page.
+.B closeTabOrQuit
+Close the tab. If this was the last open tab, close the window. If
+this was the last window open, quit.
.TP
-.B nextPageNoScroll
-Go to the next page, with the current relative scroll position.
+.B closeWindowOrQuit
+Close the window. If this was the last open window, quit.
.TP
-.B prevPage
-Go to the previous page.
+.B continuousMode
+Switch to continuous view mode.
.TP
-.B prevPageNoScroll
-Go to the previous page, with the current relative scroll position.
+.B copy
+Copy selected text to the clipboard.
.TP
-.B pageUp
-Scroll up by one screenful.
+.B endPan
+End a pan operation.
.TP
-.B pageDown
-Scroll down by one screenful.
+.B endSelection
+End a selection.
.TP
-.BI scrollLeft( n )
-Scroll left by
-.I n
-pixels.
+.B find
+Set keyboard focus to the \'find' box.
.TP
-.BI scrollRight( n )
-Scroll right by
-.I n
-pixels.
+.B findFirst
+Find the first occurrence of the search string.
.TP
-.BI scrollUp( n )
-Scroll up by
-.I n
-pixels.
+.B findNext
+Find the next occurrence of the search string.
.TP
-.BI scrollDown( n )
-Scroll down by
-.I n
-pixels.
+.B findPrevious
+Find the previous occurrence of the search string.
.TP
-.BI scrollUpPrevPage( n )
-Scroll up by
-.I n
-pixels, moving to the previous page if appropriate.
+.B focusToDocWin
+Set keyboard focus to the main document window.
.TP
-.BI scrollDownPrevPage( n )
-Scroll down by
-.I n
-pixels, moving to the next page if appropriate.
+.B focusToPageNum
+Set keyboard focus to the page number text box.
.TP
-.B scrollToTopEdge
-Scroll to the top edge of the current page, with no horizontal
-movement.
+.B followLink
+Follow a hyperlink (does nothing if the mouse is not over a link).
.TP
-.B scrollToBottomEdge
-Scroll to the bottom edge of the current page, with no horizontal
-movement.
+.B followLinkInNewTab
+Follow a hyperlink, opening PDF files in a new tab (does nothing if
+the mouse is not over a link). For links to non-PDF files, this
+command is identical to followLink.
.TP
-.B scrollToLeftEdge
-Scroll to the left edge of the current page, with no vertical
-movement.
+.B followLinkInNewTabNoSel
+Same as followLinkInNewTab, but does nothing if there is a non-empty
+selection. (This is useful as a mouse button binding.)
.TP
-.B scrollToRightEdge
-Scroll to the right edge of the current page, with no vertical
-movement.
+.B followLinkInNewWin
+Follow a hyperlink, opening PDF files in a new window (does nothing if
+the mouse is not over a link). For links to non-PDF files, this
+command is identical to followLink.
.TP
-.B scrollToTopLeft
-Scroll to the top-left corner of the current page.
+.B followLinkInNewWinNoSel
+Same as followLinkInNewWin, but does nothing if there is a non-empty
+selection. (This is useful as a mouse button binding.)
.TP
-.B scrollToBottomRight
-Scroll to the bottom-right corner of the current page.
+.B followLinkNoSel
+Same as followLink, but does nothing if there is a non-empty selection.
+(This is useful as a mouse button binding.)
.TP
-.B goForward
-Move forward along the history path.
+.B fullScreenMode
+Go to full-screen mode.
.TP
.B goBackward
Move backward along the history path.
.TP
-.BI zoomPercent( z )
-Set the zoom factor to
-.IR z %.
+.B goForward
+Move forward along the history path.
.TP
-.B zoomFitPage
-Set the zoom factor to fit-page.
+.BI gotoDest( dest )
+Go to a named destination.
.TP
-.B zoomFitWidth
-Set the zoom factor to fit-width.
+.B gotoLastPage
+Go to the last page in the PDF file.
.TP
-.B zoomIn
-Zoom in - go to the next higher zoom factor.
+.BI gotoPage( page )
+Go to the specified page.
.TP
-.B zoomOut
-Zoom out - go the next lower zoom factor.
+.BI help
+Open the help URL.
.TP
-.B rotateCW
-Rotate the page 90 degrees clockwise.
+.B horizontalContinuousMode
+Switch to horizontal continuous view mode.
.TP
-.B rotateCCW
-Rotate the page 90 degrees counterclockwise.
+.B linearSelectMode
+Set linear selection mode. In this mode, the selection follows text.
+Non-text regions cannot be selected.
.TP
-.BI setSelection( pg , ulx , uly , lrx , lry )
-Set the selection to the specified coordinates on the specified page.
+.B newTab
+Open an empty new tab.
.TP
-.B continuousMode
-Go to continuous view mode.
+.B newWindow
+Open an empty new window.
.TP
-.B singlePageMode
-Go to single-page view mode.
+.B nextPage
+Go to the next page.
.TP
-.B toggleContinuousMode
-Toggle between continuous and single page view modes.
+.B nextPageNoScroll
+Go to the next page, with the current relative scroll position.
.TP
-.B fullScreenMode
-Go to full-screen mode.
+.B nextTab
+Switch to the next tab.
.TP
-.B windowMode
-Go to window (non-full-screen) mode.
+.B open
+Open a PDF file in this tab, using the open dialog.
.TP
-.B toggleFullScreenMode
-Toggle between full-screen and window modes.
+.B openErrorWindow
+Open the error window.
.TP
-.B open
-Open a PDF file in this window, using the open dialog.
+.B openSidebar
+Open the sidebar.
.TP
-.B openInNewWin
-Open a PDF file in a new window, using the open dialog.
+.B openSidebarMoveResizeWin
+Open the sidebar, resizing the window so that the document size
+doesn't change, and moving the window so that the document stays in
+the same place on the screen.
.TP
-.BI openFile( file )
-Open a specified PDF file in this window.
+.B openSidebarResizeWin
+Open the sidebar, resizing the window so that the document size
+doesn't change.
.TP
-.BI openFileInNewWin( file )
-Open a specified PDF file in a new window.
+.B pageDown
+Scroll down by one screenful.
.TP
-.BI openFileAtDest( file , dest )
-Open a specified PDF file in this window and go to a named
-destination.
+.B pageUp
+Scroll up by one screenful.
.TP
-.BI openFileAtDestInNewWin( file , dest )
-Open a specified PDF file in a new window and go to a named
-destination.
+.B postPopupMenu
+Display the popup menu.
.TP
-.B reload
-Reload the current PDF file.
+.B prevPage
+Go to the previous page.
.TP
-.B redraw
-Redraw the window.
+.B prevPageNoScroll
+Go to the previous page, with the current relative scroll position.
.TP
-.B raise
-Raise the window to the front.
+.B prevTab
+Switch to the previous tab.
.TP
-.B closeWindow
-Close the window. If this was the last open window, clear the window,
-but don't quit from Xpdf.
+.B print
+Open the \'print' dialog.
.TP
-.B closeWindowOrQuit
-Close the window. If this was the last open window, quit from Xpdf.
+.B quit
+Quit from xpdf.
+.TP
+.B reload
+Reload the current PDF file.
+.TP
+.B rotateCCW
+Rotate the page 90 degrees counterclockwise.
+.TP
+.B rotateCW
+Rotate the page 90 degrees clockwise.
.TP
.BI run( external-command-string )
Run an external command. The following escapes are allowed in the
@@ -675,14 +580,26 @@ command must be quoted in the xpdfrc file:
.fi
.TP
-.B openOutline
-Open the outline pane.
+.B saveAs
+Save PDF via a file requester.
.TP
-.B closeOutline
-Close the outline pane.
+.B saveImage
+Open the \'save image' dialog.
.TP
-.B toggleOutline
-Toggle the outline pane between open and closed.
+.BI scrollDown( n )
+Scroll down by
+.I n
+pixels.
+.TP
+.BI scrollDownPrevPage( n )
+Scroll down by
+.I n
+pixels, moving to the next page if appropriate.
+.TP
+.BI scrollLeft( n )
+Scroll left by
+.I n
+pixels.
.TP
.BI scrollOutlineDown( n )
Scroll the outline down by
@@ -694,163 +611,105 @@ Scroll the outline up by
.I n
increments.
.TP
-.B focusToDocWin
-Set the keyboard focus to the main document window.
+.BI scrollRight( n )
+Scroll right by
+.I n
+pixels.
.TP
-.B focusToPageNum
-Set the keyboard focus to the page number text box.
+.B scrollToBottomEdge
+Scroll to the bottom edge of the current page, with no horizontal
+movement.
.TP
-.B find
-Open the 'find' dialog.
+.B scrollToBottomRight
+Scroll to the bottom-right corner of the current page.
.TP
-.B findNext
-Finds the next occurrence of the search string (no dialog).
+.B scrollToLeftEdge
+Scroll to the left edge of the current page, with no vertical
+movement.
.TP
-.B print
-Open the 'print' dialog.
+.B scrollToRightEdge
+Scroll to the right edge of the current page, with no vertical
+movement.
.TP
-.B about
-Open the 'about' dialog.
+.B scrollToTopEdge
+Scroll to the top edge of the current page, with no horizontal
+movement.
.TP
-.B quit
-Quit from xpdf.
-.PP
-The following commands depend on the current mouse position:
+.B scrollToTopLeft
+Scroll to the top-left corner of the current page.
.TP
-.B startSelection
-Start a selection, which will be extended as the mouse moves.
+.BI scrollUp( n )
+Scroll up by
+.I n
+pixels.
.TP
-.B endSelection
-End a selection.
+.BI scrollUpPrevPage( n )
+Scroll up by
+.I n
+pixels, moving to the previous page if appropriate.
+.TP
+.BI setSelection( pg , ulx , uly , lrx , lry )
+Set the selection to the specified coordinates on the specified page.
+.TP
+.B sideBySideContinuousMode
+Switch to side-by-side continuous view mode.
+.TP
+.B sideBySideSingleMode
+Switch to side-by-side two-page view mode.
+.TP
+.B singlePageMode
+Switch to single-page view mode.
.TP
.B startPan
-Start a pan, which will scroll the document as the mouse moves
+Start a pan operation at the current mouse position, which will scroll
+the document as the mouse moves.
.TP
-.B endPan
-End a pan.
+.B startSelection
+Start a selection at the current mouse position, which will be
+extended as the mouse moves.
.TP
-.B postPopupMenu
-Display the popup menu.
+.B toggleContinuousMode
+Toggle between continuous and single page view modes.
.TP
-.B followLink
-Follow a hyperlink (does nothing if the mouse is not over a link).
+.B toggleFullScreenMode
+Toggle between full-screen and window modes.
.TP
-.B followLinkInNewWin
-Follow a hyperlink, opening PDF files in a new window (does nothing if
-the mouse is not over a link). For links to non-PDF files, this
-command is identical to followLink.
+.B toggleSelectMode
+Toggle between block and linear selection mode.
.TP
-.B followLinkNoSel
-Same as followLink, but does nothing if there is a non-empty selection.
-(This is useful as a mouse button binding.)
+.B toggleSidebar
+Toggle the sidebar between open and closed.
.TP
-.B followLinkInNewWinNoSel
-Same as followLinkInNewWin, but does nothing if there is a non-empty
-selection. (This is useful as a mouse button binding.)
-.SS Default Bindings
-The default mouse bindings are as follows:
-.nf
-
- bind mousePress1 any startSelection
- bind mouseRelease1 any endSelection followLinkNoSel
- bind mousePress2 any startPan
- bind mouseRelease2 any endPan
- bind mousePress3 any postPopupMenu
- bind mousePress4 any scrollUpPrevPage(16)
- bind mousePress5 any scrollDownNextPage(16)
- bind mousePress6 any scrollLeft(16)
- bind mousePress7 any scrollRight(16)
-
-.fi
-The default key bindings are as follows:
-.nf
-
- bind ctrl-home any gotoPage(1)
- bind home any scrollToTopLeft
- bind ctrl-end any gotoLastPage
- bind end any scrollToBottomRight
- bind pgup any pageUp
- bind backspace any pageUp
- bind delete any pageUp
- bind pgdn any pageDown
- bind space any pageDown
- bind left any scrollLeft(16)
- bind right any scrollRight(16)
- bind up any scrollUp(16)
- bind down any scrollDown(16)
- bind o any open
- bind O any open
- bind r any reload
- bind R any reload
- bind f any find
- bind F any find
- bind ctrl-f any find
- bind ctrl-g any findNext
- bind ctrl-p any print
- bind n scrLockOff nextPage
- bind N scrLockOff nextPage
- bind n scrLockOn nextPageNoScroll
- bind N scrLockOn nextPageNoScroll
- bind p scrLockOff prevPage
- bind P scrLockOff prevPage
- bind p scrLockOn prevPageNoScroll
- bind P scrLockOn prevPageNoScroll
- bind v any goForward
- bind b any goBackward
- bind g any focusToPageNum
- bind 0 any zoomPercent(125)
- bind + any zoomIn
- bind - any zoomOut
- bind z any zoomFitPage
- bind w any zoomFitWidth
- bind alt-f any toggleFullScreenMode
- bind ctrl-l any redraw
- bind ctrl-w any closeWindowOrQuit
- bind ? any about
- bind q any quit
- bind Q any quit
-
-.fi
-Previous versions of xpdf included a "viKeys" X resource. It is no
-longer available, but the following bindings are equivalent:
-.nf
-
- bind h any scrollLeft(16)
- bind l any scrollRight(16)
- bind k any scrollUp(16)
- bind j any scrollDown(16)
-
-.fi
-.SH "REMOTE SERVER MODE"
-Xpdf can be started in remote server mode by specifying a server name
-(in addition to the file name and page number). For example:
-.PP
-.RS
-xpdf \-remote myServer file.pdf
-.RE
-.PP
-If there is currently no xpdf running in server mode with the name
-\'myServer', a new xpdf window will be opened. If another command:
-.PP
-.RS
-xpdf \-remote myServer another.pdf 9
-.RE
-.PP
-is issued, a new copy of xpdf will not be started. Instead, the first
-xpdf (the server) will load
-.I another.pdf
-and display page nine. If the file name is the same:
-.PP
-.RS
-xpdf \-remote myServer another.pdf 4
-.RE
-.PP
-the xpdf server will simply display the specified page.
-.PP
-The \-raise option tells the server to raise its window; it can be
-specified with or without a file name and page number.
-.PP
-The \-quit option tells the server to close its window and exit.
+.B toggleSidebarMoveResizeWin
+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.
+.TP
+.B toggleSidebarResizeWin
+Toggle the sidebar between open and closed, resizing the window so
+that the document size doesn't change.
+.TP
+.B windowMode
+Go to window (non-full-screen) mode.
+.TP
+.B zoomFitPage
+Set the zoom factor to fit-page.
+.TP
+.B zoomFitWidth
+Set the zoom factor to fit-width.
+.TP
+.B zoomIn
+Zoom in - go to the next higher zoom factor.
+.TP
+.B zoomOut
+Zoom out - go the next lower zoom factor.
+.TP
+.BI zoomPercent( z )
+Set the zoom factor to
+.IR z %.
+.TP
+.B zoomToSelection
+Zoom to the current selection.
.SH EXIT CODES
The Xpdf tools use the following exit codes:
.TP
@@ -869,7 +728,7 @@ Error related to PDF permissions.
99
Other error.
.SH AUTHOR
-The xpdf software and documentation are copyright 1996-2014 Glyph &
+The xpdf software and documentation are copyright 1996-2017 Glyph &
Cog, LLC.
.SH "SEE ALSO"
.BR pdftops (1),
@@ -883,4 +742,4 @@ Cog, LLC.
.BR pdfimages (1),
.BR xpdfrc (5)
.br
-.B http://www.foolabs.com/xpdf/
+.B http://www.xpdfreader.com/
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat b/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat
index 965b3106ed1..cf76e2490a5 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/xpdf.cat
@@ -1,31 +1,37 @@
-xpdf(1) xpdf(1)
+xpdf(1) General Commands Manual xpdf(1)
NAME
- xpdf - Portable Document Format (PDF) file viewer for X (version 3.04)
+ xpdf - Portable Document Format (PDF) file viewer (version 4.00)
SYNOPSIS
- xpdf [options] [PDF-file [page | +dest]]
+ xpdf [options] [PDF-file [:page | +dest]] ...
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
- PDF software.) Xpdf runs under the X Window System on UNIX, VMS, and
- OS/2.
+ PDF software.) Xpdf uses the Qt GUI toolkit and runs on Unix, OS X,
+ and Windows.
- To run xpdf, simply type:
+ To run xpdf, type:
xpdf file.pdf
where file.pdf is your PDF file. The file name can be followed by a
- number specifying the page which should be displayed first, e.g.:
+ page number to be displayed, prefixed with a colon:
- xpdf file.pdf 18
+ xpdf file.pdf :18
- You can also give a named destination, prefixed with '+' in place of
- the page number. (This is only useful with PDF files that provide
- named destination targets.)
+ or by a named destination, prefixed with '+' (this is only useful with
+ PDF files that provide named destination targets):
+
+ xpdf file.pdf +destinationA
+
+ If you specify multiple files, they will each be opened in a separate
+ tab:
+
+ xpdf file1.pdf file2.pdf :18 file3.pdf
You can also start xpdf without opening any files:
@@ -39,57 +45,46 @@ CONFIGURATION FILE
man page for details.
OPTIONS
- Many of the following options can be set with configuration file com-
- mands or X resources. These are listed in square brackets with the
- description of the corresponding command line option.
+ The following command line options are available. All command line
+ options must come before any PDF files to be opened.
- -g geometry
- Set the initial window geometry. (-geometry is equivalent.) [X
- resource: xpdf.geometry]
+ Many of the options can be set with configuration file commands. These
+ are listed in square brackets with the description of the corresponding
+ command line option.
+
+ -geometry geometry
+ Set the initial window geometry.
-title title
Set the window title. By default, the title will be "xpdf:
- foo.pdf". [X resource: xpdf.title]
-
- -cmap Install a private colormap. This is ignored on TrueColor visu-
- als. [X resource: xpdf.installCmap]
-
- -rgb number
- Set the size of largest RGB cube xpdf will try to allocate. The
- default is 5 (for a 5x5x5 cube); set to a smaller number to con-
- serve color table entries. This is ignored with private col-
- ormaps and on TrueColor visuals. [X resource: xpdf.rgbCubeSize]
+ 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
- paper color to default to black. [X resource: xpdf.reverseV-
- ideo]
+ paper color to default to black.
-papercolor color
Set the "paper color", i.e., the background of the page display.
- This will not work too well with PDF files that do things like
- filling in white behind the text. [X resource: xpdf.paperColor]
+ 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
Set the matte color, i.e., the color used for background outside
- the actual page area. (There is a separate setting,
- xpdf.fullScreenMatteColor, for full-screen mode.) [X resource:
- xpdf.matteColor]
+ the actual page area. The color can be #RRGGBB (hexadecimal) or
+ 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:
+ 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
- width to the window width. [config file: initialZoom; or X
- resource: xpdf.initialZoom]
-
- -cont Start in continuous view mode, i.e., with one vertical scroll
- bar for the whole document. [config file: continuousView]
-
- -freetype yes | no
- Enable or disable FreeType (a TrueType / Type 1 font raster-
- izer). This defaults to "yes". [config file: enableFreeType]
+ 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".
@@ -99,70 +94,26 @@ OPTIONS
Enable or disable vector anti-aliasing. This defaults to "yes".
[config file: vectorAntialias]
- -ps PS-file
- Set the default file name for PostScript output (i.e., the name
- which will appear in the print dialog). This can also be of the
- form '|command' to pipe the PostScript through a command. [con-
- fig file: psFile]
-
- -paper size
- Set the paper size to one of "letter", "legal", "A4", or "A3".
- This can also be set to "match", which will set the paper size
- to match the size specified in the PDF file. [config file:
- psPaperSize]
-
- -paperw size
- Set the paper width, in points. [config file: psPaperSize]
-
- -paperh size
- Set the paper height, in points. [config file: psPaperSize]
-
- -level1
- Generate Level 1 PostScript. The resulting PostScript files
- will be significantly larger (if they contain images), but will
- print on Level 1 printers. This also converts all images to
- black and white. [config file: psLevel]
-
-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]
- -eol unix | dos | mac
- Sets the end-of-line convention to use for text output. [config
- file: textEOL]
-
- -opw password
- Specify the owner password for the PDF file. Providing this
- will bypass all security restrictions.
-
- -upw password
- Specify the user password for the PDF file.
+ -pw password
+ 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 name
- Start/contact xpdf remote server with specified name (see the
- REMOTE SERVER MODE section below).
-
- -exec command
- Execute a command (see the COMMANDS section below) in an xpdf
- remote server window (with -remote only).
-
- -reload
- Reload xpdf remote server window (with -remote only).
-
- -raise Raise xpdf remote server window (with -remote only).
-
- -quit Kill xpdf remote server (with -remote only).
+ -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]
- -q Don't print any messages or errors. [config file: errQuiet]
-
-cfg config-file
Read config-file in place of ~/.xpdfrc or the system-wide config
file.
@@ -171,388 +122,385 @@ OPTIONS
-h Print usage information. (-help and --help are equivalent.)
- Several other standard X options and resources will work as expected:
-
- -display display
- [X resource: xpdf.display]
-
- -fg color
- (-foreground is equivalent.) [X resource: xpdf*Foreground]
-
- -bg color
- (-background is equivalent.) [X resource: xpdf*Background]
-
- -font font
- (-fn is equivalent.) [X resource: xpdf*fontList]
-
- The color and font options only affect the user interface elements, not
- the PDF display (the 'paper').
-
- The following X resources do not have command line option equivalents:
-
- xpdf.toolTipEnable
- Enables (if set to true) or disables (if set to false) the tool-
- tips on the toolbar buttons.
-
- xpdf.fullScreenMatteColor
- Sets the matte color to be used in full-screen mode. The
- default setting is "black".
-
CONTROLS
- On-screen controls, at the bottom of the xpdf window
- left/right arrow buttons
- Move to the previous/next page.
-
- double left/right arrow buttons
- Move backward or forward by ten pages.
-
- dashed left/right arrow buttons
- Move backward or forward along the history path.
-
- 'Page' entry box
+ 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.
+ left/right arrow buttons
+ Go backward or forward along the history path.
+
+ zoom out/in buttons
+ Zoom out or in (i.e., change magnification) incrementally.
+
zoom popup menu
Change the zoom factor (see the description of the -z option
above).
- binoculars button
- Find a text string.
+ fit width button
+ Change the zoom factor to fit the page width to the window
+ width.
- print button
- Bring up a dialog for generating a PostScript file. The dialog
- has options to set the pages to be printed and the PostScript
- file name. The file name can be '-' for stdout or '|command' to
- pipe the PostScript through a command, e.g., '|lpr'.
+ fit page button
+ Change the zoom factor to fit the page to the window size.
- '?' button
- Bring up the 'about xpdf' window.
+ 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.
- link info
- The space between the '?' and 'Quit' buttons is used to show the
- URL or external file name when the mouse is over a link.
+ 'find' box
+ Find a text string. Click in the box to activate it, type a
+ search string, then hit return.
- 'Quit' button
- Quit xpdf.
+ find next button
+ Find the next occurrence of the search string.
- Menu
- Pressing the right mouse button will post a popup menu with the follow-
- ing commands:
+ find previous button
+ Find the previous occurrence of the search string.
- Open...
- Open a new PDF file via a file requester.
+ find settings button
+ Display the current find settings: case sensitive (on/off), find
+ whole words (on/off).
- Open in new window...
- Create a new window and open a new PDF file via a file
- requester.
+ Menu bar
+ The menu bar is above the tool bar. The menu items should be self-
+ explanatory.
- Reload 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.
+ Tab list
+ The tab list is on the left, just below the tool bar. It lists all
+ open tabs.
- Save as...
- Save the current file via a file requester.
+ Outline/layers/attachments pane
+ This pane is on the left, below the tab list. The popup allows you to
+ select from outline, layers, or attachments.
- Continuous view
- Toggles between single page and continuous view modes.
-
- Rotate counterclockwise
- Rotate the page 90 degrees counterclockwise.
+ The outline is a tree-like structure of bookmarks that allows moving
+ within the PDF file. Not all PDF files have outlines.
- Rotate clockwise
- Rotate the page 90 degrees clockwise. The two rotate commands
- are intended primarily for PDF files where the rotation isn't
- correctly specified in the file.
+ Layers (a.k.a. optional content) allow parts of the PDF content to be
+ shown or hidden. Not all PDF files have layers.
- Zoom to selection
- Zoom in to the currently selected rectangle.
-
- Close Close the current window. If this is the only open window, the
- document is closed, but the window is left open (i.e., this menu
- command won't quit xpdf).
-
- Quit Quit xpdf.
-
- Outline
- If the PDF contains an outline (a.k.a., bookmarks), there will be an
- outline pane on the left side of the window. The width of the outline
- pane is adjustable with a vertical split bar via the knob near its bot-
- tom end.
+ 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. Any text inside this rectangle will be copied to
- the X selection buffer.
+ 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
+ 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 call an external command (see the
- WEB BROWSERS section below).
+ 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
+ The left mouse button is used to select text (see above).
+
+ Clicking on a link with the middle button opens the link in a new tab.
- Panning
Dragging the mouse with the middle button held down pans the window.
- Key bindings
- o Open a new PDF file via a file requester.
+ The right mouse button opens a popup menu (see popupMenuCmd in
+ xpdfrc(5)).
- r 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.
+ Key bindings
+ This section lists the default key bindings. Bindings can be changed
+ using the config file (see xpdfrc(5)).
- control-L
- Redraw the current page.
+ control-o
+ Open a new PDF file via a file requester.
- control-W
- Close the current window.
+ control-r
+ 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.
- f or control-F
- Find a text string.
+ control-f
+ Find a text string. This sets keyboard focus to the 'find' box.
control-G
Find next occurrence.
+ control-C
+ Copy selected text to the clipboard.
+
control-P
Print.
- n Move to the next page. Scrolls to the top of the page, unless
- scroll lock is turned on.
+ control-0 (control-zero)
+ Set the zoom factor to 125%.
- p Move to the previous page. Scrolls to the top of the page,
- unless scroll lock is turned on.
+ control-+ (control-plus)
+ Zoom in (increment the zoom factor by 1).
- <Space> or <PageDown> or <Next>
- Scroll down on the current page; if already at bottom, move to
- next page.
+ control-- (control-minus)
+ Zoom out (decrement the zoom factor by 1).
- <Backspace> or <Delete> or <PageUp> or <Previous>
- Scroll up on the current page; if already at top, move to previ-
- ous page.
+ control-s
+ Save PDF via a file requester.
- v Move forward along the history path.
+ control-t
+ Open a new tab.
- b Move backward along the history path.
+ control-n
+ Open a new window.
- <Home> Scroll to top of current page.
+ 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-
+ dow.
- <End> Scroll to bottom of current page.
+ control-q
+ Quit.
- control-<Home>
- Scroll to first page of document.
+ control-<tab>
+ Next tab.
- control-<End>
- Scroll to last page of document.
+ control-shift-<tab>
+ Previous tab.
- arrows Scroll the current page.
+ control-?
+ Help.
- g Activate the page number text field ("goto page").
+ alt-<left-arrow>
+ Go backward along the history path.
- 0 Set the zoom factor to 125%.
+ alt-<right-arrow>
+ Go forward along the history path.
- + Zoom in (increment the zoom factor by 1).
+ home Go to the top left of current page.
- - Zoom out (decrement the zoom factor by 1).
+ control-<home>
+ Go to the first page.
- z Set the zoom factor to 'page' (fit page to window).
+ end Go to the bottom right of current page.
- w Set the zoom factor to 'width' (fit page width to window).
+ control-<end>
+ Go to the last page.
- alt-F Toggle full-screen mode.
+ <space> or <PageDown>
+ Scroll down on the current page; if already at bottom, move to
+ next page.
- q Quit xpdf.
+ control-<PageDown> or control-<down-arrow>
+ Go to the next page. If <ScrollLock> is active, this maintains
+ the relative position on the page.
-WEB BROWSERS
- If you want to run xpdf automatically from netscape or mosaic (and
- probably other browsers) when you click on a link to a PDF file, you
- need to edit (or create) the files .mime.types and .mailcap in your
- home directory. In .mime.types add the line:
+ <PageUp>
+ Scroll up on the current page; if already at top, move to previ-
+ ous page.
- application/pdf pdf
+ control-<PageUp> or control-<up-arrow>
+ Go to the previous page. If <ScrollLock> is active, this main-
+ tains the relative position on the page.
- In .mailcap add the lines:
+ <esc> Exit full-screen mode.
- # Use xpdf to view PDF files.
- application/pdf; xpdf -q %s
+ arrows Scroll the current page.
- Make sure that xpdf is on your executable search path.
+ g Set keyboard focus to the page number entry box.
- When you click on a URL link in a PDF file, xpdf will execute the com-
- mand specified by the urlCommand config file option, replacing an
- occurrence of '%s' with the URL. For example, to call netscape with
- the URL, add this line to your config file:
+ z Set the zoom factor to 'page' (fit page to window).
- urlCommand "netscape -remote 'openURL(%s)'"
+ 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
+ fullScreenMode or toggleFullScreenModecommand.
+
+ 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
+ via a binding to the windowMode or toggleFullScreenModecommand.
COMMANDS
Xpdf's key and mouse bindings are user-configurable, using the bind and
- unbind options 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.
- Available Commands
The following commands are supported:
- gotoPage(page)
- Go to the specified page.
+ about Open the 'about' dialog.
- gotoPageNoScroll(page)
- Go to the specified page, with the current relative scroll posi-
- tion.
+ blockSelectMode
+ Set block selection mode. In this mode, the selection is a sim-
+ ple rectangle. Any part of the page can be selected, regardless
+ of the content on the page.
- gotoDest(dest)
- Go to a named destination.
+ closeSidebar
+ Close the sidebar.
- gotoLastPage
- Go to the last page in the PDF file.
+ closeSidebarMoveResizeWin
+ Close the sidebar, resizing the window so that the document size
+ doesn't change, and moving the window so that the document stays
+ in the same place on the screen.
- gotoLastPageNoScroll
- Go to the last page in the PDF file, with the current relative
- scroll position.
+ closeSidebarResizeWin
+ Close the sidebar, resizing the window so that the document size
+ doesn't change.
- nextPage
- Go to the next page.
+ closeTabOrQuit
+ Close the tab. If this was the last open tab, close the window.
+ If this was the last window open, quit.
- nextPageNoScroll
- Go to the next page, with the current relative scroll position.
+ closeWindowOrQuit
+ Close the window. If this was the last open window, quit.
- prevPage
- Go to the previous page.
+ continuousMode
+ Switch to continuous view mode.
- prevPageNoScroll
- Go to the previous page, with the current relative scroll posi-
- tion.
+ copy Copy selected text to the clipboard.
- pageUp Scroll up by one screenful.
+ endPan End a pan operation.
- pageDown
- Scroll down by one screenful.
+ endSelection
+ End a selection.
- scrollLeft(n)
- Scroll left by n pixels.
+ find Set keyboard focus to the 'find' box.
- scrollRight(n)
- Scroll right by n pixels.
+ findFirst
+ Find the first occurrence of the search string.
- scrollUp(n)
- Scroll up by n pixels.
+ findNext
+ Find the next occurrence of the search string.
- scrollDown(n)
- Scroll down by n pixels.
+ findPrevious
+ Find the previous occurrence of the search string.
- scrollUpPrevPage(n)
- Scroll up by n pixels, moving to the previous page if appropri-
- ate.
+ focusToDocWin
+ Set keyboard focus to the main document window.
- scrollDownPrevPage(n)
- Scroll down by n pixels, moving to the next page if appropriate.
+ focusToPageNum
+ Set keyboard focus to the page number text box.
- scrollToTopEdge
- Scroll to the top edge of the current page, with no horizontal
- movement.
+ followLink
+ Follow a hyperlink (does nothing if the mouse is not over a
+ link).
- scrollToBottomEdge
- Scroll to the bottom edge of the current page, with no horizon-
- tal movement.
+ followLinkInNewTab
+ Follow a hyperlink, opening PDF files in a new tab (does nothing
+ if the mouse is not over a link). For links to non-PDF files,
+ this command is identical to followLink.
- scrollToLeftEdge
- Scroll to the left edge of the current page, with no vertical
- movement.
+ followLinkInNewTabNoSel
+ Same as followLinkInNewTab, but does nothing if there is a non-
+ empty selection. (This is useful as a mouse button binding.)
- scrollToRightEdge
- Scroll to the right edge of the current page, with no vertical
- movement.
+ followLinkInNewWin
+ Follow a hyperlink, opening PDF files in a new window (does
+ nothing if the mouse is not over a link). For links to non-PDF
+ files, this command is identical to followLink.
- scrollToTopLeft
- Scroll to the top-left corner of the current page.
+ followLinkInNewWinNoSel
+ Same as followLinkInNewWin, but does nothing if there is a non-
+ empty selection. (This is useful as a mouse button binding.)
- scrollToBottomRight
- Scroll to the bottom-right corner of the current page.
+ followLinkNoSel
+ Same as followLink, but does nothing if there is a non-empty
+ selection. (This is useful as a mouse button binding.)
- goForward
- Move forward along the history path.
+ fullScreenMode
+ Go to full-screen mode.
goBackward
Move backward along the history path.
- zoomPercent(z)
- Set the zoom factor to z%.
+ goForward
+ Move forward along the history path.
- zoomFitPage
- Set the zoom factor to fit-page.
+ gotoDest(dest)
+ Go to a named destination.
- zoomFitWidth
- Set the zoom factor to fit-width.
+ gotoLastPage
+ Go to the last page in the PDF file.
- zoomIn Zoom in - go to the next higher zoom factor.
+ gotoPage(page)
+ Go to the specified page.
- zoomOut
- Zoom out - go the next lower zoom factor.
+ help Open the help URL.
- rotateCW
- Rotate the page 90 degrees clockwise.
+ horizontalContinuousMode
+ Switch to horizontal continuous view mode.
- rotateCCW
- Rotate the page 90 degrees counterclockwise.
+ linearSelectMode
+ Set linear selection mode. In this mode, the selection follows
+ text. Non-text regions cannot be selected.
- setSelection(pg,ulx,uly,lrx,lry)
- Set the selection to the specified coordinates on the specified
- page.
+ newTab Open an empty new tab.
- continuousMode
- Go to continuous view mode.
+ newWindow
+ Open an empty new window.
- singlePageMode
- Go to single-page view mode.
+ nextPage
+ Go to the next page.
- toggleContinuousMode
- Toggle between continuous and single page view modes.
+ nextPageNoScroll
+ Go to the next page, with the current relative scroll position.
- fullScreenMode
- Go to full-screen mode.
+ nextTab
+ Switch to the next tab.
- windowMode
- Go to window (non-full-screen) mode.
+ open Open a PDF file in this tab, using the open dialog.
- toggleFullScreenMode
- Toggle between full-screen and window modes.
+ openErrorWindow
+ Open the error window.
- open Open a PDF file in this window, using the open dialog.
+ openSidebar
+ Open the sidebar.
- openInNewWin
- Open a PDF file in a new window, using the open dialog.
+ openSidebarMoveResizeWin
+ Open the sidebar, resizing the window so that the document size
+ doesn't change, and moving the window so that the document stays
+ in the same place on the screen.
- openFile(file)
- Open a specified PDF file in this window.
+ openSidebarResizeWin
+ Open the sidebar, resizing the window so that the document size
+ doesn't change.
- openFileInNewWin(file)
- Open a specified PDF file in a new window.
+ pageDown
+ Scroll down by one screenful.
- openFileAtDest(file,dest)
- Open a specified PDF file in this window and go to a named des-
- tination.
+ pageUp Scroll up by one screenful.
- openFileAtDestInNewWin(file,dest)
- Open a specified PDF file in a new window and go to a named des-
- tination.
+ postPopupMenu
+ Display the popup menu.
- reload Reload the current PDF file.
+ prevPage
+ Go to the previous page.
- redraw Redraw the window.
+ prevPageNoScroll
+ Go to the previous page, with the current relative scroll posi-
+ tion.
- raise Raise the window to the front.
+ prevTab
+ Switch to the previous tab.
- closeWindow
- Close the window. If this was the last open window, clear the
- window, but don't quit from Xpdf.
+ print Open the 'print' dialog.
- closeWindowOrQuit
- Close the window. If this was the last open window, quit from
- Xpdf.
+ quit Quit from xpdf.
+
+ reload Reload the current PDF file.
+
+ rotateCCW
+ Rotate the page 90 degrees counterclockwise.
+
+ rotateCW
+ Rotate the page 90 degrees clockwise.
run(external-command-string)
- Run an external command. The following escapes are allowed in
+ Run an external command. The following escapes are allowed in
the command string:
%f => PDF file name (or an empty string if no
@@ -577,20 +525,25 @@ COMMANDS
%k => y coordinate of the mouse pointer
%% => %
- The external command string will often contain spaces, so the
+ The external command string will often contain spaces, so the
whole command must be quoted in the xpdfrc file:
bind x "run(ls -l)"
- openOutline
- Open the outline pane.
+ saveAs Save PDF via a file requester.
- closeOutline
- Close the outline pane.
+ saveImage
+ Open the 'save image' dialog.
- toggleOutline
- Toggle the outline pane between open and closed.
+ scrollDown(n)
+ Scroll down by n pixels.
+
+ scrollDownPrevPage(n)
+ Scroll down by n pixels, moving to the next page if appropriate.
+
+ scrollLeft(n)
+ Scroll left by n pixels.
scrollOutlineDown(n)
Scroll the outline down by n increments.
@@ -598,148 +551,99 @@ COMMANDS
scrollOutlineUp(n)
Scroll the outline up by n increments.
- focusToDocWin
- Set the keyboard focus to the main document window.
+ scrollRight(n)
+ Scroll right by n pixels.
- focusToPageNum
- Set the keyboard focus to the page number text box.
+ scrollToBottomEdge
+ Scroll to the bottom edge of the current page, with no horizon-
+ tal movement.
- find Open the 'find' dialog.
+ scrollToBottomRight
+ Scroll to the bottom-right corner of the current page.
- findNext
- Finds the next occurrence of the search string (no dialog).
+ scrollToLeftEdge
+ Scroll to the left edge of the current page, with no vertical
+ movement.
- print Open the 'print' dialog.
+ scrollToRightEdge
+ Scroll to the right edge of the current page, with no vertical
+ movement.
- about Open the 'about' dialog.
+ scrollToTopEdge
+ Scroll to the top edge of the current page, with no horizontal
+ movement.
- quit Quit from xpdf.
+ scrollToTopLeft
+ Scroll to the top-left corner of the current page.
- The following commands depend on the current mouse position:
+ scrollUp(n)
+ Scroll up by n pixels.
- startSelection
- Start a selection, which will be extended as the mouse moves.
+ scrollUpPrevPage(n)
+ Scroll up by n pixels, moving to the previous page if appropri-
+ ate.
- endSelection
- End a selection.
+ setSelection(pg,ulx,uly,lrx,lry)
+ Set the selection to the specified coordinates on the specified
+ page.
+
+ sideBySideContinuousMode
+ Switch to side-by-side continuous view mode.
+
+ sideBySideSingleMode
+ Switch to side-by-side two-page view mode.
+
+ singlePageMode
+ Switch to single-page view mode.
startPan
- Start a pan, which will scroll the document as the mouse moves
+ Start a pan operation at the current mouse position, which will
+ scroll the document as the mouse moves.
- endPan End a pan.
+ startSelection
+ Start a selection at the current mouse position, which will be
+ extended as the mouse moves.
- postPopupMenu
- Display the popup menu.
+ toggleContinuousMode
+ Toggle between continuous and single page view modes.
- followLink
- Follow a hyperlink (does nothing if the mouse is not over a
- link).
+ toggleFullScreenMode
+ Toggle between full-screen and window modes.
- followLinkInNewWin
- Follow a hyperlink, opening PDF files in a new window (does
- nothing if the mouse is not over a link). For links to non-PDF
- files, this command is identical to followLink.
+ toggleSelectMode
+ Toggle between block and linear selection mode.
- followLinkNoSel
- Same as followLink, but does nothing if there is a non-empty
- selection. (This is useful as a mouse button binding.)
+ toggleSidebar
+ Toggle the sidebar between open and closed.
- followLinkInNewWinNoSel
- Same as followLinkInNewWin, but does nothing if there is a non-
- empty selection. (This is useful as a mouse button binding.)
+ toggleSidebarMoveResizeWin
+ 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
+ so that the document size doesn't change.
+
+ windowMode
+ Go to window (non-full-screen) mode.
+
+ zoomFitPage
+ Set the zoom factor to fit-page.
+
+ zoomFitWidth
+ Set the zoom factor to fit-width.
+
+ zoomIn Zoom in - go to the next higher zoom factor.
+
+ zoomOut
+ Zoom out - go the next lower zoom factor.
+
+ zoomPercent(z)
+ Set the zoom factor to z%.
- Default Bindings
- The default mouse bindings are as follows:
-
- bind mousePress1 any startSelection
- bind mouseRelease1 any endSelection followLinkNoSel
- bind mousePress2 any startPan
- bind mouseRelease2 any endPan
- bind mousePress3 any postPopupMenu
- bind mousePress4 any scrollUpPrevPage(16)
- bind mousePress5 any scrollDownNextPage(16)
- bind mousePress6 any scrollLeft(16)
- bind mousePress7 any scrollRight(16)
-
- The default key bindings are as follows:
-
- bind ctrl-home any gotoPage(1)
- bind home any scrollToTopLeft
- bind ctrl-end any gotoLastPage
- bind end any scrollToBottomRight
- bind pgup any pageUp
- bind backspace any pageUp
- bind delete any pageUp
- bind pgdn any pageDown
- bind space any pageDown
- bind left any scrollLeft(16)
- bind right any scrollRight(16)
- bind up any scrollUp(16)
- bind down any scrollDown(16)
- bind o any open
- bind O any open
- bind r any reload
- bind R any reload
- bind f any find
- bind F any find
- bind ctrl-f any find
- bind ctrl-g any findNext
- bind ctrl-p any print
- bind n scrLockOff nextPage
- bind N scrLockOff nextPage
- bind n scrLockOn nextPageNoScroll
- bind N scrLockOn nextPageNoScroll
- bind p scrLockOff prevPage
- bind P scrLockOff prevPage
- bind p scrLockOn prevPageNoScroll
- bind P scrLockOn prevPageNoScroll
- bind v any goForward
- bind b any goBackward
- bind g any focusToPageNum
- bind 0 any zoomPercent(125)
- bind + any zoomIn
- bind - any zoomOut
- bind z any zoomFitPage
- bind w any zoomFitWidth
- bind alt-f any toggleFullScreenMode
- bind ctrl-l any redraw
- bind ctrl-w any closeWindowOrQuit
- bind ? any about
- bind q any quit
- bind Q any quit
-
- Previous versions of xpdf included a "viKeys" X resource. It is no
- longer available, but the following bindings are equivalent:
-
- bind h any scrollLeft(16)
- bind l any scrollRight(16)
- bind k any scrollUp(16)
- bind j any scrollDown(16)
-
-
-REMOTE SERVER MODE
- Xpdf can be started in remote server mode by specifying a server name
- (in addition to the file name and page number). For example:
-
- xpdf -remote myServer file.pdf
-
- If there is currently no xpdf running in server mode with the name
- 'myServer', a new xpdf window will be opened. If another command:
-
- xpdf -remote myServer another.pdf 9
-
- is issued, a new copy of xpdf will not be started. Instead, the first
- xpdf (the server) will load another.pdf and display page nine. If the
- file name is the same:
-
- xpdf -remote myServer another.pdf 4
-
- the xpdf server will simply display the specified page.
-
- The -raise option tells the server to raise its window; it can be spec-
- ified with or without a file name and page number.
-
- The -quit option tells the server to close its window and exit.
+ zoomToSelection
+ Zoom to the current selection.
EXIT CODES
The Xpdf tools use the following exit codes:
@@ -755,14 +659,14 @@ EXIT CODES
99 Other error.
AUTHOR
- The xpdf software and documentation are copyright 1996-2014 Glyph &
+ The xpdf software and documentation are copyright 1996-2017 Glyph &
Cog, LLC.
SEE ALSO
pdftops(1), pdftotext(1), pdftohtml(1), pdfinfo(1), pdffonts(1), pdfde-
tach(1), pdftoppm(1), pdftopng(1), pdfimages(1), xpdfrc(5)
- http://www.foolabs.com/xpdf/
+ http://www.xpdfreader.com/
- 28 May 2014 xpdf(1)
+ 10 Aug 2017 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 afb8d950795..8ae83f410a5 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-2014 Glyph & Cog, LLC
-.TH xpdfrc 5 "28 May 2014"
+.\" Copyright 2002-2017 Glyph & Cog, LLC
+.TH xpdfrc 5 "10 Aug 2017"
.SH NAME
-xpdfrc \- configuration file for Xpdf tools (version 3.04)
+xpdfrc \- configuration file for Xpdf tools (version 4.00)
.SH DESCRIPTION
All of the Xpdf tools read a single configuration file. If you have a
.I .xpdfrc
@@ -31,114 +31,6 @@ to inserting the contents of
directly into the parent config file in place of the
.I include
command. Config files can be nested arbitrarily deeply.
-.SH CHARACTER MAPPING
-.TP
-.BI nameToUnicode " map\-file"
-Specifies a file with the mapping from character names to Unicode.
-This is used to handle PDF fonts that have valid encodings but no
-ToUnicode entry. Each line of a nameToUnicode file looks like this:
-
-.I " " hex\-string name
-
-The
-.I hex\-string
-is the Unicode (UCS-2) character index, and
-.I name
-is the corresponding character name. Multiple nameToUnicode files can
-be used; if a character name is given more than once, the code in the
-last specified file is used. There is a built-in default
-nameToUnicode table with all of Adobe's standard character names.
-.TP
-.BI cidToUnicode " registry\-ordering map\-file"
-Specifies the file with the mapping from character collection to
-Unicode. Each line of a cidToUnicode file represents one character:
-
-.I " " hex\-string
-
-The
-.I hex\-string
-is the Unicode (UCS-2) index for that character. The first line maps
-CID 0, the second line CID 1, etc. File size is determined by size of
-the character collection. Only one file is allowed per character
-collection; the last specified file is used. There are no built-in
-cidToUnicode mappings.
-.TP
-.BI unicodeToUnicode " font\-name\-substring map\-file"
-This is used to work around PDF fonts which have incorrect Unicode
-information. It specifies a file which maps from the given
-(incorrect) Unicode indexes to the correct ones. The mapping will be
-used for any font whose name contains
-.IR font\-name\-substring .
-Each line of a unicodeToUnicode file represents one Unicode character:
-
-.RI " " in\-hex " " out\-hex1 " " out\-hex2 " ..."
-
-The
-.I in\-hex
-field is an input (incorrect) Unicode index, and the rest of the
-fields are one or more output (correct) Unicode indexes. Each
-occurrence of
-.I in\-hex
-will be converted to the specified output sequence.
-.TP
-.BI unicodeMap " encoding\-name map\-file"
-Specifies the file with mapping from Unicode to
-.IR encoding\-name .
-These encodings are used for text output (see below). Each line of a
-unicodeMap file represents a range of one or more Unicode characters
-which maps linearly to a range in the output encoding:
-.nf
-
-.I " " in\-start\-hex in\-end\-hex out\-start\-hex
-
-.fi
-Entries for single characters can be abbreviated to:
-.nf
-
-.I " " in\-hex out\-hex
-
-.fi
-The
-.I in\-start\-hex
-and
-.I in\-end\-hex
-fields (or the single
-.I in\-hex
-field) specify the Unicode range. The
-.I out\-start\-hex
-field (or the
-.I out\-hex
-field) specifies the start of the output encoding range. The length
-of the
-.I out\-start\-hex
-(or
-.IR out\-hex )
-string determines the length of the output characters (e.g., UTF-8
-uses different numbers of bytes to represent characters in different
-ranges). Entries must be given in increasing Unicode order. Only one
-file is allowed per encoding; the last specified file is used. The
-.IR Latin1 ,
-.IR ASCII7 ,
-.IR Symbol ,
-.IR ZapfDingbats ,
-.IR UTF-8 ,
-and
-.I UCS-2
-encodings are predefined.
-.TP
-.BI cMapDir " registry\-ordering dir"
-Specifies a search directory,
-.IR dir ,
-for CMaps for the
-.I registry\-ordering
-character collection. There can be multiple directories for a
-particular collection. There are no default CMap directories.
-.TP
-.BI toUnicodeDir " dir"
-Specifies a search directory,
-.IR dir ,
-for ToUnicode CMaps. There can be multiple ToUnicode directories.
-There are no default ToUnicode directories.
.SH GENERAL FONT CONFIGURATION
.TP
.BI fontFile " PDF\-font\-name font\-file"
@@ -195,7 +87,7 @@ with writing mode
is used (without embedding) in a PDF file, it will be translated to
the PostScript font
.IR PS\-font\-name ,
-which is assumbed to be resident in the printer. The writing mode
+which is assumed to be resident in the printer. The writing mode
must be either \'H' for horizontal or \'V' for vertical. The resident
font is assumed to use the specified encoding (which must have been
defined with the unicodeMap command).
@@ -208,7 +100,7 @@ character collection and
writing mode is used (without embedding) in a PDF file, the PostScript
font,
.IR PS\-font\-name ,
-is substituted for it. The substituted font is assumbed to be
+is substituted for it. The substituted font is assumed to be
resident in the printer. The writing mode must be either \'H' for
horizontal or \'V' for vertical. The resident font is assumed to use
the specified encoding (which must have been defined with the
@@ -268,7 +160,7 @@ By default, this is "no", and the MediaBox is used as the page size.
.TP
.BR psExpandSmaller " yes | no"
If set to "yes", PDF pages smaller than the PostScript imageable area
-are expanded to fill the imageable area. Otherwise, no scalling is
+are expanded to fill the imageable area. Otherwise, no scaling is
done on smaller pages. This defaults to "no".
.TP
.BR psShrinkLarger " yes | no"
@@ -287,7 +179,7 @@ If set to "yes", the generated PostScript will set the "Duplex"
pagedevice entry. This tells duplex-capable printers to enable
duplexing. This defaults to "no".
.TP
-.BR psLevel " level1 | level1sep | level2 | level2sep | level3 | level3Sep"
+.BR psLevel " level1 | level1sep | level2 | level2gray | level2sep | level3 | level3gray | level3Sep"
Sets the PostScript level to generate. This defaults to "level2".
.TP
.BR psPreload " yes | no"
@@ -341,6 +233,12 @@ size, in pixels. This defaults to 20000000 (20 million).
If set to "yes", all PostScript output will be rasterized. This
defaults to "no".
.TP
+.BR psNeverRasterize " yes | no"
+If set to "yes", PostScript output will never be rasterized. This
+will likely result in incorrect output for PDF files that use
+transparency. (If both psAlwaysRasterize and psNeverRasterize are set
+to "yes", the psAlwaysRasterize setting wins.) This defaults to "no".
+.TP
.BI psFile " file\-or\-command"
Sets the default PostScript file or print command for xpdf. Commands
start with a \'|' character; anything else is a file. If the file
@@ -350,7 +248,7 @@ PDF file <file>.pdf.
.TP
.BI fontDir " dir"
See the description above, in the DISPLAY FONTS section.
-.SH TEXT CONTROL
+.SH TEXT CONTROL AND CHARACTER MAPPING
.TP
.BI textEncoding " encoding\-name"
Sets the encoding to use for text output. (This can be overridden
@@ -383,24 +281,138 @@ If set to "yes", text extraction will keep all characters. If set to
characters after the first 50000 per page, avoiding extremely slow run
times for PDF files that use special fonts to do shading or
cross-hatching. This defaults to "yes".
-.SH MISCELLANEOUS SETTINGS
.TP
-.BR initialZoom " \fIpercentage\fR | page | width"
-Sets the initial zoom factor. A number specifies a zoom percentage,
-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.
+.BI nameToUnicode " map\-file"
+Specifies a file with the mapping from character names to Unicode.
+This is used to handle PDF fonts that have valid encodings but no
+ToUnicode entry. Each line of a nameToUnicode file looks like this:
+
+.I " " hex\-string name
+
+The
+.I hex\-string
+is the Unicode (UCS-2) character index, and
+.I name
+is the corresponding character name. Multiple nameToUnicode files can
+be used; if a character name is given more than once, the code in the
+last specified file is used. There is a built-in default
+nameToUnicode table with all of Adobe's standard character names.
.TP
-.BR continuousView " yes | no"
-If set to "yes", xpdf will start in continuous view mode, i.e., with
-one vertical screoll bar for the whole document. This defaults to
-"no".
+.BI cidToUnicode " registry\-ordering map\-file"
+Specifies the file with the mapping from character collection to
+Unicode. Each line of a cidToUnicode file represents one character:
+
+.I " " hex\-string
+
+The
+.I hex\-string
+is the Unicode (UCS-2) index for that character. The first line maps
+CID 0, the second line CID 1, etc. File size is determined by size of
+the character collection. Only one file is allowed per character
+collection; the last specified file is used. There are no built-in
+cidToUnicode mappings.
.TP
-.BR enableFreeType " yes | no"
-Enables or disables use of FreeType (a TrueType / Type 1 font
-rasterizer). This is only relevant if the Xpdf tools were built with
-FreeType support. ("enableFreeType" replaces the old
-"freetypeControl" option.) This option defaults to "yes".
+.BI unicodeToUnicode " font\-name\-substring map\-file"
+This is used to work around PDF fonts which have incorrect Unicode
+information. It specifies a file which maps from the given
+(incorrect) Unicode indexes to the correct ones. The mapping will be
+used for any font whose name contains
+.IR font\-name\-substring .
+Each line of a unicodeToUnicode file represents one Unicode character:
+
+.RI " " in\-hex " " out\-hex1 " " out\-hex2 " ..."
+
+The
+.I in\-hex
+field is an input (incorrect) Unicode index, and the rest of the
+fields are one or more output (correct) Unicode indexes. Each
+occurrence of
+.I in\-hex
+will be converted to the specified output sequence.
+.TP
+.BI unicodeMap " encoding\-name map\-file"
+Specifies the file with mapping from Unicode to
+.IR encoding\-name .
+These encodings are used for text output (see below). Each line of a
+unicodeMap file represents a range of one or more Unicode characters
+which maps linearly to a range in the output encoding:
+.nf
+
+.I " " in\-start\-hex in\-end\-hex out\-start\-hex
+
+.fi
+Entries for single characters can be abbreviated to:
+.nf
+
+.I " " in\-hex out\-hex
+
+.fi
+The
+.I in\-start\-hex
+and
+.I in\-end\-hex
+fields (or the single
+.I in\-hex
+field) specify the Unicode range. The
+.I out\-start\-hex
+field (or the
+.I out\-hex
+field) specifies the start of the output encoding range. The length
+of the
+.I out\-start\-hex
+(or
+.IR out\-hex )
+string determines the length of the output characters (e.g., UTF-8
+uses different numbers of bytes to represent characters in different
+ranges). Entries must be given in increasing Unicode order. Only one
+file is allowed per encoding; the last specified file is used. The
+.IR Latin1 ,
+.IR ASCII7 ,
+.IR Symbol ,
+.IR ZapfDingbats ,
+.IR UTF-8 ,
+and
+.I UCS-2
+encodings are predefined.
+.TP
+.BI cMapDir " registry\-ordering dir"
+Specifies a search directory,
+.IR dir ,
+for CMaps for the
+.I registry\-ordering
+character collection. There can be multiple directories for a
+particular collection. There are no default CMap directories.
+.TP
+.BI toUnicodeDir " dir"
+Specifies a search directory,
+.IR dir ,
+for ToUnicode CMaps. There can be multiple ToUnicode directories.
+There are no default ToUnicode directories.
+.TP
+.BI mapNumericCharNames " yes | no"
+If set to "yes", the Xpdf tools will attempt to map various numeric
+character names sometimes used in font subsets. In some cases this
+leads to usable text, and in other cases it leads to gibberish --
+there is no way for Xpdf to tell. This defaults to "yes".
+.TP
+.BI mapUnknownCharNames " yes | no"
+If set to "yes", and mapNumericCharNames is set to "no", the Xpdf
+tools will apply a simple pass-through mapping (Unicode index =
+character code) for all unrecognized glyph names. (For CID fonts,
+setting mapNumericCharNames to "no" is unnecessary.) In some cases,
+this leads to usable text, and in other cases it leads to gibberish --
+there is no way for Xpdf to tell. This defaults to "no".
+.TP
+.BI mapExtTrueTypeFontsViaUnicode " yes | no"
+When rasterizing text using an external TrueType font, there are two
+options for handling character codes. If
+mapExtTrueTypeFontsViaUnicode is set to "yes", Xpdf will use the font
+encoding/ToUnicode info to map character codes to Unicode, and then
+use the font's Unicode cmap to map Unicode to GIDs. If
+mapExtTrueTypeFontsViaUnicode is set to "no", Xpdf will assume the
+character codes are GIDs (i.e., use an identity mapping). This
+defaults to "yes".
+.SH RASTERIZER SETTINGS
.TP
.BR enableFreeType " yes | no"
Enables or disables use of FreeType (a TrueType / Type 1 font
@@ -428,11 +440,15 @@ If this is "yes", bitmaps sent to the printer will be antialiased
this is "no", printed bitmaps will not be antialiased. This defaults
to "no".
.TP
-.BR strokeAdjust " yes | no"
-Enables or disables stroke adjustment. Stroke adjustment moves
-horizontal and vertical lines by up to half a pixel to make them look
-"cleaner" when vector anti-aliasing is enabled. This defaults to
-"yes".
+.BR strokeAdjust " yes | no | cad"
+Sets the stroke adjustment mode. If set to "no", no stroke adjustment
+will be done. If set to "yes", normal stroke adjustment will be done:
+horizontal and vertical lines will be moved by up to half a pixel to
+make them look cleaner when vector anti-aliasing is enabled. If set
+to "cad", a slightly different stroke adjustment algorithm will be
+used to ensure that lines of the same original width will always have
+the same adjusted width (at the expense of allowing gaps and overlaps
+between adjacent lines). This defaults to "yes".
.TP
.BR screenType " dispersed | clustered | stochasticClustered"
Sets the halftone screen type, which will be used when generating a
@@ -474,14 +490,75 @@ rasterizer only, not the PostScript converter (except when it uses
rasterization to handle transparency). The default value is 0 (no
minimum).
.TP
-.BI drawAnnotations " yes | no"
-If set to "no", annotations will not be drawn or printed. The default
-value is "yes".
+.BI enablePathSimplification " yes | no"
+If set to "yes", simplify paths by removing points where it won't make
+a significant difference to the shape. The default value is "no".
.TP
.BI overprintPreview " yes | no"
If set to "yes", generate overprint preview output, honoring the
OP/op/OPM settings in the PDF file. Ignored for non-CMYK output. The
default value is "no".
+.SH VIEWER SETTINGS
+These settings only apply to the Xpdf GUI PDF viewer.
+.TP
+.BR initialZoom " \fIpercentage\fR | page | width"
+Sets the initial zoom factor. A number specifies a zoom percentage,
+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.
+.TP
+.BI defaultFitZoom " percentage"
+If xpdf is started with fit-page or fit-width zoom and no window
+geometry, it will calculate a desired window size based on the PDF
+page size and this defaultFitZoom value. I.e., the window size will
+be chosen such that exactly one page will fit in the window at this
+zoom factor (which must be a percentage). The default value is
+based on the screen resolution.
+.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 "no".
+.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
+not work well with PDF files that do things like filling in white
+behind the text.
+.TP
+.BI matteColor " color"
+Set the matte color, i.e., the color used for background outside the
+actual page area. The color can be #RRGGBB (hexadecimal) or a named
+color.
+.TP
+.BI fullScreenMatteColor " color"
+Set the matte color for full-screen mode. The color can be #RRGGBB
+(hexadecimal) or a named color.
+.TP
+.BI popupMenuCmd " title command ..."
+Add a command to the popup menu.
+.I Title
+is the text to be displayed in the menu.
+.I Command
+is an Xpdf command (see the COMMANDS section of the
+.BR xpdf (1)
+man page for details). Multiple commands are separated by whitespace.
+.TP
+.BI maxTileWidth " pixels"
+Set the maximum width of tiles to be used by xpdf when rasterizing
+pages. This defaults to 1500.
+.TP
+.BI maxTileHeight " pixels"
+Set the maximum height of tiles to be used by xpdf when rasterizing
+pages. This defaults to 1500.
+.TP
+.BI tileCacheSize " tiles"
+Set the maximum number of tiles to be cached by xpdf when rasterizing
+pages. This defaults to 10.
+.TP
+.BI workerThreads " numThreads"
+Set the number of worker threads to be used by xpdf when rasterizing
+pages. This defaults to 1.
.TP
.BI launchCommand " command"
Sets the command executed when you click on a "launch"-type link. The
@@ -492,45 +569,11 @@ specified with the link. Do not use "%s" in "command". By default,
this is unset, and Xpdf will simply try to execute the file (after
prompting the user).
.TP
-.BI urlCommand " command"
-Sets the command executed when you click on a URL link. The string
-"%s" will be replaced with the URL. (See the example below.) This
-has no default value.
-.TP
.BI movieCommand " command"
Sets the command executed when you click on a movie annotation. The
string "%s" will be replaced with the movie file name. This has no
default value.
.TP
-.BI mapNumericCharNames " yes | no"
-If set to "yes", the Xpdf tools will attempt to map various numeric
-character names sometimes used in font subsets. In some cases this
-leads to usable text, and in other cases it leads to gibberish --
-there is no way for Xpdf to tell. This defaults to "yes".
-.TP
-.BI mapUnknownCharNames " yes | no"
-If set to "yes", and mapNumericCharNames is set to "no", the Xpdf
-tools will apply a simple pass-through mapping (Unicode index =
-character code) for all unrecognized glyph names. (For CID fonts,
-setting mapNumericCharNames to "no" is unnecessary.) In some cases,
-this leads to usable text, and in other cases it leads to gibberish --
-there is no way for Xpdf to tell. This defaults to "no".
-.TP
-.BI mapExtTrueTypeFontsViaUnicode " yes | no"
-When rasterizing text using an external TrueType font, there are two
-options for handling character codes. If
-mapExtTrueTypeFontsViaUnicode is set to "yes", Xpdf will use the font
-encoding/ToUnicode info to map character codes to Unicode, and then
-use the font's Unicode cmap to map Unicode to GIDs. If
-mapExtTrueTypeFontsViaUnicode is set to "no", Xpdf will assume the
-character codes are GIDs (i.e., use an identity mapping). This
-defaults to "yes".
-.TP
-.BI enableXFA " yes | no"
-If set to "yes", an XFA form (if present) will be rendered in place of
-an AcroForm. If "no", an XFA form will never be rendered. This
-defaults to "yes".
-.TP
.BI bind " modifiers-key context command ..."
Add a key or mouse button binding.
.I Modifiers
@@ -551,6 +594,7 @@ can be a regular ASCII character, or any one of:
return
enter
backspace
+ esc
insert
delete
home
@@ -561,6 +605,7 @@ can be a regular ASCII character, or any one of:
f1 .. f35 (function keys)
mousePress1 .. mousePress7 (mouse buttons)
mouseRelease1 .. mouseRelease7 (mouse buttons)
+ mouseClick1 .. mouseClick7 (mouse buttons)
.fi
.I Context
@@ -607,6 +652,20 @@ Removes a key binding established with the bind command. This is most
useful to remove default key bindings before establishing new ones
(e.g., if the default key binding is given for "any" context, and you
want to create new key bindings for multiple contexts).
+.SH MISCELLANEOUS SETTINGS
+.TP
+.BI drawAnnotations " yes | no"
+If set to "no", annotations will not be drawn or printed. The default
+value is "yes".
+.TP
+.BI drawFormFields " yes | no"
+If set to "no", form fields will not be drawn or printed. The default
+value is "yes".
+.TP
+.BI enableXFA " yes | no"
+If set to "yes", an XFA form (if present) will be rendered in place of
+an AcroForm. If "no", an XFA form will never be rendered. This
+defaults to "yes".
.TP
.BI printCommands " yes | no"
If set to "yes", drawing commands are printed as they're executed
@@ -680,7 +739,7 @@ Depending on build options, it may be placed elsewhere.
This is the user's configuration file. If it exists, it will be read
in place of the system-wide file.
.SH AUTHOR
-The Xpdf software and documentation are copyright 1996-2014 Glyph &
+The Xpdf software and documentation are copyright 1996-2017 Glyph &
Cog, LLC.
.SH "SEE ALSO"
.BR xpdf (1),
@@ -694,4 +753,4 @@ Cog, LLC.
.BR pdftopng (1),
.BR pdfimages (1)
.br
-.B http://www.foolabs.com/xpdf/
+.B http://www.xpdfreader.com/
diff --git a/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat b/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat
index b8faf8a37b8..213dde746d4 100644
--- a/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat
+++ b/Build/source/libs/xpdf/xpdf-src/doc/xpdfrc.cat
@@ -1,9 +1,9 @@
-xpdfrc(5) xpdfrc(5)
+xpdfrc(5) File Formats Manual xpdfrc(5)
NAME
- xpdfrc - configuration file for Xpdf tools (version 3.04)
+ xpdfrc - configuration file for Xpdf tools (version 4.00)
DESCRIPTION
All of the Xpdf tools read a single configuration file. If you have a
@@ -30,85 +30,6 @@ INCLUDE FILES
into the parent config file in place of the include command.
Config files can be nested arbitrarily deeply.
-CHARACTER MAPPING
- nameToUnicode map-file
- Specifies a file with the mapping from character names to Uni-
- code. This is used to handle PDF fonts that have valid encod-
- ings but no ToUnicode entry. Each line of a nameToUnicode file
- looks like this:
-
- hex-string name
-
- The hex-string is the Unicode (UCS-2) character index, and name
- is the corresponding character name. Multiple nameToUnicode
- files can be used; if a character name is given more than once,
- the code in the last specified file is used. There is a built-
- in default nameToUnicode table with all of Adobe's standard
- character names.
-
- cidToUnicode registry-ordering map-file
- Specifies the file with the mapping from character collection to
- Unicode. Each line of a cidToUnicode file represents one char-
- acter:
-
- hex-string
-
- The hex-string is the Unicode (UCS-2) index for that character.
- The first line maps CID 0, the second line CID 1, etc. File
- size is determined by size of the character collection. Only
- one file is allowed per character collection; the last specified
- file is used. There are no built-in cidToUnicode mappings.
-
- unicodeToUnicode font-name-substring map-file
- This is used to work around PDF fonts which have incorrect Uni-
- code information. It specifies a file which maps from the given
- (incorrect) Unicode indexes to the correct ones. The mapping
- will be used for any font whose name contains font-name-sub-
- string. Each line of a unicodeToUnicode file represents one
- Unicode character:
-
- in-hex out-hex1 out-hex2 ...
-
- The in-hex field is an input (incorrect) Unicode index, and the
- rest of the fields are one or more output (correct) Unicode
- indexes. Each occurrence of in-hex will be converted to the
- specified output sequence.
-
- unicodeMap encoding-name map-file
- Specifies the file with mapping from Unicode to encoding-name.
- These encodings are used for text output (see below). Each line
- of a unicodeMap file represents a range of one or more Unicode
- characters which maps linearly to a range in the output encod-
- ing:
-
- in-start-hex in-end-hex out-start-hex
-
- Entries for single characters can be abbreviated to:
-
- in-hex out-hex
-
- The in-start-hex and in-end-hex fields (or the single in-hex
- field) specify the Unicode range. The out-start-hex field (or
- the out-hex field) specifies the start of the output encoding
- range. The length of the out-start-hex (or out-hex) string
- determines the length of the output characters (e.g., UTF-8 uses
- different numbers of bytes to represent characters in different
- ranges). Entries must be given in increasing Unicode order.
- Only one file is allowed per encoding; the last specified file
- is used. The Latin1, ASCII7, Symbol, ZapfDingbats, UTF-8, and
- UCS-2 encodings are predefined.
-
- cMapDir registry-ordering dir
- Specifies a search directory, dir, for CMaps for the reg-
- istry-ordering character collection. There can be multiple
- directories for a particular collection. There are no default
- CMap directories.
-
- toUnicodeDir dir
- Specifies a search directory, dir, for ToUnicode CMaps. There
- can be multiple ToUnicode directories. There are no default
- ToUnicode directories.
-
GENERAL FONT CONFIGURATION
fontFile PDF-font-name font-file
Maps a PDF font, PDF-font-name, to a font for display or Post-
@@ -149,17 +70,17 @@ POSTSCRIPT FONT CONFIGURATION
psResidentFont16 PDF-font-name wMode PS-font-name encoding
When the 16-bit (CID) font PDF-font-name with writing mode wMode
is used (without embedding) in a PDF file, it will be translated
- to the PostScript font PS-font-name, which is assumbed to be
- resident in the printer. The writing mode must be either 'H'
- for horizontal or 'V' for vertical. The resident font is
- assumed to use the specified encoding (which must have been
- defined with the unicodeMap command).
+ to the PostScript font PS-font-name, which is assumed to be res-
+ ident in the printer. The writing mode must be either 'H' for
+ horizontal or 'V' for vertical. The resident font is assumed to
+ use the specified encoding (which must have been defined with
+ the unicodeMap command).
psResidentFontCC registry-ordering wMode PS-font-name encoding
When a 16-bit (CID) font using the registry-ordering character
collection and wMode writing mode is used (without embedding) in
a PDF file, the PostScript font, PS-font-name, is substituted
- for it. The substituted font is assumbed to be resident in the
+ for it. The substituted font is assumed to be resident in the
printer. The writing mode must be either 'H' for horizontal or
'V' for vertical. The resident font is assumed to use the spec-
ified encoding (which must have been defined with the unicodeMap
@@ -219,7 +140,7 @@ POSTSCRIPT CONTROL
psExpandSmaller yes | no
If set to "yes", PDF pages smaller than the PostScript imageable
area are expanded to fill the imageable area. Otherwise, no
- scalling is done on smaller pages. This defaults to "no".
+ scaling is done on smaller pages. This defaults to "no".
psShrinkLarger yes | no
If set to yes, PDF pages larger than the PostScript imageable
@@ -237,47 +158,48 @@ POSTSCRIPT CONTROL
pagedevice entry. This tells duplex-capable printers to enable
duplexing. This defaults to "no".
- psLevel level1 | level1sep | level2 | level2sep | level3 | level3Sep
+ psLevel level1 | level1sep | level2 | level2gray | level2sep | level3 |
+ level3gray | level3Sep
Sets the PostScript level to generate. This defaults to
"level2".
psPreload yes | no
- If set to "yes", PDF forms are converted to PS procedures, and
- image data is preloaded. This uses more memory in the Post-
+ If set to "yes", PDF forms are converted to PS procedures, and
+ image data is preloaded. This uses more memory in the Post-
Script interpreter, but generates significantly smaller PS files
in situations where, e.g., the same image is drawn on every page
of a long document. This defaults to "no".
psOPI yes | no
- If set to "yes", generates PostScript OPI comments for all
- images and forms which have OPI information. This option is
+ If set to "yes", generates PostScript OPI comments for all
+ images and forms which have OPI information. This option is
only available if the Xpdf tools were compiled with OPI support.
This defaults to "no".
psASCIIHex yes | no
- If set to "yes", the ASCIIHexEncode filter will be used instead
+ If set to "yes", the ASCIIHexEncode filter will be used instead
of ASCII85Encode for binary data. This defaults to "no".
psLZW yes | no
- If set to "yes", the LZWEncode filter will be used for lossless
+ If set to "yes", the LZWEncode filter will be used for lossless
compression in PostScript output; if set to "no", the RunLength-
- Encode filter will be used instead. LZW generates better com-
- pression (smaller PS files), but may not be supported by some
+ Encode filter will be used instead. LZW generates better com-
+ pression (smaller PS files), but may not be supported by some
printers. This defaults to "yes".
psUncompressPreloadedImages yes | no
- If set to "yes", all preloaded images in PS files will uncom-
+ If set to "yes", all preloaded images in PS files will uncom-
pressed. If set to "no", the original compressed images will be
- used when possible. The "yes" setting is useful to work around
+ used when possible. The "yes" setting is useful to work around
certain buggy PostScript interpreters. This defaults to "no".
psMinLineWidth float
- Set the minimum line width, in points, for PostScript output.
+ Set the minimum line width, in points, for PostScript output.
The default value is 0 (no minimum).
psRasterResolution float
- Set the resolution (in dpi) for rasterized pages in PostScript
- output. (Pdftops will rasterize pages which use transparency.)
+ Set the resolution (in dpi) for rasterized pages in PostScript
+ output. (Pdftops will rasterize pages which use transparency.)
This defaults to 300.
psRasterMono yes | no
@@ -285,72 +207,166 @@ POSTSCRIPT CONTROL
(8-bit gray) instead of color. This defaults to "no".
psRasterSliceSize pixels
- When rasterizing pages, pdftops splits the page into horizontal
- "slices", to limit memory usage. This option sets the maximum
+ When rasterizing pages, pdftops splits the page into horizontal
+ "slices", to limit memory usage. This option sets the maximum
slice size, in pixels. This defaults to 20000000 (20 million).
psAlwaysRasterize yes | no
If set to "yes", all PostScript output will be rasterized. This
defaults to "no".
+ psNeverRasterize yes | no
+ If set to "yes", PostScript output will never be rasterized.
+ This will likely result in incorrect output for PDF files that
+ use transparency. (If both psAlwaysRasterize and psNeverRaster-
+ ize are set to "yes", the psAlwaysRasterize setting wins.) This
+ defaults to "no".
+
psFile file-or-command
- Sets the default PostScript file or print command for xpdf.
- Commands start with a '|' character; anything else is a file.
- If the file name or command contains spaces it must be quoted.
- This defaults to unset, which tells xpdf to generate a name of
+ Sets the default PostScript file or print command for xpdf.
+ Commands start with a '|' character; anything else is a file.
+ If the file name or command contains spaces it must be quoted.
+ This defaults to unset, which tells xpdf to generate a name of
the form <file>.ps for a PDF file <file>.pdf.
fontDir dir
See the description above, in the DISPLAY FONTS section.
-TEXT CONTROL
+TEXT CONTROL AND CHARACTER MAPPING
textEncoding encoding-name
Sets the encoding to use for text output. (This can be overrid-
- den with the "-enc" switch on the command line.) The encod-
- ing-name must be defined with the unicodeMap command (see
+ den with the "-enc" switch on the command line.) The encod-
+ ing-name must be defined with the unicodeMap command (see
above). This defaults to "Latin1".
textEOL unix | dos | mac
- Sets the end-of-line convention to use for text output. The
+ Sets the end-of-line convention to use for text output. The
options are:
unix = LF
dos = CR+LF
mac = CR
- (This can be overridden with the "-eol" switch on the command
- line.) The default value is based on the OS where xpdf and
+ (This can be overridden with the "-eol" switch on the command
+ line.) The default value is based on the OS where xpdf and
pdftotext were built.
textPageBreaks yes | no
- If set to "yes", text extraction will insert page breaks (form
+ If set to "yes", text extraction will insert page breaks (form
feed characters) between pages. This defaults to "yes".
textKeepTinyChars yes | no
- If set to "yes", text extraction will keep all characters. If
- set to "no", text extraction will discard tiny (smaller than 3
- point) characters after the first 50000 per page, avoiding
+ If set to "yes", text extraction will keep all characters. If
+ set to "no", text extraction will discard tiny (smaller than 3
+ point) characters after the first 50000 per page, avoiding
extremely slow run times for PDF files that use special fonts to
do shading or cross-hatching. This defaults to "yes".
-MISCELLANEOUS SETTINGS
- initialZoom percentage | page | width
- Sets the initial zoom factor. A number specifies a zoom per-
- centage, where 100 means 72 dpi. You may also specify 'page',
- to fit the page to the window size, or 'width', to fit the page
- width to the window width.
+ nameToUnicode map-file
+ Specifies a file with the mapping from character names to Uni-
+ code. This is used to handle PDF fonts that have valid encod-
+ ings but no ToUnicode entry. Each line of a nameToUnicode file
+ looks like this:
+
+ hex-string name
+
+ The hex-string is the Unicode (UCS-2) character index, and name
+ is the corresponding character name. Multiple nameToUnicode
+ files can be used; if a character name is given more than once,
+ the code in the last specified file is used. There is a built-
+ in default nameToUnicode table with all of Adobe's standard
+ character names.
+
+ cidToUnicode registry-ordering map-file
+ Specifies the file with the mapping from character collection to
+ Unicode. Each line of a cidToUnicode file represents one char-
+ acter:
+
+ hex-string
+
+ The hex-string is the Unicode (UCS-2) index for that character.
+ The first line maps CID 0, the second line CID 1, etc. File
+ size is determined by size of the character collection. Only
+ one file is allowed per character collection; the last specified
+ file is used. There are no built-in cidToUnicode mappings.
+
+ unicodeToUnicode font-name-substring map-file
+ This is used to work around PDF fonts which have incorrect Uni-
+ code information. It specifies a file which maps from the given
+ (incorrect) Unicode indexes to the correct ones. The mapping
+ will be used for any font whose name contains font-name-sub-
+ string. Each line of a unicodeToUnicode file represents one
+ Unicode character:
+
+ in-hex out-hex1 out-hex2 ...
+
+ The in-hex field is an input (incorrect) Unicode index, and the
+ rest of the fields are one or more output (correct) Unicode
+ indexes. Each occurrence of in-hex will be converted to the
+ specified output sequence.
+
+ unicodeMap encoding-name map-file
+ Specifies the file with mapping from Unicode to encoding-name.
+ These encodings are used for text output (see below). Each line
+ of a unicodeMap file represents a range of one or more Unicode
+ characters which maps linearly to a range in the output encod-
+ ing:
+
+ in-start-hex in-end-hex out-start-hex
- continuousView yes | no
- If set to "yes", xpdf will start in continuous view mode, i.e.,
- with one vertical screoll bar for the whole document. This
+ Entries for single characters can be abbreviated to:
+
+ in-hex out-hex
+
+ The in-start-hex and in-end-hex fields (or the single in-hex
+ field) specify the Unicode range. The out-start-hex field (or
+ the out-hex field) specifies the start of the output encoding
+ range. The length of the out-start-hex (or out-hex) string
+ determines the length of the output characters (e.g., UTF-8 uses
+ different numbers of bytes to represent characters in different
+ ranges). Entries must be given in increasing Unicode order.
+ Only one file is allowed per encoding; the last specified file
+ is used. The Latin1, ASCII7, Symbol, ZapfDingbats, UTF-8, and
+ UCS-2 encodings are predefined.
+
+ cMapDir registry-ordering dir
+ Specifies a search directory, dir, for CMaps for the reg-
+ istry-ordering character collection. There can be multiple
+ directories for a particular collection. There are no default
+ CMap directories.
+
+ toUnicodeDir dir
+ Specifies a search directory, dir, for ToUnicode CMaps. There
+ can be multiple ToUnicode directories. There are no default
+ ToUnicode directories.
+
+ mapNumericCharNames yes | no
+ If set to "yes", the Xpdf tools will attempt to map various
+ numeric character names sometimes used in font subsets. In some
+ cases this leads to usable text, and in other cases it leads to
+ gibberish -- there is no way for Xpdf to tell. This defaults to
+ "yes".
+
+ mapUnknownCharNames yes | no
+ If set to "yes", and mapNumericCharNames is set to "no", the
+ Xpdf tools will apply a simple pass-through mapping (Unicode
+ index = character code) for all unrecognized glyph names. (For
+ CID fonts, setting mapNumericCharNames to "no" is unnecessary.)
+ In some cases, this leads to usable text, and in other cases it
+ leads to gibberish -- there is no way for Xpdf to tell. This
defaults to "no".
- enableFreeType yes | no
- Enables or disables use of FreeType (a TrueType / Type 1 font
- rasterizer). This is only relevant if the Xpdf tools were built
- with FreeType support. ("enableFreeType" replaces the old
- "freetypeControl" option.) This option defaults to "yes".
+ mapExtTrueTypeFontsViaUnicode yes | no
+ When rasterizing text using an external TrueType font, there are
+ two options for handling character codes. If mapExtTrueType-
+ FontsViaUnicode is set to "yes", Xpdf will use the font encod-
+ ing/ToUnicode info to map character codes to Unicode, and then
+ use the font's Unicode cmap to map Unicode to GIDs. If mapExt-
+ TrueTypeFontsViaUnicode is set to "no", Xpdf will assume the
+ character codes are GIDs (i.e., use an identity mapping). This
+ defaults to "yes".
+RASTERIZER SETTINGS
enableFreeType yes | no
Enables or disables use of FreeType (a TrueType / Type 1 font
rasterizer). This is only relevant if the Xpdf tools were built
@@ -377,113 +393,142 @@ MISCELLANEOUS SETTINGS
settings). If this is "no", printed bitmaps will not be
antialiased. This defaults to "no".
- strokeAdjust yes | no
- Enables or disables stroke adjustment. Stroke adjustment moves
- horizontal and vertical lines by up to half a pixel to make them
- look "cleaner" when vector anti-aliasing is enabled. This
- defaults to "yes".
+ strokeAdjust yes | no | cad
+ Sets the stroke adjustment mode. If set to "no", no stroke
+ adjustment will be done. If set to "yes", normal stroke adjust-
+ ment will be done: horizontal and vertical lines will be moved
+ by up to half a pixel to make them look cleaner when vector
+ anti-aliasing is enabled. If set to "cad", a slightly different
+ stroke adjustment algorithm will be used to ensure that lines of
+ the same original width will always have the same adjusted width
+ (at the expense of allowing gaps and overlaps between adjacent
+ lines). This defaults to "yes".
screenType dispersed | clustered | stochasticClustered
- Sets the halftone screen type, which will be used when generat-
- ing a monochrome (1-bit) bitmap. The three options are dis-
- persed-dot dithering, clustered-dot dithering (with a round dot
- and 45-degree screen angle), and stochastic clustered-dot
- dithering. By default, "stochasticClustered" is used for reso-
+ Sets the halftone screen type, which will be used when generat-
+ ing a monochrome (1-bit) bitmap. The three options are dis-
+ persed-dot dithering, clustered-dot dithering (with a round dot
+ and 45-degree screen angle), and stochastic clustered-dot
+ dithering. By default, "stochasticClustered" is used for reso-
lutions of 300 dpi and higher, and "dispersed" is used for reso-
lutions lower then 300 dpi.
screenSize integer
- Sets the size of the (square) halftone screen threshold matrix.
- By default, this is 4 for dispersed-dot dithering, 10 for clus-
- tered-dot dithering, and 100 for stochastic clustered-dot
+ Sets the size of the (square) halftone screen threshold matrix.
+ By default, this is 4 for dispersed-dot dithering, 10 for clus-
+ tered-dot dithering, and 100 for stochastic clustered-dot
dithering.
screenDotRadius integer
- Sets the halftone screen dot radius. This is only used when
- screenType is set to stochasticClustered, and it defaults to 2.
- In clustered-dot mode, the dot radius is half of the screen
+ Sets the halftone screen dot radius. This is only used when
+ screenType is set to stochasticClustered, and it defaults to 2.
+ In clustered-dot mode, the dot radius is half of the screen
size. Dispersed-dot dithering doesn't have a dot radius.
screenGamma float
Sets the halftone screen gamma correction parameter. Gamma val-
- ues greater than 1 make the output brighter; gamma values less
+ ues greater than 1 make the output brighter; gamma values less
than 1 make it darker. The default value is 1.
screenBlackThreshold float
- When halftoning, all values below this threshold are forced to
+ When halftoning, all values below this threshold are forced to
solid black. This parameter is a floating point value between 0
(black) and 1 (white). The default value is 0.
screenWhiteThreshold float
- When halftoning, all values above this threshold are forced to
+ When halftoning, all values above this threshold are forced to
solid white. This parameter is a floating point value between 0
(black) and 1 (white). The default value is 1.
minLineWidth float
- Set the minimum line width, in device pixels. This affects the
- rasterizer only, not the PostScript converter (except when it
- uses rasterization to handle transparency). The default value
+ Set the minimum line width, in device pixels. This affects the
+ rasterizer only, not the PostScript converter (except when it
+ uses rasterization to handle transparency). The default value
is 0 (no minimum).
- drawAnnotations yes | no
- If set to "no", annotations will not be drawn or printed. The
- default value is "yes".
+ enablePathSimplification yes | no
+ If set to "yes", simplify paths by removing points where it
+ won't make a significant difference to the shape. The default
+ value is "no".
overprintPreview yes | no
If set to "yes", generate overprint preview output, honoring the
OP/op/OPM settings in the PDF file. Ignored for non-CMYK out-
put. The default value is "no".
+VIEWER SETTINGS
+ These settings only apply to the Xpdf GUI PDF viewer.
+
+ initialZoom percentage | page | width
+ Sets the initial zoom factor. A number specifies a zoom per-
+ centage, where 100 means 72 dpi. You may also specify 'page',
+ to fit the page to the window size, or 'width', to fit the page
+ width to the window width.
+
+ defaultFitZoom percentage
+ If xpdf is started with fit-page or fit-width zoom and no window
+ geometry, it will calculate a desired window size based on the
+ PDF page size and this defaultFitZoom value. I.e., the window
+ size will be chosen such that exactly one page will fit in the
+ window at this zoom factor (which must be a percentage). The
+ default value is based on the screen resolution.
+
+ 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 "no".
+
+ 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
+ filling in white behind the text.
+
+ matteColor color
+ Set the matte color, i.e., the color used for background outside
+ the actual page area. The color can be #RRGGBB (hexadecimal) or
+ a named color.
+
+ fullScreenMatteColor color
+ Set the matte color for full-screen mode. The color can be
+ #RRGGBB (hexadecimal) or a named color.
+
+ popupMenuCmd title command ...
+ Add a command to the popup menu. Title is the text to be dis-
+ played in the menu. Command is an Xpdf command (see the COM-
+ MANDS section of the xpdf(1) man page for details). Multiple
+ commands are separated by whitespace.
+
+ maxTileWidth pixels
+ Set the maximum width of tiles to be used by xpdf when rasteriz-
+ ing pages. This defaults to 1500.
+
+ maxTileHeight pixels
+ Set the maximum height of tiles to be used by xpdf when raster-
+ izing pages. This defaults to 1500.
+
+ tileCacheSize tiles
+ Set the maximum number of tiles to be cached by xpdf when ras-
+ terizing pages. This defaults to 10.
+
+ workerThreads numThreads
+ Set the number of worker threads to be used by xpdf when raster-
+ izing pages. This defaults to 1.
+
launchCommand command
- Sets the command executed when you click on a "launch"-type
- link. The intent is for the command to be a program/script
- which determines the file type and runs the appropriate viewer.
- The command line will consist of the file to be launched, fol-
- lowed by any parameters specified with the link. Do not use
- "%s" in "command". By default, this is unset, and Xpdf will
+ Sets the command executed when you click on a "launch"-type
+ link. The intent is for the command to be a program/script
+ which determines the file type and runs the appropriate viewer.
+ The command line will consist of the file to be launched, fol-
+ lowed by any parameters specified with the link. Do not use
+ "%s" in "command". By default, this is unset, and Xpdf will
simply try to execute the file (after prompting the user).
- urlCommand command
- Sets the command executed when you click on a URL link. The
- string "%s" will be replaced with the URL. (See the example
- below.) This has no default value.
-
movieCommand command
- Sets the command executed when you click on a movie annotation.
+ Sets the command executed when you click on a movie annotation.
The string "%s" will be replaced with the movie file name. This
has no default value.
- mapNumericCharNames yes | no
- If set to "yes", the Xpdf tools will attempt to map various
- numeric character names sometimes used in font subsets. In some
- cases this leads to usable text, and in other cases it leads to
- gibberish -- there is no way for Xpdf to tell. This defaults to
- "yes".
-
- mapUnknownCharNames yes | no
- If set to "yes", and mapNumericCharNames is set to "no", the
- Xpdf tools will apply a simple pass-through mapping (Unicode
- index = character code) for all unrecognized glyph names. (For
- CID fonts, setting mapNumericCharNames to "no" is unnecessary.)
- In some cases, this leads to usable text, and in other cases it
- leads to gibberish -- there is no way for Xpdf to tell. This
- defaults to "no".
-
- mapExtTrueTypeFontsViaUnicode yes | no
- When rasterizing text using an external TrueType font, there are
- two options for handling character codes. If mapExtTrueType-
- FontsViaUnicode is set to "yes", Xpdf will use the font encod-
- ing/ToUnicode info to map character codes to Unicode, and then
- use the font's Unicode cmap to map Unicode to GIDs. If mapExt-
- TrueTypeFontsViaUnicode is set to "no", Xpdf will assume the
- character codes are GIDs (i.e., use an identity mapping). This
- defaults to "yes".
-
- enableXFA yes | no
- If set to "yes", an XFA form (if present) will be rendered in
- place of an AcroForm. If "no", an XFA form will never be ren-
- dered. This defaults to "yes".
-
bind modifiers-key context command ...
Add a key or mouse button binding. Modifiers can be zero or
more of:
@@ -499,6 +544,7 @@ MISCELLANEOUS SETTINGS
return
enter
backspace
+ esc
insert
delete
home
@@ -509,6 +555,7 @@ MISCELLANEOUS SETTINGS
f1 .. f35 (function keys)
mousePress1 .. mousePress7 (mouse buttons)
mouseRelease1 .. mouseRelease7 (mouse buttons)
+ mouseClick1 .. mouseClick7 (mouse buttons)
Context is either "any" or a comma-separated combination of:
@@ -548,6 +595,20 @@ MISCELLANEOUS SETTINGS
"any" context, and you want to create new key bindings for mul-
tiple contexts).
+MISCELLANEOUS SETTINGS
+ drawAnnotations yes | no
+ If set to "no", annotations will not be drawn or printed. The
+ default value is "yes".
+
+ drawFormFields yes | no
+ If set to "no", form fields will not be drawn or printed. The
+ default value is "yes".
+
+ enableXFA yes | no
+ If set to "yes", an XFA form (if present) will be rendered in
+ place of an AcroForm. If "no", an XFA form will never be ren-
+ dered. This defaults to "yes".
+
printCommands yes | no
If set to "yes", drawing commands are printed as they're exe-
cuted (useful for debugging). This defaults to "no".
@@ -620,14 +681,14 @@ FILES
read in place of the system-wide file.
AUTHOR
- The Xpdf software and documentation are copyright 1996-2014 Glyph &
+ The Xpdf software and documentation are copyright 1996-2017 Glyph &
Cog, LLC.
SEE ALSO
xpdf(1), pdftops(1), pdftotext(1), pdftohtml(1), pdfinfo(1), pdf-
fonts(1), pdfdetach(1), pdftoppm(1), pdftopng(1), pdfimages(1)
- http://www.foolabs.com/xpdf/
+ http://www.xpdfreader.com/
- 28 May 2014 xpdfrc(5)
+ 10 Aug 2017 xpdfrc(5)
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/fofi/CMakeLists.txt
new file mode 100644
index 00000000000..076cfafb247
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/CMakeLists.txt
@@ -0,0 +1,26 @@
+#========================================================================
+#
+# fofi/CMakeLists.txt
+#
+# CMake script for the fofi library.
+#
+# Copyright 2015 Glyph & Cog, LLC
+#
+#========================================================================
+
+include_directories("${PROJECT_SOURCE_DIR}")
+include_directories("${PROJECT_BINARY_DIR}")
+include_directories("${PROJECT_SOURCE_DIR}/goo")
+
+add_library(fofi_objs OBJECT
+ FoFiBase.cc
+ FoFiEncodings.cc
+ FoFiIdentifier.cc
+ FoFiTrueType.cc
+ FoFiType1.cc
+ FoFiType1C.cc
+)
+
+add_library(fofi
+ $<TARGET_OBJECTS:fofi_objs>
+)
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc
index c9ca440b814..07cc3fcd52f 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc
@@ -15,6 +15,7 @@
#include <stdio.h>
#include <limits.h>
#include "gmem.h"
+#include "gmempp.h"
#include "FoFiBase.h"
//------------------------------------------------------------------------
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.cc
index e654fab19bf..6b3debb9dab 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.cc
@@ -13,6 +13,7 @@
#endif
#include <stdlib.h>
+#include "gmempp.h"
#include "FoFiEncodings.h"
//------------------------------------------------------------------------
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.cc
index 978cc700ee3..333fe0763b3 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.cc
@@ -17,6 +17,7 @@
#include <limits.h>
#include "gtypes.h"
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "GList.h"
#include "FoFiIdentifier.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc
index 8a1bfec7080..c1dbfe1c260 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc
@@ -19,6 +19,7 @@
#endif
#include "gtypes.h"
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "GHash.h"
#include "FoFiType1C.h"
@@ -119,7 +120,7 @@ struct TrueTypeLoca {
#define os2Tag 0x4f532f32
#define postTag 0x706f7374
-#ifdef HAVE_STD_SORT
+#if HAVE_STD_SORT
struct cmpTrueTypeLocaOffsetFunctor {
bool operator()(const TrueTypeLoca &loca1, const TrueTypeLoca &loca2) {
@@ -525,6 +526,119 @@ void FoFiTrueType::getFontMatrix(double *mat) {
delete ff;
}
+struct FoFiTrueTypeTrickyFont {
+ int cvtLen;
+ Guint cvtChecksum;
+ int fpgmLen;
+ Guint fpgmChecksum;
+ int prepLen;
+ Guint prepChecksum;
+};
+
+// This data was taken from the FreeType project.
+static FoFiTrueTypeTrickyFont trickyFonts[] = {
+ { 0x000002e4, 0x05bcf058, // MingLiU 1995
+ 0x000087c4, 0x28233bf1,
+ 0x000001e1, 0xa344a1ea },
+ { 0x000002e4, 0x05bcf058, // MingLiU 1996-
+ 0x000087c4, 0x28233bf1,
+ 0x000001e1, 0xa344a1eb },
+ { 0x00000350, 0x11e5ead4, // DFKaiShu
+ 0x00009063, 0x5a30ca3b,
+ 0x0000007e, 0x13a42602 },
+ { 0x00000350, 0x11e5ead4, // DFKaiShu2
+ 0x00008998, 0xa6e78c01,
+ 0x0000007e, 0x13a42602 },
+ { 0x00000008, 0xfffbfffc, // HuaTianKaiTi
+ 0x0000bea2, 0x9c9e48b8,
+ 0x00000008, 0x70020112 },
+ { 0x00000008, 0xfffbfffc, // HuaTianSongTi
+ 0x00017c39, 0x0a5a0483,
+ 0x00000008, 0x70020112 },
+ { 0x00000000, 0x00000000, // NEC fadpop7.ttf
+ 0x000000e5, 0x40c92555,
+ 0x0000117c, 0xa39b58e3 },
+ { 0x00000000, 0x00000000, // NEC fadrei5.ttf
+ 0x000000e5, 0x33c41652,
+ 0x00000f6a, 0x26d6c52a },
+ { 0x00000000, 0x00000000, // NEC fangot7.ttf
+ 0x0000019d, 0x6db1651d,
+ 0x00002492, 0x6c6e4b03 },
+ { 0x00000000, 0x00000000, // NEC fangyo5.ttf
+ 0x000000e5, 0x40c92555,
+ 0x0000117c, 0xde51fad0 },
+ { 0x00000000, 0x00000000, // NEC fankyo5.ttf
+ 0x000000e5, 0x85e47664,
+ 0x00001caa, 0xa6c62831 },
+ { 0x00000000, 0x00000000, // NEC fanrgo5.ttf
+ 0x0000019d, 0x2d891cfd,
+ 0x00001de8, 0xa0604633 },
+ { 0x00000000, 0x00000000, // NEC fangot5.ttc
+ 0x000001cb, 0x40aa774c,
+ 0x00001f9a, 0x9b5caa96 },
+ { 0x00000000, 0x00000000, // NEC fanmin3.ttc
+ 0x00000141, 0x0d3de9cb,
+ 0x00002280, 0xd4127766 },
+ { 0x00000000, 0x00000000, // NEC FA-Gothic, 1996
+ 0x000001f0, 0x4a692698,
+ 0x00001fca, 0x340d4346 },
+ { 0x00000000, 0x00000000, // NEC FA-Minchou, 1996
+ 0x00000166, 0xcd34c604,
+ 0x000022b0, 0x6cf31046 },
+ { 0x00000000, 0x00000000, // NEC FA-RoundGothicB, 1996
+ 0x0000019d, 0x5da75315,
+ 0x000022e0, 0x40745a5f },
+ { 0x00000000, 0x00000000, // NEC FA-RoundGothicM, 1996
+ 0x000001c2, 0xf055fc48,
+ 0x00001e18, 0x3900ded3 }
+};
+
+#define nTrickyFonts ((int)(sizeof(trickyFonts) / sizeof(FoFiTrueTypeTrickyFont)))
+
+// This looks at the length and checksum values for the cvt, fpgm, and
+// prep tables. The theory is that those tables will be the same,
+// even if the font is renamed and/or subsetted.
+GBool FoFiTrueType::checkForTrickyCJK() {
+ int cvtIdx, fpgmIdx, prepIdx;
+ int cvtLen, fpgmLen, prepLen;
+ Guint cvtChecksum, fpgmChecksum, prepChecksum;
+ int i;
+
+ if ((cvtIdx = seekTable("cvt ")) >= 0) {
+ cvtLen = tables[cvtIdx].len;
+ cvtChecksum = tables[cvtIdx].checksum;
+ } else {
+ cvtLen = 0;
+ cvtChecksum = 0;
+ }
+ if ((fpgmIdx = seekTable("fpgm")) >= 0) {
+ fpgmLen = tables[fpgmIdx].len;
+ fpgmChecksum = tables[fpgmIdx].checksum;
+ } else {
+ fpgmLen = 0;
+ fpgmChecksum = 0;
+ }
+ if ((prepIdx = seekTable("prep")) >= 0) {
+ prepLen = tables[prepIdx].len;
+ prepChecksum = tables[prepIdx].checksum;
+ } else {
+ prepLen = 0;
+ prepChecksum = 0;
+ }
+
+ for (i = 0; i < nTrickyFonts; ++i) {
+ if (cvtLen == trickyFonts[i].cvtLen &&
+ cvtChecksum == trickyFonts[i].cvtChecksum &&
+ fpgmLen == trickyFonts[i].fpgmLen &&
+ fpgmChecksum == trickyFonts[i].fpgmChecksum &&
+ prepLen == trickyFonts[i].prepLen &&
+ prepChecksum == trickyFonts[i].prepChecksum) {
+ return gTrue;
+ }
+ }
+ return gFalse;
+}
+
void FoFiTrueType::convertToType42(char *psName, char **encoding,
int *codeToGID,
FoFiOutputFunc outputFunc,
@@ -966,6 +1080,7 @@ void FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
unsortedLoca = gFalse;
i = seekTable("loca");
pos = tables[i].offset;
+ glyfLen = tables[seekTable("glyf")].len;
ok = gTrue;
for (i = 0; i <= nGlyphs; ++i) {
if (locaFmt) {
@@ -973,6 +1088,11 @@ void FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
} else {
locaTable[i].origOffset = 2 * getU16BE(pos + i*2, &ok);
}
+ if (locaTable[i].origOffset < 0 ||
+ locaTable[i].origOffset > glyfLen) {
+ locaTable[i].origOffset = glyfLen;
+ unsortedLoca = gTrue;
+ }
if (i > 0 && locaTable[i].origOffset < locaTable[i-1].origOffset) {
unsortedLoca = gTrue;
}
@@ -1562,11 +1682,6 @@ void FoFiTrueType::cvtCharStrings(char **encoding,
(*outputFunc)(outputStream, "/CharStrings 256 dict dup begin\n", 32);
(*outputFunc)(outputStream, "/.notdef 0 def\n", 15);
- // if there's no 'cmap' table, punt
- if (nCmaps == 0) {
- goto err;
- }
-
// map char name to glyph index:
// 1. use encoding to map name to char code
// 2. use codeToGID to map char code to glyph index
@@ -1597,7 +1712,6 @@ void FoFiTrueType::cvtCharStrings(char **encoding,
}
}
- err:
(*outputFunc)(outputStream, "end readonly def\n", 17);
}
@@ -2115,8 +2229,8 @@ void FoFiTrueType::parse(int fontNum, GBool allowHeadlessCFF) {
return;
}
- // make sure the loca table is sane (correct length and entries are
- // in bounds)
+ // make sure the loca table is sane (correct length)
+ // NB: out-of-bounds entries are handled in writeTTF()
if (!openTypeCFF) {
i = seekTable("loca");
if (tables[i].len < 0) {
@@ -2126,16 +2240,6 @@ void FoFiTrueType::parse(int fontNum, GBool allowHeadlessCFF) {
if (tables[i].len < (nGlyphs + 1) * (locaFmt ? 4 : 2)) {
nGlyphs = tables[i].len / (locaFmt ? 4 : 2) - 1;
}
- for (j = 0; j <= nGlyphs; ++j) {
- if (locaFmt) {
- pos = (int)getU32BE(tables[i].offset + j*4, &parsedOk);
- } else {
- pos = getU16BE(tables[i].offset + j*2, &parsedOk);
- }
- if (pos < 0 || pos > len) {
- parsedOk = gFalse;
- }
- }
if (!parsedOk) {
return;
}
@@ -2245,6 +2349,7 @@ void FoFiTrueType::readPostTable() {
stringIdx = 0;
stringPos = tablePos + 34 + 2*n;
for (i = 0; i < n; ++i) {
+ ok = gTrue;
j = getU16BE(tablePos + 34 + 2*i, &ok);
if (j < 258) {
nameToGID->removeInt(macGlyphNames[j]);
@@ -2256,12 +2361,12 @@ void FoFiTrueType::readPostTable() {
stringIdx < j;
++stringIdx, stringPos += 1 + getU8(stringPos, &ok)) ;
if (!ok) {
- goto err;
+ continue;
}
}
m = getU8(stringPos, &ok);
if (!ok || !checkRegion(stringPos + 1, m)) {
- goto err;
+ continue;
}
name = new GString((char *)&file[stringPos + 1], m);
nameToGID->removeInt(name);
@@ -2275,7 +2380,7 @@ void FoFiTrueType::readPostTable() {
for (i = 0; i < nGlyphs; ++i) {
j = getU8(tablePos + 32 + i, &ok);
if (!ok) {
- goto err;
+ continue;
}
if (j < 258) {
nameToGID->removeInt(macGlyphNames[j]);
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h
index 2cf9417d609..afa56697ba8 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h
@@ -95,6 +95,10 @@ public:
// for OpenType CFF fonts.)
void getFontMatrix(double *mat);
+ // Returns true if this looks like a CJK font that uses bytecode
+ // instructions to assemble glyphs.
+ GBool checkForTrickyCJK();
+
// Convert to a Type 42 font, suitable for embedding in a PostScript
// file. <psName> will be used as the PostScript font name (so we
// don't need to depend on the 'name' table in the font). The
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc
index 9eeb363d459..4ff1369aaf8 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc
@@ -15,6 +15,7 @@
#include <stdlib.h>
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "FoFiEncodings.h"
#include "FoFiType1.h"
@@ -198,7 +199,7 @@ void FoFiType1::parse() {
gotMatrix = gFalse;
for (i = 1, line = (char *)file;
- i <= 100 && line && (!name || !encoding);
+ i <= 100 && line && (!name || !encoding || !gotMatrix);
++i) {
// get font name
@@ -255,6 +256,7 @@ void FoFiType1::parse() {
if (code >= 0 && code < 256) {
c = *p2;
*p2 = '\0';
+ gfree(encoding[code]);
encoding[code] = copyString(p);
*p2 = c;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc
index 7986cee88f1..f4de9571d1f 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc
@@ -16,6 +16,7 @@
#include <string.h>
#include <math.h>
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "FoFiEncodings.h"
#include "FoFiType1C.h"
@@ -25,6 +26,44 @@
static char hexChars[17] = "0123456789ABCDEF";
//------------------------------------------------------------------------
+
+GBool Type1COp::isZero() {
+ switch (kind) {
+ case type1COpInteger: return intgr == 0;
+ case type1COpFloat: return flt == 0;
+ case type1COpRational: return rat.num == 0;
+ default: return gFalse; // shouldn't happen
+ }
+}
+
+GBool Type1COp::isNegative() {
+ switch (kind) {
+ case type1COpInteger: return intgr < 0;
+ case type1COpFloat: return flt < 0;
+ case type1COpRational: return (rat.num < 0) != (rat.den < 0);
+ default: return gFalse; // shouldn't happen
+ }
+}
+
+int Type1COp::toInt() {
+ switch (kind) {
+ case type1COpInteger: return intgr;
+ case type1COpFloat: return (int)flt;
+ case type1COpRational: return rat.num / rat.den;
+ default: return 0; // shouldn't happen
+ }
+}
+
+double Type1COp::toFloat() {
+ switch (kind) {
+ case type1COpInteger: return (double)intgr;
+ case type1COpFloat: return flt;
+ case type1COpRational: return (double)rat.num / (double)rat.den;
+ default: return 0.0; // shouldn't happen
+ }
+}
+
+//------------------------------------------------------------------------
// FoFiType1C
//------------------------------------------------------------------------
@@ -744,7 +783,7 @@ void FoFiType1C::convertToCIDType0(char *psName, int *codeMap, int nCodes,
break;
}
}
- if (j == privateDicts[0].nStemSnapH) {
+ if (j == privateDicts[i].nStemSnapH) {
(*outputFunc)(outputStream, "/StemSnapH [", 12);
for (j = 0; j < privateDicts[i].nStemSnapH; ++j) {
buf = GString::format("{0:s}{1:.4g}",
@@ -763,7 +802,7 @@ void FoFiType1C::convertToCIDType0(char *psName, int *codeMap, int nCodes,
break;
}
}
- if (j == privateDicts[0].nStemSnapV) {
+ if (j == privateDicts[i].nStemSnapV) {
(*outputFunc)(outputStream, "/StemSnapV [", 12);
for (j = 0; j < privateDicts[i].nStemSnapV; ++j) {
buf = GString::format("{0:s}{1:.4g}",
@@ -1060,7 +1099,7 @@ void FoFiType1C::convertToType0(char *psName, int *codeMap, int nCodes,
break;
}
}
- if (k == privateDicts[0].nStemSnapH) {
+ if (k == privateDicts[fd].nStemSnapH) {
eexecWrite(&eb, "/StemSnapH [");
for (k = 0; k < privateDicts[fd].nStemSnapH; ++k) {
buf = GString::format("{0:s}{1:.4g}",
@@ -1080,7 +1119,7 @@ void FoFiType1C::convertToType0(char *psName, int *codeMap, int nCodes,
break;
}
}
- if (k == privateDicts[0].nStemSnapV) {
+ if (k == privateDicts[fd].nStemSnapV) {
eexecWrite(&eb, "/StemSnapV [");
for (k = 0; k < privateDicts[fd].nStemSnapV; ++k) {
buf = GString::format("{0:s}{1:.4g}",
@@ -1228,11 +1267,12 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
Type1CIndex *subrIdx, Type1CPrivateDict *pDict,
GBool top) {
Type1CIndexVal val;
- GBool ok, dFP;
+ Type1COp zero, tmp;
+ GBool ok, dInt;
double d, dx, dy;
Gushort r2;
Guchar byte;
- int pos, subrBias, start, i, k;
+ int pos, subrBias, start, num, den, i, k;
start = charBuf->getLength();
if (top) {
@@ -1246,6 +1286,9 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
openPath = gFalse;
}
+ zero.kind = type1COpInteger;
+ zero.intgr = 0;
+
pos = offset;
while (pos < offset + nBytes) {
ok = gTrue;
@@ -1253,7 +1296,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
if (!ok) {
break;
}
- if (!ops[nOps - 1].isNum) {
+ if (ops[nOps - 1].kind == type1COpOperator) {
--nOps; // drop the operator
switch (ops[nOps].op) {
case 0x0001: // hstem
@@ -1265,21 +1308,47 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
//~ error(-1, "Wrong number of args (%d) to Type 2 hstem", nOps);
}
d = 0;
- dFP = gFalse;
- for (k = 0; k < nOps; k += 2) {
+ dInt = gTrue;
+ for (k = 0; k+1 < nOps; k += 2) {
// convert Type 2 edge hints (-20 or -21) to Type 1 ghost hints
- if (ops[k+1].num < 0) {
- d += ops[k].num + ops[k+1].num;
- dFP |= ops[k].isFP | ops[k+1].isFP;
- cvtNum(d, dFP, charBuf);
- cvtNum(-ops[k+1].num, ops[k+1].isFP, charBuf);
+ if (ops[k+1].isNegative()) {
+ d += ops[k].toFloat() + ops[k+1].toFloat();
+ dInt &= ops[k].kind == type1COpInteger;
+ dInt &= ops[k+1].kind == type1COpInteger;
+ if (dInt) {
+ tmp.kind = type1COpInteger;
+ tmp.intgr = (int)(d + 0.5);
+ } else {
+ tmp.kind = type1COpFloat;
+ tmp.flt = d;
+ }
+ cvtNum(tmp, charBuf);
+ if (ops[k+1].kind == type1COpInteger) {
+ tmp.kind = type1COpInteger;
+ tmp.intgr = -ops[k+1].intgr;
+ } else if (ops[k+1].kind == type1COpRational) {
+ tmp.kind = type1COpRational;
+ tmp.rat.num = -ops[k+1].rat.num;
+ tmp.rat.den = ops[k+1].rat.den;
+ } else {
+ tmp.kind = type1COpFloat;
+ tmp.flt = -ops[k+1].toFloat();
+ }
+ cvtNum(tmp, charBuf);
} else {
- d += ops[k].num;
- dFP |= ops[k].isFP;
- cvtNum(d, dFP, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- d += ops[k+1].num;
- dFP |= ops[k+1].isFP;
+ d += ops[k].toFloat();
+ dInt &= ops[k].kind == type1COpInteger;
+ if (dInt) {
+ tmp.kind = type1COpInteger;
+ tmp.intgr = (int)(d + 0.5);
+ } else {
+ tmp.kind = type1COpFloat;
+ tmp.flt = d;
+ }
+ cvtNum(tmp, charBuf);
+ cvtNum(ops[k+1], charBuf);
+ d += ops[k+1].toFloat();
+ dInt &= ops[k+1].kind == type1COpInteger;
}
charBuf->append((char)1);
}
@@ -1295,21 +1364,47 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
//~ error(-1, "Wrong number of args (%d) to Type 2 vstem", nOps);
}
d = 0;
- dFP = gFalse;
- for (k = 0; k < nOps; k += 2) {
+ dInt = gTrue;
+ for (k = 0; k+1 < nOps; k += 2) {
// convert Type 2 edge hints (-20 or -21) to Type 1 ghost hints
- if (ops[k+1].num < 0) {
- d += ops[k].num + ops[k+1].num;
- dFP |= ops[k].isFP | ops[k+1].isFP;
- cvtNum(d, dFP, charBuf);
- cvtNum(-ops[k+1].num, ops[k+1].isFP, charBuf);
+ if (ops[k+1].isNegative()) {
+ d += ops[k].toFloat() + ops[k+1].toFloat();
+ dInt &= ops[k].kind == type1COpInteger;
+ dInt &= ops[k+1].kind == type1COpInteger;
+ if (dInt) {
+ tmp.kind = type1COpInteger;
+ tmp.intgr = (int)(d + 0.5);
+ } else {
+ tmp.kind = type1COpFloat;
+ tmp.flt = d;
+ }
+ cvtNum(tmp, charBuf);
+ if (ops[k+1].kind == type1COpInteger) {
+ tmp.kind = type1COpInteger;
+ tmp.intgr = -ops[k+1].intgr;
+ } else if (ops[k+1].kind == type1COpRational) {
+ tmp.kind = type1COpRational;
+ tmp.rat.num = -ops[k+1].rat.num;
+ tmp.rat.den = ops[k+1].rat.den;
+ } else {
+ tmp.kind = type1COpFloat;
+ tmp.flt = -ops[k+1].toFloat();
+ }
+ cvtNum(tmp, charBuf);
} else {
- d += ops[k].num;
- dFP |= ops[k].isFP;
- cvtNum(d, dFP, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- d += ops[k+1].num;
- dFP |= ops[k+1].isFP;
+ d += ops[k].toFloat();
+ dInt &= ops[k].kind == type1COpInteger;
+ if (dInt) {
+ tmp.kind = type1COpInteger;
+ tmp.intgr = (int)(d + 0.5);
+ } else {
+ tmp.kind = type1COpFloat;
+ tmp.flt = d;
+ }
+ cvtNum(tmp, charBuf);
+ cvtNum(ops[k+1], charBuf);
+ d += ops[k+1].toFloat();
+ dInt &= ops[k+1].kind == type1COpInteger;
}
charBuf->append((char)3);
}
@@ -1328,7 +1423,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
if (nOps != 1) {
//~ error(-1, "Wrong number of args (%d) to Type 2 vmoveto", nOps);
}
- cvtNum(ops[0].num, ops[0].isFP, charBuf);
+ cvtNum(ops[0], charBuf);
charBuf->append((char)4);
nOps = 0;
break;
@@ -1336,9 +1431,9 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
if (nOps < 2 || nOps % 2 != 0) {
//~ error(-1, "Wrong number of args (%d) to Type 2 rlineto", nOps);
}
- for (k = 0; k < nOps; k += 2) {
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
+ for (k = 0; k+1 < nOps; k += 2) {
+ cvtNum(ops[k], charBuf);
+ cvtNum(ops[k+1], charBuf);
charBuf->append((char)5);
}
nOps = 0;
@@ -1349,7 +1444,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
//~ error(-1, "Wrong number of args (%d) to Type 2 hlineto", nOps);
}
for (k = 0; k < nOps; ++k) {
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
+ cvtNum(ops[k], charBuf);
charBuf->append((char)((k & 1) ? 7 : 6));
}
nOps = 0;
@@ -1360,7 +1455,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
//~ error(-1, "Wrong number of args (%d) to Type 2 vlineto", nOps);
}
for (k = 0; k < nOps; ++k) {
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
+ cvtNum(ops[k], charBuf);
charBuf->append((char)((k & 1) ? 6 : 7));
}
nOps = 0;
@@ -1371,12 +1466,12 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
//~ error(-1, "Wrong number of args (%d) to Type 2 rrcurveto", nOps);
}
for (k = 0; k < nOps; k += 6) {
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
- cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
- cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
- cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf);
+ cvtNum(ops[k], charBuf);
+ cvtNum(ops[k+1], charBuf);
+ cvtNum(ops[k+2], charBuf);
+ cvtNum(ops[k+3], charBuf);
+ cvtNum(ops[k+4], charBuf);
+ cvtNum(ops[k+5], charBuf);
charBuf->append((char)8);
}
nOps = 0;
@@ -1386,7 +1481,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
if (nOps >= 1) {
subrBias = (subrIdx->len < 1240)
? 107 : (subrIdx->len < 33900) ? 1131 : 32768;
- k = subrBias + (int)ops[nOps - 1].num;
+ k = subrBias + ops[nOps - 1].toInt();
--nOps;
ok = gTrue;
getIndexVal(subrIdx, k, &val, &ok);
@@ -1411,11 +1506,11 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
openPath = gFalse;
}
if (nOps == 4) {
- cvtNum(0, gFalse, charBuf);
- cvtNum(ops[0].num, ops[0].isFP, charBuf);
- cvtNum(ops[1].num, ops[1].isFP, charBuf);
- cvtNum(ops[2].num, ops[2].isFP, charBuf);
- cvtNum(ops[3].num, ops[3].isFP, charBuf);
+ cvtNum(zero, charBuf);
+ cvtNum(ops[0], charBuf);
+ cvtNum(ops[1], charBuf);
+ cvtNum(ops[2], charBuf);
+ cvtNum(ops[3], charBuf);
charBuf->append((char)12)->append((char)6);
} else if (nOps == 0) {
charBuf->append((char)14);
@@ -1492,8 +1587,8 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
if (nOps != 2) {
//~ error(-1, "Wrong number of args (%d) to Type 2 rmoveto", nOps);
}
- cvtNum(ops[0].num, ops[0].isFP, charBuf);
- cvtNum(ops[1].num, ops[1].isFP, charBuf);
+ cvtNum(ops[0], charBuf);
+ cvtNum(ops[1], charBuf);
charBuf->append((char)21);
nOps = 0;
break;
@@ -1509,7 +1604,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
if (nOps != 1) {
//~ error(-1, "Wrong number of args (%d) to Type 2 hmoveto", nOps);
}
- cvtNum(ops[0].num, ops[0].isFP, charBuf);
+ cvtNum(ops[0], charBuf);
charBuf->append((char)22);
nOps = 0;
break;
@@ -1529,17 +1624,17 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
if (nOps < 8 || (nOps - 2) % 6 != 0) {
//~ error(-1, "Wrong number of args (%d) to Type 2 rcurveline", nOps);
}
- for (k = 0; k < nOps - 2; k += 6) {
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
- cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
- cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
- cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf);
+ for (k = 0; k <= nOps - 8; k += 6) {
+ cvtNum(ops[k], charBuf);
+ cvtNum(ops[k+1], charBuf);
+ cvtNum(ops[k+2], charBuf);
+ cvtNum(ops[k+3], charBuf);
+ cvtNum(ops[k+4], charBuf);
+ cvtNum(ops[k+5], charBuf);
charBuf->append((char)8);
}
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(ops[k+1].num, ops[k].isFP, charBuf);
+ cvtNum(ops[k], charBuf);
+ cvtNum(ops[k+1], charBuf);
charBuf->append((char)5);
nOps = 0;
openPath = gTrue;
@@ -1548,17 +1643,17 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
if (nOps < 8 || (nOps - 6) % 2 != 0) {
//~ error(-1, "Wrong number of args (%d) to Type 2 rlinecurve", nOps);
}
- for (k = 0; k < nOps - 6; k += 2) {
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(ops[k+1].num, ops[k].isFP, charBuf);
+ for (k = 0; k <= nOps - 8; k += 2) {
+ cvtNum(ops[k], charBuf);
+ cvtNum(ops[k+1], charBuf);
charBuf->append((char)5);
}
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
- cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
- cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
- cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf);
+ cvtNum(ops[k], charBuf);
+ cvtNum(ops[k+1], charBuf);
+ cvtNum(ops[k+2], charBuf);
+ cvtNum(ops[k+3], charBuf);
+ cvtNum(ops[k+4], charBuf);
+ cvtNum(ops[k+5], charBuf);
charBuf->append((char)8);
nOps = 0;
openPath = gTrue;
@@ -1567,25 +1662,25 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
//~ error(-1, "Wrong number of args (%d) to Type 2 vvcurveto", nOps);
}
- if (nOps % 2 == 1) {
- cvtNum(ops[0].num, ops[0].isFP, charBuf);
- cvtNum(ops[1].num, ops[1].isFP, charBuf);
- cvtNum(ops[2].num, ops[2].isFP, charBuf);
- cvtNum(ops[3].num, ops[3].isFP, charBuf);
- cvtNum(0, gFalse, charBuf);
- cvtNum(ops[4].num, ops[4].isFP, charBuf);
+ if (nOps % 2 == 1 && nOps >= 5) {
+ cvtNum(ops[0], charBuf);
+ cvtNum(ops[1], charBuf);
+ cvtNum(ops[2], charBuf);
+ cvtNum(ops[3], charBuf);
+ cvtNum(zero, charBuf);
+ cvtNum(ops[4], charBuf);
charBuf->append((char)8);
k = 5;
} else {
k = 0;
}
- for (; k < nOps; k += 4) {
- cvtNum(0, gFalse, charBuf);
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
- cvtNum(0, gFalse, charBuf);
- cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
+ for (; k+3 < nOps; k += 4) {
+ cvtNum(zero, charBuf);
+ cvtNum(ops[k], charBuf);
+ cvtNum(ops[k+1], charBuf);
+ cvtNum(ops[k+2], charBuf);
+ cvtNum(zero, charBuf);
+ cvtNum(ops[k+3], charBuf);
charBuf->append((char)8);
}
nOps = 0;
@@ -1595,25 +1690,25 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
//~ error(-1, "Wrong number of args (%d) to Type 2 hhcurveto", nOps);
}
- if (nOps % 2 == 1) {
- cvtNum(ops[1].num, ops[1].isFP, charBuf);
- cvtNum(ops[0].num, ops[0].isFP, charBuf);
- cvtNum(ops[2].num, ops[2].isFP, charBuf);
- cvtNum(ops[3].num, ops[3].isFP, charBuf);
- cvtNum(ops[4].num, ops[4].isFP, charBuf);
- cvtNum(0, gFalse, charBuf);
+ if (nOps % 2 == 1 && nOps >= 5) {
+ cvtNum(ops[1], charBuf);
+ cvtNum(ops[0], charBuf);
+ cvtNum(ops[2], charBuf);
+ cvtNum(ops[3], charBuf);
+ cvtNum(ops[4], charBuf);
+ cvtNum(zero, charBuf);
charBuf->append((char)8);
k = 5;
} else {
k = 0;
}
- for (; k < nOps; k += 4) {
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(0, gFalse, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
- cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
- cvtNum(0, gFalse, charBuf);
+ for (; k+3 < nOps; k += 4) {
+ cvtNum(ops[k], charBuf);
+ cvtNum(zero, charBuf);
+ cvtNum(ops[k+1], charBuf);
+ cvtNum(ops[k+2], charBuf);
+ cvtNum(ops[k+3], charBuf);
+ cvtNum(zero, charBuf);
charBuf->append((char)8);
}
nOps = 0;
@@ -1621,7 +1716,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
break;
case 0x001d: // callgsubr
if (nOps >= 1) {
- k = gsubrBias + (int)ops[nOps - 1].num;
+ k = gsubrBias + ops[nOps - 1].toInt();
--nOps;
ok = gTrue;
getIndexVal(&gsubrIdx, k, &val, &ok);
@@ -1637,36 +1732,36 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
//~ error(-1, "Wrong number of args (%d) to Type 2 vhcurveto", nOps);
}
- for (k = 0; k < nOps && k != nOps-5; k += 4) {
+ for (k = 0; k+3 < nOps && k != nOps-5; k += 4) {
if (k % 8 == 0) {
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
- cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
+ cvtNum(ops[k], charBuf);
+ cvtNum(ops[k+1], charBuf);
+ cvtNum(ops[k+2], charBuf);
+ cvtNum(ops[k+3], charBuf);
charBuf->append((char)30);
} else {
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
- cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
+ cvtNum(ops[k], charBuf);
+ cvtNum(ops[k+1], charBuf);
+ cvtNum(ops[k+2], charBuf);
+ cvtNum(ops[k+3], charBuf);
charBuf->append((char)31);
}
}
if (k == nOps-5) {
if (k % 8 == 0) {
- cvtNum(0, gFalse, charBuf);
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
- cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
- cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
+ cvtNum(zero, charBuf);
+ cvtNum(ops[k], charBuf);
+ cvtNum(ops[k+1], charBuf);
+ cvtNum(ops[k+2], charBuf);
+ cvtNum(ops[k+3], charBuf);
+ cvtNum(ops[k+4], charBuf);
} else {
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(0, gFalse, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
- cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
- cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
+ cvtNum(ops[k], charBuf);
+ cvtNum(zero, charBuf);
+ cvtNum(ops[k+1], charBuf);
+ cvtNum(ops[k+2], charBuf);
+ cvtNum(ops[k+4], charBuf);
+ cvtNum(ops[k+3], charBuf);
}
charBuf->append((char)8);
}
@@ -1677,36 +1772,36 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
//~ error(-1, "Wrong number of args (%d) to Type 2 hvcurveto", nOps);
}
- for (k = 0; k < nOps && k != nOps-5; k += 4) {
+ for (k = 0; k+3 < nOps && k != nOps-5; k += 4) {
if (k % 8 == 0) {
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
- cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
+ cvtNum(ops[k], charBuf);
+ cvtNum(ops[k+1], charBuf);
+ cvtNum(ops[k+2], charBuf);
+ cvtNum(ops[k+3], charBuf);
charBuf->append((char)31);
} else {
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
- cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
+ cvtNum(ops[k], charBuf);
+ cvtNum(ops[k+1], charBuf);
+ cvtNum(ops[k+2], charBuf);
+ cvtNum(ops[k+3], charBuf);
charBuf->append((char)30);
}
}
if (k == nOps-5) {
if (k % 8 == 0) {
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(0, gFalse, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
- cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
- cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
+ cvtNum(ops[k], charBuf);
+ cvtNum(zero, charBuf);
+ cvtNum(ops[k+1], charBuf);
+ cvtNum(ops[k+2], charBuf);
+ cvtNum(ops[k+4], charBuf);
+ cvtNum(ops[k+3], charBuf);
} else {
- cvtNum(0, gFalse, charBuf);
- cvtNum(ops[k].num, ops[k].isFP, charBuf);
- cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
- cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
- cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
- cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
+ cvtNum(zero, charBuf);
+ cvtNum(ops[k], charBuf);
+ cvtNum(ops[k+1], charBuf);
+ cvtNum(ops[k+2], charBuf);
+ cvtNum(ops[k+3], charBuf);
+ cvtNum(ops[k+4], charBuf);
}
charBuf->append((char)8);
}
@@ -1717,6 +1812,18 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
// ignored
nOps = 0;
break;
+ case 0x0c0c: // div
+ if (nOps >= 2) {
+ num = ops[nOps-2].toInt();
+ den = ops[nOps-1].toInt();
+ --nOps;
+ ops[nOps-1].kind = type1COpRational;
+ ops[nOps-1].rat.num = num;
+ ops[nOps-1].rat.den = den;
+ } else {
+ //~ error(-1, "Wrong number of args (%d) to Type 2 div", nOps);
+ }
+ break;
case 0x0c03: // and
case 0x0c04: // or
case 0x0c05: // not
@@ -1724,7 +1831,6 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
case 0x0c09: // abs
case 0x0c0a: // add
case 0x0c0b: // sub
- case 0x0c0c: // div
case 0x0c0d: // load
case 0x0c0e: // neg
case 0x0c0f: // eq
@@ -1743,96 +1849,141 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
nOps = 0;
break;
case 0x0c22: // hflex
- if (nOps != 7) {
+ if (nOps == 7) {
+ cvtNum(ops[0], charBuf);
+ cvtNum(zero, charBuf);
+ cvtNum(ops[1], charBuf);
+ cvtNum(ops[2], charBuf);
+ cvtNum(ops[3], charBuf);
+ cvtNum(zero, charBuf);
+ charBuf->append((char)8);
+ cvtNum(ops[4], charBuf);
+ cvtNum(zero, charBuf);
+ cvtNum(ops[5], charBuf);
+ if (ops[2].kind == type1COpInteger) {
+ tmp.kind = type1COpInteger;
+ tmp.intgr = -ops[2].intgr;
+ } else if (ops[2].kind == type1COpRational) {
+ tmp.kind = type1COpRational;
+ tmp.rat.num = -ops[2].rat.num;
+ tmp.rat.den = ops[2].rat.den;
+ } else {
+ tmp.kind = type1COpFloat;
+ tmp.flt = -ops[2].toFloat();
+ }
+ cvtNum(tmp, charBuf);
+ cvtNum(ops[6], charBuf);
+ cvtNum(zero, charBuf);
+ charBuf->append((char)8);
+ } else {
//~ error(-1, "Wrong number of args (%d) to Type 2 hflex", nOps);
}
- cvtNum(ops[0].num, ops[0].isFP, charBuf);
- cvtNum(0, gFalse, charBuf);
- cvtNum(ops[1].num, ops[1].isFP, charBuf);
- cvtNum(ops[2].num, ops[2].isFP, charBuf);
- cvtNum(ops[3].num, ops[3].isFP, charBuf);
- cvtNum(0, gFalse, charBuf);
- charBuf->append((char)8);
- cvtNum(ops[4].num, ops[4].isFP, charBuf);
- cvtNum(0, gFalse, charBuf);
- cvtNum(ops[5].num, ops[5].isFP, charBuf);
- cvtNum(-ops[2].num, ops[2].isFP, charBuf);
- cvtNum(ops[6].num, ops[6].isFP, charBuf);
- cvtNum(0, gFalse, charBuf);
- charBuf->append((char)8);
nOps = 0;
openPath = gTrue;
break;
case 0x0c23: // flex
- if (nOps != 13) {
+ if (nOps == 13) {
+ cvtNum(ops[0], charBuf);
+ cvtNum(ops[1], charBuf);
+ cvtNum(ops[2], charBuf);
+ cvtNum(ops[3], charBuf);
+ cvtNum(ops[4], charBuf);
+ cvtNum(ops[5], charBuf);
+ charBuf->append((char)8);
+ cvtNum(ops[6], charBuf);
+ cvtNum(ops[7], charBuf);
+ cvtNum(ops[8], charBuf);
+ cvtNum(ops[9], charBuf);
+ cvtNum(ops[10], charBuf);
+ cvtNum(ops[11], charBuf);
+ charBuf->append((char)8);
+ } else {
//~ error(-1, "Wrong number of args (%d) to Type 2 flex", nOps);
}
- cvtNum(ops[0].num, ops[0].isFP, charBuf);
- cvtNum(ops[1].num, ops[1].isFP, charBuf);
- cvtNum(ops[2].num, ops[2].isFP, charBuf);
- cvtNum(ops[3].num, ops[3].isFP, charBuf);
- cvtNum(ops[4].num, ops[4].isFP, charBuf);
- cvtNum(ops[5].num, ops[5].isFP, charBuf);
- charBuf->append((char)8);
- cvtNum(ops[6].num, ops[6].isFP, charBuf);
- cvtNum(ops[7].num, ops[7].isFP, charBuf);
- cvtNum(ops[8].num, ops[8].isFP, charBuf);
- cvtNum(ops[9].num, ops[9].isFP, charBuf);
- cvtNum(ops[10].num, ops[10].isFP, charBuf);
- cvtNum(ops[11].num, ops[11].isFP, charBuf);
- charBuf->append((char)8);
nOps = 0;
openPath = gTrue;
break;
case 0x0c24: // hflex1
- if (nOps != 9) {
+ if (nOps == 9) {
+ cvtNum(ops[0], charBuf);
+ cvtNum(ops[1], charBuf);
+ cvtNum(ops[2], charBuf);
+ cvtNum(ops[3], charBuf);
+ cvtNum(ops[4], charBuf);
+ cvtNum(zero, charBuf);
+ charBuf->append((char)8);
+ cvtNum(ops[5], charBuf);
+ cvtNum(zero, charBuf);
+ cvtNum(ops[6], charBuf);
+ cvtNum(ops[7], charBuf);
+ cvtNum(ops[8], charBuf);
+ if (ops[1].kind == type1COpInteger &&
+ ops[3].kind == type1COpInteger &&
+ ops[7].kind == type1COpInteger) {
+ tmp.kind = type1COpInteger;
+ tmp.intgr = -(ops[1].intgr + ops[3].intgr + ops[7].intgr);
+ } else {
+ tmp.kind = type1COpFloat;
+ tmp.flt = -(ops[1].toFloat() + ops[3].toFloat() + ops[7].toFloat());
+ }
+ cvtNum(tmp, charBuf);
+ charBuf->append((char)8);
+ } else {
//~ error(-1, "Wrong number of args (%d) to Type 2 hflex1", nOps);
}
- cvtNum(ops[0].num, ops[0].isFP, charBuf);
- cvtNum(ops[1].num, ops[1].isFP, charBuf);
- cvtNum(ops[2].num, ops[2].isFP, charBuf);
- cvtNum(ops[3].num, ops[3].isFP, charBuf);
- cvtNum(ops[4].num, ops[4].isFP, charBuf);
- cvtNum(0, gFalse, charBuf);
- charBuf->append((char)8);
- cvtNum(ops[5].num, ops[5].isFP, charBuf);
- cvtNum(0, gFalse, charBuf);
- cvtNum(ops[6].num, ops[6].isFP, charBuf);
- cvtNum(ops[7].num, ops[7].isFP, charBuf);
- cvtNum(ops[8].num, ops[8].isFP, charBuf);
- cvtNum(-(ops[1].num + ops[3].num + ops[7].num),
- ops[1].isFP | ops[3].isFP | ops[7].isFP, charBuf);
- charBuf->append((char)8);
nOps = 0;
openPath = gTrue;
break;
case 0x0c25: // flex1
- if (nOps != 11) {
- //~ error(-1, "Wrong number of args (%d) to Type 2 flex1", nOps);
- }
- cvtNum(ops[0].num, ops[0].isFP, charBuf);
- cvtNum(ops[1].num, ops[1].isFP, charBuf);
- cvtNum(ops[2].num, ops[2].isFP, charBuf);
- cvtNum(ops[3].num, ops[3].isFP, charBuf);
- cvtNum(ops[4].num, ops[4].isFP, charBuf);
- cvtNum(ops[5].num, ops[5].isFP, charBuf);
- charBuf->append((char)8);
- cvtNum(ops[6].num, ops[6].isFP, charBuf);
- cvtNum(ops[7].num, ops[7].isFP, charBuf);
- cvtNum(ops[8].num, ops[8].isFP, charBuf);
- cvtNum(ops[9].num, ops[9].isFP, charBuf);
- dx = ops[0].num + ops[2].num + ops[4].num + ops[6].num + ops[8].num;
- dy = ops[1].num + ops[3].num + ops[5].num + ops[7].num + ops[9].num;
- if (fabs(dx) > fabs(dy)) {
- cvtNum(ops[10].num, ops[10].isFP, charBuf);
- cvtNum(-dy, ops[1].isFP | ops[3].isFP | ops[5].isFP |
- ops[7].isFP | ops[9].isFP, charBuf);
+ if (nOps == 11) {
+ cvtNum(ops[0], charBuf);
+ cvtNum(ops[1], charBuf);
+ cvtNum(ops[2], charBuf);
+ cvtNum(ops[3], charBuf);
+ cvtNum(ops[4], charBuf);
+ cvtNum(ops[5], charBuf);
+ charBuf->append((char)8);
+ cvtNum(ops[6], charBuf);
+ cvtNum(ops[7], charBuf);
+ cvtNum(ops[8], charBuf);
+ cvtNum(ops[9], charBuf);
+ dx = ops[0].toFloat() + ops[2].toFloat() + ops[4].toFloat()
+ + ops[6].toFloat() + ops[8].toFloat();
+ dy = ops[1].toFloat() + ops[3].toFloat() + ops[5].toFloat()
+ + ops[7].toFloat() + ops[9].toFloat();
+ if (fabs(dx) > fabs(dy)) {
+ cvtNum(ops[10], charBuf);
+ if (ops[1].kind == type1COpInteger &&
+ ops[3].kind == type1COpInteger &&
+ ops[5].kind == type1COpInteger &&
+ ops[7].kind == type1COpInteger &&
+ ops[9].kind == type1COpInteger) {
+ tmp.kind = type1COpInteger;
+ tmp.intgr = -(int)dy;
+ } else {
+ tmp.kind = type1COpFloat;
+ tmp.flt = -dy;
+ }
+ cvtNum(tmp, charBuf);
+ } else {
+ if (ops[0].kind == type1COpInteger &&
+ ops[2].kind == type1COpInteger &&
+ ops[4].kind == type1COpInteger &&
+ ops[6].kind == type1COpInteger &&
+ ops[8].kind == type1COpInteger) {
+ tmp.kind = type1COpInteger;
+ tmp.intgr = -(int)dx;
+ } else {
+ tmp.kind = type1COpFloat;
+ tmp.flt = -dx;
+ }
+ cvtNum(tmp, charBuf);
+ cvtNum(ops[10], charBuf);
+ }
+ charBuf->append((char)8);
} else {
- cvtNum(-dx, ops[0].isFP | ops[2].isFP | ops[4].isFP |
- ops[6].isFP | ops[8].isFP, charBuf);
- cvtNum(ops[10].num, ops[10].isFP, charBuf);
+ //~ error(-1, "Wrong number of args (%d) to Type 2 flex1", nOps);
}
- charBuf->append((char)8);
nOps = 0;
openPath = gTrue;
break;
@@ -1858,52 +2009,46 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
void FoFiType1C::cvtGlyphWidth(GBool useOp, GString *charBuf,
Type1CPrivateDict *pDict) {
- double w;
- GBool wFP;
+ Type1COp zero, w;
int i;
if (useOp) {
- w = pDict->nominalWidthX + ops[0].num;
- wFP = pDict->nominalWidthXFP | ops[0].isFP;
+ if (pDict->nominalWidthXInt & (ops[0].kind == type1COpInteger)) {
+ w.kind = type1COpInteger;
+ w.intgr = (int)(pDict->nominalWidthX + ops[0].intgr);
+ } else {
+ w.kind = type1COpFloat;
+ w.flt = pDict->nominalWidthX + ops[0].toFloat();
+ }
for (i = 1; i < nOps; ++i) {
ops[i-1] = ops[i];
}
--nOps;
} else {
- w = pDict->defaultWidthX;
- wFP = pDict->defaultWidthXFP;
+ if (pDict->defaultWidthXInt) {
+ w.kind = type1COpInteger;
+ w.intgr = (int)pDict->defaultWidthX;
+ } else {
+ w.kind = type1COpFloat;
+ w.flt = pDict->defaultWidthX;
+ }
}
- cvtNum(0, gFalse, charBuf);
- cvtNum(w, wFP, charBuf);
+ zero.kind = type1COpInteger;
+ zero.intgr = 0;
+ cvtNum(zero, charBuf);
+ cvtNum(w, charBuf);
charBuf->append((char)13);
}
-void FoFiType1C::cvtNum(double x, GBool isFP, GString *charBuf) {
+void FoFiType1C::cvtNum(Type1COp op, GString *charBuf) {
+ Type1COp tmp;
Guchar buf[12];
int y, n;
n = 0;
- if (isFP) {
- if (x >= -32768 && x < 32768) {
- y = (int)(x * 256.0);
- buf[0] = 255;
- buf[1] = (Guchar)(y >> 24);
- buf[2] = (Guchar)(y >> 16);
- buf[3] = (Guchar)(y >> 8);
- buf[4] = (Guchar)y;
- buf[5] = 255;
- buf[6] = 0;
- buf[7] = 0;
- buf[8] = 1;
- buf[9] = 0;
- buf[10] = 12;
- buf[11] = 12;
- n = 12;
- } else {
- //~ error(-1, "Type 2 fixed point constant out of range");
- }
- } else {
- y = (int)x;
+ switch (op.kind) {
+ case type1COpInteger:
+ y = op.intgr;
if (y >= -107 && y <= 107) {
buf[0] = (Guchar)(y + 139);
n = 1;
@@ -1925,6 +2070,39 @@ void FoFiType1C::cvtNum(double x, GBool isFP, GString *charBuf) {
buf[4] = (Guchar)y;
n = 5;
}
+ break;
+ case type1COpFloat:
+ if (op.flt >= -32768 && op.flt < 32768) {
+ y = (int)(op.flt * 256.0);
+ buf[0] = 255;
+ buf[1] = (Guchar)(y >> 24);
+ buf[2] = (Guchar)(y >> 16);
+ buf[3] = (Guchar)(y >> 8);
+ buf[4] = (Guchar)y;
+ buf[5] = 255;
+ buf[6] = 0;
+ buf[7] = 0;
+ buf[8] = 1;
+ buf[9] = 0;
+ buf[10] = 12;
+ buf[11] = 12;
+ n = 12;
+ } else {
+ //~ error(-1, "Type 2 fixed point constant out of range");
+ }
+ break;
+ case type1COpRational:
+ tmp.kind = type1COpInteger;
+ tmp.intgr = op.rat.num;
+ cvtNum(tmp, charBuf);
+ tmp.intgr = op.rat.den;
+ cvtNum(tmp, charBuf);
+ buf[0] = 0x0c;
+ buf[1] = 0x0c;
+ n = 2;
+ break;
+ default: // shouldn't happen
+ break;
}
charBuf->append((char *)buf, n);
}
@@ -2161,47 +2339,51 @@ void FoFiType1C::readTopDict() {
if (!parsedOk) {
break;
}
- if (!ops[nOps - 1].isNum) {
+ if (ops[nOps - 1].kind == type1COpOperator) {
--nOps; // drop the operator
if (topDict.firstOp < 0) {
topDict.firstOp = ops[nOps].op;
}
switch (ops[nOps].op) {
- case 0x0000: topDict.versionSID = (int)ops[0].num; break;
- case 0x0001: topDict.noticeSID = (int)ops[0].num; break;
- case 0x0c00: topDict.copyrightSID = (int)ops[0].num; break;
- case 0x0002: topDict.fullNameSID = (int)ops[0].num; break;
- case 0x0003: topDict.familyNameSID = (int)ops[0].num; break;
- case 0x0004: topDict.weightSID = (int)ops[0].num; break;
- case 0x0c01: topDict.isFixedPitch = (int)ops[0].num; break;
- case 0x0c02: topDict.italicAngle = ops[0].num; break;
- case 0x0c03: topDict.underlinePosition = ops[0].num; break;
- case 0x0c04: topDict.underlineThickness = ops[0].num; break;
- case 0x0c05: topDict.paintType = (int)ops[0].num; break;
- case 0x0c06: topDict.charstringType = (int)ops[0].num; break;
- case 0x0c07: topDict.fontMatrix[0] = ops[0].num;
- topDict.fontMatrix[1] = ops[1].num;
- topDict.fontMatrix[2] = ops[2].num;
- topDict.fontMatrix[3] = ops[3].num;
- topDict.fontMatrix[4] = ops[4].num;
- topDict.fontMatrix[5] = ops[5].num;
- topDict.hasFontMatrix = gTrue; break;
- case 0x000d: topDict.uniqueID = (int)ops[0].num; break;
- case 0x0005: topDict.fontBBox[0] = ops[0].num;
- topDict.fontBBox[1] = ops[1].num;
- topDict.fontBBox[2] = ops[2].num;
- topDict.fontBBox[3] = ops[3].num; break;
- case 0x0c08: topDict.strokeWidth = ops[0].num; break;
- case 0x000f: topDict.charsetOffset = (int)ops[0].num; break;
- case 0x0010: topDict.encodingOffset = (int)ops[0].num; break;
- case 0x0011: topDict.charStringsOffset = (int)ops[0].num; break;
- case 0x0012: topDict.privateSize = (int)ops[0].num;
- topDict.privateOffset = (int)ops[1].num; break;
- case 0x0c1e: topDict.registrySID = (int)ops[0].num;
- topDict.orderingSID = (int)ops[1].num;
- topDict.supplement = (int)ops[2].num; break;
- case 0x0c24: topDict.fdArrayOffset = (int)ops[0].num; break;
- case 0x0c25: topDict.fdSelectOffset = (int)ops[0].num; break;
+ case 0x0000: topDict.versionSID = ops[0].toInt(); break;
+ case 0x0001: topDict.noticeSID = ops[0].toInt(); break;
+ case 0x0c00: topDict.copyrightSID = ops[0].toInt(); break;
+ case 0x0002: topDict.fullNameSID = ops[0].toInt(); break;
+ case 0x0003: topDict.familyNameSID = ops[0].toInt(); break;
+ case 0x0004: topDict.weightSID = ops[0].toInt(); break;
+ case 0x0c01: topDict.isFixedPitch = ops[0].toInt(); break;
+ case 0x0c02: topDict.italicAngle = ops[0].toFloat(); break;
+ case 0x0c03: topDict.underlinePosition = ops[0].toFloat(); break;
+ case 0x0c04: topDict.underlineThickness = ops[0].toFloat(); break;
+ case 0x0c05: topDict.paintType = ops[0].toInt(); break;
+ case 0x0c06: topDict.charstringType = ops[0].toInt(); break;
+ case 0x0c07: topDict.fontMatrix[0] = ops[0].toFloat();
+ topDict.fontMatrix[1] = ops[1].toFloat();
+ topDict.fontMatrix[2] = ops[2].toFloat();
+ topDict.fontMatrix[3] = ops[3].toFloat();
+ topDict.fontMatrix[4] = ops[4].toFloat();
+ topDict.fontMatrix[5] = ops[5].toFloat();
+ topDict.hasFontMatrix = gTrue;
+ break;
+ case 0x000d: topDict.uniqueID = ops[0].toInt(); break;
+ case 0x0005: topDict.fontBBox[0] = ops[0].toFloat();
+ topDict.fontBBox[1] = ops[1].toFloat();
+ topDict.fontBBox[2] = ops[2].toFloat();
+ topDict.fontBBox[3] = ops[3].toFloat();
+ break;
+ case 0x0c08: topDict.strokeWidth = ops[0].toFloat(); break;
+ case 0x000f: topDict.charsetOffset = ops[0].toInt(); break;
+ case 0x0010: topDict.encodingOffset = ops[0].toInt(); break;
+ case 0x0011: topDict.charStringsOffset = ops[0].toInt(); break;
+ case 0x0012: topDict.privateSize = ops[0].toInt();
+ topDict.privateOffset = ops[1].toInt();
+ break;
+ case 0x0c1e: topDict.registrySID = ops[0].toInt();
+ topDict.orderingSID = ops[1].toInt();
+ topDict.supplement = ops[2].toInt();
+ break;
+ case 0x0c24: topDict.fdArrayOffset = ops[0].toInt(); break;
+ case 0x0c25: topDict.fdSelectOffset = ops[0].toInt(); break;
}
nOps = 0;
}
@@ -2227,22 +2409,22 @@ void FoFiType1C::readFD(int offset, int length, Type1CPrivateDict *pDict) {
if (!parsedOk) {
return;
}
- if (!ops[nOps - 1].isNum) {
+ if (ops[nOps - 1].kind == type1COpOperator) {
if (ops[nOps - 1].op == 0x0012) {
if (nOps < 3) {
parsedOk = gFalse;
return;
}
- pSize = (int)ops[0].num;
- pOffset = (int)ops[1].num;
+ pSize = ops[0].toInt();
+ pOffset = ops[1].toInt();
break;
} else if (ops[nOps - 1].op == 0x0c07) {
- fontMatrix[0] = ops[0].num;
- fontMatrix[1] = ops[1].num;
- fontMatrix[2] = ops[2].num;
- fontMatrix[3] = ops[3].num;
- fontMatrix[4] = ops[4].num;
- fontMatrix[5] = ops[5].num;
+ fontMatrix[0] = ops[0].toFloat();
+ fontMatrix[1] = ops[1].toFloat();
+ fontMatrix[2] = ops[2].toFloat();
+ fontMatrix[3] = ops[3].toFloat();
+ fontMatrix[4] = ops[4].toFloat();
+ fontMatrix[5] = ops[5].toFloat();
hasFontMatrix = gTrue;
}
nOps = 0;
@@ -2283,9 +2465,9 @@ void FoFiType1C::readPrivateDict(int offset, int length,
pDict->initialRandomSeed = 0;
pDict->subrsOffset = 0;
pDict->defaultWidthX = 0;
- pDict->defaultWidthXFP = gFalse;
+ pDict->defaultWidthXInt = gTrue;
pDict->nominalWidthX = 0;
- pDict->nominalWidthXFP = gFalse;
+ pDict->nominalWidthXInt = gTrue;
// no dictionary
if (offset == 0 || length == 0) {
@@ -2299,7 +2481,7 @@ void FoFiType1C::readPrivateDict(int offset, int length,
if (!parsedOk) {
break;
}
- if (!ops[nOps - 1].isNum) {
+ if (ops[nOps - 1].kind == type1COpOperator) {
--nOps; // drop the operator
switch (ops[nOps].op) {
case 0x0006:
@@ -2319,20 +2501,20 @@ void FoFiType1C::readPrivateDict(int offset, int length,
type1CMaxOtherBlues);
break;
case 0x0c09:
- pDict->blueScale = ops[0].num;
+ pDict->blueScale = ops[0].toFloat();
break;
case 0x0c0a:
- pDict->blueShift = (int)ops[0].num;
+ pDict->blueShift = ops[0].toInt();
break;
case 0x0c0b:
- pDict->blueFuzz = (int)ops[0].num;
+ pDict->blueFuzz = ops[0].toInt();
break;
case 0x000a:
- pDict->stdHW = ops[0].num;
+ pDict->stdHW = ops[0].toFloat();
pDict->hasStdHW = gTrue;
break;
case 0x000b:
- pDict->stdVW = ops[0].num;
+ pDict->stdVW = ops[0].toFloat();
pDict->hasStdVW = gTrue;
break;
case 0x0c0c:
@@ -2344,31 +2526,31 @@ void FoFiType1C::readPrivateDict(int offset, int length,
type1CMaxStemSnap);
break;
case 0x0c0e:
- pDict->forceBold = ops[0].num != 0;
+ pDict->forceBold = !ops[0].isZero();
pDict->hasForceBold = gTrue;
break;
case 0x0c0f:
- pDict->forceBoldThreshold = ops[0].num;
+ pDict->forceBoldThreshold = ops[0].toFloat();
break;
case 0x0c11:
- pDict->languageGroup = (int)ops[0].num;
+ pDict->languageGroup = ops[0].toInt();
break;
case 0x0c12:
- pDict->expansionFactor = ops[0].num;
+ pDict->expansionFactor = ops[0].toFloat();
break;
case 0x0c13:
- pDict->initialRandomSeed = (int)ops[0].num;
+ pDict->initialRandomSeed = ops[0].toInt();
break;
case 0x0013:
- pDict->subrsOffset = offset + (int)ops[0].num;
+ pDict->subrsOffset = offset + ops[0].toInt();
break;
case 0x0014:
- pDict->defaultWidthX = ops[0].num;
- pDict->defaultWidthXFP = ops[0].isFP;
+ pDict->defaultWidthX = ops[0].toFloat();
+ pDict->defaultWidthXInt = ops[0].kind == type1COpInteger;
break;
case 0x0015:
- pDict->nominalWidthX = ops[0].num;
- pDict->nominalWidthXFP = ops[0].isFP;
+ pDict->nominalWidthX = ops[0].toFloat();
+ pDict->nominalWidthXInt = ops[0].kind == type1COpInteger;
break;
}
nOps = 0;
@@ -2584,8 +2766,6 @@ int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) {
int b0, b1, nyb0, nyb1, x, i;
b0 = getU8(pos++, ok);
- op.isNum = gTrue;
- op.isFP = gFalse;
if (b0 == 28) {
x = getU8(pos++, ok);
@@ -2593,7 +2773,8 @@ int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) {
if (x & 0x8000) {
x |= ~0xffff;
}
- op.num = x;
+ op.kind = type1COpInteger;
+ op.intgr = x;
} else if (!charstring && b0 == 29) {
x = getU8(pos++, ok);
@@ -2603,7 +2784,8 @@ int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) {
if (x & 0x80000000) {
x |= ~0xffffffff;
}
- op.num = x;
+ op.kind = type1COpInteger;
+ op.intgr = x;
} else if (!charstring && b0 == 30) {
i = 0;
@@ -2636,17 +2818,20 @@ int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) {
}
} while (i < 64);
buf[i] = '\0';
- op.num = atof(buf);
- op.isFP = gTrue;
+ op.kind = type1COpFloat;
+ op.flt = atof(buf);
} else if (b0 >= 32 && b0 <= 246) {
- op.num = b0 - 139;
+ op.kind = type1COpInteger;
+ op.intgr = b0 - 139;
} else if (b0 >= 247 && b0 <= 250) {
- op.num = ((b0 - 247) << 8) + getU8(pos++, ok) + 108;
+ op.kind = type1COpInteger;
+ op.intgr = ((b0 - 247) << 8) + getU8(pos++, ok) + 108;
} else if (b0 >= 251 && b0 <= 254) {
- op.num = -((b0 - 251) << 8) - getU8(pos++, ok) - 108;
+ op.kind = type1COpInteger;
+ op.intgr = -((b0 - 251) << 8) - getU8(pos++, ok) - 108;
} else if (charstring && b0 == 255) {
x = getU8(pos++, ok);
@@ -2656,15 +2841,15 @@ int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) {
if (x & 0x80000000) {
x |= ~0xffffffff;
}
- op.num = (double)x / 65536.0;
- op.isFP = gTrue;
+ op.kind = type1COpFloat;
+ op.flt = (double)x / 65536.0;
} else if (b0 == 12) {
- op.isNum = gFalse;
+ op.kind = type1COpOperator;
op.op = 0x0c00 + getU8(pos++, ok);
} else {
- op.isNum = gFalse;
+ op.kind = type1COpOperator;
op.op = b0;
}
@@ -2685,7 +2870,7 @@ int FoFiType1C::getDeltaIntArray(int *arr, int maxLen) {
}
x = 0;
for (i = 0; i < n; ++i) {
- x += (int)ops[i].num;
+ x += ops[i].toInt();
arr[i] = x;
}
return n;
@@ -2701,7 +2886,7 @@ int FoFiType1C::getDeltaFPArray(double *arr, int maxLen) {
}
x = 0;
for (i = 0; i < n; ++i) {
- x += ops[i].num;
+ x += ops[i].toFloat();
arr[i] = x;
}
return n;
@@ -2736,6 +2921,8 @@ void FoFiType1C::getIndexVal(Type1CIndex *idx, int i,
int pos0, pos1;
if (i < 0 || i >= idx->len) {
+ val->pos = 0;
+ val->len = 0;
*ok = gFalse;
return;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h
index 0c5b4fb6ead..ae869687898 100644
--- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h
+++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h
@@ -105,18 +105,34 @@ struct Type1CPrivateDict {
int initialRandomSeed;
int subrsOffset;
double defaultWidthX;
- GBool defaultWidthXFP;
+ GBool defaultWidthXInt;
double nominalWidthX;
- GBool nominalWidthXFP;
+ GBool nominalWidthXInt;
};
+// operand kind
+enum Type1COpKind {
+ type1COpOperator,
+ type1COpInteger,
+ type1COpFloat,
+ type1COpRational
+};
+
+// operand
struct Type1COp {
- GBool isNum; // true -> number, false -> operator
- GBool isFP; // true -> floating point number, false -> int
+ Type1COpKind kind;
union {
- double num; // if num is true
- int op; // if num is false
+ int op; // type1COpOperator
+ int intgr; // type1COpInteger
+ double flt; // type1COpFloat
+ struct {
+ int num, den; // type1COpRational
+ } rat;
};
+ GBool isZero();
+ GBool isNegative();
+ int toInt();
+ double toFloat();
};
struct Type1CEexecBuf {
@@ -204,7 +220,7 @@ private:
GBool top);
void cvtGlyphWidth(GBool useOp, GString *charBuf,
Type1CPrivateDict *pDict);
- void cvtNum(double x, GBool isFP, GString *charBuf);
+ void cvtNum(Type1COp op, GString *charBuf);
void eexecWrite(Type1CEexecBuf *eb, const char *s);
void eexecWriteCharstring(Type1CEexecBuf *eb, Guchar *s, int n);
void writePSString(char *s, FoFiOutputFunc outputFunc, void *outputStream);
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/Makefile.dep b/Build/source/libs/xpdf/xpdf-src/fofi/Makefile.dep
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/fofi/Makefile.dep
+++ /dev/null
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/Makefile.in b/Build/source/libs/xpdf/xpdf-src/fofi/Makefile.in
deleted file mode 100644
index d00f83f1c25..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/fofi/Makefile.in
+++ /dev/null
@@ -1,71 +0,0 @@
-#========================================================================
-#
-# FoFi library Makefile
-#
-# Copyright 2003 Glyph & Cog, LLC
-#
-#========================================================================
-
-SHELL = /bin/sh
-
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-GOOSRCDIR = $(srcdir)/../goo
-GOOLIBDIR = ../goo
-
-CXXFLAGS = @CXXFLAGS@ @DEFS@ -I.. -I$(srcdir)/.. -I$(GOOSRCDIR) -I$(srcdir)
-
-CXX = @CXX@
-AR = @AR@
-RANLIB = @RANLIB@
-
-LIBPREFIX = @LIBPREFIX@
-
-#------------------------------------------------------------------------
-
-.SUFFIXES: .cc
-
-.cc.o:
- $(CXX) $(CXXFLAGS) -c $<
-
-#------------------------------------------------------------------------
-
-CXX_SRC = \
- $(srcdir)/FoFiBase.cc \
- $(srcdir)/FoFiEncodings.cc \
- $(srcdir)/FoFiIdentifier.cc \
- $(srcdir)/FoFiTrueType.cc \
- $(srcdir)/FoFiType1.cc \
- $(srcdir)/FoFiType1C.cc
-
-#------------------------------------------------------------------------
-
-all: $(LIBPREFIX)fofi.a
-
-#------------------------------------------------------------------------
-
-FOFI_OBJS = \
- FoFiBase.o \
- FoFiEncodings.o \
- FoFiIdentifier.o \
- FoFiTrueType.o \
- FoFiType1.o \
- FoFiType1C.o
-
-$(LIBPREFIX)fofi.a: $(FOFI_OBJS)
- rm -f $(LIBPREFIX)fofi.a
- $(AR) $(LIBPREFIX)fofi.a $(FOFI_OBJS)
- $(RANLIB) $(LIBPREFIX)fofi.a
-
-#------------------------------------------------------------------------
-
-clean:
- rm -f $(FOFI_OBJS) $(LIBPREFIX)fofi.a
-
-#------------------------------------------------------------------------
-
-depend:
- $(CXX) $(CXXFLAGS) -MM $(CXX_SRC) >Makefile.dep
-
--include Makefile.dep
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/goo/CMakeLists.txt
new file mode 100644
index 00000000000..7302dbbe08c
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/goo/CMakeLists.txt
@@ -0,0 +1,27 @@
+#========================================================================
+#
+# goo/CMakeLists.txt
+#
+# CMake script for the goo library.
+#
+# Copyright 2015 Glyph & Cog, LLC
+#
+#========================================================================
+
+include_directories("${PROJECT_SOURCE_DIR}")
+include_directories("${PROJECT_BINARY_DIR}")
+
+add_library(goo_objs OBJECT
+ FixedPoint.cc
+ GHash.cc
+ GList.cc
+ GString.cc
+ gfile.cc
+ gmem.cc
+ gmempp.cc
+ parseargs.c
+)
+
+add_library(goo
+ $<TARGET_OBJECTS:goo_objs>
+)
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.cc b/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.cc
index 34661ad0f30..503a06aa9c7 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.cc
+++ b/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.cc
@@ -16,6 +16,7 @@
#pragma implementation
#endif
+#include "gmempp.h"
#include "FixedPoint.h"
#define ln2 ((FixedPoint)0.69314718)
@@ -113,7 +114,7 @@ GBool FixedPoint::divCheck(FixedPoint x, FixedPoint y, FixedPoint *result) {
z >= ((FixPtInt64)1 << 31) || z < -((FixPtInt64)1 << 31)) {
return gFalse;
}
- result->val = z;
+ result->val = (int)z;
return gTrue;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h b/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h
index 1f4be7095d0..438343fc585 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h
+++ b/Build/source/libs/xpdf/xpdf-src/goo/FixedPoint.h
@@ -49,35 +49,35 @@ public:
FixedPoint operator =(FixedPoint x) { val = x.val; return *this; }
- int operator ==(FixedPoint x) const { return val == x.val; }
- int operator ==(double x) const { return *this == (FixedPoint)x; }
- int operator ==(int x) const { return *this == (FixedPoint)x; }
- int operator ==(long x) const { return *this == (FixedPoint)x; }
-
- int operator !=(FixedPoint x) const { return val != x.val; }
- int operator !=(double x) const { return *this != (FixedPoint)x; }
- int operator !=(int x) const { return *this != (FixedPoint)x; }
- int operator !=(long x) const { return *this != (FixedPoint)x; }
-
- int operator <(FixedPoint x) const { return val < x.val; }
- int operator <(double x) const { return *this < (FixedPoint)x; }
- int operator <(int x) const { return *this < (FixedPoint)x; }
- int operator <(long x) const { return *this < (FixedPoint)x; }
-
- int operator <=(FixedPoint x) const { return val <= x.val; }
- int operator <=(double x) const { return *this <= (FixedPoint)x; }
- int operator <=(int x) const { return *this <= (FixedPoint)x; }
- int operator <=(long x) const { return *this <= (FixedPoint)x; }
-
- int operator >(FixedPoint x) const { return val > x.val; }
- int operator >(double x) const { return *this > (FixedPoint)x; }
- int operator >(int x) const { return *this > (FixedPoint)x; }
- int operator >(long x) const { return *this > (FixedPoint)x; }
-
- int operator >=(FixedPoint x) const { return val >= x.val; }
- int operator >=(double x) const { return *this >= (FixedPoint)x; }
- int operator >=(int x) const { return *this >= (FixedPoint)x; }
- int operator >=(long x) const { return *this >= (FixedPoint)x; }
+ bool operator ==(FixedPoint x) const { return val == x.val; }
+ bool operator ==(double x) const { return *this == (FixedPoint)x; }
+ bool operator ==(int x) const { return *this == (FixedPoint)x; }
+ bool operator ==(long x) const { return *this == (FixedPoint)x; }
+
+ bool operator !=(FixedPoint x) const { return val != x.val; }
+ bool operator !=(double x) const { return *this != (FixedPoint)x; }
+ bool operator !=(int x) const { return *this != (FixedPoint)x; }
+ bool operator !=(long x) const { return *this != (FixedPoint)x; }
+
+ bool operator <(FixedPoint x) const { return val < x.val; }
+ bool operator <(double x) const { return *this < (FixedPoint)x; }
+ bool operator <(int x) const { return *this < (FixedPoint)x; }
+ bool operator <(long x) const { return *this < (FixedPoint)x; }
+
+ bool operator <=(FixedPoint x) const { return val <= x.val; }
+ bool operator <=(double x) const { return *this <= (FixedPoint)x; }
+ bool operator <=(int x) const { return *this <= (FixedPoint)x; }
+ bool operator <=(long x) const { return *this <= (FixedPoint)x; }
+
+ bool operator >(FixedPoint x) const { return val > x.val; }
+ bool operator >(double x) const { return *this > (FixedPoint)x; }
+ bool operator >(int x) const { return *this > (FixedPoint)x; }
+ bool operator >(long x) const { return *this > (FixedPoint)x; }
+
+ bool operator >=(FixedPoint x) const { return val >= x.val; }
+ bool operator >=(double x) const { return *this >= (FixedPoint)x; }
+ bool operator >=(int x) const { return *this >= (FixedPoint)x; }
+ bool operator >=(long x) const { return *this >= (FixedPoint)x; }
FixedPoint operator -() { return make(-val); }
@@ -136,7 +136,6 @@ public:
static FixedPoint avg(FixedPoint x, FixedPoint y)
{ return make((x.val >> 1) + (y.val >> 1) + ((x.val | y.val) & 1)); }
-
static FixedPoint sqrt(FixedPoint x);
static FixedPoint pow(FixedPoint x, FixedPoint y);
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/GHash.cc b/Build/source/libs/xpdf/xpdf-src/goo/GHash.cc
index 32e85b41dea..e6b32440fb9 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/GHash.cc
+++ b/Build/source/libs/xpdf/xpdf-src/goo/GHash.cc
@@ -13,6 +13,7 @@
#endif
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "GHash.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/GList.cc b/Build/source/libs/xpdf/xpdf-src/goo/GList.cc
index 5d9cba3787e..c194818a743 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/GList.cc
+++ b/Build/source/libs/xpdf/xpdf-src/goo/GList.cc
@@ -15,6 +15,7 @@
#include <stdlib.h>
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "GList.h"
//------------------------------------------------------------------------
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/GMutex.h b/Build/source/libs/xpdf/xpdf-src/goo/GMutex.h
index 5d5621af2ae..972e4da7f97 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/GMutex.h
+++ b/Build/source/libs/xpdf/xpdf-src/goo/GMutex.h
@@ -3,14 +3,26 @@
// GMutex.h
//
// Portable mutex macros.
+// Portable atomic increment/decrement.
//
-// Copyright 2002-2003 Glyph & Cog, LLC
+// Copyright 2002-2014 Glyph & Cog, LLC
//
//========================================================================
#ifndef GMUTEX_H
#define GMUTEX_H
+#ifdef _WIN32
+# include <windows.h>
+# include <intrin.h>
+#else
+# include <pthread.h>
+#endif
+
+//------------------------------------------------------------------------
+// GMutex
+//------------------------------------------------------------------------
+
// Usage:
//
// GMutex m;
@@ -24,8 +36,6 @@
#ifdef _WIN32
-#include <windows.h>
-
typedef CRITICAL_SECTION GMutex;
#define gInitMutex(m) InitializeCriticalSection(m)
@@ -35,8 +45,6 @@ typedef CRITICAL_SECTION GMutex;
#else // assume pthreads
-#include <pthread.h>
-
typedef pthread_mutex_t GMutex;
#define gInitMutex(m) pthread_mutex_init(m, NULL)
@@ -46,4 +54,41 @@ typedef pthread_mutex_t GMutex;
#endif
+//------------------------------------------------------------------------
+// atomic increment/decrement
+//------------------------------------------------------------------------
+
+// NB: this must be "long" to work on Windows
+typedef long GAtomicCounter;
+
+// Increment *counter by one and return the final value (after the
+// increment).
+static inline GAtomicCounter gAtomicIncrement(GAtomicCounter *counter) {
+ GAtomicCounter newVal;
+
+#if defined(_WIN32)
+ newVal = _InterlockedIncrement(counter);
+#elif defined(__GNUC__) // this also works for LLVM/clang
+ newVal = __sync_add_and_fetch(counter, 1);
+#else
+# error "gAtomicIncrement is not defined for this compiler/platform"
+#endif
+ return newVal;
+}
+
+// Decrement *counter by one and return the final value (after the
+// decrement).
+static inline GAtomicCounter gAtomicDecrement(GAtomicCounter *counter) {
+ GAtomicCounter newVal;
+
+#if defined(_WIN32)
+ newVal = _InterlockedDecrement(counter);
+#elif defined(__GNUC__) // this also works for LLVM/clang
+ newVal = __sync_sub_and_fetch(counter, 1);
+#else
+# error "gAtomicDecrement is not defined for this compiler/platform"
#endif
+ return newVal;
+}
+
+#endif // GMUTEX_H
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/GString.cc b/Build/source/libs/xpdf/xpdf-src/goo/GString.cc
index adf7739c9aa..b56ed58ba16 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/GString.cc
+++ b/Build/source/libs/xpdf/xpdf-src/goo/GString.cc
@@ -21,6 +21,7 @@
#include <math.h>
#include <limits.h>
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
//------------------------------------------------------------------------
@@ -755,8 +756,9 @@ GString *GString::upperCase() {
int i;
for (i = 0; i < length; ++i) {
- if (islower(s[i]))
- s[i] = toupper(s[i]);
+ if (islower(s[i] & 0xff)) {
+ s[i] = toupper(s[i] & 0xff);
+ }
}
return this;
}
@@ -765,8 +767,9 @@ GString *GString::lowerCase() {
int i;
for (i = 0; i < length; ++i) {
- if (isupper(s[i]))
- s[i] = tolower(s[i]);
+ if (isupper(s[i] & 0xff)) {
+ s[i] = tolower(s[i] & 0xff);
+ }
}
return this;
}
@@ -778,7 +781,7 @@ int GString::cmp(GString *str) {
n1 = length;
n2 = str->length;
for (i = 0, p1 = s, p2 = str->s; i < n1 && i < n2; ++i, ++p1, ++p2) {
- x = *p1 - *p2;
+ x = (*p1 & 0xff) - (*p2 & 0xff);
if (x != 0) {
return x;
}
@@ -795,7 +798,7 @@ int GString::cmpN(GString *str, int n) {
for (i = 0, p1 = s, p2 = str->s;
i < n1 && i < n2 && i < n;
++i, ++p1, ++p2) {
- x = *p1 - *p2;
+ x = (*p1 & 0xff) - (*p2 & 0xff);
if (x != 0) {
return x;
}
@@ -812,7 +815,7 @@ int GString::cmp(const char *sA) {
n1 = length;
for (i = 0, p1 = s, p2 = sA; i < n1 && *p2; ++i, ++p1, ++p2) {
- x = *p1 - *p2;
+ x = (*p1 & 0xff) - (*p2 & 0xff);
if (x != 0) {
return x;
}
@@ -832,7 +835,7 @@ int GString::cmpN(const char *sA, int n) {
n1 = length;
for (i = 0, p1 = s, p2 = sA; i < n1 && *p2 && i < n; ++i, ++p1, ++p2) {
- x = *p1 - *p2;
+ x = (*p1 & 0xff) - (*p2 & 0xff);
if (x != 0) {
return x;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/Makefile.dep b/Build/source/libs/xpdf/xpdf-src/goo/Makefile.dep
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/goo/Makefile.dep
+++ /dev/null
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/Makefile.in b/Build/source/libs/xpdf/xpdf-src/goo/Makefile.in
deleted file mode 100644
index f61d4030f60..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/goo/Makefile.in
+++ /dev/null
@@ -1,71 +0,0 @@
-#========================================================================
-#
-# Goo library Makefile
-#
-# Copyright 1996-2003 Glyph & Cog, LLC
-#
-#========================================================================
-
-SHELL = /bin/sh
-
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-CFLAGS = @CFLAGS@ @DEFS@ -I.. -I$(srcdir)/.. -I$(srcdir)
-CXXFLAGS = @CXXFLAGS@ @DEFS@ -I.. -I$(srcdir)/.. -I$(srcdir)
-
-CC = @CC@
-CXX = @CXX@
-AR = @AR@
-RANLIB = @RANLIB@
-
-LIBPREFIX = @LIBPREFIX@
-
-#------------------------------------------------------------------------
-
-.SUFFIXES: .cc
-
-.cc.o:
- $(CXX) $(CXXFLAGS) -c $<
-
-#------------------------------------------------------------------------
-
-CXX_SRC = \
- $(srcdir)/GHash.cc \
- $(srcdir)/GList.cc \
- $(srcdir)/GString.cc \
- $(srcdir)/gmem.cc \
- $(srcdir)/gmempp.cc \
- $(srcdir)/gfile.cc \
- $(srcdir)/FixedPoint.cc
-
-C_SRC = \
- $(srcdir)/parseargs.c
-
-#------------------------------------------------------------------------
-
-all: $(LIBPREFIX)Goo.a
-
-#------------------------------------------------------------------------
-
-GOO_CXX_OBJS = GHash.o GList.o GString.o gmem.o gmempp.o gfile.o FixedPoint.o
-GOO_C_OBJS = parseargs.o
-GOO_OBJS = $(GOO_CXX_OBJS) $(GOO_C_OBJS)
-
-$(LIBPREFIX)Goo.a: $(GOO_OBJS)
- rm -f $(LIBPREFIX)Goo.a
- $(AR) $(LIBPREFIX)Goo.a $(GOO_OBJS)
- $(RANLIB) $(LIBPREFIX)Goo.a
-
-#------------------------------------------------------------------------
-
-clean:
- rm -f $(GOO_OBJS) $(LIBPREFIX)Goo.a
-
-#------------------------------------------------------------------------
-
-depend:
- $(CXX) $(CXXFLAGS) -MM $(CXX_SRC) >Makefile.dep
- $(CC) $(CFLAGS) -MM $(C_SRC) >>Makefile.dep
-
--include Makefile.dep
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc b/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc
index 777870df71b..f51dbe36100 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc
+++ b/Build/source/libs/xpdf/xpdf-src/goo/gfile.cc
@@ -17,9 +17,7 @@
# include <time.h>
# include <direct.h>
#else
-# if defined(MACOS)
-# include <sys/stat.h>
-# elif !defined(ACORN)
+# if !defined(ACORN)
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
@@ -27,13 +25,14 @@
# include <time.h>
# include <limits.h>
# include <string.h>
-# if !defined(VMS) && !defined(ACORN) && !defined(MACOS)
+# if !defined(VMS) && !defined(ACORN)
# include <pwd.h>
# endif
# if defined(VMS) && (__DECCXX_VER < 50200000)
# include <unixlib.h>
# endif
#endif // _WIN32
+#include "gmempp.h"
#include "GString.h"
#include "gfile.h"
@@ -69,10 +68,6 @@ GString *getHomeDir() {
//---------- RISCOS ----------
return new GString("@");
-#elif defined(MACOS)
- //---------- MacOS ----------
- return new GString(":");
-
#else
//---------- Unix ----------
char *s;
@@ -104,8 +99,6 @@ GString *getCurrentDir() {
if (GetCurrentDirectoryA(sizeof(buf), buf))
#elif defined(ACORN)
if (strcpy(buf, "@"))
-#elif defined(MACOS)
- if (strcpy(buf, ":"))
#else
if (getcwd(buf, sizeof(buf)))
#endif
@@ -186,23 +179,6 @@ GString *appendToPath(GString *path, const char *fileName) {
}
return path;
-#elif defined(MACOS)
- //---------- MacOS ----------
- char *p;
- int i;
-
- path->append(":");
- i = path->getLength();
- path->append(fileName);
- for (p = path->getCString() + i; *p; ++p) {
- if (*p == '/') {
- *p = ':';
- } else if (*p == '.') {
- *p = ':';
- }
- }
- return path;
-
#elif defined(__EMX__)
//---------- OS/2+EMX ----------
int i;
@@ -310,14 +286,6 @@ GString *grabPath(char *fileName) {
return new GString(fileName, p - fileName);
return new GString();
-#elif defined(MACOS)
- //---------- MacOS ----------
- char *p;
-
- if ((p = strrchr(fileName, ':')))
- return new GString(fileName, p - fileName);
- return new GString();
-
#else
//---------- Unix ----------
char *p;
@@ -342,10 +310,6 @@ GBool isAbsolutePath(char *path) {
//---------- RISCOS ----------
return path[0] == '$';
-#elif defined(MACOS)
- //---------- MacOS ----------
- return path[0] != ':';
-
#else
//---------- Unix ----------
return path[0] == '/';
@@ -383,11 +347,6 @@ GString *makePathAbsolute(GString *path) {
path->insert(0, '@');
return path;
-#elif defined(MACOS)
- //---------- MacOS ----------
- path->del(0, 1);
- return path;
-
#else
//---------- Unix and OS/2+EMX ----------
struct passwd *pw;
@@ -453,25 +412,29 @@ GBool openTempFile(GString **name, FILE **f,
const char *mode, const char *ext) {
#if defined(_WIN32)
//---------- Win32 ----------
- char *tempDir;
+ char tempPath[MAX_PATH + 1];
GString *s, *s2;
FILE *f2;
+ DWORD n;
int t, i;
// this has the standard race condition problem, but I haven't found
// a better way to generate temp file names with extensions on
// Windows
- if ((tempDir = getenv("TEMP"))) {
- s = new GString(tempDir);
- s->append('\\');
+ n = GetTempPathA(sizeof(tempPath), tempPath);
+ if (n > 0 && n <= sizeof(tempPath)) {
+ s = new GString(tempPath);
+ if (tempPath[n-1] != '\\') {
+ s->append('\\');
+ }
} else {
- s = new GString();
+ s = new GString(".\\");
}
- s->appendf("x_{0:d}_{1:d}_",
+ s->appendf("xpdf_{0:d}_{1:d}_",
(int)GetCurrentProcessId(), (int)GetCurrentThreadId());
t = (int)time(NULL);
for (i = 0; i < 1000; ++i) {
- s2 = s->copy()->appendf("{0:d}", t + i);
+ s2 = GString::format("{0:t}{1:d}", s, t + i);
if (ext) {
s2->append(ext);
}
@@ -491,7 +454,7 @@ GBool openTempFile(GString **name, FILE **f,
}
delete s;
return gFalse;
-#elif defined(VMS) || defined(__EMX__) || defined(ACORN) || defined(MACOS)
+#elif defined(VMS) || defined(__EMX__) || defined(ACORN)
//---------- non-Unix ----------
char *s;
@@ -730,152 +693,3 @@ GFileOffset gftell(FILE *f) {
return ftell(f);
#endif
}
-
-//------------------------------------------------------------------------
-// GDir and GDirEntry
-//------------------------------------------------------------------------
-
-GDirEntry::GDirEntry(char *dirPath, char *nameA, GBool doStat) {
-#ifdef VMS
- char *p;
-#elif defined(_WIN32)
- int fa;
- GString *s;
-#elif defined(ACORN)
-#else
- struct stat st;
- GString *s;
-#endif
-
- name = new GString(nameA);
- dir = gFalse;
- if (doStat) {
-#ifdef VMS
- if (!strcmp(nameA, "-") ||
- ((p = strrchr(nameA, '.')) && !strncmp(p, ".DIR;", 5)))
- dir = gTrue;
-#elif defined(ACORN)
-#else
- s = new GString(dirPath);
- appendToPath(s, nameA);
-#ifdef _WIN32
- fa = GetFileAttributesA(s->getCString());
- dir = (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY));
-#else
- if (stat(s->getCString(), &st) == 0)
- dir = S_ISDIR(st.st_mode);
-#endif
- delete s;
-#endif
- }
-}
-
-GDirEntry::~GDirEntry() {
- delete name;
-}
-
-GDir::GDir(char *name, GBool doStatA) {
- path = new GString(name);
- doStat = doStatA;
-#if defined(_WIN32)
- GString *tmp;
-
- tmp = path->copy();
- tmp->append("/*.*");
- hnd = FindFirstFileA(tmp->getCString(), &ffd);
- delete tmp;
-#elif defined(ACORN)
-#elif defined(MACOS)
-#elif defined(ANDROID)
-#else
- dir = opendir(name);
-#ifdef VMS
- needParent = strchr(name, '[') != NULL;
-#endif
-#endif
-}
-
-GDir::~GDir() {
- delete path;
-#if defined(_WIN32)
- if (hnd) {
- FindClose(hnd);
- hnd = NULL;
- }
-#elif defined(ACORN)
-#elif defined(MACOS)
-#elif defined(ANDROID)
-#else
- if (dir)
- closedir(dir);
-#endif
-}
-
-GDirEntry *GDir::getNextEntry() {
- GDirEntry *e;
-
-#if defined(_WIN32)
- if (hnd) {
- e = new GDirEntry(path->getCString(), ffd.cFileName, doStat);
- if (hnd && !FindNextFileA(hnd, &ffd)) {
- FindClose(hnd);
- hnd = NULL;
- }
- } else {
- e = NULL;
- }
-#elif defined(ACORN)
-#elif defined(MACOS)
-#elif defined(ANDROID)
-#elif defined(VMS)
- struct dirent *ent;
- e = NULL;
- if (dir) {
- if (needParent) {
- e = new GDirEntry(path->getCString(), "-", doStat);
- needParent = gFalse;
- return e;
- }
- ent = readdir(dir);
- if (ent) {
- e = new GDirEntry(path->getCString(), ent->d_name, doStat);
- }
- }
-#else
- struct dirent *ent;
- e = NULL;
- if (dir) {
- ent = (struct dirent *)readdir(dir);
- if (ent && !strcmp(ent->d_name, ".")) {
- ent = (struct dirent *)readdir(dir);
- }
- if (ent) {
- e = new GDirEntry(path->getCString(), ent->d_name, doStat);
- }
- }
-#endif
-
- return e;
-}
-
-void GDir::rewind() {
-#ifdef _WIN32
- GString *tmp;
-
- if (hnd)
- FindClose(hnd);
- tmp = path->copy();
- tmp->append("/*.*");
- hnd = FindFirstFileA(tmp->getCString(), &ffd);
- delete tmp;
-#elif defined(ACORN)
-#elif defined(MACOS)
-#elif defined(ANDROID)
-#else
- if (dir)
- rewinddir(dir);
-#ifdef VMS
- needParent = strchr(path->getCString(), '[') != NULL;
-#endif
-#endif
-}
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/gfile.h b/Build/source/libs/xpdf/xpdf-src/goo/gfile.h
index 5b171e62089..bf4322dbcbe 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/gfile.h
+++ b/Build/source/libs/xpdf/xpdf-src/goo/gfile.h
@@ -22,30 +22,10 @@
# include <windows.h>
# endif
#elif defined(ACORN)
-#elif defined(MACOS)
-# include <ctime.h>
#elif defined(ANDROID)
#else
# include <unistd.h>
# include <sys/types.h>
-# ifdef VMS
-# include "vms_dirent.h"
-# elif HAVE_DIRENT_H
-# include <dirent.h>
-# define NAMLEN(d) strlen((d)->d_name)
-# else
-# define dirent direct
-# define NAMLEN(d) (d)->d_namlen
-# if HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# endif
-# if HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# endif
-# if HAVE_NDIR_H
-# include <ndir.h>
-# endif
-# endif
#endif
#include "gtypes.h"
@@ -132,48 +112,4 @@ extern int gfseek(FILE *f, GFileOffset offset, int whence);
// Like ftell, but returns a 64-bit file offset if available.
extern GFileOffset gftell(FILE *f);
-//------------------------------------------------------------------------
-// GDir and GDirEntry
-//------------------------------------------------------------------------
-
-class GDirEntry {
-public:
-
- GDirEntry(char *dirPath, char *nameA, GBool doStat);
- ~GDirEntry();
- GString *getName() { return name; }
- GBool isDir() { return dir; }
-
-private:
-
- GString *name; // dir/file name
- GBool dir; // is it a directory?
-};
-
-class GDir {
-public:
-
- GDir(char *name, GBool doStatA = gTrue);
- ~GDir();
- GDirEntry *getNextEntry();
- void rewind();
-
-private:
-
- GString *path; // directory path
- GBool doStat; // call stat() for each entry?
-#if defined(_WIN32)
- WIN32_FIND_DATAA ffd;
- HANDLE hnd;
-#elif defined(ACORN)
-#elif defined(MACOS)
-#elif defined(ANDROID)
-#else
- DIR *dir; // the DIR structure from opendir()
-#ifdef VMS
- GBool needParent; // need to return an entry for [-]
-#endif
-#endif
-};
-
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/gmem.cc b/Build/source/libs/xpdf/xpdf-src/goo/gmem.cc
index 6fd51364071..c28d3e07fd6 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/gmem.cc
+++ b/Build/source/libs/xpdf/xpdf-src/goo/gmem.cc
@@ -12,6 +12,9 @@
#include <stddef.h>
#include <string.h>
#include <limits.h>
+#if MULTITHREADED && defined(_WIN32)
+# include <windows.h>
+#endif
#include "gmem.h"
#ifdef DEBUG_MEM
@@ -28,7 +31,7 @@ typedef struct _GMemHdr {
#define gMemMagic 0xabcd9999
-#if gmemTrlSize==8
+#if ULONG_MAX > 0xffffffffL
#define gMemDeadVal 0xdeadbeefdeadbeefUL
#else
#define gMemDeadVal 0xdeadbeefUL
@@ -46,16 +49,43 @@ static int gMemAlloc = 0;
static int gMemInUse = 0;
static int gMaxMemInUse = 0;
+#if MULTITHREADED
+# ifdef _WIN32
+ static CRITICAL_SECTION gMemMutex;
+ static INIT_ONCE gMemMutexInitStruct = INIT_ONCE_STATIC_INIT;
+ static BOOL CALLBACK gMemMutexInitFunc(PINIT_ONCE initOnce, PVOID param,
+ PVOID *context) {
+ InitializeCriticalSection(&gMemMutex);
+ return TRUE;
+ }
+# define gMemInitMutex InitOnceExecuteOnce(&gMemMutexInitStruct, \
+ &gMemMutexInitFunc, NULL, NULL)
+# define gMemLock EnterCriticalSection(&gMemMutex);
+# define gMemUnlock LeaveCriticalSection(&gMemMutex);
+# else
+# include <pthread.h>
+ static pthread_mutex_t gMemMutex = PTHREAD_MUTEX_INITIALIZER;
+# define gMemInitMutex
+# define gMemLock pthread_mutex_lock(&gMemMutex)
+# define gMemUnlock pthread_mutex_unlock(&gMemMutex)
+# endif
+#else
+# define gMemInitMutex
+# define gMemLock
+# define gMemUnlock
+#endif
+
#endif /* DEBUG_MEM */
-void *gmalloc(int size) GMEM_EXCEP {
#ifdef DEBUG_MEM
+void *gmalloc(int size, int ignore) GMEM_EXCEP {
int size1;
char *mem;
GMemHdr *hdr;
void *data;
unsigned long *trl, *p;
+ gMemInitMutex;
if (size < 0) {
gMemError("Invalid memory allocation size");
}
@@ -71,7 +101,12 @@ void *gmalloc(int size) GMEM_EXCEP {
trl = (unsigned long *)(mem + gMemHdrSize + size1);
hdr->magic = gMemMagic;
hdr->size = size;
- hdr->index = gMemIndex++;
+ if (ignore) {
+ hdr->index = -1;
+ } else {
+ hdr->index = gMemIndex++;
+ }
+ gMemLock;
if (gMemTail) {
gMemTail->next = hdr;
hdr->prev = gMemTail;
@@ -86,11 +121,14 @@ void *gmalloc(int size) GMEM_EXCEP {
if (gMemInUse > gMaxMemInUse) {
gMaxMemInUse = gMemInUse;
}
+ gMemUnlock;
for (p = (unsigned long *)data; p <= trl; ++p) {
*p = gMemDeadVal;
}
return data;
+}
#else
+void *gmalloc(int size) GMEM_EXCEP {
void *p;
if (size < 0) {
@@ -103,8 +141,8 @@ void *gmalloc(int size) GMEM_EXCEP {
gMemError("Out of memory");
}
return p;
-#endif
}
+#endif
void *grealloc(void *p, int size) GMEM_EXCEP {
#ifdef DEBUG_MEM
@@ -192,6 +230,7 @@ void gfree(void *p) {
if (p) {
hdr = (GMemHdr *)((char *)p - gMemHdrSize);
+ gMemLock;
if (hdr->magic == gMemMagic &&
((hdr->prev == NULL) == (hdr == gMemHead)) &&
((hdr->next == NULL) == (hdr == gMemTail))) {
@@ -207,6 +246,7 @@ void gfree(void *p) {
}
--gMemAlloc;
gMemInUse -= hdr->size;
+ gMemUnlock;
size = gMemDataSize(hdr->size);
trl = (unsigned long *)((char *)hdr + gMemHdrSize + size);
if (*trl != gMemDeadVal) {
@@ -218,6 +258,7 @@ void gfree(void *p) {
}
free(hdr);
} else {
+ gMemUnlock;
fprintf(stderr, "Attempted to free bad address %p\n", p);
}
}
@@ -240,17 +281,25 @@ void gMemError(const char *msg) GMEM_EXCEP {
#ifdef DEBUG_MEM
void gMemReport(FILE *f) {
GMemHdr *p;
+ int left;
fprintf(f, "%d memory allocations in all\n", gMemIndex);
fprintf(f, "maximum memory in use: %d bytes\n", gMaxMemInUse);
+ left = 0;
if (gMemAlloc > 0) {
- fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
- fprintf(f, " index size\n");
- fprintf(f, "-------- --------\n");
for (p = gMemHead; p; p = p->next) {
- fprintf(f, "%8d %8d\n", p->index, p->size);
+ if (p->index >= 0) {
+ if (!left) {
+ fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
+ fprintf(f, " index size\n");
+ fprintf(f, "-------- --------\n");
+ left = 1;
+ }
+ fprintf(f, "%8d %8d\n", p->index, p->size);
+ }
}
- } else {
+ }
+ if (!left) {
fprintf(f, "No memory blocks left allocated\n");
}
}
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/gmem.h b/Build/source/libs/xpdf/xpdf-src/goo/gmem.h
index bfa9658e451..e836e2dd6e8 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/gmem.h
+++ b/Build/source/libs/xpdf/xpdf-src/goo/gmem.h
@@ -36,7 +36,11 @@ extern "C" {
* Same as malloc, but prints error message and exits if malloc()
* returns NULL.
*/
+#ifdef DEBUG_MEM
+extern void *gmalloc(int size, int ignore = 0) GMEM_EXCEP;
+#else
extern void *gmalloc(int size) GMEM_EXCEP;
+#endif
/*
* Same as realloc, but prints error message and exits if realloc()
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/gmempp.cc b/Build/source/libs/xpdf/xpdf-src/goo/gmempp.cc
index b1ee970d38a..fe5790b1f58 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/gmempp.cc
+++ b/Build/source/libs/xpdf/xpdf-src/goo/gmempp.cc
@@ -10,23 +10,42 @@
#include <aconf.h>
#include "gmem.h"
+// NB: do not include gmempp.h here.
#ifdef DEBUG_MEM
void *operator new(size_t size) {
- return gmalloc((int)size);
+ return gmalloc((int)size, 1);
+}
+
+void *operator new(size_t size, int dummy) {
+ return gmalloc((int)size, 0);
}
void *operator new[](size_t size) {
- return gmalloc((int)size);
+ return gmalloc((int)size, 1);
+}
+
+void *operator new[](size_t size, int dummy) {
+ return gmalloc((int)size, 0);
}
void operator delete(void *p) {
gfree(p);
}
+// This is only called if a constructor throws an exception.
+void operator delete(void *p, int dummy) {
+ gfree(p);
+}
+
void operator delete[](void *p) {
gfree(p);
}
+// This is only called if a constructor throws an exception.
+void operator delete[](void *p, int dummy) {
+ gfree(p);
+}
+
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/gmempp.h b/Build/source/libs/xpdf/xpdf-src/goo/gmempp.h
new file mode 100644
index 00000000000..27f7fe786c5
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/goo/gmempp.h
@@ -0,0 +1,48 @@
+//========================================================================
+//
+// gmempp.h
+//
+// Redefine the new and delete operators to call the debugging malloc.
+//
+// This is a hack: some libraries (Qt) allocate global objects and
+// never free them, so this file #define's new to have an argument, so
+// that we can differentiate our new calls from external library new
+// calls. Calls from external libraries will not be counted when
+// un-freed memory is listed. There's no guarantee that this will
+// work in all cases: if some external library also defines a new
+// operator that takes the same extra argument, things will break
+// horribly.
+//
+// This entire .h file is wrapped in '#ifdef DEBUG_MEM'. I.e., if you
+// don't define DEBUG_MEM, this hack goes away and can't cause any
+// problems. Do not define DEBUG_MEM in production code.
+//
+// To use this .h file, it must be #included *after* all system
+// includes. Calls to new in any modules that do not include this .h
+// file will not be counted as un-freed memory.
+//
+//========================================================================
+
+#ifndef GMEMPP_H
+#define GMEMPP_H
+
+#ifdef DEBUG_MEM
+
+#include <stdlib.h>
+
+extern void *operator new(size_t size, int dummy);
+extern void *operator new[](size_t size, int dummy);
+
+// These have to be defined (and declared) to avoid a compiler warning
+// with Visual Studio.
+extern void operator delete(void *p, int dummy);
+extern void operator delete[](void *p, int dummy);
+
+// This transforms 'new Foo(...)' into 'new (1) Foo(...)', which
+// forces a call to the operator new variant with the 'int dummy' arg.
+#define debug_new new (1)
+#define new debug_new
+
+#endif // DEBUG_MEM
+
+#endif // GMEMPP_H
diff --git a/Build/source/libs/xpdf/xpdf-src/goo/parseargs.c b/Build/source/libs/xpdf/xpdf-src/goo/parseargs.c
index fdefa6c3351..2f5844f06d4 100644
--- a/Build/source/libs/xpdf/xpdf-src/goo/parseargs.c
+++ b/Build/source/libs/xpdf/xpdf-src/goo/parseargs.c
@@ -26,14 +26,19 @@ GBool parseArgs(ArgDesc *args, int *argc, char *argv[]) {
while (i < *argc) {
if (!strcmp(argv[i], "--")) {
--*argc;
- for (j = i; j < *argc; ++j)
+ for (j = i; j < *argc; ++j) {
argv[j] = argv[j+1];
+ }
break;
} else if ((arg = findArg(args, argv[i]))) {
- if (!grabArg(arg, i, argc, argv))
+ if (!grabArg(arg, i, argc, argv)) {
ok = gFalse;
+ }
+ } else if (argv[i][0] == '-') {
+ ok = gFalse;
+ break;
} else {
- ++i;
+ break;
}
}
return ok;
@@ -65,7 +70,7 @@ void printUsage(const char *program, const char *otherArgs, ArgDesc *args) {
break;
case argFP:
case argFPDummy:
- typ = " <fp>";
+ typ = " <number>";
break;
case argString:
case argStringDummy:
diff --git a/Build/source/libs/xpdf/xpdf-src/misc/hello.pdf b/Build/source/libs/xpdf/xpdf-src/misc/hello.pdf
deleted file mode 100644
index d097335982d..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/misc/hello.pdf
+++ /dev/null
Binary files differ
diff --git a/Build/source/libs/xpdf/xpdf-src/misc/xpdf.dt b/Build/source/libs/xpdf/xpdf-src/misc/xpdf.dt
deleted file mode 100644
index d3d41b7c897..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/misc/xpdf.dt
+++ /dev/null
@@ -1,28 +0,0 @@
-# simple CDE action for xpdf
-# written by Roland.Mainz@informatik.med.uni-giessen.de
-#
-# To use, copy this file into $HOME/.dt/types
-#
-# NOTE: this overrides the actions AcroRead and AcroReadPrint
-# defined in /usr/dt/appconfig/types/C/solaris.dt
-
-ACTION AcroRead
-{
- TYPE COMMAND
- WINDOW_TYPE NO_STDIO
- EXEC_STRING xpdf "%(File)Arg_1%"
-}
-
-# NOTE: Add a '-level1' switch to pdftops if your printer does not
-# support Level 2 Postscript.
-ACTION AcroReadPrint
-{
- TYPE COMMAND
- WINDOW_TYPE NO_STDIO
- EXEC_STRING ksh -c ' \
- MYFILE="%(File)Arg_1%" ; \
- pdftops "${MYFILE}" /dev/stdout | \
- dtlp -w -b "${MYFILE}"'
-}
-
-# EOF.
diff --git a/Build/source/libs/xpdf/xpdf-src/ms_make.bat b/Build/source/libs/xpdf/xpdf-src/ms_make.bat
deleted file mode 100755
index 684b26fd1ce..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/ms_make.bat
+++ /dev/null
@@ -1,134 +0,0 @@
-set CC=cl
-set CXX=cl
-set FT2DIR=..\freetype-2.5.3
-rem *** Set PNGDIR and ZLIBDIR to build pdftohtml
-rem set PNGDIR=..\libpng-1.5.12
-rem set ZLIBDIR=..\zlib-1.2.7
-set CFLAGS=/I.. /I..\goo /I..\fofi /I..\splash /O2 /nologo /I%FT2DIR%\include
-set CXXFLAGS=%CFLAGS% /TP
-set LIBPROG=lib
-set LINKFLAGS=/MT /nologo
-
-copy aconf-win32.h aconf.h
-
-cd goo
-%CXX% %CXXFLAGS% /c GHash.cc
-%CXX% %CXXFLAGS% /c GList.cc
-%CXX% %CXXFLAGS% /c GString.cc
-%CXX% %CXXFLAGS% /c gmem.cc
-%CXX% %CXXFLAGS% /c gmempp.cc
-%CXX% %CXXFLAGS% /c gfile.cc
-%CC% %CFLAGS% /c parseargs.c
-%LIBPROG% /nologo /out:Goo.lib GHash.obj GList.obj GString.obj gmempp.obj gfile.obj gmem.obj parseargs.obj
-
-cd ..\fofi
-%CXX% %CXXFLAGS% /c FoFiBase.cc
-%CXX% %CXXFLAGS% /c FoFiEncodings.cc
-%CXX% %CXXFLAGS% /c FoFiIdentifier.cc
-%CXX% %CXXFLAGS% /c FoFiTrueType.cc
-%CXX% %CXXFLAGS% /c FoFiType1.cc
-%CXX% %CXXFLAGS% /c FoFiType1C.cc
-%LIBPROG% /nologo /out:fofi.lib FoFiBase.obj FoFiEncodings.obj FoFiIdentifier.obj FoFiTrueType.obj FoFiType1.obj FoFiType1C.obj
-
-cd ..\splash
-%CXX% %CXXFLAGS% /c Splash.cc
-%CXX% %CXXFLAGS% /c SplashBitmap.cc
-%CXX% %CXXFLAGS% /c SplashClip.cc
-%CXX% %CXXFLAGS% /c SplashFTFont.cc
-%CXX% %CXXFLAGS% /c SplashFTFontEngine.cc
-%CXX% %CXXFLAGS% /c SplashFTFontFile.cc
-%CXX% %CXXFLAGS% /c SplashFont.cc
-%CXX% %CXXFLAGS% /c SplashFontEngine.cc
-%CXX% %CXXFLAGS% /c SplashFontFile.cc
-%CXX% %CXXFLAGS% /c SplashFontFileID.cc
-%CXX% %CXXFLAGS% /c SplashPath.cc
-%CXX% %CXXFLAGS% /c SplashPattern.cc
-%CXX% %CXXFLAGS% /c SplashScreen.cc
-%CXX% %CXXFLAGS% /c SplashState.cc
-%CXX% %CXXFLAGS% /c SplashXPath.cc
-%CXX% %CXXFLAGS% /c SplashXPathScanner.cc
-%LIBPROG% /nologo /out:splash.lib Splash.obj SplashBitmap.obj SplashClip.obj SplashFTFont.obj SplashFTFontEngine.obj SplashFTFontFile.obj SplashFont.obj SplashFontEngine.obj SplashFontFile.obj SplashFontFileID.obj SplashPath.obj SplashPattern.obj SplashScreen.obj SplashState.obj SplashXPath.obj SplashXPathScanner.obj
-
-cd ..\xpdf
-%CXX% %CXXFLAGS% /c AcroForm.cc
-%CXX% %CXXFLAGS% /c Annot.cc
-%CXX% %CXXFLAGS% /c Array.cc
-%CXX% %CXXFLAGS% /c BuiltinFont.cc
-%CXX% %CXXFLAGS% /c BuiltinFontTables.cc
-%CXX% %CXXFLAGS% /c CMap.cc
-%CXX% %CXXFLAGS% /c Catalog.cc
-%CXX% %CXXFLAGS% /c CharCodeToUnicode.cc
-%CXX% %CXXFLAGS% /c Decrypt.cc
-%CXX% %CXXFLAGS% /c Dict.cc
-%CXX% %CXXFLAGS% /c Error.cc
-%CXX% %CXXFLAGS% /c FontEncodingTables.cc
-%CXX% %CXXFLAGS% /c Form.cc
-%CXX% %CXXFLAGS% /c Function.cc
-%CXX% %CXXFLAGS% /c Gfx.cc
-%CXX% %CXXFLAGS% /c GfxFont.cc
-%CXX% %CXXFLAGS% /c GfxState.cc
-%CXX% %CXXFLAGS% /c GlobalParams.cc
-%CXX% %CXXFLAGS% /c ImageOutputDev.cc
-%CXX% %CXXFLAGS% /c JArithmeticDecoder.cc
-%CXX% %CXXFLAGS% /c JBIG2Stream.cc
-%CXX% %CXXFLAGS% /c JPXStream.cc
-%CXX% %CXXFLAGS% /c Lexer.cc
-%CXX% %CXXFLAGS% /c Link.cc
-%CXX% %CXXFLAGS% /c NameToCharCode.cc
-%CXX% %CXXFLAGS% /c Object.cc
-%CXX% %CXXFLAGS% /c OptionalContent.cc
-%CXX% %CXXFLAGS% /c Outline.cc
-%CXX% %CXXFLAGS% /c OutputDev.cc
-%CXX% %CXXFLAGS% /c PDFDoc.cc
-%CXX% %CXXFLAGS% /c PDFDocEncoding.cc
-%CXX% %CXXFLAGS% /c PSOutputDev.cc
-%CXX% %CXXFLAGS% /c PSTokenizer.cc
-%CXX% %CXXFLAGS% /c Page.cc
-%CXX% %CXXFLAGS% /c Parser.cc
-%CXX% %CXXFLAGS% /c PreScanOutputDev.cc
-%CXX% %CXXFLAGS% /c SecurityHandler.cc
-%CXX% %CXXFLAGS% /c SplashOutputDev.cc
-%CXX% %CXXFLAGS% /c Stream.cc
-%CXX% %CXXFLAGS% /c TextOutputDev.cc
-%CXX% %CXXFLAGS% /c TextString.cc
-%CXX% %CXXFLAGS% /c UnicodeMap.cc
-%CXX% %CXXFLAGS% /c UnicodeTypeTable.cc
-%CXX% %CXXFLAGS% /c XFAForm.cc
-%CXX% %CXXFLAGS% /c XRef.cc
-%CXX% %CXXFLAGS% /c Zoox.cc
-%CXX% %CXXFLAGS% /c pdftops.cc
-%CXX% %CXXFLAGS% /c pdftotext.cc
-%CXX% %CXXFLAGS% /c pdftoppm.cc
-%CXX% %CXXFLAGS% /c pdfinfo.cc
-%CXX% %CXXFLAGS% /c pdffonts.cc
-%CXX% %CXXFLAGS% /c pdfdetach.cc
-%CXX% %CXXFLAGS% /c pdfimages.cc
-
-%CXX% %LINKFLAGS% /Fepdftops.exe AcroForm.obj Annot.obj Array.obj BuiltinFont.obj BuiltinFontTables.obj Catalog.obj CharCodeToUnicode.obj CMap.obj Decrypt.obj Dict.obj Error.obj FontEncodingTables.obj Form.obj Function.obj Gfx.obj GfxFont.obj GfxState.obj GlobalParams.obj JArithmeticDecoder.obj JBIG2Stream.obj JPXStream.obj Lexer.obj Link.obj NameToCharCode.obj Object.obj OptionalContent.obj Outline.obj OutputDev.obj Page.obj Parser.obj PDFDoc.obj PDFDocEncoding.obj PSOutputDev.obj PSTokenizer.obj PreScanOutputDev.obj SecurityHandler.obj SplashOutputDev.obj Stream.obj TextString.obj UnicodeMap.obj XFAForm.obj XRef.obj Zoox.obj pdftops.obj ..\splash\splash.lib ..\fofi\fofi.lib ..\goo\Goo.lib %FT2DIR%\freetype2.lib shell32.lib user32.lib gdi32.lib advapi32.lib
-
-%CXX% %LINKFLAGS% /Fepdftotext.exe AcroForm.obj Annot.obj Array.obj BuiltinFont.obj BuiltinFontTables.obj Catalog.obj CharCodeToUnicode.obj CMap.obj Decrypt.obj Dict.obj Error.obj FontEncodingTables.obj Form.obj Function.obj Gfx.obj GfxFont.obj GfxState.obj GlobalParams.obj JArithmeticDecoder.obj JBIG2Stream.obj JPXStream.obj Lexer.obj Link.obj NameToCharCode.obj Object.obj OptionalContent.obj Outline.obj OutputDev.obj Page.obj Parser.obj PDFDoc.obj PDFDocEncoding.obj PSTokenizer.obj SecurityHandler.obj Stream.obj TextOutputDev.obj TextString.obj UnicodeMap.obj UnicodeTypeTable.obj XFAForm.obj XRef.obj Zoox.obj pdftotext.obj ..\fofi\fofi.lib ..\goo\Goo.lib shell32.lib user32.lib gdi32.lib advapi32.lib
-
-%CXX% %LINKFLAGS% /Fepdftoppm.exe AcroForm.obj Annot.obj Array.obj BuiltinFont.obj BuiltinFontTables.obj Catalog.obj CharCodeToUnicode.obj CMap.obj Decrypt.obj Dict.obj Error.obj FontEncodingTables.obj Form.obj Function.obj Gfx.obj GfxFont.obj GfxState.obj GlobalParams.obj JArithmeticDecoder.obj JBIG2Stream.obj JPXStream.obj Lexer.obj Link.obj NameToCharCode.obj Object.obj OptionalContent.obj Outline.obj OutputDev.obj Page.obj Parser.obj PDFDoc.obj PDFDocEncoding.obj PSTokenizer.obj SecurityHandler.obj SplashOutputDev.obj Stream.obj TextString.obj UnicodeMap.obj UnicodeTypeTable.obj XFAForm.obj XRef.obj Zoox.obj pdftoppm.obj ..\splash\splash.lib ..\fofi\fofi.lib ..\goo\Goo.lib %FT2DIR%\freetype2.lib shell32.lib user32.lib gdi32.lib advapi32.lib
-
-%CXX% %LINKFLAGS% /Fepdfinfo.exe AcroForm.obj Annot.obj Array.obj BuiltinFont.obj BuiltinFontTables.obj Catalog.obj CharCodeToUnicode.obj CMap.obj Decrypt.obj Dict.obj Error.obj FontEncodingTables.obj Form.obj Function.obj Gfx.obj GfxFont.obj GfxState.obj GlobalParams.obj JArithmeticDecoder.obj JBIG2Stream.obj JPXStream.obj Lexer.obj Link.obj NameToCharCode.obj Object.obj OptionalContent.obj Outline.obj OutputDev.obj Page.obj Parser.obj PDFDoc.obj PDFDocEncoding.obj PSTokenizer.obj SecurityHandler.obj Stream.obj TextString.obj UnicodeMap.obj XFAForm.obj XRef.obj Zoox.obj pdfinfo.obj ..\fofi\fofi.lib ..\goo\Goo.lib shell32.lib user32.lib gdi32.lib advapi32.lib
-
-%CXX% %LINKFLAGS% /Fepdffonts.exe AcroForm.obj Annot.obj Array.obj BuiltinFont.obj BuiltinFontTables.obj Catalog.obj CharCodeToUnicode.obj CMap.obj Decrypt.obj Dict.obj Error.obj FontEncodingTables.obj Form.obj Function.obj Gfx.obj GfxFont.obj GfxState.obj GlobalParams.obj JArithmeticDecoder.obj JBIG2Stream.obj JPXStream.obj Lexer.obj Link.obj NameToCharCode.obj Object.obj OptionalContent.obj Outline.obj OutputDev.obj Page.obj Parser.obj PDFDoc.obj PDFDocEncoding.obj PSTokenizer.obj SecurityHandler.obj Stream.obj TextString.obj UnicodeMap.obj XFAForm.obj XRef.obj Zoox.obj pdffonts.obj ..\fofi\fofi.lib ..\goo\Goo.lib shell32.lib user32.lib gdi32.lib advapi32.lib
-
-%CXX% %LINKFLAGS% /Fepdfdetach.exe AcroForm.obj Annot.obj Array.obj BuiltinFont.obj BuiltinFontTables.obj Catalog.obj CharCodeToUnicode.obj CMap.obj Decrypt.obj Dict.obj Error.obj FontEncodingTables.obj Form.obj Function.obj Gfx.obj GfxFont.obj GfxState.obj GlobalParams.obj JArithmeticDecoder.obj JBIG2Stream.obj JPXStream.obj Lexer.obj Link.obj NameToCharCode.obj Object.obj OptionalContent.obj Outline.obj OutputDev.obj Page.obj Parser.obj PDFDoc.obj PDFDocEncoding.obj PSTokenizer.obj SecurityHandler.obj Stream.obj TextString.obj UnicodeMap.obj XFAForm.obj XRef.obj Zoox.obj pdfdetach.obj ..\fofi\fofi.lib ..\goo\Goo.lib shell32.lib user32.lib gdi32.lib advapi32.lib
-
-%CXX% %LINKFLAGS% /Fepdfimages.exe AcroForm.obj Annot.obj Array.obj BuiltinFont.obj BuiltinFontTables.obj Catalog.obj CharCodeToUnicode.obj CMap.obj Decrypt.obj Dict.obj Error.obj FontEncodingTables.obj Form.obj Function.obj Gfx.obj GfxFont.obj GfxState.obj GlobalParams.obj ImageOutputDev.obj JArithmeticDecoder.obj JBIG2Stream.obj JPXStream.obj Lexer.obj Link.obj NameToCharCode.obj Object.obj OptionalContent.obj Outline.obj OutputDev.obj Page.obj Parser.obj PDFDoc.obj PDFDocEncoding.obj PSTokenizer.obj SecurityHandler.obj Stream.obj TextString.obj UnicodeMap.obj XFAForm.obj XRef.obj Zoox.obj pdfimages.obj ..\fofi\fofi.lib ..\goo\Goo.lib shell32.lib user32.lib gdi32.lib advapi32.lib
-
-if x%PNGDIR% == x goto noHTML
-if x%ZLIBDIR% == x goto noHTML
-
-%CXX% %CXXFLAGS% /I%PNGDIR% /I%ZLIBDIR% /c pdftopng.cc
-%CXX% %LINKFLAGS% /Fepdftopng.exe AcroForm.obj Annot.obj Array.obj BuiltinFont.obj BuiltinFontTables.obj Catalog.obj CharCodeToUnicode.obj CMap.obj Decrypt.obj Dict.obj Error.obj FontEncodingTables.obj Form.obj Function.obj Gfx.obj GfxFont.obj GfxState.obj GlobalParams.obj JArithmeticDecoder.obj JBIG2Stream.obj JPXStream.obj Lexer.obj Link.obj NameToCharCode.obj Object.obj OptionalContent.obj Outline.obj OutputDev.obj Page.obj Parser.obj PDFDoc.obj PDFDocEncoding.obj PSTokenizer.obj SecurityHandler.obj SplashOutputDev.obj Stream.obj TextString.obj UnicodeMap.obj UnicodeTypeTable.obj XFAForm.obj XRef.obj Zoox.obj pdftopng.obj ..\splash\splash.lib ..\fofi\fofi.lib ..\goo\Goo.lib %FT2DIR%\freetype2.lib %PNGDIR%\libpng.lib %ZLIBDIR%\zlib.lib shell32.lib user32.lib gdi32.lib advapi32.lib
-
-echo "building pdftohtml"
-%CXX% %CXXFLAGS% /I%PNGDIR% /I%ZLIBDIR% /c HTMLGen.cc
-%CXX% %CXXFLAGS% /I%PNGDIR% /I%ZLIBDIR% /c pdftohtml.cc
-%CXX% %LINKFLAGS% /Fepdftohtml.exe AcroForm.obj Annot.obj Array.obj BuiltinFont.obj BuiltinFontTables.obj Catalog.obj CharCodeToUnicode.obj CMap.obj Decrypt.obj Dict.obj Error.obj FontEncodingTables.obj Form.obj Function.obj Gfx.obj GfxFont.obj GfxState.obj GlobalParams.obj HTMLGen.obj JArithmeticDecoder.obj JBIG2Stream.obj JPXStream.obj Lexer.obj Link.obj NameToCharCode.obj Object.obj OptionalContent.obj Outline.obj OutputDev.obj Page.obj Parser.obj PDFDoc.obj PDFDocEncoding.obj PSTokenizer.obj SecurityHandler.obj SplashOutputDev.obj Stream.obj TextOutputDev.obj TextString.obj UnicodeMap.obj UnicodeTypeTable.obj XFAForm.obj XRef.obj Zoox.obj pdftohtml.obj ..\splash\splash.lib ..\fofi\fofi.lib ..\goo\Goo.lib %FT2DIR%\freetype2.lib %PNGDIR%\libpng.lib %ZLIBDIR%\zlib.lib shell32.lib user32.lib gdi32.lib advapi32.lib
-
-:noHTML
-
-cd ..
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt
new file mode 100644
index 00000000000..f84968cfb2a
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt
@@ -0,0 +1,47 @@
+#========================================================================
+#
+# splash/CMakeLists.txt
+#
+# CMake script for the splash library.
+#
+# Copyright 2015 Glyph & Cog, LLC
+#
+#========================================================================
+
+if (HAVE_SPLASH)
+ include_directories("${PROJECT_SOURCE_DIR}")
+ include_directories("${PROJECT_BINARY_DIR}")
+ include_directories("${PROJECT_SOURCE_DIR}/goo")
+ include_directories("${PROJECT_SOURCE_DIR}/fofi")
+ include_directories("${FREETYPE_INCLUDE_DIRS}")
+
+ if (HAVE_DTYPE4_H)
+ include_directories("${DTYPE_INCLUDE_DIR}")
+ set(DTYPE_SRCS
+ SplashDT4Font.cc SplashDT4FontEngine.cc SplashDT4FontFile.cc)
+ endif ()
+
+ add_library(splash_objs OBJECT
+ Splash.cc
+ SplashBitmap.cc
+ SplashClip.cc
+ SplashFTFont.cc
+ SplashFTFontEngine.cc
+ SplashFTFontFile.cc
+ SplashFont.cc
+ SplashFontEngine.cc
+ SplashFontFile.cc
+ SplashFontFileID.cc
+ SplashPath.cc
+ SplashPattern.cc
+ SplashScreen.cc
+ SplashState.cc
+ SplashXPath.cc
+ SplashXPathScanner.cc
+ ${DTYPE_SRCS}
+ )
+
+ add_library(splash
+ $<TARGET_OBJECTS:splash_objs>
+ )
+endif ()
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Makefile.dep b/Build/source/libs/xpdf/xpdf-src/splash/Makefile.dep
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/splash/Makefile.dep
+++ /dev/null
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Makefile.in b/Build/source/libs/xpdf/xpdf-src/splash/Makefile.in
deleted file mode 100644
index 6479b1543ee..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/splash/Makefile.in
+++ /dev/null
@@ -1,93 +0,0 @@
-#========================================================================
-#
-# Splash library Makefile
-#
-# Copyright 2003 Glyph & Cog, LLC
-#
-#========================================================================
-
-SHELL = /bin/sh
-
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-GOOSRCDIR = $(srcdir)/../goo
-GOOLIBDIR = ../goo
-FOFISRCDIR = $(srcdir)/../fofi
-FOFILIBDIR = ../fofi
-
-CXXFLAGS = @CXXFLAGS@ @DEFS@ -I.. -I$(srcdir)/.. -I$(GOOSRCDIR) -I$(FOFISRCDIR) -I$(srcdir) @freetype2_CFLAGS@
-
-CXX = @CXX@
-AR = @AR@
-RANLIB = @RANLIB@
-
-LIBPREFIX = @LIBPREFIX@
-
-#------------------------------------------------------------------------
-
-.SUFFIXES: .cc
-
-.cc.o:
- $(CXX) $(CXXFLAGS) -c $<
-
-#------------------------------------------------------------------------
-
-CXX_SRC = \
- $(srcdir)/Splash.cc \
- $(srcdir)/SplashBitmap.cc \
- $(srcdir)/SplashClip.cc \
- $(srcdir)/SplashFTFont.cc \
- $(srcdir)/SplashFTFontEngine.cc \
- $(srcdir)/SplashFTFontFile.cc \
- $(srcdir)/SplashFont.cc \
- $(srcdir)/SplashFontEngine.cc \
- $(srcdir)/SplashFontFile.cc \
- $(srcdir)/SplashFontFileID.cc \
- $(srcdir)/SplashPath.cc \
- $(srcdir)/SplashPattern.cc \
- $(srcdir)/SplashScreen.cc \
- $(srcdir)/SplashState.cc \
- $(srcdir)/SplashXPath.cc \
- $(srcdir)/SplashXPathScanner.cc
-
-#------------------------------------------------------------------------
-
-all: $(LIBPREFIX)splash.a
-
-#------------------------------------------------------------------------
-
-SPLASH_OBJS = \
- Splash.o \
- SplashBitmap.o \
- SplashClip.o \
- SplashFTFont.o \
- SplashFTFontEngine.o \
- SplashFTFontFile.o \
- SplashFont.o \
- SplashFontEngine.o \
- SplashFontFile.o \
- SplashFontFileID.o \
- SplashPath.o \
- SplashPattern.o \
- SplashScreen.o \
- SplashState.o \
- SplashXPath.o \
- SplashXPathScanner.o
-
-$(LIBPREFIX)splash.a: $(SPLASH_OBJS)
- rm -f $(LIBPREFIX)splash.a
- $(AR) $(LIBPREFIX)splash.a $(SPLASH_OBJS)
- $(RANLIB) $(LIBPREFIX)splash.a
-
-#------------------------------------------------------------------------
-
-clean:
- rm -f $(SPLASH_OBJS) $(LIBPREFIX)splash.a
-
-#------------------------------------------------------------------------
-
-depend:
- $(CXX) $(CXXFLAGS) -MM $(CXX_SRC) >Makefile.dep
-
--include Makefile.dep
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
index d9035b37aa9..0810fbc3bd2 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
@@ -15,7 +15,9 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
+#include <math.h>
#include "gmem.h"
+#include "gmempp.h"
#include "SplashErrorCodes.h"
#include "SplashMath.h"
#include "SplashBitmap.h"
@@ -29,9 +31,12 @@
#include "SplashGlyphBitmap.h"
#include "Splash.h"
-//------------------------------------------------------------------------
+// the MSVC math.h doesn't define this
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
-#define splashAAGamma 0.67
+//------------------------------------------------------------------------
// distance of Bezier control point from center for circle approximation
// = (4 * (sqrt(2) - 1) / 3) * r
@@ -123,17 +128,6 @@ SplashPipeResultColorCtrl Splash::pipeResultColorAlphaBlend[] = {
};
//------------------------------------------------------------------------
-
-static void blendXor(SplashColorPtr src, SplashColorPtr dest,
- SplashColorPtr blend, SplashColorMode cm) {
- int i;
-
- for (i = 0; i < splashColorModeNComps[cm]; ++i) {
- blend[i] = src[i] ^ dest[i];
- }
-}
-
-//------------------------------------------------------------------------
// modified region
//------------------------------------------------------------------------
@@ -269,7 +263,7 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
Guchar shape, aSrc, aDest, alphaI, alphaIm1, alpha0, aResult;
SplashColor cSrc, cDest, cBlend;
Guchar shapeVal, cResult0, cResult1, cResult2, cResult3;
- int cSrcStride, shapeStride, x, lastX, t, i;
+ int cSrcStride, shapeStride, x, lastX, t;
SplashColorPtr destColorPtr;
Guchar destColorMask;
Guchar *destAlphaPtr;
@@ -396,49 +390,33 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
pipe->pattern->getColor(x, y, pipe->cSrcVal);
}
+ cResult0 = cResult1 = cResult2 = cResult3 = 0; // make gcc happy
+
if (pipe->noTransparency && !state->blendFunc) {
- //----- write destination pixel
+ //----- result color
switch (bitmap->mode) {
case splashModeMono1:
- cResult0 = state->grayTransfer[cSrcPtr[0]];
- if (state->screen->test(x, y, cResult0)) {
- *destColorPtr |= destColorMask;
- } else {
- *destColorPtr &= ~destColorMask;
- }
- destColorPtr += destColorMask & 1;
- destColorMask = (destColorMask << 7) | (destColorMask >> 1);
- break;
case splashModeMono8:
- *destColorPtr++ = state->grayTransfer[cSrcPtr[0]];
+ cResult0 = state->grayTransfer[cSrcPtr[0]];
break;
case splashModeRGB8:
- destColorPtr[0] = state->rgbTransferR[cSrcPtr[0]];
- destColorPtr[1] = state->rgbTransferG[cSrcPtr[1]];
- destColorPtr[2] = state->rgbTransferB[cSrcPtr[2]];
- destColorPtr += 3;
- break;
case splashModeBGR8:
- destColorPtr[0] = state->rgbTransferB[cSrcPtr[2]];
- destColorPtr[1] = state->rgbTransferG[cSrcPtr[1]];
- destColorPtr[2] = state->rgbTransferR[cSrcPtr[0]];
- destColorPtr += 3;
+ cResult0 = state->rgbTransferR[cSrcPtr[0]];
+ cResult1 = state->rgbTransferG[cSrcPtr[1]];
+ cResult2 = state->rgbTransferB[cSrcPtr[2]];
break;
#if SPLASH_CMYK
case splashModeCMYK8:
- destColorPtr[0] = state->cmykTransferC[cSrcPtr[0]];
- destColorPtr[1] = state->cmykTransferM[cSrcPtr[1]];
- destColorPtr[2] = state->cmykTransferY[cSrcPtr[2]];
- destColorPtr[3] = state->cmykTransferK[cSrcPtr[3]];
- destColorPtr += 4;
+ cResult0 = state->cmykTransferC[cSrcPtr[0]];
+ cResult1 = state->cmykTransferM[cSrcPtr[1]];
+ cResult2 = state->cmykTransferY[cSrcPtr[2]];
+ cResult3 = state->cmykTransferK[cSrcPtr[3]];
break;
#endif
}
- if (destAlphaPtr) {
- *destAlphaPtr++ = 255;
- }
+ aResult = 255;
} else { // if (noTransparency && !blendFunc)
@@ -516,17 +494,42 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
aDest = 0xff;
}
- //----- overprint
+ //----- read source color; handle overprint
- for (i = 0; i < bitmapComps; ++i) {
+ switch (bitmap->mode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ cSrc[0] = state->grayTransfer[cSrcPtr[0]];
+ break;
+ case splashModeRGB8:
+ case splashModeBGR8:
+ cSrc[0] = state->rgbTransferR[cSrcPtr[0]];
+ cSrc[1] = state->rgbTransferG[cSrcPtr[1]];
+ cSrc[2] = state->rgbTransferB[cSrcPtr[2]];
+ break;
#if SPLASH_CMYK
- if (state->overprintMask & (1 << i)) {
- cSrc[i] = cSrcPtr[i];
+ case splashModeCMYK8:
+ if (state->overprintMask & 0x01) {
+ cSrc[0] = state->cmykTransferC[cSrcPtr[0]];
} else {
- cSrc[i] = div255(aDest * cDest[i]);
+ cSrc[0] = div255(aDest * cDest[0]);
}
-#else
- cSrc[i] = cSrcPtr[i];
+ if (state->overprintMask & 0x02) {
+ cSrc[1] = state->cmykTransferM[cSrcPtr[1]];
+ } else {
+ cSrc[1] = div255(aDest * cDest[1]);
+ }
+ if (state->overprintMask & 0x04) {
+ cSrc[2] = state->cmykTransferY[cSrcPtr[2]];
+ } else {
+ cSrc[2] = div255(aDest * cDest[2]);
+ }
+ if (state->overprintMask & 0x08) {
+ cSrc[3] = state->cmykTransferK[cSrcPtr[3]];
+ } else {
+ cSrc[3] = div255(aDest * cDest[3]);
+ }
+ break;
#endif
}
@@ -629,32 +632,22 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
//----- result color
- cResult0 = cResult1 = cResult2 = cResult3 = 0; // make gcc happy
-
switch (pipe->resultColorCtrl) {
case splashPipeResultColorNoAlphaBlendMono:
- cResult0 = state->grayTransfer[div255((255 - aDest) * cSrc[0] +
- aDest * cBlend[0])];
+ cResult0 = div255((255 - aDest) * cSrc[0] + aDest * cBlend[0]);
break;
case splashPipeResultColorNoAlphaBlendRGB:
- cResult0 = state->rgbTransferR[div255((255 - aDest) * cSrc[0] +
- aDest * cBlend[0])];
- cResult1 = state->rgbTransferG[div255((255 - aDest) * cSrc[1] +
- aDest * cBlend[1])];
- cResult2 = state->rgbTransferB[div255((255 - aDest) * cSrc[2] +
- aDest * cBlend[2])];
+ cResult0 = div255((255 - aDest) * cSrc[0] + aDest * cBlend[0]);
+ cResult1 = div255((255 - aDest) * cSrc[1] + aDest * cBlend[1]);
+ cResult2 = div255((255 - aDest) * cSrc[2] + aDest * cBlend[2]);
break;
#if SPLASH_CMYK
case splashPipeResultColorNoAlphaBlendCMYK:
- cResult0 = state->cmykTransferC[div255((255 - aDest) * cSrc[0] +
- aDest * cBlend[0])];
- cResult1 = state->cmykTransferM[div255((255 - aDest) * cSrc[1] +
- aDest * cBlend[1])];
- cResult2 = state->cmykTransferY[div255((255 - aDest) * cSrc[2] +
- aDest * cBlend[2])];
- cResult3 = state->cmykTransferK[div255((255 - aDest) * cSrc[3] +
- aDest * cBlend[3])];
+ cResult0 = div255((255 - aDest) * cSrc[0] + aDest * cBlend[0]);
+ cResult1 = div255((255 - aDest) * cSrc[1] + aDest * cBlend[1]);
+ cResult2 = div255((255 - aDest) * cSrc[2] + aDest * cBlend[2]);
+ cResult3 = div255((255 - aDest) * cSrc[3] + aDest * cBlend[3]);
break;
#endif
@@ -662,8 +655,7 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
if (alphaI == 0) {
cResult0 = 0;
} else {
- cResult0 = state->grayTransfer[((alphaI - aSrc) * cDest[0] +
- aSrc * cSrc[0]) / alphaI];
+ cResult0 = ((alphaI - aSrc) * cDest[0] + aSrc * cSrc[0]) / alphaI;
}
break;
case splashPipeResultColorAlphaNoBlendRGB:
@@ -672,12 +664,9 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
cResult1 = 0;
cResult2 = 0;
} else {
- cResult0 = state->rgbTransferR[((alphaI - aSrc) * cDest[0] +
- aSrc * cSrc[0]) / alphaI];
- cResult1 = state->rgbTransferG[((alphaI - aSrc) * cDest[1] +
- aSrc * cSrc[1]) / alphaI];
- cResult2 = state->rgbTransferB[((alphaI - aSrc) * cDest[2] +
- aSrc * cSrc[2]) / alphaI];
+ cResult0 = ((alphaI - aSrc) * cDest[0] + aSrc * cSrc[0]) / alphaI;
+ cResult1 = ((alphaI - aSrc) * cDest[1] + aSrc * cSrc[1]) / alphaI;
+ cResult2 = ((alphaI - aSrc) * cDest[2] + aSrc * cSrc[2]) / alphaI;
}
break;
#if SPLASH_CMYK
@@ -688,14 +677,10 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
cResult2 = 0;
cResult3 = 0;
} else {
- cResult0 = state->cmykTransferC[((alphaI - aSrc) * cDest[0] +
- aSrc * cSrc[0]) / alphaI];
- cResult1 = state->cmykTransferM[((alphaI - aSrc) * cDest[1] +
- aSrc * cSrc[1]) / alphaI];
- cResult2 = state->cmykTransferY[((alphaI - aSrc) * cDest[2] +
- aSrc * cSrc[2]) / alphaI];
- cResult3 = state->cmykTransferK[((alphaI - aSrc) * cDest[3] +
- aSrc * cSrc[3]) / alphaI];
+ cResult0 = ((alphaI - aSrc) * cDest[0] + aSrc * cSrc[0]) / alphaI;
+ cResult1 = ((alphaI - aSrc) * cDest[1] + aSrc * cSrc[1]) / alphaI;
+ cResult2 = ((alphaI - aSrc) * cDest[2] + aSrc * cSrc[2]) / alphaI;
+ cResult3 = ((alphaI - aSrc) * cDest[3] + aSrc * cSrc[3]) / alphaI;
}
break;
#endif
@@ -704,10 +689,10 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
if (alphaI == 0) {
cResult0 = 0;
} else {
- cResult0 = state->grayTransfer[((alphaI - aSrc) * cDest[0] +
- aSrc * ((255 - alphaIm1) * cSrc[0] +
- alphaIm1 * cBlend[0]) / 255) /
- alphaI];
+ cResult0 = ((alphaI - aSrc) * cDest[0] +
+ aSrc * ((255 - alphaIm1) * cSrc[0] +
+ alphaIm1 * cBlend[0]) / 255)
+ / alphaI;
}
break;
case splashPipeResultColorAlphaBlendRGB:
@@ -716,18 +701,18 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
cResult1 = 0;
cResult2 = 0;
} else {
- cResult0 = state->rgbTransferR[((alphaI - aSrc) * cDest[0] +
- aSrc * ((255 - alphaIm1) * cSrc[0] +
- alphaIm1 * cBlend[0]) / 255) /
- alphaI];
- cResult1 = state->rgbTransferG[((alphaI - aSrc) * cDest[1] +
- aSrc * ((255 - alphaIm1) * cSrc[1] +
- alphaIm1 * cBlend[1]) / 255) /
- alphaI];
- cResult2 = state->rgbTransferB[((alphaI - aSrc) * cDest[2] +
- aSrc * ((255 - alphaIm1) * cSrc[2] +
- alphaIm1 * cBlend[2]) / 255) /
- alphaI];
+ cResult0 = ((alphaI - aSrc) * cDest[0] +
+ aSrc * ((255 - alphaIm1) * cSrc[0] +
+ alphaIm1 * cBlend[0]) / 255)
+ / alphaI;
+ cResult1 = ((alphaI - aSrc) * cDest[1] +
+ aSrc * ((255 - alphaIm1) * cSrc[1] +
+ alphaIm1 * cBlend[1]) / 255)
+ / alphaI;
+ cResult2 = ((alphaI - aSrc) * cDest[2] +
+ aSrc * ((255 - alphaIm1) * cSrc[2] +
+ alphaIm1 * cBlend[2]) / 255)
+ / alphaI;
}
break;
#if SPLASH_CMYK
@@ -738,73 +723,69 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
cResult2 = 0;
cResult3 = 0;
} else {
- cResult0 =
- state->cmykTransferC[((alphaI - aSrc) * cDest[0] +
- aSrc * ((255 - alphaIm1) * cSrc[0] +
- alphaIm1 * cBlend[0]) / 255) /
- alphaI];
- cResult1 =
- state->cmykTransferM[((alphaI - aSrc) * cDest[1] +
- aSrc * ((255 - alphaIm1) * cSrc[1] +
- alphaIm1 * cBlend[1]) / 255) /
- alphaI];
- cResult2 =
- state->cmykTransferY[((alphaI - aSrc) * cDest[2] +
- aSrc * ((255 - alphaIm1) * cSrc[2] +
- alphaIm1 * cBlend[2]) / 255) /
- alphaI];
- cResult3 =
- state->cmykTransferK[((alphaI - aSrc) * cDest[3] +
- aSrc * ((255 - alphaIm1) * cSrc[3] +
- alphaIm1 * cBlend[3]) / 255) /
- alphaI];
+ cResult0 = ((alphaI - aSrc) * cDest[0] +
+ aSrc * ((255 - alphaIm1) * cSrc[0] +
+ alphaIm1 * cBlend[0]) / 255)
+ / alphaI;
+ cResult1 = ((alphaI - aSrc) * cDest[1] +
+ aSrc * ((255 - alphaIm1) * cSrc[1] +
+ alphaIm1 * cBlend[1]) / 255)
+ / alphaI;
+ cResult2 = ((alphaI - aSrc) * cDest[2] +
+ aSrc * ((255 - alphaIm1) * cSrc[2] +
+ alphaIm1 * cBlend[2]) / 255)
+ / alphaI;
+ cResult3 = ((alphaI - aSrc) * cDest[3] +
+ aSrc * ((255 - alphaIm1) * cSrc[3] +
+ alphaIm1 * cBlend[3]) / 255)
+ / alphaI;
}
break;
#endif
}
- //----- write destination pixel
+ } // if (noTransparency && !blendFunc)
- switch (bitmap->mode) {
- case splashModeMono1:
- if (state->screen->test(x, y, cResult0)) {
- *destColorPtr |= destColorMask;
- } else {
- *destColorPtr &= ~destColorMask;
- }
- destColorPtr += destColorMask & 1;
- destColorMask = (destColorMask << 7) | (destColorMask >> 1);
- break;
- case splashModeMono8:
- *destColorPtr++ = cResult0;
- break;
- case splashModeRGB8:
- destColorPtr[0] = cResult0;
- destColorPtr[1] = cResult1;
- destColorPtr[2] = cResult2;
- destColorPtr += 3;
- break;
- case splashModeBGR8:
- destColorPtr[0] = cResult2;
- destColorPtr[1] = cResult1;
- destColorPtr[2] = cResult0;
- destColorPtr += 3;
- break;
+ //----- write destination pixel
+
+ switch (bitmap->mode) {
+ case splashModeMono1:
+ if (state->screen->test(x, y, cResult0)) {
+ *destColorPtr |= destColorMask;
+ } else {
+ *destColorPtr &= ~destColorMask;
+ }
+ destColorPtr += destColorMask & 1;
+ destColorMask = (destColorMask << 7) | (destColorMask >> 1);
+ break;
+ case splashModeMono8:
+ *destColorPtr++ = cResult0;
+ break;
+ case splashModeRGB8:
+ destColorPtr[0] = cResult0;
+ destColorPtr[1] = cResult1;
+ destColorPtr[2] = cResult2;
+ destColorPtr += 3;
+ break;
+ case splashModeBGR8:
+ destColorPtr[0] = cResult2;
+ destColorPtr[1] = cResult1;
+ destColorPtr[2] = cResult0;
+ destColorPtr += 3;
+ break;
#if SPLASH_CMYK
- case splashModeCMYK8:
- destColorPtr[0] = cResult0;
- destColorPtr[1] = cResult1;
- destColorPtr[2] = cResult2;
- destColorPtr[3] = cResult3;
- destColorPtr += 4;
- break;
+ case splashModeCMYK8:
+ destColorPtr[0] = cResult0;
+ destColorPtr[1] = cResult1;
+ destColorPtr[2] = cResult2;
+ destColorPtr[3] = cResult3;
+ destColorPtr += 4;
+ break;
#endif
- }
- if (destAlphaPtr) {
- *destAlphaPtr++ = aResult;
- }
-
- } // if (noTransparency && !blendFunc)
+ }
+ if (destAlphaPtr) {
+ *destAlphaPtr++ = aResult;
+ }
cSrcPtr += cSrcStride;
shapePtr2 += shapeStride;
@@ -821,6 +802,7 @@ void Splash::pipeRunSimpleMono1(SplashPipe *pipe, int x0, int x1, int y,
Guchar cResult0;
SplashColorPtr destColorPtr;
Guchar destColorMask;
+ SplashScreenCursor screenCursor;
int cSrcStride, x;
if (cSrcPtr) {
@@ -839,11 +821,13 @@ void Splash::pipeRunSimpleMono1(SplashPipe *pipe, int x0, int x1, int y,
destColorPtr = &bitmap->data[y * bitmap->rowSize + (x0 >> 3)];
destColorMask = 0x80 >> (x0 & 7);
+ screenCursor = state->screen->getTestCursor(y);
+
for (x = x0; x <= x1; ++x) {
//----- write destination pixel
cResult0 = state->grayTransfer[cSrcPtr[0]];
- if (state->screen->test(x, y, cResult0)) {
+ if (state->screen->testWithCursor(screenCursor, x, cResult0)) {
*destColorPtr |= destColorMask;
} else {
*destColorPtr &= ~destColorMask;
@@ -1013,9 +997,10 @@ void Splash::pipeRunSimpleCMYK8(SplashPipe *pipe, int x0, int x1, int y,
// bitmap->mode == splashModeMono1 && !bitmap->alpha
void Splash::pipeRunShapeMono1(SplashPipe *pipe, int x0, int x1, int y,
Guchar *shapePtr, SplashColorPtr cSrcPtr) {
- Guchar shape, aSrc, cDest0, cResult0;
+ Guchar shape, aSrc, cSrc0, cDest0, cResult0;
SplashColorPtr destColorPtr;
Guchar destColorMask;
+ SplashScreenCursor screenCursor;
int cSrcStride, x, lastX;
if (cSrcPtr) {
@@ -1041,6 +1026,8 @@ void Splash::pipeRunShapeMono1(SplashPipe *pipe, int x0, int x1, int y,
destColorPtr = &bitmap->data[y * bitmap->rowSize + (x0 >> 3)];
destColorMask = 0x80 >> (x0 & 7);
+ screenCursor = state->screen->getTestCursor(y);
+
for (x = x0; x <= x1; ++x) {
//----- shape
@@ -1054,19 +1041,27 @@ void Splash::pipeRunShapeMono1(SplashPipe *pipe, int x0, int x1, int y,
}
lastX = x;
- //----- read destination pixel
- cDest0 = (*destColorPtr & destColorMask) ? 0xff : 0x00;
+ //----- source color
+ cSrc0 = state->grayTransfer[cSrcPtr[0]];
//----- source alpha
aSrc = shape;
- //----- result color
- // note: aDest = alphaI = aResult = 0xff
- cResult0 = state->grayTransfer[(Guchar)div255((0xff - aSrc) * cDest0 +
- aSrc * cSrcPtr[0])];
+ //----- special case for aSrc = 255
+ if (aSrc == 255) {
+ cResult0 = cSrc0;
+ } else {
+
+ //----- read destination pixel
+ cDest0 = (*destColorPtr & destColorMask) ? 0xff : 0x00;
+
+ //----- result color
+ // note: aDest = alphaI = aResult = 0xff
+ cResult0 = (Guchar)div255((0xff - aSrc) * cDest0 + aSrc * cSrc0);
+ }
//----- write destination pixel
- if (state->screen->test(x, y, cResult0)) {
+ if (state->screen->testWithCursor(screenCursor, x, cResult0)) {
*destColorPtr |= destColorMask;
} else {
*destColorPtr &= ~destColorMask;
@@ -1086,7 +1081,7 @@ void Splash::pipeRunShapeMono1(SplashPipe *pipe, int x0, int x1, int y,
// bitmap->mode == splashModeMono8 && bitmap->alpha
void Splash::pipeRunShapeMono8(SplashPipe *pipe, int x0, int x1, int y,
Guchar *shapePtr, SplashColorPtr cSrcPtr) {
- Guchar shape, aSrc, aDest, alphaI, aResult, cDest0, cResult0;
+ Guchar shape, aSrc, aDest, alphaI, aResult, cSrc0, cDest0, cResult0;
SplashColorPtr destColorPtr;
Guchar *destAlphaPtr;
int cSrcStride, x, lastX;
@@ -1127,23 +1122,37 @@ void Splash::pipeRunShapeMono8(SplashPipe *pipe, int x0, int x1, int y,
}
lastX = x;
- //----- read destination pixel
- cDest0 = *destColorPtr;
- aDest = *destAlphaPtr;
+ //----- source color
+ cSrc0 = state->grayTransfer[cSrcPtr[0]];
//----- source alpha
aSrc = shape;
- //----- result alpha and non-isolated group element correction
- aResult = aSrc + aDest - div255(aSrc * aDest);
- alphaI = aResult;
-
- //----- result color
- if (alphaI == 0) {
- cResult0 = 0;
+ //----- special case for aSrc = 255
+ if (aSrc == 255) {
+ aResult = 255;
+ cResult0 = cSrc0;
} else {
- cResult0 = state->grayTransfer[(Guchar)(((alphaI - aSrc) * cDest0 +
- aSrc * cSrcPtr[0]) / alphaI)];
+
+ //----- read destination alpha
+ aDest = *destAlphaPtr;
+
+ //----- special case for aDest = 0
+ if (aDest == 0) {
+ aResult = aSrc;
+ cResult0 = cSrc0;
+ } else {
+
+ //----- read destination pixel
+ cDest0 = *destColorPtr;
+
+ //----- result alpha and non-isolated group element correction
+ aResult = aSrc + aDest - div255(aSrc * aDest);
+ alphaI = aResult;
+
+ //----- result color
+ cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI);
+ }
}
//----- write destination pixel
@@ -1163,6 +1172,7 @@ void Splash::pipeRunShapeMono8(SplashPipe *pipe, int x0, int x1, int y,
void Splash::pipeRunShapeRGB8(SplashPipe *pipe, int x0, int x1, int y,
Guchar *shapePtr, SplashColorPtr cSrcPtr) {
Guchar shape, aSrc, aDest, alphaI, aResult;
+ Guchar cSrc0, cSrc1, cSrc2;
Guchar cDest0, cDest1, cDest2;
Guchar cResult0, cResult1, cResult2;
SplashColorPtr destColorPtr;
@@ -1205,31 +1215,47 @@ void Splash::pipeRunShapeRGB8(SplashPipe *pipe, int x0, int x1, int y,
}
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 = shape;
- //----- result alpha and non-isolated group element correction
- aResult = aSrc + aDest - div255(aSrc * aDest);
- alphaI = aResult;
-
- //----- result color
- if (alphaI == 0) {
- cResult0 = 0;
- cResult1 = 0;
- cResult2 = 0;
+ //----- special case for aSrc = 255
+ if (aSrc == 255) {
+ aResult = 255;
+ cResult0 = cSrc0;
+ cResult1 = cSrc1;
+ cResult2 = cSrc2;
} else {
- cResult0 = state->rgbTransferR[(Guchar)(((alphaI - aSrc) * cDest0 +
- aSrc * cSrcPtr[0]) / alphaI)];
- cResult1 = state->rgbTransferG[(Guchar)(((alphaI - aSrc) * cDest1 +
- aSrc * cSrcPtr[1]) / alphaI)];
- cResult2 = state->rgbTransferB[(Guchar)(((alphaI - aSrc) * cDest2 +
- aSrc * cSrcPtr[2]) / alphaI)];
+
+ //----- read destination alpha
+ aDest = *destAlphaPtr;
+
+ //----- special case for aDest = 0
+ if (aDest == 0) {
+ aResult = aSrc;
+ cResult0 = cSrc0;
+ cResult1 = cSrc1;
+ cResult2 = cSrc2;
+ } else {
+
+ //----- read destination pixel
+ cDest0 = destColorPtr[0];
+ cDest1 = destColorPtr[1];
+ cDest2 = destColorPtr[2];
+
+ //----- result alpha and non-isolated group element correction
+ aResult = aSrc + aDest - div255(aSrc * aDest);
+ alphaI = aResult;
+
+ //----- result color
+ 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
@@ -1252,6 +1278,7 @@ void Splash::pipeRunShapeRGB8(SplashPipe *pipe, int x0, int x1, int y,
void Splash::pipeRunShapeBGR8(SplashPipe *pipe, int x0, int x1, int y,
Guchar *shapePtr, SplashColorPtr cSrcPtr) {
Guchar shape, aSrc, aDest, alphaI, aResult;
+ Guchar cSrc0, cSrc1, cSrc2;
Guchar cDest0, cDest1, cDest2;
Guchar cResult0, cResult1, cResult2;
SplashColorPtr destColorPtr;
@@ -1294,31 +1321,47 @@ void Splash::pipeRunShapeBGR8(SplashPipe *pipe, int x0, int x1, int y,
}
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 = shape;
- //----- result alpha and non-isolated group element correction
- aResult = aSrc + aDest - div255(aSrc * aDest);
- alphaI = aResult;
-
- //----- result color
- if (alphaI == 0) {
- cResult0 = 0;
- cResult1 = 0;
- cResult2 = 0;
+ //----- special case for aSrc = 255
+ if (aSrc == 255) {
+ aResult = 255;
+ cResult0 = cSrc0;
+ cResult1 = cSrc1;
+ cResult2 = cSrc2;
} else {
- cResult0 = state->rgbTransferR[(Guchar)(((alphaI - aSrc) * cDest0 +
- aSrc * cSrcPtr[0]) / alphaI)];
- cResult1 = state->rgbTransferG[(Guchar)(((alphaI - aSrc) * cDest1 +
- aSrc * cSrcPtr[1]) / alphaI)];
- cResult2 = state->rgbTransferB[(Guchar)(((alphaI - aSrc) * cDest2 +
- aSrc * cSrcPtr[2]) / alphaI)];
+
+ //----- read destination alpha
+ aDest = *destAlphaPtr;
+
+ //----- special case for aDest = 0
+ if (aDest == 0) {
+ aResult = aSrc;
+ cResult0 = cSrc0;
+ cResult1 = cSrc1;
+ cResult2 = cSrc2;
+ } else {
+
+ //----- read destination pixel
+ cDest0 = destColorPtr[2];
+ cDest1 = destColorPtr[1];
+ cDest2 = destColorPtr[0];
+
+ //----- result alpha and non-isolated group element correction
+ aResult = aSrc + aDest - div255(aSrc * aDest);
+ alphaI = aResult;
+
+ //----- result color
+ 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
@@ -1394,22 +1437,22 @@ void Splash::pipeRunShapeCMYK8(SplashPipe *pipe, int x0, int x1, int y,
//----- overprint
if (state->overprintMask & 1) {
- cSrc0 = cSrcPtr[0];
+ cSrc0 = state->cmykTransferC[cSrcPtr[0]];
} else {
cSrc0 = div255(aDest * cDest0);
}
if (state->overprintMask & 2) {
- cSrc1 = cSrcPtr[1];
+ cSrc1 = state->cmykTransferM[cSrcPtr[1]];
} else {
cSrc1 = div255(aDest * cDest1);
}
if (state->overprintMask & 4) {
- cSrc2 = cSrcPtr[2];
+ cSrc2 = state->cmykTransferY[cSrcPtr[2]];
} else {
cSrc2 = div255(aDest * cDest2);
}
if (state->overprintMask & 8) {
- cSrc3 = cSrcPtr[3];
+ cSrc3 = state->cmykTransferK[cSrcPtr[3]];
} else {
cSrc3 = div255(aDest * cDest3);
}
@@ -1417,25 +1460,34 @@ void Splash::pipeRunShapeCMYK8(SplashPipe *pipe, int x0, int x1, int y,
//----- source alpha
aSrc = shape;
- //----- result alpha and non-isolated group element correction
- aResult = aSrc + aDest - div255(aSrc * aDest);
- alphaI = aResult;
-
- //----- result color
- if (alphaI == 0) {
- cResult0 = 0;
- cResult1 = 0;
- cResult2 = 0;
- cResult3 = 0;
+ //----- special case for aSrc = 255
+ if (aSrc == 255) {
+ aResult = 255;
+ cResult0 = cSrc0;
+ cResult1 = cSrc1;
+ cResult2 = cSrc2;
+ cResult3 = cSrc3;
} else {
- cResult0 = state->cmykTransferC[(Guchar)(((alphaI - aSrc) * cDest0 +
- aSrc * cSrc0) / alphaI)];
- cResult1 = state->cmykTransferM[(Guchar)(((alphaI - aSrc) * cDest1 +
- aSrc * cSrc1) / alphaI)];
- cResult2 = state->cmykTransferY[(Guchar)(((alphaI - aSrc) * cDest2 +
- aSrc * cSrc2) / alphaI)];
- cResult3 = state->cmykTransferK[(Guchar)(((alphaI - aSrc) * cDest3 +
- aSrc * cSrc3) / alphaI)];
+
+ //----- special case for aDest = 0
+ if (aDest == 0) {
+ aResult = aSrc;
+ cResult0 = cSrc0;
+ cResult1 = cSrc1;
+ cResult2 = cSrc2;
+ cResult3 = cSrc3;
+ } else {
+
+ //----- result alpha and non-isolated group element correction
+ aResult = aSrc + aDest - div255(aSrc * aDest);
+ alphaI = aResult;
+
+ //----- result color
+ 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
@@ -1462,9 +1514,10 @@ void Splash::pipeRunShapeCMYK8(SplashPipe *pipe, int x0, int x1, int y,
// bitmap->mode == splashModeMono1 && !bitmap->alpha
void Splash::pipeRunAAMono1(SplashPipe *pipe, int x0, int x1, int y,
Guchar *shapePtr, SplashColorPtr cSrcPtr) {
- Guchar shape, aSrc, cDest0, cResult0;
+ Guchar shape, aSrc, cSrc0, cDest0, cResult0;
SplashColorPtr destColorPtr;
Guchar destColorMask;
+ SplashScreenCursor screenCursor;
int cSrcStride, x, lastX;
if (cSrcPtr) {
@@ -1490,6 +1543,8 @@ void Splash::pipeRunAAMono1(SplashPipe *pipe, int x0, int x1, int y,
destColorPtr = &bitmap->data[y * bitmap->rowSize + (x0 >> 3)];
destColorMask = 0x80 >> (x0 & 7);
+ screenCursor = state->screen->getTestCursor(y);
+
for (x = x0; x <= x1; ++x) {
//----- shape
@@ -1506,16 +1561,18 @@ void Splash::pipeRunAAMono1(SplashPipe *pipe, int x0, int x1, int y,
//----- read destination pixel
cDest0 = (*destColorPtr & destColorMask) ? 0xff : 0x00;
+ //----- source color
+ cSrc0 = state->grayTransfer[cSrcPtr[0]];
+
//----- source alpha
aSrc = div255(pipe->aInput * shape);
//----- result color
// note: aDest = alphaI = aResult = 0xff
- cResult0 = state->grayTransfer[(Guchar)div255((0xff - aSrc) * cDest0 +
- aSrc * cSrcPtr[0])];
+ cResult0 = (Guchar)div255((0xff - aSrc) * cDest0 + aSrc * cSrc0);
//----- write destination pixel
- if (state->screen->test(x, y, cResult0)) {
+ if (state->screen->testWithCursor(screenCursor, x, cResult0)) {
*destColorPtr |= destColorMask;
} else {
*destColorPtr &= ~destColorMask;
@@ -1537,7 +1594,7 @@ void Splash::pipeRunAAMono1(SplashPipe *pipe, int x0, int x1, int y,
// bitmap->mode == splashModeMono8 && bitmap->alpha
void Splash::pipeRunAAMono8(SplashPipe *pipe, int x0, int x1, int y,
Guchar *shapePtr, SplashColorPtr cSrcPtr) {
- Guchar shape, aSrc, aDest, alphaI, aResult, cDest0, cResult0;
+ Guchar shape, aSrc, aDest, alphaI, aResult, cSrc0, cDest0, cResult0;
SplashColorPtr destColorPtr;
Guchar *destAlphaPtr;
int cSrcStride, x, lastX;
@@ -1582,6 +1639,9 @@ void Splash::pipeRunAAMono8(SplashPipe *pipe, int x0, int x1, int y,
cDest0 = *destColorPtr;
aDest = *destAlphaPtr;
+ //----- source color
+ cSrc0 = state->grayTransfer[cSrcPtr[0]];
+
//----- source alpha
aSrc = div255(pipe->aInput * shape);
@@ -1593,8 +1653,7 @@ void Splash::pipeRunAAMono8(SplashPipe *pipe, int x0, int x1, int y,
if (alphaI == 0) {
cResult0 = 0;
} else {
- cResult0 = state->grayTransfer[(Guchar)(((alphaI - aSrc) * cDest0 +
- aSrc * cSrcPtr[0]) / alphaI)];
+ cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI);
}
//----- write destination pixel
@@ -1616,6 +1675,7 @@ void Splash::pipeRunAAMono8(SplashPipe *pipe, int x0, int x1, int y,
void Splash::pipeRunAARGB8(SplashPipe *pipe, int x0, int x1, int y,
Guchar *shapePtr, SplashColorPtr cSrcPtr) {
Guchar shape, aSrc, aDest, alphaI, aResult;
+ Guchar cSrc0, cSrc1, cSrc2;
Guchar cDest0, cDest1, cDest2;
Guchar cResult0, cResult1, cResult2;
SplashColorPtr destColorPtr;
@@ -1664,6 +1724,11 @@ void Splash::pipeRunAARGB8(SplashPipe *pipe, int x0, int x1, int y,
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);
@@ -1677,12 +1742,9 @@ void Splash::pipeRunAARGB8(SplashPipe *pipe, int x0, int x1, int y,
cResult1 = 0;
cResult2 = 0;
} else {
- cResult0 = state->rgbTransferR[(Guchar)(((alphaI - aSrc) * cDest0 +
- aSrc * cSrcPtr[0]) / alphaI)];
- cResult1 = state->rgbTransferG[(Guchar)(((alphaI - aSrc) * cDest1 +
- aSrc * cSrcPtr[1]) / alphaI)];
- cResult2 = state->rgbTransferB[(Guchar)(((alphaI - aSrc) * cDest2 +
- aSrc * cSrcPtr[2]) / alphaI)];
+ 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
@@ -1707,6 +1769,7 @@ void Splash::pipeRunAARGB8(SplashPipe *pipe, int x0, int x1, int y,
void Splash::pipeRunAABGR8(SplashPipe *pipe, int x0, int x1, int y,
Guchar *shapePtr, SplashColorPtr cSrcPtr) {
Guchar shape, aSrc, aDest, alphaI, aResult;
+ Guchar cSrc0, cSrc1, cSrc2;
Guchar cDest0, cDest1, cDest2;
Guchar cResult0, cResult1, cResult2;
SplashColorPtr destColorPtr;
@@ -1755,6 +1818,11 @@ void Splash::pipeRunAABGR8(SplashPipe *pipe, int x0, int x1, int y,
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);
@@ -1768,12 +1836,9 @@ void Splash::pipeRunAABGR8(SplashPipe *pipe, int x0, int x1, int y,
cResult1 = 0;
cResult2 = 0;
} else {
- cResult0 = state->rgbTransferR[(Guchar)(((alphaI - aSrc) * cDest0 +
- aSrc * cSrcPtr[0]) / alphaI)];
- cResult1 = state->rgbTransferG[(Guchar)(((alphaI - aSrc) * cDest1 +
- aSrc * cSrcPtr[1]) / alphaI)];
- cResult2 = state->rgbTransferB[(Guchar)(((alphaI - aSrc) * cDest2 +
- aSrc * cSrcPtr[2]) / alphaI)];
+ 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
@@ -1851,22 +1916,22 @@ void Splash::pipeRunAACMYK8(SplashPipe *pipe, int x0, int x1, int y,
//----- overprint
if (state->overprintMask & 1) {
- cSrc0 = cSrcPtr[0];
+ cSrc0 = state->cmykTransferC[cSrcPtr[0]];
} else {
cSrc0 = div255(aDest * cDest0);
}
if (state->overprintMask & 2) {
- cSrc1 = cSrcPtr[1];
+ cSrc1 = state->cmykTransferM[cSrcPtr[1]];
} else {
cSrc1 = div255(aDest * cDest1);
}
if (state->overprintMask & 4) {
- cSrc2 = cSrcPtr[2];
+ cSrc2 = state->cmykTransferY[cSrcPtr[2]];
} else {
cSrc2 = div255(aDest * cDest2);
}
if (state->overprintMask & 8) {
- cSrc3 = cSrcPtr[3];
+ cSrc3 = state->cmykTransferK[cSrcPtr[3]];
} else {
cSrc3 = div255(aDest * cDest3);
}
@@ -1885,14 +1950,10 @@ void Splash::pipeRunAACMYK8(SplashPipe *pipe, int x0, int x1, int y,
cResult2 = 0;
cResult3 = 0;
} else {
- cResult0 = state->cmykTransferC[(Guchar)(((alphaI - aSrc) * cDest0 +
- aSrc * cSrc0) / alphaI)];
- cResult1 = state->cmykTransferM[(Guchar)(((alphaI - aSrc) * cDest1 +
- aSrc * cSrc1) / alphaI)];
- cResult2 = state->cmykTransferY[(Guchar)(((alphaI - aSrc) * cDest2 +
- aSrc * cSrc2) / alphaI)];
- cResult3 = state->cmykTransferK[(Guchar)(((alphaI - aSrc) * cDest3 +
- aSrc * cSrc3) / alphaI)];
+ 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
@@ -1931,8 +1992,6 @@ inline void Splash::transform(SplashCoord *matrix,
Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
SplashScreenParams *screenParams) {
- int i;
-
bitmap = bitmapA;
bitmapComps = splashColorModeNComps[bitmap->mode];
vectorAntialias = vectorAntialiasA;
@@ -1940,13 +1999,12 @@ Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
state = new SplashState(bitmap->width, bitmap->height, vectorAntialias,
screenParams);
scanBuf = (Guchar *)gmalloc(bitmap->width);
- if (vectorAntialias) {
- for (i = 0; i <= 255; ++i) {
- aaGamma[i] = (Guchar)splashRound(
- splashPow((SplashCoord)i / (SplashCoord)255,
- splashAAGamma) * 255);
- }
+ if (bitmap->mode == splashModeMono1) {
+ scanBuf2 = (Guchar *)gmalloc(bitmap->width);
+ } else {
+ scanBuf2 = NULL;
}
+ groupBackBitmap = NULL;
minLineWidth = 0;
clearModRegion();
debugMode = gFalse;
@@ -1954,8 +2012,6 @@ Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
SplashScreen *screenA) {
- int i;
-
bitmap = bitmapA;
bitmapComps = splashColorModeNComps[bitmap->mode];
vectorAntialias = vectorAntialiasA;
@@ -1963,13 +2019,12 @@ Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
state = new SplashState(bitmap->width, bitmap->height, vectorAntialias,
screenA);
scanBuf = (Guchar *)gmalloc(bitmap->width);
- if (vectorAntialias) {
- for (i = 0; i <= 255; ++i) {
- aaGamma[i] = (Guchar)splashRound(
- splashPow((SplashCoord)i / (SplashCoord)255,
- splashAAGamma) * 255);
- }
+ if (bitmap->mode == splashModeMono1) {
+ scanBuf2 = (Guchar *)gmalloc(bitmap->width);
+ } else {
+ scanBuf2 = NULL;
}
+ groupBackBitmap = NULL;
minLineWidth = 0;
clearModRegion();
debugMode = gFalse;
@@ -1981,6 +2036,7 @@ Splash::~Splash() {
}
delete state;
gfree(scanBuf);
+ gfree(scanBuf2);
}
//------------------------------------------------------------------------
@@ -2047,7 +2103,7 @@ SplashCoord Splash::getLineDashPhase() {
return state->lineDashPhase;
}
-GBool Splash::getStrokeAdjust() {
+SplashStrokeAdjustMode Splash::getStrokeAdjust() {
return state->strokeAdjust;
}
@@ -2128,7 +2184,7 @@ void Splash::setLineDash(SplashCoord *lineDash, int lineDashLength,
state->setLineDash(lineDash, lineDashLength, lineDashPhase);
}
-void Splash::setStrokeAdjust(GBool strokeAdjust) {
+void Splash::setStrokeAdjust(SplashStrokeAdjustMode strokeAdjust) {
state->strokeAdjust = strokeAdjust;
}
@@ -2169,6 +2225,10 @@ void Splash::setOverprintMask(Guint overprintMask) {
state->overprintMask = overprintMask;
}
+void Splash::setEnablePathSimplification(GBool en) {
+ state->enablePathSimplification = en;
+}
+
//------------------------------------------------------------------------
// state save/restore
//------------------------------------------------------------------------
@@ -2300,7 +2360,8 @@ void Splash::clear(SplashColorPtr color, Guchar alpha) {
SplashError Splash::stroke(SplashPath *path) {
SplashPath *path2, *dPath;
- SplashCoord t0, t1, t2, t3, w, w2;
+ SplashCoord t0, t1, t2, t3, w, w2, lineDashMax, lineDashTotal;
+ int lineCap, lineJoin, i;
if (debugMode) {
printf("stroke [dash:%d] [width:%.2f]:\n",
@@ -2312,15 +2373,6 @@ SplashError Splash::stroke(SplashPath *path) {
return splashErrEmptyPath;
}
path2 = flattenPath(path, state->matrix, state->flatness);
- if (state->lineDashLength > 0) {
- dPath = makeDashedPath(path2);
- delete path2;
- path2 = dPath;
- if (path2->length == 0) {
- delete path2;
- return splashErrEmptyPath;
- }
- }
// Compute an approximation of the transformed line width.
// Given a CTM of [m0 m1],
@@ -2341,10 +2393,62 @@ SplashError Splash::stroke(SplashPath *path) {
w = (t1 < t2) ? t1 : t2;
}
w2 = w * state->lineWidth;
+
+ // construct the dashed path
+ if (state->lineDashLength > 0) {
+
+ // check the maximum transformed dash element length (using the
+ // same approximation as for line width) -- if it's less than 0.1
+ // pixel, don't apply the dash pattern; this avoids a huge
+ // performance/memory hit with PDF files that use absurd dash
+ // patterns like [0.0007 0.0003]
+ lineDashTotal = 0;
+ lineDashMax = 0;
+ for (i = 0; i < state->lineDashLength; ++i) {
+ lineDashTotal += state->lineDash[i];
+ if (state->lineDash[i] > lineDashMax) {
+ lineDashMax = state->lineDash[i];
+ }
+ }
+ // Acrobat simply draws nothing if the dash array is [0]
+ if (lineDashTotal == 0) {
+ delete path2;
+ return splashOk;
+ }
+ if (w * lineDashMax > 0.1) {
+
+ dPath = makeDashedPath(path2);
+ delete path2;
+ path2 = dPath;
+ if (path2->length == 0) {
+ delete path2;
+ return splashErrEmptyPath;
+ }
+ }
+ }
+
+ // round caps on narrow lines look bad, and can't be
+ // stroke-adjusted, so use projecting caps instead (but we can't do
+ // this if there are zero-length dashes or segments, because those
+ // turn into round dots)
+ lineCap = state->lineCap;
+ lineJoin = state->lineJoin;
+ if (state->strokeAdjust == splashStrokeAdjustCAD &&
+ w2 < 3.5) {
+ if (lineCap == splashLineCapRound &&
+ !state->lineDashContainsZeroLengthDashes() &&
+ !path->containsZeroLengthSubpaths()) {
+ lineCap = splashLineCapProjecting;
+ }
+ if (lineJoin == splashLineJoinRound) {
+ lineJoin = splashLineJoinBevel;
+ }
+ }
+
// if there is a min line width set, and the transformed line width
// is smaller, use the min line width
if (w > 0 && w2 < minLineWidth) {
- strokeWide(path2, minLineWidth / w);
+ strokeWide(path2, minLineWidth / w, splashLineCapButt, splashLineJoinBevel);
} else if (bitmap->mode == splashModeMono1) {
// in monochrome mode, use 0-width lines for any transformed line
// width <= 1 -- lines less than 1 pixel wide look too fat without
@@ -2352,7 +2456,7 @@ SplashError Splash::stroke(SplashPath *path) {
if (w2 < 1.001) {
strokeNarrow(path2);
} else {
- strokeWide(path2, state->lineWidth);
+ strokeWide(path2, state->lineWidth, lineCap, lineJoin);
}
} else {
// in gray and color modes, only use 0-width lines if the line
@@ -2360,7 +2464,7 @@ SplashError Splash::stroke(SplashPath *path) {
if (state->lineWidth == 0) {
strokeNarrow(path2);
} else {
- strokeWide(path2, state->lineWidth);
+ strokeWide(path2, state->lineWidth, lineCap, lineJoin);
}
}
@@ -2380,7 +2484,9 @@ void Splash::strokeNarrow(SplashPath *path) {
nClipRes[0] = nClipRes[1] = nClipRes[2] = 0;
- xPath = new SplashXPath(path, state->matrix, state->flatness, gFalse);
+ xPath = new SplashXPath(path, state->matrix, state->flatness, gFalse,
+ state->enablePathSimplification,
+ state->strokeAdjust);
pipeInit(&pipe, state->strokePattern,
(Guchar)splashRound(state->strokeAlpha * 255),
@@ -2497,10 +2603,11 @@ void Splash::drawStrokeSpan(SplashPipe *pipe, int x0, int x1, int y,
(this->*pipe->run)(pipe, x0, x1, y, scanBuf + x0, NULL);
}
-void Splash::strokeWide(SplashPath *path, SplashCoord w) {
+void Splash::strokeWide(SplashPath *path, SplashCoord w,
+ int lineCap, int lineJoin) {
SplashPath *path2;
- path2 = makeStrokePath(path, w, gFalse);
+ path2 = makeStrokePath(path, w, lineCap, lineJoin, gFalse);
fillWithPattern(path2, gFalse, state->strokePattern, state->strokeAlpha);
delete path2;
}
@@ -2636,8 +2743,8 @@ SplashPath *Splash::makeDashedPath(SplashPath *path) {
SplashCoord lineDashTotal;
SplashCoord lineDashStartPhase, lineDashDist, segLen;
SplashCoord x0, y0, x1, y1, xa, ya;
- GBool lineDashStartOn, lineDashOn, newPath;
- int lineDashStartIdx, lineDashIdx;
+ GBool lineDashStartOn, lineDashEndOn, lineDashOn, newPath;
+ int lineDashStartIdx, lineDashIdx, subpathStart, nDashes;
int i, j, k;
lineDashTotal = 0;
@@ -2649,6 +2756,13 @@ SplashPath *Splash::makeDashedPath(SplashPath *path) {
return new SplashPath();
}
lineDashStartPhase = state->lineDashPhase;
+ if (lineDashStartPhase > lineDashTotal * 2) {
+ i = splashFloor(lineDashStartPhase / (lineDashTotal * 2));
+ lineDashStartPhase -= lineDashTotal * i * 2;
+ } else if (lineDashStartPhase < 0) {
+ i = splashCeil(-lineDashStartPhase / (lineDashTotal * 2));
+ lineDashStartPhase += lineDashTotal * i * 2;
+ }
i = splashFloor(lineDashStartPhase / lineDashTotal);
lineDashStartPhase -= (SplashCoord)i * lineDashTotal;
lineDashStartOn = gTrue;
@@ -2657,7 +2771,9 @@ SplashPath *Splash::makeDashedPath(SplashPath *path) {
while (lineDashStartPhase >= state->lineDash[lineDashStartIdx]) {
lineDashStartOn = !lineDashStartOn;
lineDashStartPhase -= state->lineDash[lineDashStartIdx];
- ++lineDashStartIdx;
+ if (++lineDashStartIdx == state->lineDashLength) {
+ lineDashStartIdx = 0;
+ }
}
}
@@ -2674,8 +2790,11 @@ SplashPath *Splash::makeDashedPath(SplashPath *path) {
// initialize the dash parameters
lineDashOn = lineDashStartOn;
+ lineDashEndOn = lineDashStartOn;
lineDashIdx = lineDashStartIdx;
lineDashDist = state->lineDash[lineDashIdx] - lineDashStartPhase;
+ subpathStart = dPath->length;
+ nDashes = 0;
// process each segment of the subpath
newPath = gTrue;
@@ -2691,11 +2810,31 @@ SplashPath *Splash::makeDashedPath(SplashPath *path) {
// process the segment
while (segLen > 0) {
- if (lineDashDist >= segLen) {
+ // Special case for zero-length dash segments: draw a very
+ // short -- but not zero-length -- segment. This ensures that
+ // we get the correct behavior with butt and projecting line
+ // caps. The PS/PDF specs imply that zero-length segments are
+ // not drawn unless the line cap is round, but Acrobat and
+ // Ghostscript both draw very short segments (for butt caps)
+ // and squares (for projecting caps).
+ if (lineDashDist == 0) {
if (lineDashOn) {
if (newPath) {
dPath->moveTo(x0, y0);
newPath = gFalse;
+ ++nDashes;
+ }
+ xa = x0 + ((SplashCoord)0.001 / segLen) * (x1 - x0);
+ ya = y0 + ((SplashCoord)0.001 / segLen) * (y1 - y0);
+ dPath->lineTo(xa, ya);
+ }
+
+ } else if (lineDashDist >= segLen) {
+ if (lineDashOn) {
+ if (newPath) {
+ dPath->moveTo(x0, y0);
+ newPath = gFalse;
+ ++nDashes;
}
dPath->lineTo(x1, y1);
}
@@ -2709,6 +2848,7 @@ SplashPath *Splash::makeDashedPath(SplashPath *path) {
if (newPath) {
dPath->moveTo(x0, y0);
newPath = gFalse;
+ ++nDashes;
}
dPath->lineTo(xa, ya);
}
@@ -2718,6 +2858,8 @@ SplashPath *Splash::makeDashedPath(SplashPath *path) {
lineDashDist = 0;
}
+ lineDashEndOn = lineDashOn;
+
// get the next entry in the dash array
if (lineDashDist <= 0) {
lineDashOn = !lineDashOn;
@@ -2729,6 +2871,31 @@ SplashPath *Splash::makeDashedPath(SplashPath *path) {
}
}
}
+
+ // in a closed subpath, where the dash pattern is "on" at both the
+ // start and end of the subpath, we need to merge the start and
+ // end to get a proper line join
+ if ((path->flags[j] & splashPathClosed) &&
+ lineDashStartOn &&
+ lineDashEndOn) {
+ if (nDashes == 1) {
+ dPath->close();
+ } else if (nDashes > 1) {
+ k = subpathStart;
+ do {
+ ++k;
+ dPath->lineTo(dPath->pts[k].x, dPath->pts[k].y);
+ } while (!(dPath->flags[k] & splashPathLast));
+ ++k;
+ memmove(&dPath->pts[subpathStart], &dPath->pts[k],
+ (dPath->length - k) * sizeof(SplashPathPoint));
+ memmove(&dPath->flags[subpathStart], &dPath->flags[k],
+ (dPath->length - k) * sizeof(Guchar));
+ dPath->length -= k - subpathStart;
+ dPath->curSubpath -= k - subpathStart;
+ }
+ }
+
i = j + 1;
}
@@ -2750,7 +2917,7 @@ SplashError Splash::fillWithPattern(SplashPath *path, GBool eo,
SplashPath *path2;
SplashXPath *xPath;
SplashXPathScanner *scanner;
- int xMin, yMin, xMax, yMax, x, y, t;
+ int xMin, yMin, xMax, xMin2, xMax2, yMax, y, t;
SplashClipResult clipRes;
if (path->length == 0) {
@@ -2763,7 +2930,9 @@ SplashError Splash::fillWithPattern(SplashPath *path, GBool eo,
path2 = tweakFillPath(path);
- xPath = new SplashXPath(path2, state->matrix, state->flatness, gTrue);
+ xPath = new SplashXPath(path2, state->matrix, state->flatness, gTrue,
+ state->enablePathSimplification,
+ state->strokeAdjust);
if (path2 != path) {
delete path2;
}
@@ -2806,23 +2975,25 @@ SplashError Splash::fillWithPattern(SplashPath *path, GBool eo,
// draw the spans
if (vectorAntialias && !inShading) {
for (y = yMin; y <= yMax; ++y) {
- scanner->getSpan(scanBuf, y, xMin, xMax);
- if (clipRes != splashClipAllInside) {
- state->clip->clipSpan(scanBuf, y, xMin, xMax, state->strokeAdjust);
- }
- for (x = xMin; x <= xMax; ++x) {
- scanBuf[x] = aaGamma[scanBuf[x]];
+ scanner->getSpan(scanBuf, y, xMin, xMax, &xMin2, &xMax2);
+ if (xMin2 <= xMax2) {
+ if (clipRes != splashClipAllInside) {
+ state->clip->clipSpan(scanBuf, y, xMin2, xMax2,
+ state->strokeAdjust);
+ }
+ (this->*pipe.run)(&pipe, xMin2, xMax2, y, scanBuf + xMin2, NULL);
}
- (this->*pipe.run)(&pipe, xMin, xMax, y, scanBuf + xMin, NULL);
}
} else {
for (y = yMin; y <= yMax; ++y) {
- scanner->getSpanBinary(scanBuf, y, xMin, xMax);
- if (clipRes != splashClipAllInside) {
- state->clip->clipSpanBinary(scanBuf, y, xMin, xMax,
- state->strokeAdjust);
+ scanner->getSpanBinary(scanBuf, y, xMin, xMax, &xMin2, &xMax2);
+ if (xMin2 <= xMax2) {
+ if (clipRes != splashClipAllInside) {
+ state->clip->clipSpanBinary(scanBuf, y, xMin2, xMax2,
+ state->strokeAdjust);
+ }
+ (this->*pipe.run)(&pipe, xMin2, xMax2, y, scanBuf + xMin2, NULL);
}
- (this->*pipe.run)(&pipe, xMin, xMax, y, scanBuf + xMin, NULL);
}
}
}
@@ -2849,7 +3020,7 @@ SplashPath *Splash::tweakFillPath(SplashPath *path) {
SplashCoord xx0, yy0, xx1, yy1, dx, dy, d, wx, wy, w;
int n;
- if (!state->strokeAdjust || path->hints) {
+ if (state->strokeAdjust == splashStrokeAdjustOff || path->hints) {
return path;
}
@@ -2887,7 +3058,7 @@ SplashPath *Splash::tweakFillPath(SplashPath *path) {
splashAbs(path->pts[1].y - path->pts[2].y) < 0.001)))) {
wx = state->matrix[0] + state->matrix[2];
wy = state->matrix[1] + state->matrix[3];
- w = sqrt(wx*wx + wy*wy);
+ w = splashSqrt(wx*wx + wy*wy);
if (w < 0.001) {
w = 0;
} else {
@@ -2905,7 +3076,7 @@ SplashPath *Splash::tweakFillPath(SplashPath *path) {
}
dx = xx1 - xx0;
dy = yy1 - yy0;
- d = sqrt(dx * dx + dy * dy);
+ d = splashSqrt(dx * dx + dy * dy);
if (d < 0.001) {
d = 0;
} else {
@@ -2995,6 +3166,10 @@ GBool Splash::pathAllOutside(SplashPath *path) {
} else if (y > yMax2) {
yMax2 = y;
}
+ // sanity-check the coordinates - xMinI/yMinI/xMaxI/yMaxI are
+ // 32-bit integers, so coords need to be < 2^31
+ SplashXPath::clampCoords(&xMin2, &yMin2);
+ SplashXPath::clampCoords(&xMax2, &yMax2);
xMinI = splashFloor(xMin2);
yMinI = splashFloor(yMin2);
xMaxI = splashFloor(xMax2);
@@ -3005,77 +3180,6 @@ GBool Splash::pathAllOutside(SplashPath *path) {
splashClipAllOutside;
}
-SplashError Splash::xorFill(SplashPath *path, GBool eo) {
- SplashPipe pipe;
- SplashXPath *xPath;
- SplashXPathScanner *scanner;
- int xMin, yMin, xMax, yMax, y, t;
- SplashClipResult clipRes;
- SplashBlendFunc origBlendFunc;
-
- if (path->length == 0) {
- return splashErrEmptyPath;
- }
- if (pathAllOutside(path)) {
- opClipRes = splashClipAllOutside;
- return splashOk;
- }
- xPath = new SplashXPath(path, state->matrix, state->flatness, gTrue);
- xMin = xPath->getXMin();
- yMin = xPath->getYMin();
- xMax = xPath->getXMax();
- yMax = xPath->getYMax();
- if (xMin > xMax || yMin > yMax) {
- delete xPath;
- return splashOk;
- }
- scanner = new SplashXPathScanner(xPath, eo, yMin, yMax);
-
- // check clipping
- if ((clipRes = state->clip->testRect(xMin, yMin, xMax, yMax,
- state->strokeAdjust))
- != splashClipAllOutside) {
-
- if ((t = state->clip->getXMinI(state->strokeAdjust)) > xMin) {
- xMin = t;
- }
- if ((t = state->clip->getXMaxI(state->strokeAdjust)) < xMax) {
- xMax = t;
- }
- if ((t = state->clip->getYMinI(state->strokeAdjust)) > yMin) {
- yMin = t;
- }
- if ((t = state->clip->getYMaxI(state->strokeAdjust)) < yMax) {
- yMax = t;
- }
- if (xMin > xMax || yMin > yMax) {
- delete scanner;
- delete xPath;
- return splashOk;
- }
-
- origBlendFunc = state->blendFunc;
- state->blendFunc = &blendXor;
- pipeInit(&pipe, state->fillPattern, 255, gTrue, gFalse);
-
- // draw the spans
- for (y = yMin; y <= yMax; ++y) {
- scanner->getSpanBinary(scanBuf, y, xMin, xMax);
- if (clipRes != splashClipAllInside) {
- state->clip->clipSpanBinary(scanBuf, y, xMin, xMax,
- state->strokeAdjust);
- }
- (this->*pipe.run)(&pipe, xMin, xMax, y, scanBuf + xMin, NULL);
- }
- state->blendFunc = origBlendFunc;
- }
- opClipRes = clipRes;
-
- delete scanner;
- delete xPath;
- return splashOk;
-}
-
SplashError Splash::fillChar(SplashCoord x, SplashCoord y,
int c, SplashFont *font) {
SplashGlyphBitmap glyph;
@@ -3208,14 +3312,14 @@ SplashError Splash::fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph) {
void Splash::getImageBounds(SplashCoord xyMin, SplashCoord xyMax,
int *xyMinI, int *xyMaxI) {
- if (state->strokeAdjust) {
- splashStrokeAdjust(xyMin, xyMax, xyMinI, xyMaxI);
- } else {
+ if (state->strokeAdjust == splashStrokeAdjustOff) {
*xyMinI = splashFloor(xyMin);
*xyMaxI = splashFloor(xyMax);
if (*xyMaxI <= *xyMinI) {
*xyMaxI = *xyMinI + 1;
}
+ } else {
+ splashStrokeAdjust(xyMin, xyMax, xyMinI, xyMaxI, state->strokeAdjust);
}
}
@@ -3254,8 +3358,14 @@ SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
// stream-mode upscaling -- this is slower, so we only use it if the
// upscaled mask is large (in which case clipping should remove many
// pixels)
- if (wSize > 2 * w && hSize > 2 * h && wSize * hSize > 1000000) {
+#if USE_FIXEDPOINT
+ if ((wSize > 2 * w && hSize > 2 * h && (int)wSize > 1000000 / (int)hSize) ||
+ (wSize > w && hSize > h && (int)wSize > 10000000 / (int)hSize)) {
+#else
+ if ((wSize > 2 * w && hSize > 2 * h && wSize * hSize > 1000000) ||
+ (wSize > w && hSize > h && wSize * hSize > 10000000)) {
upscaleMask(src, srcData, w, h, mat, glyphMode, interpolate);
+#endif
// scaling only
} else if (mat[0] > 0 && minorAxisZero && mat[3] > 0) {
@@ -3462,10 +3572,12 @@ void Splash::upscaleMask(SplashImageMaskSource src, void *srcData,
if (y1 >= srcHeight) {
y1 = srcHeight - 1;
}
- pix0 = ((SplashCoord)1 - sx) * unscaledImage[y0 * srcWidth + x0]
- + sx * unscaledImage[y0 * srcWidth + x1];
- pix1 = ((SplashCoord)1 - sx) * unscaledImage[y1 * srcWidth + x0]
- + sx * unscaledImage[y1 * srcWidth + x1];
+ pix0 = ((SplashCoord)1 - sx)
+ * (SplashCoord)unscaledImage[y0 * srcWidth + x0]
+ + sx * (SplashCoord)unscaledImage[y0 * srcWidth + x1];
+ pix1 = ((SplashCoord)1 - sx)
+ * (SplashCoord)unscaledImage[y1 * srcWidth + x0]
+ + sx * (SplashCoord)unscaledImage[y1 * srcWidth + x1];
scanBuf[x] = (Guchar)splashRound(((SplashCoord)1 - sy) * pix0
+ sy * pix1);
} else {
@@ -4041,10 +4153,10 @@ void Splash::scaleMaskYuXu(SplashImageMaskSource src, void *srcData,
int scaledWidth, int scaledHeight,
SplashBitmap *dest) {
Guchar *lineBuf;
- Guint pix;
- Guchar *destPtr0, *destPtr;
- int yp, yq, xp, xq, yt, y, yStep, xt, x, xStep, xx;
- int i, j;
+ Guchar pix;
+ Guchar *srcPtr, *destPtr;
+ int yp, yq, xp, xq, yt, y, yStep, xt, x, xStep;
+ int i;
// Bresenham parameters for y scale
yp = scaledHeight / srcHeight;
@@ -4060,7 +4172,7 @@ void Splash::scaleMaskYuXu(SplashImageMaskSource src, void *srcData,
// init y scale Bresenham
yt = 0;
- destPtr0 = dest->data;
+ destPtr = dest->data;
for (y = 0; y < srcHeight; ++y) {
// y scale Bresenham
@@ -4077,7 +4189,8 @@ void Splash::scaleMaskYuXu(SplashImageMaskSource src, void *srcData,
// init x scale Bresenham
xt = 0;
- xx = 0;
+ // generate one row
+ srcPtr = lineBuf;
for (x = 0; x < srcWidth; ++x) {
// x scale Bresenham
@@ -4089,20 +4202,20 @@ void Splash::scaleMaskYuXu(SplashImageMaskSource src, void *srcData,
}
// compute the final pixel
- pix = lineBuf[x] ? 255 : 0;
+ pix = *srcPtr ? 255 : 0;
+ ++srcPtr;
- // store the pixel
- for (i = 0; i < yStep; ++i) {
- for (j = 0; j < xStep; ++j) {
- destPtr = destPtr0 + i * scaledWidth + xx + j;
- *destPtr++ = (Guchar)pix;
- }
+ // duplicate the pixel horizontally
+ for (i = 0; i < xStep; ++i) {
+ *destPtr++ = pix;
}
-
- xx += xStep;
}
- destPtr0 += yStep * scaledWidth;
+ // duplicate the row vertically
+ for (i = 1 ; i < yStep; ++i) {
+ memcpy(destPtr, destPtr - scaledWidth, scaledWidth);
+ destPtr += scaledWidth;
+ }
}
gfree(lineBuf);
@@ -4149,11 +4262,11 @@ void Splash::scaleMaskYuXuI(SplashImageMaskSource src, void *srcData,
xSrc1 = srcWidth - 1;
}
lineBuf0[x] = (Guchar)(int)
- ((xs * lineBuf0[xSrc0] +
- ((SplashCoord)1 - xs) * lineBuf0[xSrc1]) * 255);
+ ((xs * (int)lineBuf0[xSrc0] +
+ ((SplashCoord)1 - xs) * (int)lineBuf0[xSrc1]) * 255);
lineBuf1[x] = (Guchar)(int)
- ((xs * lineBuf1[xSrc0] +
- ((SplashCoord)1 - xs) * lineBuf1[xSrc1]) * 255);
+ ((xs * (int)lineBuf1[xSrc0] +
+ ((SplashCoord)1 - xs) * (int)lineBuf1[xSrc1]) * 255);
}
destPtr = dest->data;
@@ -4193,8 +4306,8 @@ void Splash::scaleMaskYuXuI(SplashImageMaskSource src, void *srcData,
xSrc1 = srcWidth - 1;
}
lineBuf1[x] = (Guchar)(int)
- ((xs * lineBuf1[xSrc0] +
- ((SplashCoord)1 - xs) * lineBuf1[xSrc1]) * 255);
+ ((xs * (int)lineBuf1[xSrc0] +
+ ((SplashCoord)1 - xs) * (int)lineBuf1[xSrc1]) * 255);
}
++yBuf;
@@ -4203,8 +4316,8 @@ void Splash::scaleMaskYuXuI(SplashImageMaskSource src, void *srcData,
// do the vertical interpolation
for (x = 0; x < scaledWidth; ++x) {
- pix = (Guchar)(int)(ys * lineBuf0[x] +
- ((SplashCoord)1 - ys) * lineBuf1[x]);
+ pix = (Guchar)(int)(ys * (int)lineBuf0[x] +
+ ((SplashCoord)1 - ys) * (int)lineBuf1[x]);
// store the pixel
*destPtr++ = pix;
@@ -4329,7 +4442,13 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
// stream-mode upscaling -- this is slower, so we only use it if the
// upscaled image is large (in which case clipping should remove
// many pixels)
- if (wSize > 2 * w && hSize > 2 * h && wSize * hSize > 1000000) {
+#if USE_FIXEDPOINT
+ if ((wSize > 2 * w && hSize > 2 * h && (int)wSize > 1000000 / (int)hSize) ||
+ (wSize > w && hSize > h && (int)wSize > 10000000 / (int)hSize)) {
+#else
+ if ((wSize > 2 * w && hSize > 2 * h && wSize * hSize > 1000000) ||
+ (wSize > w && hSize > h && wSize * hSize > 10000000)) {
+#endif
upscaleImage(src, srcData, srcMode, nComps, srcAlpha,
w, h, mat, interpolate);
@@ -4367,7 +4486,7 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
}
// scaling plus horizontal flip
- } else if (mat[0] > 0 && minorAxisZero && mat[3] > 0) {
+ } else if (mat[0] < 0 && minorAxisZero && mat[3] > 0) {
getImageBounds(mat[0] + mat[4], mat[4], &x0, &x1);
getImageBounds(mat[5], mat[3] + mat[5], &y0, &y1);
clipRes = state->clip->testRect(x0, y0, x1 - 1, y1 - 1,
@@ -4384,7 +4503,7 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
}
// scaling plus horizontal and vertical flips
- } else if (mat[0] > 0 && minorAxisZero && mat[3] < 0) {
+ } else if (mat[0] < 0 && minorAxisZero && mat[3] < 0) {
getImageBounds(mat[0] + mat[4], mat[4], &x0, &x1);
getImageBounds(mat[3] + mat[5], mat[5], &y0, &y1);
clipRes = state->clip->testRect(x0, y0, x1 - 1, y1 - 1,
@@ -4557,16 +4676,18 @@ void Splash::upscaleImage(SplashImageSource src, void *srcData,
q10 = &unscaledImage[(y1 * srcWidth + x0) * nComps];
q11 = &unscaledImage[(y1 * srcWidth + x1) * nComps];
for (i = 0; i < nComps; ++i) {
- pix0 = ((SplashCoord)1 - sx) * *q00++ + sx * *q01++;
- pix1 = ((SplashCoord)1 - sx) * *q10++ + sx * *q11++;
+ pix0 = ((SplashCoord)1 - sx) * (int)*q00++ + sx * (int)*q01++;
+ pix1 = ((SplashCoord)1 - sx) * (int)*q10++ + sx * (int)*q11++;
*p++ = (Guchar)splashRound(((SplashCoord)1 - sy) * pix0
+ sy * pix1);
}
if (srcAlpha) {
- pix0 = ((SplashCoord)1 - sx) * unscaledAlpha[y0 * srcWidth + x0]
- + sx * unscaledAlpha[y0 * srcWidth + x1];
- pix1 = ((SplashCoord)1 - sx) * unscaledAlpha[y1 * srcWidth + x0]
- + sx * unscaledAlpha[y1 * srcWidth + x1];
+ pix0 = ((SplashCoord)1 - sx)
+ * (SplashCoord)unscaledAlpha[y0 * srcWidth + x0]
+ + sx * (SplashCoord)unscaledAlpha[y0 * srcWidth + x1];
+ pix1 = ((SplashCoord)1 - sx)
+ * (SplashCoord)unscaledAlpha[y1 * srcWidth + x0]
+ + sx * (SplashCoord)unscaledAlpha[y1 * srcWidth + x1];
scanBuf[x] = (Guchar)splashRound(((SplashCoord)1 - sy) * pix0
+ sy * pix1);
} else {
@@ -5139,6 +5260,12 @@ void Splash::scaleImageYdXu(SplashImageSource src, void *srcData,
alphaPixBuf = NULL;
}
+ // make gcc happy
+ pix[0] = pix[1] = pix[2] = 0;
+#if SPLASH_CMYK
+ pix[3] = 0;
+#endif
+
// init y scale Bresenham
yt = 0;
@@ -5266,6 +5393,12 @@ void Splash::scaleImageYuXd(SplashImageSource src, void *srcData,
alphaLineBuf = NULL;
}
+ // make gcc happy
+ pix[0] = pix[1] = pix[2] = 0;
+#if SPLASH_CMYK
+ pix[3] = 0;
+#endif
+
// init y scale Bresenham
yt = 0;
@@ -5380,11 +5513,15 @@ void Splash::scaleImageYuXu(SplashImageSource src, void *srcData,
int scaledWidth, int scaledHeight,
SplashBitmap *dest) {
Guchar *lineBuf, *alphaLineBuf;
- Guint pix[splashMaxColorComps];
+ Guchar pix0, pix1, pix2;
+#if SPLASH_CMYK
+ Guchar pix3;
+#endif
Guint alpha;
- Guchar *destPtr0, *destPtr, *destAlphaPtr0, *destAlphaPtr;
- int yp, yq, xp, xq, yt, y, yStep, xt, x, xStep, xx;
- int i, j;
+ Guchar *srcPtr, *srcAlphaPtr;
+ Guchar *destPtr, *destAlphaPtr;
+ int yp, yq, xp, xq, yt, y, yStep, xt, x, xStep;
+ int i;
// Bresenham parameters for y scale
yp = scaledHeight / srcHeight;
@@ -5405,8 +5542,8 @@ void Splash::scaleImageYuXu(SplashImageSource src, void *srcData,
// init y scale Bresenham
yt = 0;
- destPtr0 = dest->data;
- destAlphaPtr0 = dest->alpha;
+ destPtr = dest->data;
+ destAlphaPtr = dest->alpha;
for (y = 0; y < srcHeight; ++y) {
// y scale Bresenham
@@ -5423,7 +5560,9 @@ void Splash::scaleImageYuXu(SplashImageSource src, void *srcData,
// init x scale Bresenham
xt = 0;
- xx = 0;
+ // generate one row
+ srcPtr = lineBuf;
+ srcAlphaPtr = alphaLineBuf;
for (x = 0; x < srcWidth; ++x) {
// x scale Bresenham
@@ -5434,41 +5573,35 @@ void Splash::scaleImageYuXu(SplashImageSource src, void *srcData,
xStep = xp;
}
- // compute the final pixel
- for (i = 0; i < nComps; ++i) {
- pix[i] = lineBuf[x * nComps + i];
- }
-
- // store the pixel
+ // duplicate the pixel horizontally
switch (srcMode) {
case splashModeMono8:
- for (i = 0; i < yStep; ++i) {
- for (j = 0; j < xStep; ++j) {
- destPtr = destPtr0 + (i * scaledWidth + xx + j) * nComps;
- *destPtr++ = (Guchar)pix[0];
- }
+ pix0 = *srcPtr++;
+ for (i = 0; i < xStep; ++i) {
+ *destPtr++ = pix0;
}
break;
case splashModeRGB8:
- for (i = 0; i < yStep; ++i) {
- for (j = 0; j < xStep; ++j) {
- destPtr = destPtr0 + (i * scaledWidth + xx + j) * nComps;
- *destPtr++ = (Guchar)pix[0];
- *destPtr++ = (Guchar)pix[1];
- *destPtr++ = (Guchar)pix[2];
- }
+ pix0 = *srcPtr++;
+ pix1 = *srcPtr++;
+ pix2 = *srcPtr++;
+ for (i = 0; i < xStep; ++i) {
+ *destPtr++ = pix0;
+ *destPtr++ = pix1;
+ *destPtr++ = pix2;
}
break;
#if SPLASH_CMYK
case splashModeCMYK8:
- for (i = 0; i < yStep; ++i) {
- for (j = 0; j < xStep; ++j) {
- destPtr = destPtr0 + (i * scaledWidth + xx + j) * nComps;
- *destPtr++ = (Guchar)pix[0];
- *destPtr++ = (Guchar)pix[1];
- *destPtr++ = (Guchar)pix[2];
- *destPtr++ = (Guchar)pix[3];
- }
+ pix0 = *srcPtr++;
+ pix1 = *srcPtr++;
+ pix2 = *srcPtr++;
+ pix3 = *srcPtr++;
+ for (i = 0; i < xStep; ++i) {
+ *destPtr++ = pix0;
+ *destPtr++ = pix1;
+ *destPtr++ = pix2;
+ *destPtr++ = pix3;
}
break;
#endif
@@ -5478,23 +5611,26 @@ void Splash::scaleImageYuXu(SplashImageSource src, void *srcData,
break;
}
- // process alpha
+ // duplicate the alpha value horizontally
if (srcAlpha) {
- alpha = alphaLineBuf[x];
- for (i = 0; i < yStep; ++i) {
- for (j = 0; j < xStep; ++j) {
- destAlphaPtr = destAlphaPtr0 + i * scaledWidth + xx + j;
- *destAlphaPtr = (Guchar)alpha;
- }
+ alpha = *srcAlphaPtr++;
+ for (i = 0; i < xStep; ++i) {
+ *destAlphaPtr++ = alpha;
}
}
-
- xx += xStep;
}
- destPtr0 += yStep * scaledWidth * nComps;
+ // duplicate the row vertically
+ for (i = 1; i < yStep; ++i) {
+ memcpy(destPtr, destPtr - scaledWidth * nComps,
+ scaledWidth * nComps);
+ destPtr += scaledWidth * nComps;
+ }
if (srcAlpha) {
- destAlphaPtr0 += yStep * scaledWidth;
+ for (i = 1; i < yStep; ++i) {
+ memcpy(destAlphaPtr, destAlphaPtr - scaledWidth, scaledWidth);
+ destAlphaPtr += scaledWidth;
+ }
}
}
@@ -5555,22 +5691,28 @@ void Splash::scaleImageYuXuI(SplashImageSource src, void *srcData,
}
for (i = 0; i < nComps; ++i) {
lineBuf0[x*nComps+i] = (Guchar)(int)
- (xs * lineBuf0[xSrc0*nComps+i] +
- ((SplashCoord)1 - xs) * lineBuf0[xSrc1*nComps+i]);
+ (xs * (int)lineBuf0[xSrc0*nComps+i] +
+ ((SplashCoord)1 - xs) * (int)lineBuf0[xSrc1*nComps+i]);
lineBuf1[x*nComps+i] = (Guchar)(int)
- (xs * lineBuf1[xSrc0*nComps+i] +
- ((SplashCoord)1 - xs) * lineBuf1[xSrc1*nComps+i]);
+ (xs * (int)lineBuf1[xSrc0*nComps+i] +
+ ((SplashCoord)1 - xs) * (int)lineBuf1[xSrc1*nComps+i]);
}
if (srcAlpha) {
alphaLineBuf0[x] = (Guchar)(int)
- (xs * alphaLineBuf0[xSrc0] +
- ((SplashCoord)1 - xs) * alphaLineBuf0[xSrc1]);
+ (xs * (int)alphaLineBuf0[xSrc0] +
+ ((SplashCoord)1 - xs) * (int)alphaLineBuf0[xSrc1]);
alphaLineBuf1[x] = (Guchar)(int)
- (xs * alphaLineBuf1[xSrc0] +
- ((SplashCoord)1 - xs) * alphaLineBuf1[xSrc1]);
+ (xs * (int)alphaLineBuf1[xSrc0] +
+ ((SplashCoord)1 - xs) * (int)alphaLineBuf1[xSrc1]);
}
}
+ // make gcc happy
+ pix[0] = pix[1] = pix[2] = 0;
+#if SPLASH_CMYK
+ pix[3] = 0;
+#endif
+
destPtr = dest->data;
destAlphaPtr = dest->alpha;
for (y = 0; y < scaledHeight; ++y) {
@@ -5612,14 +5754,14 @@ void Splash::scaleImageYuXuI(SplashImageSource src, void *srcData,
xSrc1 = srcWidth - 1;
}
for (i = 0; i < nComps; ++i) {
- lineBuf1[x*nComps+i] =
- (Guchar)(int)(xs * lineBuf1[xSrc0*nComps+i] +
- ((SplashCoord)1 - xs) * lineBuf1[xSrc1*nComps+i]);
+ lineBuf1[x*nComps+i] = (Guchar)(int)
+ (xs * (int)lineBuf1[xSrc0*nComps+i] +
+ ((SplashCoord)1 - xs) * (int)lineBuf1[xSrc1*nComps+i]);
}
if (srcAlpha) {
- alphaLineBuf1[x] =
- (Guchar)(int)(xs * alphaLineBuf1[xSrc0] +
- ((SplashCoord)1 - xs) * alphaLineBuf1[xSrc1]);
+ alphaLineBuf1[x] = (Guchar)(int)
+ (xs * (int)alphaLineBuf1[xSrc0] +
+ ((SplashCoord)1 - xs) * (int)alphaLineBuf1[xSrc1]);
}
}
@@ -5630,8 +5772,9 @@ void Splash::scaleImageYuXuI(SplashImageSource src, void *srcData,
for (x = 0; x < scaledWidth; ++x) {
for (i = 0; i < nComps; ++i) {
- pix[i] = (Guchar)(int)(ys * lineBuf0[x*nComps+i] +
- ((SplashCoord)1 - ys) * lineBuf1[x*nComps+i]);
+ pix[i] = (Guchar)(int)
+ (ys * (int)lineBuf0[x*nComps+i] +
+ ((SplashCoord)1 - ys) * (int)lineBuf1[x*nComps+i]);
}
// store the pixel
@@ -5661,8 +5804,8 @@ void Splash::scaleImageYuXuI(SplashImageSource src, void *srcData,
// process alpha
if (srcAlpha) {
*destAlphaPtr++ = (Guchar)(int)
- (ys * alphaLineBuf0[x] +
- ((SplashCoord)1 - ys) * alphaLineBuf1[x]);
+ (ys * (int)alphaLineBuf0[x] +
+ ((SplashCoord)1 - ys) * (int)alphaLineBuf1[x]);
}
}
}
@@ -5878,82 +6021,287 @@ SplashError Splash::composite(SplashBitmap *src, int xSrc, int ySrc,
int xDest, int yDest, int w, int h,
GBool noClip, GBool nonIsolated) {
SplashPipe pipe;
- int x0, x1, y0, y1, y, t;
+ Guchar *mono1Ptr, *lineBuf, *linePtr;
+ Guchar mono1Mask, b;
+ int x0, x1, x, y0, y1, y, t;
- if (src->mode != bitmap->mode) {
+ if (!(src->mode == bitmap->mode ||
+ (src->mode == splashModeMono8 && bitmap->mode == splashModeMono1) ||
+ (src->mode == splashModeRGB8 && bitmap->mode == splashModeBGR8))) {
return splashErrModeMismatch;
}
pipeInit(&pipe, NULL,
(Guchar)splashRound(state->fillAlpha * 255),
!noClip || src->alpha != NULL, nonIsolated);
- if (noClip) {
- if (src->alpha) {
- for (y = 0; y < h; ++y) {
- // this uses shape instead of alpha, which isn't technically
- // correct, but works out the same
- (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y,
- src->getAlphaPtr() +
- (ySrc + y) * src->getWidth() + xSrc,
- src->getDataPtr() + (ySrc + y) * src->getRowSize() +
- xSrc * bitmapComps);
+ if (src->mode == splashModeMono1) {
+ // in mono1 mode, pipeRun expects the source to be in mono8
+ // format, so we need to extract the source color values into
+ // scanBuf, expanding them from mono1 to mono8
+ if (noClip) {
+ if (src->alpha) {
+ for (y = 0; y < h; ++y) {
+ mono1Ptr = src->getDataPtr()
+ + (ySrc + y) * src->rowSize + (xSrc >> 3);
+ mono1Mask = 0x80 >> (xSrc & 7);
+ for (x = 0; x < w; ++x) {
+ scanBuf[x] = (*mono1Ptr & mono1Mask) ? 0xff : 0x00;
+ mono1Ptr += mono1Mask & 1;
+ mono1Mask = (mono1Mask << 7) | (mono1Mask >> 1);
+ }
+ // this uses shape instead of alpha, which isn't technically
+ // correct, but works out the same
+ (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y,
+ src->getAlphaPtr() +
+ (ySrc + y) * src->getWidth() + xSrc,
+ scanBuf);
+ }
+ } else {
+ for (y = 0; y < h; ++y) {
+ mono1Ptr = src->getDataPtr()
+ + (ySrc + y) * src->rowSize + (xSrc >> 3);
+ mono1Mask = 0x80 >> (xSrc & 7);
+ for (x = 0; x < w; ++x) {
+ scanBuf[x] = (*mono1Ptr & mono1Mask) ? 0xff : 0x00;
+ mono1Ptr += mono1Mask & 1;
+ mono1Mask = (mono1Mask << 7) | (mono1Mask >> 1);
+ }
+ (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y,
+ NULL,
+ scanBuf);
+ }
}
} else {
- for (y = 0; y < h; ++y) {
- (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y,
- NULL,
- src->getDataPtr() + (ySrc + y) * src->getRowSize() +
- xSrc * bitmapComps);
+ x0 = xDest;
+ if ((t = state->clip->getXMinI(state->strokeAdjust)) > x0) {
+ x0 = t;
+ }
+ x1 = xDest + w;
+ if ((t = state->clip->getXMaxI(state->strokeAdjust) + 1) < x1) {
+ x1 = t;
+ }
+ y0 = yDest;
+ if ((t = state->clip->getYMinI(state->strokeAdjust)) > y0) {
+ y0 = t;
+ }
+ y1 = yDest + h;
+ if ((t = state->clip->getYMaxI(state->strokeAdjust) + 1) < y1) {
+ y1 = t;
+ }
+ if (x0 < x1 && y0 < y1) {
+ if (src->alpha) {
+ for (y = y0; y < y1; ++y) {
+ mono1Ptr = src->getDataPtr()
+ + (ySrc + y - yDest) * src->rowSize
+ + ((xSrc + x0 - xDest) >> 3);
+ mono1Mask = 0x80 >> ((xSrc + x0 - xDest) & 7);
+ for (x = x0; x < x1; ++x) {
+ scanBuf[x] = (*mono1Ptr & mono1Mask) ? 0xff : 0x00;
+ mono1Ptr += mono1Mask & 1;
+ mono1Mask = (mono1Mask << 7) | (mono1Mask >> 1);
+ }
+ memcpy(scanBuf2 + x0,
+ src->getAlphaPtr() + (ySrc + y - yDest) * src->getWidth() +
+ (xSrc + x0 - xDest),
+ x1 - x0);
+ if (!state->clip->clipSpanBinary(scanBuf2, y, x0, x1 - 1,
+ state->strokeAdjust)) {
+ continue;
+ }
+ // this uses shape instead of alpha, which isn't technically
+ // correct, but works out the same
+ (this->*pipe.run)(&pipe, x0, x1 - 1, y,
+ scanBuf2 + x0,
+ scanBuf + x0);
+ }
+ } else {
+ for (y = y0; y < y1; ++y) {
+ mono1Ptr = src->getDataPtr()
+ + (ySrc + y - yDest) * src->rowSize
+ + ((xSrc + x0 - xDest) >> 3);
+ mono1Mask = 0x80 >> ((xSrc + x0 - xDest) & 7);
+ for (x = x0; x < x1; ++x) {
+ scanBuf[x] = (*mono1Ptr & mono1Mask) ? 0xff : 0x00;
+ mono1Ptr += mono1Mask & 1;
+ mono1Mask = (mono1Mask << 7) | (mono1Mask >> 1);
+ }
+ memset(scanBuf2 + x0, 0xff, x1 - x0);
+ if (!state->clip->clipSpanBinary(scanBuf2, y, x0, x1 - 1,
+ state->strokeAdjust)) {
+ continue;
+ }
+ (this->*pipe.run)(&pipe, x0, x1 - 1, y,
+ scanBuf2 + x0,
+ scanBuf + x0);
+ }
+ }
}
}
- } else {
- x0 = xDest;
- if ((t = state->clip->getXMinI(state->strokeAdjust)) > x0) {
- x0 = t;
- }
- x1 = xDest + w;
- if ((t = state->clip->getXMaxI(state->strokeAdjust) + 1) < x1) {
- x1 = t;
- }
- y0 = yDest;
- if ((t = state->clip->getYMinI(state->strokeAdjust)) > y0) {
- y0 = t;
- }
- y1 = yDest + h;
- if ((t = state->clip->getYMaxI(state->strokeAdjust) + 1) < y1) {
- y1 = t;
- }
- if (x0 < x1 && y0 < y1) {
+
+ } else if (src->mode == splashModeBGR8) {
+ // in BGR8 mode, pipeRun expects the source to be in RGB8 format,
+ // so we need to swap bytes
+ lineBuf = (Guchar *)gmallocn(w, 3);
+ if (noClip) {
if (src->alpha) {
- for (y = y0; y < y1; ++y) {
- memcpy(scanBuf + x0,
- src->getAlphaPtr() + (ySrc + y - yDest) * src->getWidth() +
- (xSrc + x0 - xDest),
- x1 - x0);
- if (!state->clip->clipSpanBinary(scanBuf, y, x0, x1 - 1,
- state->strokeAdjust)) {
- continue;
+ for (y = 0; y < h; ++y) {
+ memcpy(lineBuf,
+ src->getDataPtr() + (ySrc + y) * src->rowSize + xSrc * 3,
+ w * 3);
+ for (x = 0, linePtr = lineBuf; x < w; ++x, linePtr += 3) {
+ b = linePtr[0];
+ linePtr[0] = linePtr[2];
+ linePtr[2] = b;
}
// this uses shape instead of alpha, which isn't technically
// correct, but works out the same
- (this->*pipe.run)(&pipe, x0, x1 - 1, y,
- scanBuf + x0,
- src->getDataPtr() +
- (ySrc + y - yDest) * src->getRowSize() +
- (xSrc + x0 - xDest) * bitmapComps);
+ (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y,
+ src->getAlphaPtr() +
+ (ySrc + y) * src->getWidth() + xSrc,
+ lineBuf);
}
} else {
- for (y = y0; y < y1; ++y) {
- memset(scanBuf + x0, 0xff, x1 - x0);
- if (!state->clip->clipSpanBinary(scanBuf, y, x0, x1 - 1,
- state->strokeAdjust)) {
- continue;
+ for (y = 0; y < h; ++y) {
+ memcpy(lineBuf,
+ src->getDataPtr() + (ySrc + y) * src->rowSize + xSrc * 3,
+ w * 3);
+ for (x = 0, linePtr = lineBuf; x < w; ++x, linePtr += 3) {
+ b = linePtr[0];
+ linePtr[0] = linePtr[2];
+ linePtr[2] = b;
}
(this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y,
- scanBuf + x0,
- src->getDataPtr() +
- (ySrc + y - yDest) * src->getRowSize() +
- (xSrc - xDest) * bitmapComps);
+ NULL, lineBuf);
+ }
+ }
+ } else {
+ x0 = xDest;
+ if ((t = state->clip->getXMinI(state->strokeAdjust)) > x0) {
+ x0 = t;
+ }
+ x1 = xDest + w;
+ if ((t = state->clip->getXMaxI(state->strokeAdjust) + 1) < x1) {
+ x1 = t;
+ }
+ y0 = yDest;
+ if ((t = state->clip->getYMinI(state->strokeAdjust)) > y0) {
+ y0 = t;
+ }
+ y1 = yDest + h;
+ if ((t = state->clip->getYMaxI(state->strokeAdjust) + 1) < y1) {
+ y1 = t;
+ }
+ if (x0 < x1 && y0 < y1) {
+ if (src->alpha) {
+ for (y = y0; y < y1; ++y) {
+ memcpy(scanBuf + x0,
+ src->getAlphaPtr() + (ySrc + y - yDest) * src->getWidth() +
+ (xSrc + x0 - xDest),
+ x1 - x0);
+ state->clip->clipSpan(scanBuf, y, x0, x1 - 1, state->strokeAdjust);
+ memcpy(lineBuf,
+ src->getDataPtr() +
+ (ySrc + y - yDest) * src->rowSize +
+ (xSrc + x0 - xDest) * 3,
+ (x1 - x0) * 3);
+ for (x = 0, linePtr = lineBuf; x < x1 - x0; ++x, linePtr += 3) {
+ b = linePtr[0];
+ linePtr[0] = linePtr[2];
+ linePtr[2] = b;
+ }
+ // this uses shape instead of alpha, which isn't technically
+ // correct, but works out the same
+ (this->*pipe.run)(&pipe, x0, x1 - 1, y,
+ scanBuf + x0, lineBuf);
+ }
+ } else {
+ for (y = y0; y < y1; ++y) {
+ memset(scanBuf + x0, 0xff, x1 - x0);
+ state->clip->clipSpan(scanBuf, y, x0, x1 - 1, state->strokeAdjust);
+ memcpy(lineBuf,
+ src->getDataPtr() +
+ (ySrc + y - yDest) * src->rowSize +
+ (xSrc + x0 - xDest) * 3,
+ (x1 - x0) * 3);
+ for (x = 0, linePtr = lineBuf; x < x1 - x0; ++x, linePtr += 3) {
+ b = linePtr[0];
+ linePtr[0] = linePtr[2];
+ linePtr[2] = b;
+ }
+ (this->*pipe.run)(&pipe, x0, x1 - 1, yDest + y,
+ scanBuf + x0,
+ src->getDataPtr() +
+ (ySrc + y - yDest) * src->rowSize +
+ (xSrc + x0 - xDest) * bitmapComps);
+ }
+ }
+ }
+ }
+ gfree(lineBuf);
+
+ } else { // src->mode not mono1 or BGR8
+ if (noClip) {
+ if (src->alpha) {
+ for (y = 0; y < h; ++y) {
+ // this uses shape instead of alpha, which isn't technically
+ // correct, but works out the same
+ (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y,
+ src->getAlphaPtr() +
+ (ySrc + y) * src->getWidth() + xSrc,
+ src->getDataPtr() + (ySrc + y) * src->rowSize +
+ xSrc * bitmapComps);
+ }
+ } else {
+ for (y = 0; y < h; ++y) {
+ (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y,
+ NULL,
+ src->getDataPtr() + (ySrc + y) * src->rowSize +
+ xSrc * bitmapComps);
+ }
+ }
+ } else {
+ x0 = xDest;
+ if ((t = state->clip->getXMinI(state->strokeAdjust)) > x0) {
+ x0 = t;
+ }
+ x1 = xDest + w;
+ if ((t = state->clip->getXMaxI(state->strokeAdjust) + 1) < x1) {
+ x1 = t;
+ }
+ y0 = yDest;
+ if ((t = state->clip->getYMinI(state->strokeAdjust)) > y0) {
+ y0 = t;
+ }
+ y1 = yDest + h;
+ if ((t = state->clip->getYMaxI(state->strokeAdjust) + 1) < y1) {
+ y1 = t;
+ }
+ if (x0 < x1 && y0 < y1) {
+ if (src->alpha) {
+ for (y = y0; y < y1; ++y) {
+ memcpy(scanBuf + x0,
+ src->getAlphaPtr() + (ySrc + y - yDest) * src->getWidth() +
+ (xSrc + x0 - xDest),
+ x1 - x0);
+ state->clip->clipSpan(scanBuf, y, x0, x1 - 1, state->strokeAdjust);
+ // this uses shape instead of alpha, which isn't technically
+ // correct, but works out the same
+ (this->*pipe.run)(&pipe, x0, x1 - 1, y,
+ scanBuf + x0,
+ src->getDataPtr() +
+ (ySrc + y - yDest) * src->rowSize +
+ (xSrc + x0 - xDest) * bitmapComps);
+ }
+ } else {
+ for (y = y0; y < y1; ++y) {
+ memset(scanBuf + x0, 0xff, x1 - x0);
+ state->clip->clipSpan(scanBuf, y, x0, x1 - 1, state->strokeAdjust);
+ (this->*pipe.run)(&pipe, x0, x1 - 1, yDest + y,
+ scanBuf + x0,
+ src->getDataPtr() +
+ (ySrc + y - yDest) * src->rowSize +
+ (xSrc + x0 - xDest) * bitmapComps);
+ }
}
}
}
@@ -5980,13 +6328,21 @@ void Splash::compositeBackground(SplashColorPtr color) {
mask = 0x80;
for (x = 0; x < bitmap->width; ++x) {
alpha = *q++;
- alpha1 = 255 - alpha;
- c = (*p & mask) ? 0xff : 0x00;
- c = div255(alpha1 * color0 + alpha * c);
- if (c & 0x80) {
- *p |= mask;
- } else {
- *p &= ~mask;
+ if (alpha == 0) {
+ if (color0 & 0x80) {
+ *p |= mask;
+ } else {
+ *p &= ~mask;
+ }
+ } else if (alpha != 255) {
+ alpha1 = 255 - alpha;
+ c = (*p & mask) ? 0xff : 0x00;
+ c = div255(alpha1 * color0 + alpha * c);
+ if (c & 0x80) {
+ *p |= mask;
+ } else {
+ *p &= ~mask;
+ }
}
if (!(mask >>= 1)) {
mask = 0x80;
@@ -6002,8 +6358,12 @@ void Splash::compositeBackground(SplashColorPtr color) {
q = &bitmap->alpha[y * bitmap->width];
for (x = 0; x < bitmap->width; ++x) {
alpha = *q++;
- alpha1 = 255 - alpha;
- p[0] = div255(alpha1 * color0 + alpha * p[0]);
+ if (alpha == 0) {
+ p[0] = color0;
+ } else if (alpha != 255) {
+ alpha1 = 255 - alpha;
+ p[0] = div255(alpha1 * color0 + alpha * p[0]);
+ }
++p;
}
}
@@ -6018,10 +6378,16 @@ void Splash::compositeBackground(SplashColorPtr color) {
q = &bitmap->alpha[y * bitmap->width];
for (x = 0; x < bitmap->width; ++x) {
alpha = *q++;
- alpha1 = 255 - alpha;
- p[0] = div255(alpha1 * color0 + alpha * p[0]);
- p[1] = div255(alpha1 * color1 + alpha * p[1]);
- p[2] = div255(alpha1 * color2 + alpha * p[2]);
+ if (alpha == 0) {
+ p[0] = color0;
+ p[1] = color1;
+ p[2] = color2;
+ } else if (alpha != 255) {
+ alpha1 = 255 - alpha;
+ p[0] = div255(alpha1 * color0 + alpha * p[0]);
+ p[1] = div255(alpha1 * color1 + alpha * p[1]);
+ p[2] = div255(alpha1 * color2 + alpha * p[2]);
+ }
p += 3;
}
}
@@ -6037,11 +6403,18 @@ void Splash::compositeBackground(SplashColorPtr color) {
q = &bitmap->alpha[y * bitmap->width];
for (x = 0; x < bitmap->width; ++x) {
alpha = *q++;
- alpha1 = 255 - alpha;
- p[0] = div255(alpha1 * color0 + alpha * p[0]);
- p[1] = div255(alpha1 * color1 + alpha * p[1]);
- p[2] = div255(alpha1 * color2 + alpha * p[2]);
- p[3] = div255(alpha1 * color3 + alpha * p[3]);
+ if (alpha == 0) {
+ p[0] = color0;
+ p[1] = color1;
+ p[2] = color2;
+ p[3] = color3;
+ } else if (alpha != 255) {
+ alpha1 = 255 - alpha;
+ p[0] = div255(alpha1 * color0 + alpha * p[0]);
+ p[1] = div255(alpha1 * color1 + alpha * p[1]);
+ p[2] = div255(alpha1 * color2 + alpha * p[2]);
+ p[3] = div255(alpha1 * color3 + alpha * p[3]);
+ }
p += 4;
}
}
@@ -6120,11 +6493,95 @@ SplashError Splash::blitTransparent(SplashBitmap *src, int xSrc, int ySrc,
return splashOk;
}
+SplashError Splash::blitCorrectedAlpha(SplashBitmap *dest, int xSrc, int ySrc,
+ int xDest, int yDest, int w, int h) {
+ SplashColorPtr p, q;
+ Guchar *alpha0Ptr;
+ Guchar alpha0, aSrc;
+ int x, y, mask, srcMask;
+
+ if (bitmap->mode != dest->mode ||
+ !bitmap->alpha ||
+ !dest->alpha ||
+ !groupBackBitmap) {
+ return splashErrModeMismatch;
+ }
+
+ switch (bitmap->mode) {
+ case splashModeMono1:
+ for (y = 0; y < h; ++y) {
+ p = &dest->data[(yDest + y) * dest->rowSize + (xDest >> 3)];
+ mask = 0x80 >> (xDest & 7);
+ q = &bitmap->data[(ySrc + y) * bitmap->rowSize + (xSrc >> 3)];
+ srcMask = 0x80 >> (xSrc & 7);
+ for (x = 0; x < w; ++x) {
+ if (*q & srcMask) {
+ *p |= mask;
+ } else {
+ *p &= ~mask;
+ }
+ if (!(mask >>= 1)) {
+ mask = 0x80;
+ ++p;
+ }
+ if (!(srcMask >>= 1)) {
+ srcMask = 0x80;
+ ++q;
+ }
+ }
+ }
+ break;
+ case splashModeMono8:
+ for (y = 0; y < h; ++y) {
+ p = &dest->data[(yDest + y) * dest->rowSize + xDest];
+ q = &bitmap->data[(ySrc + y) * bitmap->rowSize + xSrc];
+ memcpy(p, q, w);
+ }
+ break;
+ case splashModeRGB8:
+ case splashModeBGR8:
+ for (y = 0; y < h; ++y) {
+ p = &dest->data[(yDest + y) * dest->rowSize + 3 * xDest];
+ q = &bitmap->data[(ySrc + y) * bitmap->rowSize + 3 * xSrc];
+ memcpy(p, q, 3 * w);
+ }
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ for (y = 0; y < h; ++y) {
+ p = &dest->data[(yDest + y) * dest->rowSize + 4 * xDest];
+ q = &bitmap->data[(ySrc + y) * bitmap->rowSize + 4 * xSrc];
+ memcpy(p, q, 4 * w);
+ }
+ break;
+#endif
+ }
+
+ for (y = 0; y < h; ++y) {
+ p = &dest->alpha[(yDest + y) * dest->width + xDest];
+ q = &bitmap->alpha[(ySrc + y) * bitmap->width + xSrc];
+ alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + ySrc + y)
+ * groupBackBitmap->width +
+ (groupBackX + xSrc)];
+ for (x = 0; x < w; ++x) {
+ alpha0 = *alpha0Ptr++;
+ aSrc = *q++;
+ *p++ = alpha0 + aSrc - div255(alpha0 * aSrc);
+ }
+ }
+
+ return splashOk;
+}
+
SplashPath *Splash::makeStrokePath(SplashPath *path, SplashCoord w,
- GBool flatten) {
+ int lineCap, int lineJoin,
+ GBool flatten) {
SplashPath *pathIn, *dashPath, *pathOut;
SplashCoord d, dx, dy, wdx, wdy, dxNext, dyNext, wdxNext, wdyNext;
SplashCoord crossprod, dotprod, miter, m;
+ SplashCoord angle, angleNext, dAngle, xc, yc;
+ SplashCoord dxJoin, dyJoin, dJoin, kappa;
+ SplashCoord cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
GBool first, last, closed;
int subpathStart0, subpathStart1, seg, i0, i1, j0, j1, k0, k1;
int left0, left1, left2, right0, right1, right2, join0, join1, join2;
@@ -6184,7 +6641,7 @@ SplashPath *Splash::makeStrokePath(SplashPath *path, SplashCoord w,
j1 = j0;
}
if (pathIn->flags[i1] & splashPathLast) {
- if (first && state->lineCap == splashLineCapRound) {
+ if (first && lineCap == splashLineCapRound) {
// special case: zero-length subpath with round line caps -->
// draw a circle
pathOut->moveTo(pathIn->pts[i0].x + (SplashCoord)0.5 * w,
@@ -6250,16 +6707,17 @@ SplashPath *Splash::makeStrokePath(SplashPath *path, SplashCoord w,
wdy = (SplashCoord)0.5 * w * dy;
// draw the start cap
- pathOut->moveTo(pathIn->pts[i0].x - wdy, pathIn->pts[i0].y + wdx);
if (i0 == subpathStart0) {
- firstPt = pathOut->length - 1;
+ firstPt = pathOut->length;
}
if (first && !closed) {
- switch (state->lineCap) {
+ switch (lineCap) {
case splashLineCapButt:
+ pathOut->moveTo(pathIn->pts[i0].x - wdy, pathIn->pts[i0].y + wdx);
pathOut->lineTo(pathIn->pts[i0].x + wdy, pathIn->pts[i0].y - wdx);
break;
case splashLineCapRound:
+ pathOut->moveTo(pathIn->pts[i0].x - wdy, pathIn->pts[i0].y + wdx);
pathOut->curveTo(pathIn->pts[i0].x - wdy - bezierCircle * wdx,
pathIn->pts[i0].y + wdx - bezierCircle * wdy,
pathIn->pts[i0].x - wdx - bezierCircle * wdy,
@@ -6274,29 +6732,27 @@ SplashPath *Splash::makeStrokePath(SplashPath *path, SplashCoord w,
pathIn->pts[i0].y - wdx);
break;
case splashLineCapProjecting:
- pathOut->lineTo(pathIn->pts[i0].x - wdx - wdy,
+ pathOut->moveTo(pathIn->pts[i0].x - wdx - wdy,
pathIn->pts[i0].y + wdx - wdy);
pathOut->lineTo(pathIn->pts[i0].x - wdx + wdy,
pathIn->pts[i0].y - wdx - wdy);
- pathOut->lineTo(pathIn->pts[i0].x + wdy,
- pathIn->pts[i0].y - wdx);
break;
}
} else {
+ pathOut->moveTo(pathIn->pts[i0].x - wdy, pathIn->pts[i0].y + wdx);
pathOut->lineTo(pathIn->pts[i0].x + wdy, pathIn->pts[i0].y - wdx);
}
- // draw the left side of the segment rectangle
+ // draw the left side of the segment rectangle and the end cap
left2 = pathOut->length - 1;
- pathOut->lineTo(pathIn->pts[j0].x + wdy, pathIn->pts[j0].y - wdx);
-
- // draw the end cap
if (last && !closed) {
- switch (state->lineCap) {
+ switch (lineCap) {
case splashLineCapButt:
+ pathOut->lineTo(pathIn->pts[j0].x + wdy, pathIn->pts[j0].y - wdx);
pathOut->lineTo(pathIn->pts[j0].x - wdy, pathIn->pts[j0].y + wdx);
break;
case splashLineCapRound:
+ pathOut->lineTo(pathIn->pts[j0].x + wdy, pathIn->pts[j0].y - wdx);
pathOut->curveTo(pathIn->pts[j0].x + wdy + bezierCircle * wdx,
pathIn->pts[j0].y - wdx + bezierCircle * wdy,
pathIn->pts[j0].x + wdx + bezierCircle * wdy,
@@ -6315,11 +6771,10 @@ SplashPath *Splash::makeStrokePath(SplashPath *path, SplashCoord w,
pathIn->pts[j0].y - wdx + wdy);
pathOut->lineTo(pathIn->pts[j0].x - wdy + wdx,
pathIn->pts[j0].y + wdx + wdy);
- pathOut->lineTo(pathIn->pts[j0].x - wdy,
- pathIn->pts[j0].y + wdx);
break;
}
} else {
+ pathOut->lineTo(pathIn->pts[j0].x + wdy, pathIn->pts[j0].y - wdx);
pathOut->lineTo(pathIn->pts[j0].x - wdy, pathIn->pts[j0].y + wdx);
}
@@ -6327,7 +6782,7 @@ SplashPath *Splash::makeStrokePath(SplashPath *path, SplashCoord w,
// (NB: if stroke adjustment is enabled, the closepath operation MUST
// add a segment because this segment is used for a hint)
right2 = pathOut->length - 1;
- pathOut->close(state->strokeAdjust);
+ pathOut->close(state->strokeAdjust != splashStrokeAdjustOff);
// draw the join
join2 = pathOut->length;
@@ -6372,43 +6827,121 @@ SplashPath *Splash::makeStrokePath(SplashPath *path, SplashCoord w,
}
// round join
- if (state->lineJoin == splashLineJoinRound) {
- pathOut->moveTo(pathIn->pts[j0].x + (SplashCoord)0.5 * w,
- pathIn->pts[j0].y);
- pathOut->curveTo(pathIn->pts[j0].x + (SplashCoord)0.5 * w,
- pathIn->pts[j0].y + bezierCircle2 * w,
- pathIn->pts[j0].x + bezierCircle2 * w,
- pathIn->pts[j0].y + (SplashCoord)0.5 * w,
- pathIn->pts[j0].x,
- pathIn->pts[j0].y + (SplashCoord)0.5 * w);
- pathOut->curveTo(pathIn->pts[j0].x - bezierCircle2 * w,
- pathIn->pts[j0].y + (SplashCoord)0.5 * w,
- pathIn->pts[j0].x - (SplashCoord)0.5 * w,
- pathIn->pts[j0].y + bezierCircle2 * w,
- pathIn->pts[j0].x - (SplashCoord)0.5 * w,
- pathIn->pts[j0].y);
- pathOut->curveTo(pathIn->pts[j0].x - (SplashCoord)0.5 * w,
- pathIn->pts[j0].y - bezierCircle2 * w,
- pathIn->pts[j0].x - bezierCircle2 * w,
- pathIn->pts[j0].y - (SplashCoord)0.5 * w,
- pathIn->pts[j0].x,
- pathIn->pts[j0].y - (SplashCoord)0.5 * w);
- pathOut->curveTo(pathIn->pts[j0].x + bezierCircle2 * w,
- pathIn->pts[j0].y - (SplashCoord)0.5 * w,
- pathIn->pts[j0].x + (SplashCoord)0.5 * w,
- pathIn->pts[j0].y - bezierCircle2 * w,
- pathIn->pts[j0].x + (SplashCoord)0.5 * w,
- pathIn->pts[j0].y);
+ if (lineJoin == splashLineJoinRound) {
+ // join angle < 180
+ if (crossprod < 0) {
+ angle = atan2((double)dx, (double)-dy);
+ angleNext = atan2((double)dxNext, (double)-dyNext);
+ if (angle < angleNext) {
+ angle += 2 * M_PI;
+ }
+ dAngle = (angle - angleNext) / M_PI;
+ if (dAngle < 0.501) {
+ // span angle is <= 90 degrees -> draw a single arc
+ kappa = dAngle * bezierCircle * w;
+ cx1 = pathIn->pts[j0].x - wdy + kappa * dx;
+ cy1 = pathIn->pts[j0].y + wdx + kappa * dy;
+ cx2 = pathIn->pts[j0].x - wdyNext - kappa * dxNext;
+ cy2 = pathIn->pts[j0].y + wdxNext - kappa * dyNext;
+ pathOut->moveTo(pathIn->pts[j0].x, pathIn->pts[j0].y);
+ pathOut->lineTo(pathIn->pts[j0].x - wdyNext,
+ pathIn->pts[j0].y + wdxNext);
+ pathOut->curveTo(cx2, cy2, cx1, cy1,
+ pathIn->pts[j0].x - wdy,
+ pathIn->pts[j0].y + wdx);
+ } else {
+ // span angle is > 90 degrees -> split into two arcs
+ dJoin = splashDist(-wdy, wdx, -wdyNext, wdxNext);
+ if (dJoin > 0) {
+ dxJoin = (-wdyNext + wdy) / dJoin;
+ dyJoin = (wdxNext - wdx) / dJoin;
+ xc = pathIn->pts[j0].x
+ + (SplashCoord)0.5 * w
+ * cos((double)((SplashCoord)0.5 * (angle + angleNext)));
+ yc = pathIn->pts[j0].y
+ + (SplashCoord)0.5 * w
+ * sin((double)((SplashCoord)0.5 * (angle + angleNext)));
+ kappa = dAngle * bezierCircle2 * w;
+ cx1 = pathIn->pts[j0].x - wdy + kappa * dx;
+ cy1 = pathIn->pts[j0].y + wdx + kappa * dy;
+ cx2 = xc - kappa * dxJoin;
+ cy2 = yc - kappa * dyJoin;
+ cx3 = xc + kappa * dxJoin;
+ cy3 = yc + kappa * dyJoin;
+ cx4 = pathIn->pts[j0].x - wdyNext - kappa * dxNext;
+ cy4 = pathIn->pts[j0].y + wdxNext - kappa * dyNext;
+ pathOut->moveTo(pathIn->pts[j0].x, pathIn->pts[j0].y);
+ pathOut->lineTo(pathIn->pts[j0].x - wdyNext,
+ pathIn->pts[j0].y + wdxNext);
+ pathOut->curveTo(cx4, cy4, cx3, cy3, xc, yc);
+ pathOut->curveTo(cx2, cy2, cx1, cy1,
+ pathIn->pts[j0].x - wdy,
+ pathIn->pts[j0].y + wdx);
+ }
+ }
+
+ // join angle >= 180
+ } else {
+ angle = atan2((double)-dx, (double)dy);
+ angleNext = atan2((double)-dxNext, (double)dyNext);
+ if (angleNext < angle) {
+ angleNext += 2 * M_PI;
+ }
+ dAngle = (angleNext - angle) / M_PI;
+ if (dAngle < 0.501) {
+ // span angle is <= 90 degrees -> draw a single arc
+ kappa = dAngle * bezierCircle * w;
+ cx1 = pathIn->pts[j0].x + wdy + kappa * dx;
+ cy1 = pathIn->pts[j0].y - wdx + kappa * dy;
+ cx2 = pathIn->pts[j0].x + wdyNext - kappa * dxNext;
+ cy2 = pathIn->pts[j0].y - wdxNext - kappa * dyNext;
+ pathOut->moveTo(pathIn->pts[j0].x, pathIn->pts[j0].y);
+ pathOut->lineTo(pathIn->pts[j0].x + wdy,
+ pathIn->pts[j0].y - wdx);
+ pathOut->curveTo(cx1, cy1, cx2, cy2,
+ pathIn->pts[j0].x + wdyNext,
+ pathIn->pts[j0].y - wdxNext);
+ } else {
+ // span angle is > 90 degrees -> split into two arcs
+ dJoin = splashDist(wdy, -wdx, wdyNext, -wdxNext);
+ if (dJoin > 0) {
+ dxJoin = (wdyNext - wdy) / dJoin;
+ dyJoin = (-wdxNext + wdx) / dJoin;
+ xc = pathIn->pts[j0].x
+ + (SplashCoord)0.5 * w
+ * cos((double)((SplashCoord)0.5 * (angle + angleNext)));
+ yc = pathIn->pts[j0].y
+ + (SplashCoord)0.5 * w
+ * sin((double)((SplashCoord)0.5 * (angle + angleNext)));
+ kappa = dAngle * bezierCircle2 * w;
+ cx1 = pathIn->pts[j0].x + wdy + kappa * dx;
+ cy1 = pathIn->pts[j0].y - wdx + kappa * dy;
+ cx2 = xc - kappa * dxJoin;
+ cy2 = yc - kappa * dyJoin;
+ cx3 = xc + kappa * dxJoin;
+ cy3 = yc + kappa * dyJoin;
+ cx4 = pathIn->pts[j0].x + wdyNext - kappa * dxNext;
+ cy4 = pathIn->pts[j0].y - wdxNext - kappa * dyNext;
+ pathOut->moveTo(pathIn->pts[j0].x, pathIn->pts[j0].y);
+ pathOut->lineTo(pathIn->pts[j0].x + wdy,
+ pathIn->pts[j0].y - wdx);
+ pathOut->curveTo(cx1, cy1, cx2, cy2, xc, yc);
+ pathOut->curveTo(cx3, cy3, cx4, cy4,
+ pathIn->pts[j0].x + wdyNext,
+ pathIn->pts[j0].y - wdxNext);
+ }
+ }
+ }
} else {
pathOut->moveTo(pathIn->pts[j0].x, pathIn->pts[j0].y);
- // angle < 180
+ // join angle < 180
if (crossprod < 0) {
pathOut->lineTo(pathIn->pts[j0].x - wdyNext,
pathIn->pts[j0].y + wdxNext);
// miter join inside limit
- if (state->lineJoin == splashLineJoinMiter &&
+ if (lineJoin == splashLineJoinMiter &&
splashSqrt(miter) <= state->miterLimit) {
pathOut->lineTo(pathIn->pts[j0].x - wdy + wdx * m,
pathIn->pts[j0].y + wdx + wdy * m);
@@ -6420,12 +6953,12 @@ SplashPath *Splash::makeStrokePath(SplashPath *path, SplashCoord w,
pathIn->pts[j0].y + wdx);
}
- // angle >= 180
+ // join angle >= 180
} else {
pathOut->lineTo(pathIn->pts[j0].x + wdy,
pathIn->pts[j0].y - wdx);
// miter join inside limit
- if (state->lineJoin == splashLineJoinMiter &&
+ if (lineJoin == splashLineJoinMiter &&
splashSqrt(miter) <= state->miterLimit) {
pathOut->lineTo(pathIn->pts[j0].x + wdy + wdx * m,
pathIn->pts[j0].y - wdx + wdy * m);
@@ -6443,36 +6976,106 @@ SplashPath *Splash::makeStrokePath(SplashPath *path, SplashCoord w,
}
// add stroke adjustment hints
- if (state->strokeAdjust) {
- if (seg == 0 && !closed) {
- if (state->lineCap == splashLineCapButt) {
+ if (state->strokeAdjust != splashStrokeAdjustOff) {
+
+ // subpath with one segment
+ if (seg == 0 && last) {
+ switch (lineCap) {
+ case splashLineCapButt:
pathOut->addStrokeAdjustHint(firstPt, left2 + 1,
- firstPt, firstPt + 1);
- if (last) {
- pathOut->addStrokeAdjustHint(firstPt, left2 + 1,
- left2 + 1, left2 + 2);
- }
- } else if (state->lineCap == splashLineCapProjecting) {
- if (last) {
- pathOut->addStrokeAdjustHint(firstPt + 1, left2 + 2,
- firstPt + 1, firstPt + 2);
- pathOut->addStrokeAdjustHint(firstPt + 1, left2 + 2,
- left2 + 2, left2 + 3);
- } else {
- pathOut->addStrokeAdjustHint(firstPt + 1, left2 + 1,
- firstPt + 1, firstPt + 2);
+ firstPt, pathOut->length - 1);
+ break;
+ case splashLineCapProjecting:
+ pathOut->addStrokeAdjustHint(firstPt, left2 + 1,
+ firstPt, pathOut->length - 1, gTrue);
+ break;
+ case splashLineCapRound:
+ break;
+ }
+ pathOut->addStrokeAdjustHint(left2, right2,
+ firstPt, pathOut->length - 1);
+ } else {
+
+ // start of subpath
+ if (seg == 1) {
+
+ // start cap
+ if (!closed) {
+ switch (lineCap) {
+ case splashLineCapButt:
+ pathOut->addStrokeAdjustHint(firstPt, left1 + 1,
+ firstPt, firstPt + 1);
+ pathOut->addStrokeAdjustHint(firstPt, left1 + 1,
+ right1 + 1, right1 + 1);
+ break;
+ case splashLineCapProjecting:
+ pathOut->addStrokeAdjustHint(firstPt, left1 + 1,
+ firstPt, firstPt + 1, gTrue);
+ pathOut->addStrokeAdjustHint(firstPt, left1 + 1,
+ right1 + 1, right1 + 1, gTrue);
+ break;
+ case splashLineCapRound:
+ break;
+ }
}
+
+ // first segment
+ pathOut->addStrokeAdjustHint(left1, right1, firstPt, left2);
+ pathOut->addStrokeAdjustHint(left1, right1, right2 + 1, right2 + 1);
}
- }
- if (seg >= 1) {
- if (seg >= 2) {
+
+ // middle of subpath
+ if (seg > 1) {
pathOut->addStrokeAdjustHint(left1, right1, left0 + 1, right0);
pathOut->addStrokeAdjustHint(left1, right1, join0, left2);
- } else {
- pathOut->addStrokeAdjustHint(left1, right1, firstPt, left2);
+ pathOut->addStrokeAdjustHint(left1, right1, right2 + 1, right2 + 1);
+ }
+
+ // end of subpath
+ if (last) {
+
+ if (closed) {
+ // first segment
+ pathOut->addStrokeAdjustHint(leftFirst, rightFirst,
+ left2 + 1, right2);
+ pathOut->addStrokeAdjustHint(leftFirst, rightFirst,
+ join2, pathOut->length - 1);
+
+ // last segment
+ pathOut->addStrokeAdjustHint(left2, right2,
+ left1 + 1, right1);
+ pathOut->addStrokeAdjustHint(left2, right2,
+ join1, pathOut->length - 1);
+ pathOut->addStrokeAdjustHint(left2, right2,
+ leftFirst - 1, leftFirst);
+ pathOut->addStrokeAdjustHint(left2, right2,
+ rightFirst + 1, rightFirst + 1);
+
+ } else {
+
+ // last segment
+ pathOut->addStrokeAdjustHint(left2, right2,
+ left1 + 1, right1);
+ pathOut->addStrokeAdjustHint(left2, right2,
+ join1, pathOut->length - 1);
+
+ // end cap
+ switch (lineCap) {
+ case splashLineCapButt:
+ pathOut->addStrokeAdjustHint(left2 - 1, left2 + 1,
+ left2 + 1, left2 + 2);
+ break;
+ case splashLineCapProjecting:
+ pathOut->addStrokeAdjustHint(left2 - 1, left2 + 1,
+ left2 + 1, left2 + 2, gTrue);
+ break;
+ case splashLineCapRound:
+ break;
+ }
+ }
}
- pathOut->addStrokeAdjustHint(left1, right1, right2 + 1, right2 + 1);
}
+
left0 = left1;
left1 = left2;
right0 = right1;
@@ -6483,34 +7086,6 @@ SplashPath *Splash::makeStrokePath(SplashPath *path, SplashCoord w,
leftFirst = left2;
rightFirst = right2;
}
- if (last) {
- if (seg >= 2) {
- pathOut->addStrokeAdjustHint(left1, right1, left0 + 1, right0);
- pathOut->addStrokeAdjustHint(left1, right1,
- join0, pathOut->length - 1);
- } else {
- pathOut->addStrokeAdjustHint(left1, right1,
- firstPt, pathOut->length - 1);
- }
- if (closed) {
- pathOut->addStrokeAdjustHint(left1, right1, firstPt, leftFirst);
- pathOut->addStrokeAdjustHint(left1, right1,
- rightFirst + 1, rightFirst + 1);
- pathOut->addStrokeAdjustHint(leftFirst, rightFirst,
- left1 + 1, right1);
- pathOut->addStrokeAdjustHint(leftFirst, rightFirst,
- join1, pathOut->length - 1);
- }
- if (!closed && seg > 0) {
- if (state->lineCap == splashLineCapButt) {
- pathOut->addStrokeAdjustHint(left1 - 1, left1 + 1,
- left1 + 1, left1 + 2);
- } else if (state->lineCap == splashLineCapProjecting) {
- pathOut->addStrokeAdjustHint(left1 - 1, left1 + 2,
- left1 + 2, left1 + 3);
- }
- }
- }
}
i0 = j0;
@@ -6525,6 +7100,29 @@ SplashPath *Splash::makeStrokePath(SplashPath *path, SplashCoord w,
return pathOut;
}
+SplashClipResult Splash::limitRectToClipRect(int *xMin, int *yMin,
+ int *xMax, int *yMax) {
+ int t;
+
+ if ((t = state->clip->getXMinI(state->strokeAdjust)) > *xMin) {
+ *xMin = t;
+ }
+ if ((t = state->clip->getXMaxI(state->strokeAdjust) + 1) < *xMax) {
+ *xMax = t;
+ }
+ if ((t = state->clip->getYMinI(state->strokeAdjust)) > *yMin) {
+ *yMin = t;
+ }
+ if ((t = state->clip->getYMaxI(state->strokeAdjust) + 1) < *yMax) {
+ *yMax = t;
+ }
+ if (*xMin >= *xMax || *yMin >= *yMax) {
+ return splashClipAllOutside;
+ }
+ return state->clip->testRect(*xMin, *yMin, *xMax - 1, *yMax - 1,
+ state->strokeAdjust);
+}
+
void Splash::dumpPath(SplashPath *path) {
int i;
@@ -6536,6 +7134,15 @@ void Splash::dumpPath(SplashPath *path) {
(path->flags[i] & splashPathClosed) ? " closed" : "",
(path->flags[i] & splashPathCurve) ? " curve" : "");
}
+ if (path->hintsLength == 0) {
+ printf(" no hints\n");
+ } else {
+ for (i = 0; i < path->hintsLength; ++i) {
+ printf(" hint %3d: ctrl0=%d ctrl1=%d pts=%d..%d\n",
+ i, path->hints[i].ctrl0, path->hints[i].ctrl1,
+ path->hints[i].firstPt, path->hints[i].lastPt);
+ }
+ }
}
void Splash::dumpXPath(SplashXPath *path) {
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.h b/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
index 7409e0cd6b4..3ca57982e15 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
@@ -95,7 +95,7 @@ public:
SplashCoord *getLineDash();
int getLineDashLength();
SplashCoord getLineDashPhase();
- GBool getStrokeAdjust();
+ SplashStrokeAdjustMode getStrokeAdjust();
SplashClip *getClip();
SplashBitmap *getSoftMask();
GBool getInNonIsolatedGroup();
@@ -118,7 +118,7 @@ public:
// the <lineDash> array will be copied
void setLineDash(SplashCoord *lineDash, int lineDashLength,
SplashCoord lineDashPhase);
- void setStrokeAdjust(GBool strokeAdjust);
+ void setStrokeAdjust(SplashStrokeAdjustMode strokeAdjust);
// NB: uses transformed coordinates.
void clipResetToRect(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1);
@@ -133,6 +133,7 @@ public:
GBool nonIsolated, GBool knockout);
void setTransfer(Guchar *red, Guchar *green, Guchar *blue, Guchar *gray);
void setOverprintMask(Guint overprintMask);
+ void setEnablePathSimplification(GBool en);
//----- state save/restore
@@ -150,9 +151,6 @@ public:
// Fill a path using the current fill pattern.
SplashError fill(SplashPath *path, GBool eo);
- // Fill a path, XORing with the current fill pattern.
- SplashError xorFill(SplashPath *path, GBool eo);
-
// Draw a character, using the current fill pattern.
SplashError fillChar(SplashCoord x, SplashCoord y, int c, SplashFont *font);
@@ -213,6 +211,12 @@ public:
SplashError blitTransparent(SplashBitmap *src, int xSrc, int ySrc,
int xDest, int yDest, int w, int h);
+ // Copy a rectangular region from the bitmap belonging to this
+ // Splash object to <dest>. The alpha values are corrected for a
+ // non-isolated group.
+ SplashError blitCorrectedAlpha(SplashBitmap *dest, int xSrc, int ySrc,
+ int xDest, int yDest, int w, int h);
+
//----- misc
// Construct a path for a stroke, given the path to be stroked and
@@ -220,8 +224,15 @@ public:
// the current state. If <flatten> is true, this function will
// first flatten the path and handle the linedash.
SplashPath *makeStrokePath(SplashPath *path, SplashCoord w,
+ int lineCap, int lineJoin,
GBool flatten = gTrue);
+ // Reduce the size of a rectangle as much as possible by moving any
+ // edges that are completely outside the clip region. Returns the
+ // clipping status of the resulting rectangle.
+ SplashClipResult limitRectToClipRect(int *xMin, int *yMin,
+ int *xMax, int *yMax);
+
// Return the associated bitmap.
SplashBitmap *getBitmap() { return bitmap; }
@@ -296,7 +307,8 @@ private:
void updateModY(int y);
void strokeNarrow(SplashPath *path);
void drawStrokeSpan(SplashPipe *pipe, int x0, int x1, int y, GBool noClip);
- void strokeWide(SplashPath *path, SplashCoord w);
+ void strokeWide(SplashPath *path, SplashCoord w,
+ int lineCap, int lineJoin);
SplashPath *flattenPath(SplashPath *path, SplashCoord *matrix,
SplashCoord flatness);
void flattenCurve(SplashCoord x0, SplashCoord y0,
@@ -407,10 +419,10 @@ private:
int bitmapComps;
SplashState *state;
Guchar *scanBuf;
+ Guchar *scanBuf2;
SplashBitmap // for transparency groups, this is the bitmap
*groupBackBitmap; // containing the alpha0/color0 values
int groupBackX, groupBackY; // offset within groupBackBitmap
- Guchar aaGamma[256];
SplashCoord minLineWidth;
int modXMin, modYMin, modXMax, modYMax;
SplashClipResult opClipRes;
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc
index 3606a917beb..32ecc3fdd03 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc
@@ -15,6 +15,7 @@
#include <stdio.h>
#include <limits.h>
#include "gmem.h"
+#include "gmempp.h"
#include "SplashErrorCodes.h"
#include "SplashBitmap.h"
@@ -154,7 +155,18 @@ SplashError SplashBitmap::writePNMFile(FILE *f) {
#if SPLASH_CMYK
case splashModeCMYK8:
- // PNM doesn't support CMYK
+ fprintf(f, "P7\n");
+ fprintf(f, "WIDTH %d\n", width);
+ fprintf(f, "HEIGHT %d\n", height);
+ fprintf(f, "DEPTH 4\n");
+ fprintf(f, "MAXVAL 255\n");
+ fprintf(f, "TUPLTYPE CMYK\n");
+ fprintf(f, "ENDHDR\n");
+ row = data;
+ for (y = 0; y < height; ++y) {
+ fwrite(row, 1, 4 * width, f);
+ row += rowSize;
+ }
break;
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.cc
index 6865c574f4e..bf7b802cf0d 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.cc
@@ -15,6 +15,7 @@
#include <stdlib.h>
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "SplashErrorCodes.h"
#include "SplashPath.h"
#include "SplashXPath.h"
@@ -52,6 +53,8 @@ SplashClip::SplashClip(int hardXMinA, int hardYMinA,
eo = NULL;
scanners = NULL;
length = size = 0;
+ isSimple = gTrue;
+ prev = NULL;
if ((w = hardXMax + 1) <= 0) {
w = 1;
}
@@ -59,7 +62,7 @@ SplashClip::SplashClip(int hardXMinA, int hardYMinA,
}
SplashClip::SplashClip(SplashClip *clip) {
- int w, i;
+ int w;
hardXMin = clip->hardXMin;
hardYMin = clip->hardYMin;
@@ -75,17 +78,12 @@ SplashClip::SplashClip(SplashClip *clip) {
yMaxI = clip->yMaxI;
intBoundsValid = clip->intBoundsValid;
intBoundsStrokeAdjust = clip->intBoundsStrokeAdjust;
- length = clip->length;
- size = clip->size;
- paths = (SplashXPath **)gmallocn(size, sizeof(SplashXPath *));
- eo = (Guchar *)gmallocn(size, sizeof(Guchar));
- scanners = (SplashXPathScanner **)
- gmallocn(size, sizeof(SplashXPathScanner *));
- for (i = 0; i < length; ++i) {
- paths[i] = clip->paths[i]->copy();
- eo[i] = clip->eo[i];
- scanners[i] = new SplashXPathScanner(paths[i], eo[i], yMinI, yMaxI);
- }
+ paths = NULL;
+ eo = NULL;
+ scanners = NULL;
+ length = size = 0;
+ isSimple = clip->isSimple;
+ prev = clip;
if ((w = splashCeil(xMax)) <= 0) {
w = 1;
}
@@ -96,8 +94,8 @@ SplashClip::~SplashClip() {
int i;
for (i = 0; i < length; ++i) {
- delete paths[i];
delete scanners[i];
+ delete paths[i];
}
gfree(paths);
gfree(eo);
@@ -136,6 +134,8 @@ void SplashClip::resetToRect(SplashCoord x0, SplashCoord y0,
eo = NULL;
scanners = NULL;
length = size = 0;
+ isSimple = gTrue;
+ prev = NULL;
if (x0 < x1) {
xMin = x0;
@@ -202,11 +202,15 @@ SplashError SplashClip::clipToRect(SplashCoord x0, SplashCoord y0,
}
SplashError SplashClip::clipToPath(SplashPath *path, SplashCoord *matrix,
- SplashCoord flatness, GBool eoA) {
+ SplashCoord flatness, GBool eoA,
+ GBool enablePathSimplification,
+ SplashStrokeAdjustMode strokeAdjust) {
SplashXPath *xPath;
SplashCoord t;
- xPath = new SplashXPath(path, matrix, flatness, gTrue);
+ xPath = new SplashXPath(path, matrix, flatness, gTrue,
+ enablePathSimplification,
+ strokeAdjust);
// check for an empty path
if (xPath->length == 0) {
@@ -218,33 +222,8 @@ SplashError SplashClip::clipToPath(SplashPath *path, SplashCoord *matrix,
}
// check for a rectangle
- if (xPath->length == 4 &&
- xPath->segs[0].y0 == xPath->segs[0].y1 &&
- xPath->segs[1].x0 == xPath->segs[1].x1 &&
- xPath->segs[2].x0 == xPath->segs[2].x1 &&
- xPath->segs[3].y0 == xPath->segs[3].y1) {
- clipToRect(xPath->segs[1].x0, xPath->segs[0].y0,
- xPath->segs[2].x0, xPath->segs[3].y0);
- delete xPath;
- return splashOk;
- }
- if (xPath->length == 4 &&
- xPath->segs[0].x0 == xPath->segs[0].x1 &&
- xPath->segs[1].y0 == xPath->segs[1].y1 &&
- xPath->segs[2].x0 == xPath->segs[2].x1 &&
- xPath->segs[3].y0 == xPath->segs[3].y1) {
- clipToRect(xPath->segs[0].x0, xPath->segs[1].y0,
- xPath->segs[2].x0, xPath->segs[3].y0);
- delete xPath;
- return splashOk;
- }
- if (xPath->length == 4 &&
- xPath->segs[0].x0 == xPath->segs[0].x1 &&
- xPath->segs[1].x0 == xPath->segs[1].x1 &&
- xPath->segs[2].y0 == xPath->segs[2].y1 &&
- xPath->segs[3].y0 == xPath->segs[3].y1) {
- clipToRect(xPath->segs[0].x0, xPath->segs[2].y0,
- xPath->segs[1].x0, xPath->segs[3].y0);
+ if (xPath->isRect) {
+ clipToRect(xPath->rectX0, xPath->rectY0, xPath->rectX1, xPath->rectY1);
delete xPath;
return splashOk;
}
@@ -268,13 +247,14 @@ SplashError SplashClip::clipToPath(SplashPath *path, SplashCoord *matrix,
scanners[length] = new SplashXPathScanner(xPath, eoA, splashFloor(yMin),
splashCeil(yMax) - 1);
++length;
+ isSimple = gFalse;
return splashOk;
}
SplashClipResult SplashClip::testRect(int rectXMin, int rectYMin,
int rectXMax, int rectYMax,
- GBool strokeAdjust) {
+ SplashStrokeAdjustMode strokeAdjust) {
// In general, this function tests the rectangle:
// x = [rectXMin, rectXMax + 1) (note: coords are ints)
// y = [rectYMin, rectYMax + 1)
@@ -282,7 +262,7 @@ SplashClipResult SplashClip::testRect(int rectXMin, int rectYMin,
// x = [xMin, xMax) (note: coords are fp)
// y = [yMin, yMax)
- if (strokeAdjust && length == 0) {
+ if (strokeAdjust != splashStrokeAdjustOff && isSimple) {
// special case for stroke adjustment with a simple clipping
// rectangle -- the clipping region is:
// x = [xMinI, xMaxI + 1)
@@ -313,7 +293,7 @@ SplashClipResult SplashClip::testRect(int rectXMin, int rectYMin,
(SplashCoord)rectYMin >= yMax) {
return splashClipAllOutside;
}
- if (length == 0 &&
+ if (isSimple &&
(SplashCoord)rectXMin >= xMin &&
(SplashCoord)(rectXMax + 1) <= xMax &&
(SplashCoord)rectYMin >= yMin &&
@@ -325,9 +305,10 @@ SplashClipResult SplashClip::testRect(int rectXMin, int rectYMin,
}
void SplashClip::clipSpan(Guchar *line, int y, int x0, int x1,
- GBool strokeAdjust) {
+ SplashStrokeAdjustMode strokeAdjust) {
+ SplashClip *clip;
SplashCoord d;
- int x0a, x1a, x, i;
+ int x0a, x1a, x0b, x1b, x, i;
updateIntBounds(strokeAdjust);
@@ -360,7 +341,7 @@ void SplashClip::clipSpan(Guchar *line, int y, int x0, int x1,
//--- clip to the floating point rectangle
// (if stroke adjustment is disabled)
- if (!strokeAdjust) {
+ if (strokeAdjust == splashStrokeAdjustOff) {
// clip left edge (xMin)
if (x0a == xMinI) {
@@ -391,22 +372,31 @@ void SplashClip::clipSpan(Guchar *line, int y, int x0, int x1,
}
}
- if (length == 0) {
+ if (isSimple) {
return;
}
//--- clip to the paths
- for (i = 0; i < length; ++i) {
- scanners[i]->getSpan(buf, y, x0a, x1a);
- for (x = x0a; x <= x1a; ++x) {
- line[x] = mul255(line[x], buf[x]);
+ for (clip = this; clip; clip = clip->prev) {
+ for (i = 0; i < clip->length; ++i) {
+ clip->scanners[i]->getSpan(buf, y, x0a, x1a, &x0b, &x1b);
+ if (x0a < x0b) {
+ memset(line + x0a, 0, x0b - x0a);
+ }
+ for (x = x0b; x <= x1b; ++x) {
+ line[x] = mul255(line[x], buf[x]);
+ }
+ if (x1b < x1a) {
+ memset(line + x1b + 1, 0, x1a - x1b);
+ }
}
}
}
GBool SplashClip::clipSpanBinary(Guchar *line, int y, int x0, int x1,
- GBool strokeAdjust) {
+ SplashStrokeAdjustMode strokeAdjust) {
+ SplashClip *clip;
int x0a, x1a, x0b, x1b, x, i;
Guchar any;
@@ -438,7 +428,7 @@ GBool SplashClip::clipSpanBinary(Guchar *line, int y, int x0, int x1,
return gFalse;
}
- if (length == 0) {
+ if (isSimple) {
for (x = x0a; x <= x1a; ++x) {
if (line[x]) {
return gTrue;
@@ -448,52 +438,63 @@ GBool SplashClip::clipSpanBinary(Guchar *line, int y, int x0, int x1,
}
any = 0;
- for (i = 0; i < length; ++i) {
- scanners[i]->getSpanBinary(buf, y, x0a, x1a);
- for (x0b = x0a; x0b <= x1a && !buf[x0b]; ++x0b) ;
- if (x0a < x0b) {
- memset(line + x0a, 0, x0b - x0a);
- }
- for (x1b = x1a; x1b >= x0b && !buf[x1b]; --x1b) ;
- if (x1b < x1a) {
- memset(line + x1b + 1, 0, x1a - x1b);
- }
- for (x = x0b; x <= x1b; ++x) {
- line[x] &= buf[x];
- any |= line[x];
+ for (clip = this; clip; clip = clip->prev) {
+ for (i = 0; i < clip->length; ++i) {
+ clip->scanners[i]->getSpanBinary(buf, y, x0a, x1a, &x0b, &x1b);
+ if (x0a < x0b) {
+ memset(line + x0a, 0, x0b - x0a);
+ }
+ for (x = x0b; x <= x1b; ++x) {
+ line[x] &= buf[x];
+ any |= line[x];
+ }
+ if (x1b < x1a) {
+ memset(line + x1b + 1, 0, x1a - x1b);
+ }
}
}
return any != 0;
}
-int SplashClip::getXMinI(GBool strokeAdjust) {
+int SplashClip::getXMinI(SplashStrokeAdjustMode strokeAdjust) {
updateIntBounds(strokeAdjust);
return xMinI;
}
-int SplashClip::getXMaxI(GBool strokeAdjust) {
+int SplashClip::getXMaxI(SplashStrokeAdjustMode strokeAdjust) {
updateIntBounds(strokeAdjust);
return xMaxI;
}
-int SplashClip::getYMinI(GBool strokeAdjust) {
+int SplashClip::getYMinI(SplashStrokeAdjustMode strokeAdjust) {
updateIntBounds(strokeAdjust);
return yMinI;
}
-int SplashClip::getYMaxI(GBool strokeAdjust) {
+int SplashClip::getYMaxI(SplashStrokeAdjustMode strokeAdjust) {
updateIntBounds(strokeAdjust);
return yMaxI;
}
-void SplashClip::updateIntBounds(GBool strokeAdjust) {
+int SplashClip::getNumPaths() {
+ SplashClip *clip;
+ int n;
+
+ n = 0;
+ for (clip = this; clip; clip = clip->prev) {
+ n += clip->length;
+ }
+ return n;
+}
+
+void SplashClip::updateIntBounds(SplashStrokeAdjustMode strokeAdjust) {
if (intBoundsValid && strokeAdjust == intBoundsStrokeAdjust) {
return;
}
- if (strokeAdjust && length == 0) {
- splashStrokeAdjust(xMin, xMax, &xMinI, &xMaxI);
- splashStrokeAdjust(yMin, yMax, &yMinI, &yMaxI);
+ if (strokeAdjust != splashStrokeAdjustOff && isSimple) {
+ splashStrokeAdjust(xMin, xMax, &xMinI, &xMaxI, strokeAdjust);
+ splashStrokeAdjust(yMin, yMax, &yMinI, &yMaxI, strokeAdjust);
} else {
xMinI = splashFloor(xMin);
yMinI = splashFloor(yMin);
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.h
index 42986222976..fb86ed8fd72 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.h
@@ -57,7 +57,9 @@ public:
// Interesect the clip with <path>.
SplashError clipToPath(SplashPath *path, SplashCoord *matrix,
- SplashCoord flatness, GBool eoA);
+ SplashCoord flatness, GBool eoA,
+ GBool enablePathSimplification,
+ SplashStrokeAdjustMode strokeAdjust);
// Tests a rectangle against the clipping region. Returns one of:
// - splashClipAllInside if the entire rectangle is inside the
@@ -70,18 +72,18 @@ public:
// outside the clipping region
SplashClipResult testRect(int rectXMin, int rectYMin,
int rectXMax, int rectYMax,
- GBool strokeAdjust);
+ SplashStrokeAdjustMode strokeAdjust);
// Clip a scan line. Modifies line[] by multiplying with clipping
// shape values for one scan line: ([x0, x1], y).
void clipSpan(Guchar *line, int y, int x0, int x1,
- GBool strokeAdjust);
+ SplashStrokeAdjustMode strokeAdjust);
// Like clipSpan(), but uses the values 0 and 255 only.
// Returns true if there are any non-zero values in the result
// (i.e., returns false if the entire line is clipped out).
GBool clipSpanBinary(Guchar *line, int y, int x0, int x1,
- GBool strokeAdjust);
+ SplashStrokeAdjustMode strokeAdjust);
// Get the rectangle part of the clip region.
SplashCoord getXMin() { return xMin; }
@@ -90,19 +92,19 @@ public:
SplashCoord getYMax() { return yMax; }
// Get the rectangle part of the clip region, in integer coordinates.
- int getXMinI(GBool strokeAdjust);
- int getXMaxI(GBool strokeAdjust);
- int getYMinI(GBool strokeAdjust);
- int getYMaxI(GBool strokeAdjust);
+ int getXMinI(SplashStrokeAdjustMode strokeAdjust);
+ int getXMaxI(SplashStrokeAdjustMode strokeAdjust);
+ int getYMinI(SplashStrokeAdjustMode strokeAdjust);
+ int getYMaxI(SplashStrokeAdjustMode strokeAdjust);
// Get the number of arbitrary paths used by the clip region.
- int getNumPaths() { return length; }
+ int getNumPaths();
private:
SplashClip(SplashClip *clip);
void grow(int nPaths);
- void updateIntBounds(GBool strokeAdjust);
+ void updateIntBounds(SplashStrokeAdjustMode strokeAdjust);
int hardXMin, hardYMin, // coordinates cannot fall outside of
hardXMax, hardYMax; // [hardXMin, hardXMax), [hardYMin, hardYMax)
@@ -120,6 +122,8 @@ private:
Guchar *eo;
SplashXPathScanner **scanners;
int length, size;
+ GBool isSimple;
+ SplashClip *prev;
Guchar *buf;
};
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.cc
index 6fc6b946b65..884092b050c 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.cc
@@ -8,7 +8,7 @@
#include <aconf.h>
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
#ifdef USE_GCC_PRAGMAS
#pragma implementation
@@ -19,6 +19,7 @@
#include FT_SIZES_H
#include FT_GLYPH_H
#include "gmem.h"
+#include "gmempp.h"
#include "SplashMath.h"
#include "SplashGlyphBitmap.h"
#include "SplashPath.h"
@@ -66,6 +67,10 @@ SplashFTFont::SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA,
// if the textMat values are too small, FreeType's fixed point
// arithmetic doesn't work so well
textScale = splashDist(0, 0, textMat[2], textMat[3]) / size;
+ // avoid problems with singular (or close-to-singular) matrices
+ if (textScale < 0.00001) {
+ textScale = 0.00001;
+ }
div = face->bbox.xMax > 20000 ? 65536 : 1;
@@ -220,7 +225,7 @@ GBool SplashFTFont::makeGlyph(int c, int xFrac, int yFrac,
SplashFTFontFile *ff;
FT_Vector offset;
FT_GlyphSlot slot;
- FT_UInt gid;
+ int gid;
FT_Int32 flags;
int rowSize;
Guchar *p, *q;
@@ -235,11 +240,11 @@ GBool SplashFTFont::makeGlyph(int c, int xFrac, int yFrac,
slot = ff->face->glyph;
if (ff->codeToGID && c < ff->codeToGIDLen) {
- gid = (FT_UInt)ff->codeToGID[c];
+ gid = ff->codeToGID[c];
} else {
- gid = (FT_UInt)c;
+ gid = c;
}
- if (ff->trueType && gid < 0) {
+ if (ff->fontType == splashFontTrueType && gid < 0) {
// skip the TrueType notdef glyph
return gFalse;
}
@@ -258,13 +263,19 @@ GBool SplashFTFont::makeGlyph(int c, int xFrac, int yFrac,
flags = FT_LOAD_NO_BITMAP;
if (ff->engine->flags & splashFTNoHinting) {
flags |= FT_LOAD_NO_HINTING;
- } else if (ff->useLightHinting) {
+ } else if (ff->fontType == splashFontType1) {
flags |= FT_LOAD_TARGET_LIGHT;
} else {
flags |= FT_LOAD_NO_AUTOHINT;
}
- if (FT_Load_Glyph(ff->face, gid, flags)) {
- return gFalse;
+ if (FT_Load_Glyph(ff->face, (FT_UInt)gid, flags)) {
+ // fonts with broken hinting instructions can cause errors here;
+ // try again with no hinting (this is probably only relevant for
+ // TrueType fonts)
+ flags = FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING;
+ if (FT_Load_Glyph(ff->face, (FT_UInt)gid, flags)) {
+ return gFalse;
+ }
}
if (FT_Render_Glyph(slot, aa ? FT_RENDER_MODE_NORMAL
: FT_RENDER_MODE_MONO)) {
@@ -321,7 +332,7 @@ SplashPath *SplashFTFont::getGlyphPath(int c) {
SplashFTFontFile *ff;
SplashFTFontPath path;
FT_GlyphSlot slot;
- FT_UInt gid;
+ int gid;
FT_Glyph glyph;
ff = (SplashFTFontFile *)fontFile;
@@ -331,14 +342,20 @@ SplashPath *SplashFTFont::getGlyphPath(int c) {
if (ff->codeToGID && c < ff->codeToGIDLen) {
gid = ff->codeToGID[c];
} else {
- gid = (FT_UInt)c;
+ gid = c;
}
- if (ff->trueType && gid < 0) {
+ if (ff->fontType == splashFontTrueType && gid < 0) {
// skip the TrueType notdef glyph
return NULL;
}
- if (FT_Load_Glyph(ff->face, gid, FT_LOAD_NO_BITMAP)) {
- return NULL;
+ if (FT_Load_Glyph(ff->face, (FT_UInt)gid, FT_LOAD_NO_BITMAP)) {
+ // fonts with broken hinting instructions can cause errors here;
+ // try again with no hinting (this is probably only relevant for
+ // TrueType fonts)
+ if (FT_Load_Glyph(ff->face, (FT_UInt)gid,
+ FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING)) {
+ return NULL;
+ }
}
if (FT_Get_Glyph(slot, &glyph)) {
return NULL;
@@ -429,4 +446,4 @@ static int glyphPathCubicTo(const FT_Vector *ctrl1, const FT_Vector *ctrl2,
return 0;
}
-#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#endif // HAVE_FREETYPE_H
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.h
index 560b74c3bfe..ac08b007747 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.h
@@ -11,7 +11,7 @@
#include <aconf.h>
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
#ifdef USE_GCC_PRAGMAS
#pragma interface
@@ -55,6 +55,6 @@ private:
SplashCoord textScale;
};
-#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#endif // HAVE_FREETYPE_H
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.cc
index 3ba033c9db3..33939541051 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.cc
@@ -8,7 +8,7 @@
#include <aconf.h>
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
#ifdef USE_GCC_PRAGMAS
#pragma implementation
@@ -19,6 +19,7 @@
# include <unistd.h>
#endif
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "gfile.h"
#include "FoFiTrueType.h"
@@ -87,13 +88,13 @@ SplashFontFile *SplashFTFontEngine::loadType1Font(SplashFontFileID *idA,
GBool deleteFile,
#endif
const char **enc) {
- return SplashFTFontFile::loadType1Font(this, idA,
+ return SplashFTFontFile::loadType1Font(this, idA, splashFontType1,
#if LOAD_FONTS_FROM_MEM
fontBuf,
#else
fileName, deleteFile,
#endif
- enc, gTrue);
+ enc);
}
SplashFontFile *SplashFTFontEngine::loadType1CFont(SplashFontFileID *idA,
@@ -104,13 +105,13 @@ SplashFontFile *SplashFTFontEngine::loadType1CFont(SplashFontFileID *idA,
GBool deleteFile,
#endif
const char **enc) {
- return SplashFTFontFile::loadType1Font(this, idA,
+ return SplashFTFontFile::loadType1Font(this, idA, splashFontType1C,
#if LOAD_FONTS_FROM_MEM
fontBuf,
#else
fileName, deleteFile,
#endif
- enc, gFalse);
+ enc);
}
SplashFontFile *SplashFTFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA,
@@ -143,8 +144,8 @@ SplashFontFile *SplashFTFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA,
fontBuf2 = new GString();
ff->convertToType1(NULL, enc, gFalse, &gstringWrite, fontBuf2);
delete ff;
- ret = SplashFTFontFile::loadType1Font(this, idA, fontBuf2, enc,
- gFalse);
+ ret = SplashFTFontFile::loadType1Font(this, idA, splashFontType1,
+ fontBuf2, enc);
if (ret) {
delete fontBuf;
} else {
@@ -159,8 +160,9 @@ SplashFontFile *SplashFTFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA,
ff->convertToType1(NULL, enc, gFalse, &fileWrite, tmpFile);
delete ff;
fclose(tmpFile);
- ret = SplashFTFontFile::loadType1Font(this, idA, tmpFileName->getCString(),
- gTrue, enc, gFalse);
+ ret = SplashFTFontFile::loadType1Font(this, idA, splashFontType1,
+ tmpFileName->getCString(),
+ gTrue, enc);
if (ret) {
if (deleteFile) {
unlink(fileName);
@@ -172,32 +174,36 @@ SplashFontFile *SplashFTFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA,
#endif
} else {
delete ff;
- ret = SplashFTFontFile::loadType1Font(this, idA,
+ ret = SplashFTFontFile::loadType1Font(this, idA, splashFontOpenTypeT1C,
#if LOAD_FONTS_FROM_MEM
fontBuf,
#else
fileName, deleteFile,
#endif
- enc, gFalse);
+ enc);
}
return ret;
}
SplashFontFile *SplashFTFontEngine::loadCIDFont(SplashFontFileID *idA,
#if LOAD_FONTS_FROM_MEM
- GString *fontBuf
+ GString *fontBuf,
#else
char *fileName,
- GBool deleteFile
+ GBool deleteFile,
#endif
- ) {
+ int *codeToGID,
+ int codeToGIDLen) {
FoFiType1C *ff;
int *cidToGIDMap;
int nCIDs;
SplashFontFile *ret;
// check for a CFF font
- if (useCIDs) {
+ if (codeToGID) {
+ cidToGIDMap = NULL;
+ nCIDs = 0;
+ } else if (useCIDs) {
cidToGIDMap = NULL;
nCIDs = 0;
#if LOAD_FONTS_FROM_MEM
@@ -212,13 +218,14 @@ SplashFontFile *SplashFTFontEngine::loadCIDFont(SplashFontFileID *idA,
cidToGIDMap = NULL;
nCIDs = 0;
}
- ret = SplashFTFontFile::loadCIDFont(this, idA,
+ ret = SplashFTFontFile::loadCIDFont(this, idA, splashFontCID,
#if LOAD_FONTS_FROM_MEM
fontBuf,
#else
fileName, deleteFile,
#endif
- cidToGIDMap, nCIDs);
+ codeToGID ? codeToGID : cidToGIDMap,
+ codeToGID ? codeToGIDLen : nCIDs);
if (!ret) {
gfree(cidToGIDMap);
}
@@ -266,8 +273,8 @@ SplashFontFile *SplashFTFontEngine::loadOpenTypeCFFFont(SplashFontFileID *idA,
if (!useCIDs) {
cidToGIDMap = ff->getCIDToGIDMap(&nCIDs);
}
- ret = SplashFTFontFile::loadCIDFont(this, idA, fontBuf2,
- cidToGIDMap, nCIDs);
+ ret = SplashFTFontFile::loadCIDFont(this, idA, splashFontOpenTypeCFF,
+ fontBuf2, cidToGIDMap, nCIDs);
if (ret) {
delete fontBuf;
} else {
@@ -284,7 +291,7 @@ SplashFontFile *SplashFTFontEngine::loadOpenTypeCFFFont(SplashFontFileID *idA,
if (!useCIDs) {
cidToGIDMap = ff->getCIDToGIDMap(&nCIDs);
}
- ret = SplashFTFontFile::loadCIDFont(this, idA,
+ ret = SplashFTFontFile::loadCIDFont(this, idA, splashFontOpenTypeCFF,
tmpFileName->getCString(), gTrue,
cidToGIDMap, nCIDs);
if (ret) {
@@ -300,7 +307,7 @@ SplashFontFile *SplashFTFontEngine::loadOpenTypeCFFFont(SplashFontFileID *idA,
if (!codeToGID && !useCIDs && ff->isOpenTypeCFF()) {
cidToGIDMap = ff->getCIDToGIDMap(&nCIDs);
}
- ret = SplashFTFontFile::loadCIDFont(this, idA,
+ ret = SplashFTFontFile::loadCIDFont(this, idA, splashFontOpenTypeCFF,
#if LOAD_FONTS_FROM_MEM
fontBuf,
#else
@@ -356,7 +363,7 @@ SplashFontFile *SplashFTFontEngine::loadTrueTypeFont(SplashFontFileID *idA,
fclose(tmpFile);
#endif
delete ff;
- ret = SplashFTFontFile::loadTrueTypeFont(this, idA,
+ ret = SplashFTFontFile::loadTrueTypeFont(this, idA, splashFontTrueType,
#if LOAD_FONTS_FROM_MEM
fontBuf2,
#else
@@ -382,4 +389,4 @@ SplashFontFile *SplashFTFontEngine::loadTrueTypeFont(SplashFontFileID *idA,
return ret;
}
-#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#endif // HAVE_FREETYPE_H
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.h
index 37e882007fe..24db3c6cdba 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.h
@@ -11,7 +11,7 @@
#include <aconf.h>
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
#ifdef USE_GCC_PRAGMAS
#pragma interface
@@ -60,11 +60,11 @@ public:
const char **enc);
SplashFontFile *loadCIDFont(SplashFontFileID *idA,
#if LOAD_FONTS_FROM_MEM
- GString *fontBuf
+ GString *fontBuf,
#else
- char *fileName, GBool deleteFile
+ char *fileName, GBool deleteFile,
#endif
- );
+ int *codeToGID, int codeToGIDLen);
SplashFontFile *loadOpenTypeCFFFont(SplashFontFileID *idA,
#if LOAD_FONTS_FROM_MEM
GString *fontBuf,
@@ -94,6 +94,6 @@ private:
friend class SplashFTFont;
};
-#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#endif // HAVE_FREETYPE_H
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.cc
index 5b01fcf490c..b5fd02af4a0 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.cc
@@ -8,13 +8,14 @@
#include <aconf.h>
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "SplashFTFontEngine.h"
#include "SplashFTFont.h"
@@ -26,14 +27,14 @@
SplashFontFile *SplashFTFontFile::loadType1Font(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
+ SplashFontType fontTypeA,
#if LOAD_FONTS_FROM_MEM
GString *fontBufA,
#else
char *fileNameA,
GBool deleteFileA,
#endif
- const char **encA,
- GBool useLightHintingA) {
+ const char **encA) {
FT_Face faceA;
int *codeToGIDA;
const char *name;
@@ -55,18 +56,18 @@ SplashFontFile *SplashFTFontFile::loadType1Font(SplashFTFontEngine *engineA,
}
}
- return new SplashFTFontFile(engineA, idA,
+ return new SplashFTFontFile(engineA, idA, fontTypeA,
#if LOAD_FONTS_FROM_MEM
fontBufA,
#else
fileNameA, deleteFileA,
#endif
- faceA, codeToGIDA, 256,
- gFalse, useLightHintingA);
+ faceA, codeToGIDA, 256);
}
SplashFontFile *SplashFTFontFile::loadCIDFont(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
+ SplashFontType fontTypeA,
#if LOAD_FONTS_FROM_MEM
GString *fontBufA,
#else
@@ -86,18 +87,18 @@ SplashFontFile *SplashFTFontFile::loadCIDFont(SplashFTFontEngine *engineA,
return NULL;
}
- return new SplashFTFontFile(engineA, idA,
+ return new SplashFTFontFile(engineA, idA, fontTypeA,
#if LOAD_FONTS_FROM_MEM
fontBufA,
#else
fileNameA, deleteFileA,
#endif
- faceA, codeToGIDA, codeToGIDLenA,
- gFalse, gFalse);
+ faceA, codeToGIDA, codeToGIDLenA);
}
SplashFontFile *SplashFTFontFile::loadTrueTypeFont(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
+ SplashFontType fontTypeA,
#if LOAD_FONTS_FROM_MEM
GString *fontBufA,
#else
@@ -118,38 +119,35 @@ SplashFontFile *SplashFTFontFile::loadTrueTypeFont(SplashFTFontEngine *engineA,
return NULL;
}
- return new SplashFTFontFile(engineA, idA,
+ return new SplashFTFontFile(engineA, idA, fontTypeA,
#if LOAD_FONTS_FROM_MEM
fontBufA,
#else
fileNameA, deleteFileA,
#endif
- faceA, codeToGIDA, codeToGIDLenA,
- gTrue, gFalse);
+ faceA, codeToGIDA, codeToGIDLenA);
}
SplashFTFontFile::SplashFTFontFile(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
+ SplashFontType fontTypeA,
#if LOAD_FONTS_FROM_MEM
GString *fontBufA,
#else
char *fileNameA, GBool deleteFileA,
#endif
FT_Face faceA,
- int *codeToGIDA, int codeToGIDLenA,
- GBool trueTypeA, GBool useLightHintingA):
+ int *codeToGIDA, int codeToGIDLenA):
#if LOAD_FONTS_FROM_MEM
- SplashFontFile(idA, fontBufA)
+ SplashFontFile(idA, fontTypeA, fontBufA)
#else
- SplashFontFile(idA, fileNameA, deleteFileA)
+ SplashFontFile(idA, fontTypeA, fileNameA, deleteFileA)
#endif
{
engine = engineA;
face = faceA;
codeToGID = codeToGIDA;
codeToGIDLen = codeToGIDLenA;
- trueType = trueTypeA;
- useLightHinting = useLightHintingA;
}
SplashFTFontFile::~SplashFTFontFile() {
@@ -170,4 +168,4 @@ SplashFont *SplashFTFontFile::makeFont(SplashCoord *mat,
return font;
}
-#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#endif // HAVE_FREETYPE_H
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.h
index 21fa517a594..3a6b9b7aa43 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.h
@@ -11,7 +11,7 @@
#include <aconf.h>
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
#ifdef USE_GCC_PRAGMAS
#pragma interface
@@ -33,15 +33,16 @@ public:
static SplashFontFile *loadType1Font(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
+ SplashFontType fontTypeA,
#if LOAD_FONTS_FROM_MEM
GString *fontBufA,
#else
char *fileNameA, GBool deleteFileA,
#endif
- const char **encA,
- GBool useLightHintingA);
+ const char **encA);
static SplashFontFile *loadCIDFont(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
+ SplashFontType fontTypeA,
#if LOAD_FONTS_FROM_MEM
GString *fontBufA,
#else
@@ -50,6 +51,7 @@ public:
int *codeToGIDA, int codeToGIDLenA);
static SplashFontFile *loadTrueTypeFont(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
+ SplashFontType fontTypeA,
#if LOAD_FONTS_FROM_MEM
GString *fontBufA,
#else
@@ -71,25 +73,23 @@ private:
SplashFTFontFile(SplashFTFontEngine *engineA,
SplashFontFileID *idA,
+ SplashFontType fontTypeA,
#if LOAD_FONTS_FROM_MEM
GString *fontBufA,
#else
char *fileNameA, GBool deleteFileA,
#endif
FT_Face faceA,
- int *codeToGIDA, int codeToGIDLenA,
- GBool trueTypeA, GBool useLightHintingA);
+ int *codeToGIDA, int codeToGIDLenA);
SplashFTFontEngine *engine;
FT_Face face;
int *codeToGID;
int codeToGIDLen;
- GBool trueType;
- GBool useLightHinting;
friend class SplashFTFont;
};
-#endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#endif // HAVE_FREETYPE_H
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.cc
index 37a320050be..add34311756 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.cc
@@ -14,6 +14,7 @@
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "SplashMath.h"
#include "SplashGlyphBitmap.h"
#include "SplashFontFile.h"
@@ -66,6 +67,12 @@ void SplashFont::initCache() {
// deal with rounding errors
glyphW = xMax - xMin + 3;
glyphH = yMax - yMin + 3;
+ if (glyphW > 1000 || glyphH > 1000) {
+ // if the glyphs are too large, don't cache them -- setting the
+ // cache bitmap size to something tiny will cause getGlyph() to
+ // fall back to the uncached case
+ glyphW = glyphH = 1;
+ }
if (aa) {
glyphSize = glyphW * glyphH;
} else {
@@ -76,7 +83,7 @@ void SplashFont::initCache() {
cacheAssoc = splashFontCacheAssoc;
for (cacheSets = splashFontCacheMaxSets;
cacheSets > 1 &&
- cacheSets * cacheAssoc * glyphSize > splashFontCacheSize;
+ glyphSize > splashFontCacheSize / (cacheSets * cacheAssoc);
cacheSets >>= 1) ;
cache = (Guchar *)gmallocn(cacheSets * cacheAssoc, glyphSize);
cacheTags = (SplashFontCacheTag *)gmallocn(cacheSets * cacheAssoc,
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.h
index 3d151122a14..2bb96545867 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.h
@@ -17,6 +17,7 @@
#include "gtypes.h"
#include "SplashTypes.h"
+#include "SplashMath.h"
struct SplashGlyphBitmap;
struct SplashFontCacheTag;
@@ -54,10 +55,14 @@ public:
GBool matches(SplashFontFile *fontFileA, SplashCoord *matA,
SplashCoord *textMatA) {
return fontFileA == fontFile &&
- matA[0] == mat[0] && matA[1] == mat[1] &&
- matA[2] == mat[2] && matA[3] == mat[3] &&
- textMatA[0] == textMat[0] && textMatA[1] == textMat[1] &&
- textMatA[2] == textMat[2] && textMatA[3] == textMat[3];
+ splashAbs(matA[0] - mat[0]) < 0.0001 &&
+ splashAbs(matA[1] - mat[1]) < 0.0001 &&
+ splashAbs(matA[2] - mat[2]) < 0.0001 &&
+ splashAbs(matA[3] - mat[3]) < 0.0001 &&
+ splashAbs(textMatA[0] - textMat[0]) < 0.0001 &&
+ splashAbs(textMatA[1] - textMat[1]) < 0.0001 &&
+ splashAbs(textMatA[2] - textMat[2]) < 0.0001 &&
+ splashAbs(textMatA[3] - textMat[3]) < 0.0001;
}
// Get a glyph - this does a cache lookup first, and if not found,
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc
index d4673a7a7c4..e435fe80c9a 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc
@@ -18,6 +18,7 @@
# include <unistd.h>
#endif
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "SplashMath.h"
#include "SplashFTFontEngine.h"
@@ -37,7 +38,7 @@ extern "C" int unlink(char *filename);
//------------------------------------------------------------------------
SplashFontEngine::SplashFontEngine(
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
GBool enableFreeType,
Guint freeTypeFlags,
#endif
@@ -48,7 +49,7 @@ SplashFontEngine::SplashFontEngine(
fontCache[i] = NULL;
}
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
if (enableFreeType) {
ftEngine = SplashFTFontEngine::init(aa, freeTypeFlags);
} else {
@@ -66,7 +67,7 @@ SplashFontEngine::~SplashFontEngine() {
}
}
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
if (ftEngine) {
delete ftEngine;
}
@@ -99,7 +100,7 @@ SplashFontFile *SplashFontEngine::loadType1Font(SplashFontFileID *idA,
SplashFontFile *fontFile;
fontFile = NULL;
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
if (!fontFile && ftEngine) {
fontFile = ftEngine->loadType1Font(idA,
#if LOAD_FONTS_FROM_MEM
@@ -135,7 +136,7 @@ SplashFontFile *SplashFontEngine::loadType1CFont(SplashFontFileID *idA,
SplashFontFile *fontFile;
fontFile = NULL;
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
if (!fontFile && ftEngine) {
fontFile = ftEngine->loadType1CFont(idA,
#if LOAD_FONTS_FROM_MEM
@@ -171,7 +172,7 @@ SplashFontFile *SplashFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA,
SplashFontFile *fontFile;
fontFile = NULL;
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
if (!fontFile && ftEngine) {
fontFile = ftEngine->loadOpenTypeT1CFont(idA,
#if LOAD_FONTS_FROM_MEM
@@ -198,24 +199,25 @@ SplashFontFile *SplashFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA,
SplashFontFile *SplashFontEngine::loadCIDFont(SplashFontFileID *idA,
#if LOAD_FONTS_FROM_MEM
- GString *fontBuf
+ GString *fontBuf,
#else
char *fileName,
- GBool deleteFile
+ GBool deleteFile,
#endif
- ) {
+ int *codeToGID,
+ int codeToGIDLen) {
SplashFontFile *fontFile;
fontFile = NULL;
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
if (!fontFile && ftEngine) {
fontFile = ftEngine->loadCIDFont(idA,
#if LOAD_FONTS_FROM_MEM
- fontBuf
+ fontBuf,
#else
- fileName, deleteFile
+ fileName, deleteFile,
#endif
- );
+ codeToGID, codeToGIDLen);
}
#endif
@@ -244,7 +246,7 @@ SplashFontFile *SplashFontEngine::loadOpenTypeCFFFont(SplashFontFileID *idA,
SplashFontFile *fontFile;
fontFile = NULL;
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
if (!fontFile && ftEngine) {
fontFile = ftEngine->loadOpenTypeCFFFont(idA,
#if LOAD_FONTS_FROM_MEM
@@ -283,7 +285,7 @@ SplashFontFile *SplashFontEngine::loadTrueTypeFont(SplashFontFileID *idA,
SplashFontFile *fontFile;
fontFile = NULL;
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
if (!fontFile && ftEngine) {
fontFile = ftEngine->loadTrueTypeFont(idA,
#if LOAD_FONTS_FROM_MEM
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h
index 43eb6d3eb48..ac2558ee52d 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h
@@ -29,7 +29,7 @@ class SplashFont;
#define splashFontCacheSize 16
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
#define splashFTNoHinting (1 << 0)
#endif
@@ -42,7 +42,7 @@ public:
// Create a font engine.
SplashFontEngine(
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
GBool enableFreeType,
Guint freeTypeFlags,
#endif
@@ -78,11 +78,11 @@ public:
const char **enc);
SplashFontFile *loadCIDFont(SplashFontFileID *idA,
#if LOAD_FONTS_FROM_MEM
- GString *fontBuf
+ GString *fontBuf,
#else
- char *fileName, GBool deleteFile
+ char *fileName, GBool deleteFile,
#endif
- );
+ int *codeToGID, int codeToGIDLen);
SplashFontFile *loadOpenTypeCFFFont(SplashFontFileID *idA,
#if LOAD_FONTS_FROM_MEM
GString *fontBuf,
@@ -115,7 +115,7 @@ private:
SplashFont *fontCache[splashFontCacheSize];
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
SplashFTFontEngine *ftEngine;
#endif
};
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.cc
index d0e36a20c49..2d260e38239 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.cc
@@ -16,6 +16,7 @@
#ifndef _WIN32
# include <unistd.h>
#endif
+#include "gmempp.h"
#include "GString.h"
#include "SplashFontFile.h"
#include "SplashFontFileID.h"
@@ -31,6 +32,7 @@ extern "C" int unlink(char *filename);
//------------------------------------------------------------------------
SplashFontFile::SplashFontFile(SplashFontFileID *idA,
+ SplashFontType fontTypeA,
#if LOAD_FONTS_FROM_MEM
GString *fontBufA
#else
@@ -38,6 +40,7 @@ SplashFontFile::SplashFontFile(SplashFontFileID *idA,
#endif
) {
id = idA;
+ fontType = fontTypeA;
#if LOAD_FONTS_FROM_MEM
fontBuf = fontBufA;
#else
@@ -60,11 +63,22 @@ SplashFontFile::~SplashFontFile() {
}
void SplashFontFile::incRefCnt() {
+#if MULTITHREADED
+ gAtomicIncrement(&refCnt);
+#else
++refCnt;
+#endif
}
void SplashFontFile::decRefCnt() {
- if (!--refCnt) {
+ GBool done;
+
+#if MULTITHREADED
+ done = gAtomicDecrement(&refCnt) == 0;
+#else
+ done = --refCnt == 0;
+#endif
+ if (done) {
delete this;
}
}
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.h
index 5f53eced170..133e6ab87dc 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.h
@@ -18,12 +18,30 @@
#include "gtypes.h"
#include "SplashTypes.h"
+#if MULTITHREADED
+#include "GMutex.h"
+#endif
+
class GString;
class SplashFontEngine;
class SplashFont;
class SplashFontFileID;
//------------------------------------------------------------------------
+// SplashFontType
+//------------------------------------------------------------------------
+
+enum SplashFontType {
+ splashFontType1, // GfxFontType.fontType1
+ splashFontType1C, // GfxFontType.fontType1C
+ splashFontOpenTypeT1C, // GfxFontType.fontType1COT
+ splashFontCID, // GfxFontType.fontCIDType0/fontCIDType0C
+ splashFontOpenTypeCFF, // GfxFontType.fontCIDType0COT
+ splashFontTrueType // GfxFontType.fontTrueType/fontTrueTypeOT/
+ // fontCIDType2/fontCIDType2OT
+};
+
+//------------------------------------------------------------------------
// SplashFontFile
//------------------------------------------------------------------------
@@ -49,6 +67,7 @@ public:
protected:
SplashFontFile(SplashFontFileID *idA,
+ SplashFontType fontTypeA,
#if LOAD_FONTS_FROM_MEM
GString *fontBufA
#else
@@ -57,13 +76,18 @@ protected:
);
SplashFontFileID *id;
+ SplashFontType fontType;
#if LOAD_FONTS_FROM_MEM
GString *fontBuf;
#else
GString *fileName;
GBool deleteFile;
#endif
+#if MULTITHREADED
+ GAtomicCounter refCnt;
+#else
int refCnt;
+#endif
friend class SplashFontEngine;
};
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.cc
index 327484788f6..27f52031d50 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.cc
@@ -12,6 +12,7 @@
#pragma implementation
#endif
+#include "gmempp.h"
#include "SplashFontFileID.h"
//------------------------------------------------------------------------
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h
index 4b7ab1fdfbd..b57c8fdacc5 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h
@@ -12,9 +12,13 @@
#include <aconf.h>
#if USE_FIXEDPONT
-#include "FixedPoint.h"
+# include "FixedPoint.h"
#else
-#include <math.h>
+# include <math.h>
+# if (defined(__GNUC__) && defined(__SSE2__)) || \
+ (defined(_WIN32) && (_M_IX86_FP == 2 || defined(_M_X64)))
+# include <emmintrin.h>
+# endif
#endif
#include "SplashTypes.h"
@@ -26,14 +30,40 @@ static inline SplashCoord splashAbs(SplashCoord x) {
#endif
}
+// floor() and (int)() are implemented separately, which results
+// in changing the FPCW multiple times - so we optimize it with
+// some inline assembly or SSE intrinsics.
static inline int splashFloor(SplashCoord x) {
#if USE_FIXEDPOINT
+
+ //--- fixed point
+
return FixedPoint::floor(x);
-#else
-#if __GNUC__ && __i386__
- // floor() and (int)() are implemented separately, which results
- // in changing the FPCW multiple times - so we optimize it with
- // some inline assembly
+
+#elif (defined(__GNUC__) && defined(__SSE2__)) || \
+ (defined(_WIN32) && (_M_IX86_FP == 2 || defined(_M_X64)))
+
+ //--- SSE2 intrinsics
+ // 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
+
+#elif defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__)
+
+ //--- x87 inline assembly (gcc/clang)
+ // (this code fails on OSX for reasons I don't understand)
+
Gushort oldCW, newCW, t;
int result;
@@ -48,10 +78,11 @@ static inline int splashFloor(SplashCoord x) {
: "=m" (oldCW), "=m" (newCW), "=m" (result), "=r" (t)
: "t" (x));
return result;
+
#elif defined(_WIN32) && defined(_M_IX86)
- // floor() and (int)() are implemented separately, which results
- // in changing the FPCW multiple times - so we optimize it with
- // some inline assembly
+
+ //--- x87 inline assembly (VC)
+
Gushort oldCW, newCW;
int result;
@@ -65,20 +96,50 @@ static inline int splashFloor(SplashCoord x) {
__asm fistp DWORD PTR result
__asm fldcw WORD PTR oldCW
return result;
+
#else
+
+ //--- all others
+
return (int)floor(x);
-#endif
+
#endif
}
+// ceil() and (int)() are implemented separately, which results
+// in changing the FPCW multiple times - so we optimize it with
+// some inline assembly or SSE intrinsics.
static inline int splashCeil(SplashCoord x) {
#if USE_FIXEDPOINT
+
+ //--- fixed point
+
return FixedPoint::ceil(x);
-#else
-#if __GNUC__ && __i386__
- // ceil() and (int)() are implemented separately, which results
- // in changing the FPCW multiple times - so we optimize it with
- // some inline assembly
+
+#elif (defined(__GNUC__) && defined(__SSE2__)) || \
+ (defined(_WIN32) && (_M_IX86_FP == 2 || defined(_M_X64)))
+
+ //--- SSE2 intrinsics
+ // 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
+
+#elif defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__)
+
+ //--- x87 inline assembly (gcc/clang)
+ // (this code fails on OSX for reasons I don't understand)
+
Gushort oldCW, newCW, t;
int result;
@@ -93,7 +154,11 @@ static inline int splashCeil(SplashCoord x) {
: "=m" (oldCW), "=m" (newCW), "=m" (result), "=r" (t)
: "t" (x));
return result;
+
#elif defined(_WIN32) && defined(_M_IX86)
+
+ //--- x87 inline assembly (VC)
+
// ceil() and (int)() are implemented separately, which results
// in changing the FPCW multiple times - so we optimize it with
// some inline assembly
@@ -110,56 +175,29 @@ static inline int splashCeil(SplashCoord x) {
__asm fistp DWORD PTR result
__asm fldcw WORD PTR oldCW
return result;
+
#else
+
+ //--- all others
+
return (int)ceil(x);
-#endif
+
#endif
}
static inline int splashRound(SplashCoord x) {
#if USE_FIXEDPOINT
+
+ //--- fixed point
+
return FixedPoint::round(x);
+
#else
-#if __GNUC__ && __i386__
- // this could use round-to-nearest mode and avoid the "+0.5",
- // but that produces slightly different results (because i+0.5
- // sometimes rounds up and sometimes down using the even rule)
- Gushort oldCW, newCW, t;
- int result;
- x += 0.5;
- __asm__ volatile("fnstcw %0\n"
- "movw %0, %3\n"
- "andw $0xf3ff, %3\n"
- "orw $0x0400, %3\n"
- "movw %3, %1\n" // round down
- "fldcw %1\n"
- "fistl %2\n"
- "fldcw %0\n"
- : "=m" (oldCW), "=m" (newCW), "=m" (result), "=r" (t)
- : "t" (x));
- return result;
-#elif defined(_WIN32) && defined(_M_IX86)
- // this could use round-to-nearest mode and avoid the "+0.5",
- // but that produces slightly different results (because i+0.5
- // sometimes rounds up and sometimes down using the even rule)
- Gushort oldCW, newCW;
- int result;
+ //--- all others
+
+ return splashFloor(x + 0.5);
- x += 0.5;
- __asm fld QWORD PTR x
- __asm fnstcw WORD PTR oldCW
- __asm mov ax, WORD PTR oldCW
- __asm and ax, 0xf3ff
- __asm or ax, 0x0400
- __asm mov WORD PTR newCW, ax // round down
- __asm fldcw WORD PTR newCW
- __asm fistp DWORD PTR result
- __asm fldcw WORD PTR oldCW
- return result;
-#else
- return (int)floor(x + 0.5);
-#endif
#endif
}
@@ -262,23 +300,53 @@ static inline GBool splashCheckDet(SplashCoord m11, SplashCoord m12,
// but
// xMin = 10.1 xMax = 11.3 (width = 1.2)
// --> xMinI = 10 xMaxI = 12 (width = 2)
+//
+// 4. Use a hybrid approach, choosing between two of the above
+// options, based on width. E.g., use #2 if width <= 4, and use #1
+// if width > 4.
+//
+// If w >= 0 and strokeAdjMode is splashStrokeAdjustCAD then a special
+// mode for projecting line caps is enabled, with w being the
+// transformed line width.
+
static inline void splashStrokeAdjust(SplashCoord xMin, SplashCoord xMax,
- int *xMinI, int *xMaxI) {
+ int *xMinI, int *xMaxI,
+ SplashStrokeAdjustMode strokeAdjMode,
+ SplashCoord w = -1) {
int x0, x1;
- // NB: enable exactly one of these.
+ // this will never be called with strokeAdjMode == splashStrokeAdjustOff
+ if (strokeAdjMode == splashStrokeAdjustCAD) {
+ x0 = splashRound(xMin);
+ if (w >= 0) {
+ x1 = splashRound(xMax - w) + splashRound(w);
+ } else {
+ x1 = x0 + splashRound(xMax - xMin);
+ }
+ } else {
+ // NB: enable exactly one of these.
#if 1 // 1. Round both edge coordinates.
- x0 = splashRound(xMin);
- x1 = splashRound(xMax);
+ x0 = splashRound(xMin);
+ x1 = splashRound(xMax);
#endif
#if 0 // 2. Round the min coordinate; add the ceiling of the width.
- x0 = splashRound(xMin);
- x1 = x0 + splashCeil(xMax - xMin);
+ x0 = splashRound(xMin);
+ x1 = x0 + splashCeil(xMax - xMin);
#endif
#if 0 // 3. Use floor on the min coord and ceiling on the max coord.
- x0 = splashFloor(xMin);
- x1 = splashCeil(xMax);
+ x0 = splashFloor(xMin);
+ x1 = splashCeil(xMax);
#endif
+#if 0 // 4. Hybrid.
+ SplashCoord w = xMax - xMin;
+ x0 = splashRound(xMin);
+ if (w > 4) {
+ x1 = splashRound(xMax);
+ } else {
+ x1 = x0 + splashRound(w);
+ }
+#endif
+ }
if (x1 == x0) {
++x1;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.cc
index 4ee8be02809..8bf2575a083 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.cc
@@ -14,6 +14,7 @@
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "SplashErrorCodes.h"
#include "SplashPath.h"
@@ -156,7 +157,8 @@ SplashError SplashPath::close(GBool force) {
}
void SplashPath::addStrokeAdjustHint(int ctrl0, int ctrl1,
- int firstPt, int lastPt) {
+ int firstPt, int lastPt,
+ GBool projectingCap) {
if (hintsLength == hintsSize) {
hintsSize = hintsLength ? 2 * hintsLength : 8;
hints = (SplashPathHint *)greallocn(hints, hintsSize,
@@ -166,6 +168,7 @@ void SplashPath::addStrokeAdjustHint(int ctrl0, int ctrl1,
hints[hintsLength].ctrl1 = ctrl1;
hints[hintsLength].firstPt = firstPt;
hints[hintsLength].lastPt = lastPt;
+ hints[hintsLength].projectingCap = projectingCap;
++hintsLength;
}
@@ -186,3 +189,25 @@ GBool SplashPath::getCurPt(SplashCoord *x, SplashCoord *y) {
*y = pts[length - 1].y;
return gTrue;
}
+
+GBool SplashPath::containsZeroLengthSubpaths() {
+ GBool zeroLength;
+ int i;
+
+ zeroLength = gTrue; // make gcc happy
+ for (i = 0; i < length; ++i) {
+ if (flags[i] & splashPathFirst) {
+ zeroLength = gTrue;
+ } else {
+ if (pts[i].x != pts[i-1].x || pts[i].y != pts[i-1].y) {
+ zeroLength = gFalse;
+ }
+ if (flags[i] & splashPathLast) {
+ if (zeroLength) {
+ return gTrue;
+ }
+ }
+ }
+ }
+ return gFalse;
+}
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.h
index a8715302042..b5732b8b408 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.h
@@ -49,6 +49,7 @@ struct SplashPathPoint {
struct SplashPathHint {
int ctrl0, ctrl1;
int firstPt, lastPt;
+ GBool projectingCap;
};
//------------------------------------------------------------------------
@@ -89,7 +90,10 @@ public:
// Add a stroke adjustment hint. The controlling segments are
// <ctrl0> and <ctrl1> (where segments are identified by their first
// point), and the points to be adjusted are <firstPt> .. <lastPt>.
- void addStrokeAdjustHint(int ctrl0, int ctrl1, int firstPt, int lastPt);
+ // <projectingCap> is true if the points are part of a projecting
+ // line cap.
+ void addStrokeAdjustHint(int ctrl0, int ctrl1, int firstPt, int lastPt,
+ GBool projectingCap = gFalse);
// Add (<dx>, <dy>) to every point on this path.
void offset(SplashCoord dx, SplashCoord dy);
@@ -102,6 +106,10 @@ public:
// Get the current point.
GBool getCurPt(SplashCoord *x, SplashCoord *y);
+ // Returns true if the path contains one or more zero length
+ // subpaths.
+ GBool containsZeroLengthSubpaths();
+
private:
SplashPath(SplashPath *path);
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.cc
index 6ca4fb274e8..55ae865111c 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.cc
@@ -12,6 +12,7 @@
#pragma implementation
#endif
+#include "gmempp.h"
#include "SplashMath.h"
#include "SplashScreen.h"
#include "SplashPattern.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.cc
index 68a762f7f2a..41c852531f1 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.cc
@@ -18,6 +18,7 @@
#include <algorithm>
#endif
#include "gmem.h"
+#include "gmempp.h"
#include "SplashMath.h"
#include "SplashScreen.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.h
index 4e9767be5f6..560e2759d82 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.h
@@ -21,6 +21,8 @@
// SplashScreen
//------------------------------------------------------------------------
+typedef Guchar *SplashScreenCursor;
+
class SplashScreen {
public:
@@ -39,6 +41,20 @@ public:
return value < mat[(yy << log2Size) + xx] ? 0 : 1;
}
+ // To do a series of tests with the same y value, call
+ // getTestCursor(y), and then call testWithCursor(cursor, x, value)
+ // for each x.
+ SplashScreenCursor getTestCursor(int y) {
+ int yy;
+ yy = y & sizeM1;
+ return &mat[yy << log2Size];
+ }
+
+ int testWithCursor(SplashScreenCursor cursor, int x, Guchar value) {
+ int xx = x & sizeM1;
+ return value >= cursor[xx];
+ }
+
// Returns true if value is above the white threshold or below the
// black threshold, i.e., if the corresponding halftone will be
// solid white or black.
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc
index 09c1949eb3d..17ac8d17a19 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc
@@ -14,6 +14,7 @@
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "SplashPattern.h"
#include "SplashScreen.h"
#include "SplashClip.h"
@@ -55,7 +56,7 @@ SplashState::SplashState(int width, int height, GBool vectorAntialias,
lineDash = NULL;
lineDashLength = 0;
lineDashPhase = 0;
- strokeAdjust = gFalse;
+ strokeAdjust = splashStrokeAdjustOff;
clip = new SplashClip(0, 0, width, height);
clipIsShared = gFalse;
softMask = NULL;
@@ -67,12 +68,15 @@ SplashState::SplashState(int width, int height, GBool vectorAntialias,
rgbTransferG[i] = (Guchar)i;
rgbTransferB[i] = (Guchar)i;
grayTransfer[i] = (Guchar)i;
+#if SPLASH_CMYK
cmykTransferC[i] = (Guchar)i;
cmykTransferM[i] = (Guchar)i;
cmykTransferY[i] = (Guchar)i;
cmykTransferK[i] = (Guchar)i;
+#endif
}
overprintMask = 0xffffffff;
+ enablePathSimplification = gFalse;
next = NULL;
}
@@ -99,7 +103,7 @@ SplashState::SplashState(int width, int height, GBool vectorAntialias,
lineDash = NULL;
lineDashLength = 0;
lineDashPhase = 0;
- strokeAdjust = gFalse;
+ strokeAdjust = splashStrokeAdjustOff;
clip = new SplashClip(0, 0, width, height);
clipIsShared = gFalse;
softMask = NULL;
@@ -111,12 +115,15 @@ SplashState::SplashState(int width, int height, GBool vectorAntialias,
rgbTransferG[i] = (Guchar)i;
rgbTransferB[i] = (Guchar)i;
grayTransfer[i] = (Guchar)i;
+#if SPLASH_CMYK
cmykTransferC[i] = (Guchar)i;
cmykTransferM[i] = (Guchar)i;
cmykTransferY[i] = (Guchar)i;
cmykTransferK[i] = (Guchar)i;
+#endif
}
overprintMask = 0xffffffff;
+ enablePathSimplification = gFalse;
next = NULL;
}
@@ -153,11 +160,14 @@ SplashState::SplashState(SplashState *state) {
memcpy(rgbTransferG, state->rgbTransferG, 256);
memcpy(rgbTransferB, state->rgbTransferB, 256);
memcpy(grayTransfer, state->grayTransfer, 256);
+#if SPLASH_CMYK
memcpy(cmykTransferC, state->cmykTransferC, 256);
memcpy(cmykTransferM, state->cmykTransferM, 256);
memcpy(cmykTransferY, state->cmykTransferY, 256);
memcpy(cmykTransferK, state->cmykTransferK, 256);
+#endif
overprintMask = state->overprintMask;
+ enablePathSimplification = state->enablePathSimplification;
next = NULL;
}
@@ -202,6 +212,32 @@ void SplashState::setLineDash(SplashCoord *lineDashA, int lineDashLengthA,
lineDashPhase = lineDashPhaseA;
}
+GBool SplashState::lineDashContainsZeroLengthDashes() {
+ int i;
+
+ if (lineDashLength == 0) {
+ return gFalse;
+ }
+
+ // if the line dash array has an odd number of elements, we need to
+ // check all of the elements; if the length is even, we only need to
+ // check even-number elements
+ if (lineDashLength & 1) {
+ for (i = 0; i < lineDashLength; ++i) {
+ if (lineDash[i] == 0) {
+ return gTrue;
+ }
+ }
+ } else {
+ for (i = 0; i < lineDashLength; i += 2) {
+ if (lineDash[i] == 0) {
+ return gTrue;
+ }
+ }
+ }
+ return gFalse;
+}
+
void SplashState::clipResetToRect(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1) {
if (clipIsShared) {
@@ -225,7 +261,8 @@ SplashError SplashState::clipToPath(SplashPath *path, GBool eo) {
clip = clip->copy();
clipIsShared = gFalse;
}
- return clip->clipToPath(path, matrix, flatness, eo);
+ return clip->clipToPath(path, matrix, flatness, eo,
+ enablePathSimplification, strokeAdjust);
}
void SplashState::setSoftMask(SplashBitmap *softMaskA) {
@@ -238,16 +275,20 @@ void SplashState::setSoftMask(SplashBitmap *softMaskA) {
void SplashState::setTransfer(Guchar *red, Guchar *green, Guchar *blue,
Guchar *gray) {
+#if SPLASH_CMYK
int i;
+#endif
memcpy(rgbTransferR, red, 256);
memcpy(rgbTransferG, green, 256);
memcpy(rgbTransferB, blue, 256);
memcpy(grayTransfer, gray, 256);
+#if SPLASH_CMYK
for (i = 0; i < 256; ++i) {
cmykTransferC[i] = 255 - rgbTransferR[255 - i];
cmykTransferM[i] = 255 - rgbTransferG[255 - i];
cmykTransferY[i] = 255 - rgbTransferB[255 - i];
cmykTransferK[i] = 255 - grayTransfer[255 - i];
}
+#endif
}
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h
index fe773a5403f..2a957cecd19 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h
@@ -70,6 +70,10 @@ public:
void setLineDash(SplashCoord *lineDashA, int lineDashLengthA,
SplashCoord lineDashPhaseA);
+ // Returns true if the current line dash pattern contains one or
+ // more zero-length "on" sections (dashes).
+ GBool lineDashContainsZeroLengthDashes();
+
void clipResetToRect(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1);
SplashError clipToRect(SplashCoord x0, SplashCoord y0,
@@ -101,7 +105,7 @@ private:
SplashCoord *lineDash;
int lineDashLength;
SplashCoord lineDashPhase;
- GBool strokeAdjust;
+ SplashStrokeAdjustMode strokeAdjust;
SplashClip *clip;
GBool clipIsShared;
SplashBitmap *softMask;
@@ -112,11 +116,14 @@ private:
rgbTransferG[256],
rgbTransferB[256];
Guchar grayTransfer[256];
+#if SPLASH_CMYK
Guchar cmykTransferC[256],
cmykTransferM[256],
cmykTransferY[256],
cmykTransferK[256];
+#endif
Guint overprintMask;
+ GBool enablePathSimplification;
SplashState *next; // used by Splash class
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashTypes.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashTypes.h
index 240cb6f7b8c..0e1829dcf1d 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashTypes.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashTypes.h
@@ -107,6 +107,16 @@ typedef void (*SplashBlendFunc)(SplashColorPtr src, SplashColorPtr dest,
SplashColorPtr blend, SplashColorMode cm);
//------------------------------------------------------------------------
+// stroke adjustment mode
+//------------------------------------------------------------------------
+
+enum SplashStrokeAdjustMode {
+ splashStrokeAdjustOff,
+ splashStrokeAdjustNormal,
+ splashStrokeAdjustCAD
+};
+
+//------------------------------------------------------------------------
// screen parameters
//------------------------------------------------------------------------
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
index a1599885e2b..f0164a85bd4 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
@@ -18,12 +18,18 @@
#include <algorithm>
#endif
#include "gmem.h"
+#include "gmempp.h"
#include "SplashMath.h"
#include "SplashPath.h"
#include "SplashXPath.h"
//------------------------------------------------------------------------
+#define minCosSquaredJoinAngle 0.75
+#define maxPointToLineDistanceSquared 0.04
+
+//------------------------------------------------------------------------
+
struct SplashXPathPoint {
SplashCoord x, y;
};
@@ -54,29 +60,58 @@ inline void SplashXPath::transform(SplashCoord *matrix,
// SplashXPath
//------------------------------------------------------------------------
+// SplashXPath segment coords are clipped to +/-maxCoord to avoid
+// problems. The xMin/yMin/xMax/yMax fields are 32-bit integers, so
+// coords need to be < 2^31 / aa{Horiz,Vert}.
+#define maxCoord 100000000.0
+
+void SplashXPath::clampCoords(SplashCoord *x, SplashCoord *y) {
+#if !USE_FIXEDPOINT
+ if (*x > maxCoord) {
+ *x = maxCoord;
+ } else if (*x < -maxCoord) {
+ *x = -maxCoord;
+ }
+ if (*y > maxCoord) {
+ *y = maxCoord;
+ } else if (*y < -maxCoord) {
+ *y = -maxCoord;
+ }
+#endif
+}
+
SplashXPath::SplashXPath(SplashPath *path, SplashCoord *matrix,
- SplashCoord flatness, GBool closeSubpaths) {
+ SplashCoord flatness, GBool closeSubpaths,
+ GBool simplify,
+ SplashStrokeAdjustMode strokeAdjMode) {
SplashXPathPoint *pts;
- SplashCoord x0, y0, x1, y1, x2, y2, x3, y3, xsp, ysp;
- SplashCoord xMinFP, xMaxFP, yMinFP, yMaxFP;
- int curSubpath, i;
+ SplashCoord x0, y0, x1, y1, x2, y2, x3, y3, xsp, ysp, t;
+ int curSubpath, firstSegInSubpath, i;
+ GBool adjusted;
- // transform the points
+ //--- transform the points
pts = (SplashXPathPoint *)gmallocn(path->length, sizeof(SplashXPathPoint));
for (i = 0; i < path->length; ++i) {
transform(matrix, path->pts[i].x, path->pts[i].y, &pts[i].x, &pts[i].y);
+ clampCoords(&pts[i].x, &pts[i].y);
}
- // do stroke adjustment
+ //--- do stroke adjustment
if (path->hints) {
- strokeAdjust(pts, path->hints, path->hintsLength);
+ adjusted = strokeAdjust(pts, path->hints, path->hintsLength,
+ strokeAdjMode);
+ } else {
+ adjusted = gFalse;
}
+ //--- construct the segments
+
segs = NULL;
length = size = 0;
x0 = y0 = xsp = ysp = 0; // make gcc happy
curSubpath = 0;
+ firstSegInSubpath = 0;
i = 0;
while (i < path->length) {
@@ -123,66 +158,85 @@ SplashXPath::SplashXPath(SplashPath *path, SplashCoord *matrix,
++i;
}
- // close a subpath
- if (closeSubpaths &&
- (path->flags[i-1] & splashPathLast) &&
- (pts[i-1].x != pts[curSubpath].x ||
- pts[i-1].y != pts[curSubpath].y)) {
- addSegment(x0, y0, xsp, ysp);
+ // end a subpath
+ if (path->flags[i-1] & splashPathLast) {
+ if (closeSubpaths &&
+ (pts[i-1].x != pts[curSubpath].x ||
+ pts[i-1].y != pts[curSubpath].y)) {
+ addSegment(x0, y0, xsp, ysp);
+ }
+ if (simplify && !adjusted) {
+ mergeSegments(firstSegInSubpath);
+ }
+ firstSegInSubpath = length;
}
}
}
gfree(pts);
+ finishSegments();
+
+ //--- check for a rectangle
+ isRect = gFalse;
+ rectX0 = rectY0 = rectX1 = rectY1 = 0;
+ if (length == 4) {
#if HAVE_STD_SORT
- std::sort(segs, segs + length, SplashXPathSeg::cmpY);
+ std::sort(segs, segs + length, SplashXPathSeg::cmpY);
#else
- qsort(segs, length, sizeof(SplashXPathSeg), &SplashXPathSeg::cmpY);
+ qsort(segs, length, sizeof(SplashXPathSeg), &SplashXPathSeg::cmpY);
#endif
-
- if (length == 0) {
- xMin = yMin = xMax = yMax = 0;
- } else {
- if (segs[0].x0 < segs[0].x1) {
- xMinFP = segs[0].x0;
- xMaxFP = segs[0].x1;
- } else {
- xMinFP = segs[0].x1;
- xMaxFP = segs[0].x0;
+ if (segs[0].y0 == segs[0].y1 &&
+ segs[1].x0 == segs[1].x1 &&
+ segs[2].x0 == segs[2].x1 &&
+ segs[3].y0 == segs[3].y1) {
+ isRect = gTrue;
+ rectX0 = segs[1].x0;
+ rectX1 = segs[2].x0;
+ rectY0 = segs[0].y0;
+ rectY1 = segs[3].y0;
+ } else if (segs[0].x0 == segs[0].x1 &&
+ segs[1].y0 == segs[1].y1 &&
+ segs[2].x0 == segs[2].x1 &&
+ segs[3].y0 == segs[3].y1) {
+ isRect = gTrue;
+ rectX0 = segs[0].x0;
+ rectX1 = segs[2].x0;
+ rectY0 = segs[1].y0;
+ rectY1 = segs[3].y0;
+ } else if (segs[0].x0 == segs[0].x1 &&
+ segs[1].x0 == segs[1].x1 &&
+ segs[2].y0 == segs[2].y1 &&
+ segs[3].y0 == segs[3].y1) {
+ isRect = gTrue;
+ rectX0 = segs[0].x0;
+ rectX1 = segs[1].x0;
+ rectY0 = segs[2].y0;
+ rectY1 = segs[3].y0;
}
- yMinFP = segs[0].y0;
- yMaxFP = segs[0].y1;
- for (i = 1; i < length; ++i) {
- if (segs[i].x0 < xMinFP) {
- xMinFP = segs[i].x0;
- } else if (segs[i].x0 > xMaxFP) {
- xMaxFP = segs[i].x0;
- }
- if (segs[i].x1 < xMinFP) {
- xMinFP = segs[i].x1;
- } else if (segs[i].x1 > xMaxFP) {
- xMaxFP = segs[i].x1;
+ if (isRect) {
+ if (rectX0 > rectX1) {
+ t = rectX0; rectX0 = rectX1; rectX1 = t;
}
- if (segs[i].y1 > yMaxFP) {
- yMaxFP = segs[i].y1;
+ if (rectY0 > rectY1) {
+ t = rectY0; rectY0 = rectY1; rectY1 = t;
}
}
- xMin = splashFloor(xMinFP);
- yMin = splashFloor(yMinFP);
- xMax = splashFloor(xMaxFP);
- yMax = splashFloor(yMaxFP);
}
}
-void SplashXPath::strokeAdjust(SplashXPathPoint *pts,
- SplashPathHint *hints, int nHints) {
+GBool SplashXPath::strokeAdjust(SplashXPathPoint *pts,
+ SplashPathHint *hints, int nHints,
+ SplashStrokeAdjustMode strokeAdjMode) {
SplashXPathAdjust *adjusts, *adjust;
SplashPathHint *hint;
SplashCoord x0, y0, x1, y1, x2, y2, x3, y3;
- SplashCoord adj0, adj1, d;
+ SplashCoord adj0, adj1, w, d;
int xi0, xi1;
int i, j;
+ GBool adjusted;
+
+ adjusted = gFalse;
// set up the stroke adjustment hints
adjusts = (SplashXPathAdjust *)gmallocn(nHints, sizeof(SplashXPathAdjust));
@@ -192,14 +246,21 @@ void SplashXPath::strokeAdjust(SplashXPathPoint *pts,
x1 = pts[hint->ctrl0 + 1].x; y1 = pts[hint->ctrl0 + 1].y;
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) {
adjusts[i].vert = gTrue;
adj0 = x0;
adj1 = x2;
+ if (hint->projectingCap) {
+ w = splashAbs(y1 - y0);
+ }
} else if (y0 == y1 && y2 == y3) {
adjusts[i].vert = gFalse;
adj0 = y0;
adj1 = y2;
+ if (hint->projectingCap) {
+ w = splashAbs(x1 - x0);
+ }
} else {
goto done;
}
@@ -220,7 +281,7 @@ void SplashXPath::strokeAdjust(SplashXPathPoint *pts,
adjusts[i].xmb = (SplashCoord)0.5 * (adj0 + adj1) + d;
adjusts[i].x1a = adj1 - d;
adjusts[i].x1b = adj1 + d;
- splashStrokeAdjust(adj0, adj1, &xi0, &xi1);
+ splashStrokeAdjust(adj0, adj1, &xi0, &xi1, strokeAdjMode, w);
adjusts[i].x0 = (SplashCoord)xi0;
// the "minus epsilon" thing here is needed when vector
// antialiasing is turned off -- otherwise stroke adjusted lines
@@ -255,9 +316,11 @@ void SplashXPath::strokeAdjust(SplashXPathPoint *pts,
}
}
}
+ adjusted = gTrue;
done:
gfree(adjusts);
+ return adjusted;
}
SplashXPath::SplashXPath(SplashXPath *xPath) {
@@ -380,38 +443,202 @@ void SplashXPath::addCurve(SplashCoord x0, SplashCoord y0,
void SplashXPath::addSegment(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1) {
grow(1);
- if (y0 <= y1) {
- segs[length].x0 = x0;
- segs[length].y0 = y0;
- segs[length].x1 = x1;
- segs[length].y1 = y1;
- segs[length].count = 1;
- } else {
- segs[length].x0 = x1;
- segs[length].y0 = y1;
- segs[length].x1 = x0;
- segs[length].y1 = y0;
- segs[length].count = -1;
+ segs[length].x0 = x0;
+ segs[length].y0 = y0;
+ segs[length].x1 = x1;
+ segs[length].y1 = y1;
+ ++length;
+}
+
+// Returns true if the angle between (x0,y0)-(x1,y1) and
+// (x1,y1)-(x2,y2) is close to 180 degrees.
+static GBool joinAngleIsFlat(SplashCoord x0, SplashCoord y0,
+ SplashCoord x1, SplashCoord y1,
+ SplashCoord x2, SplashCoord y2) {
+ SplashCoord dx1, dy1, dx2, dy2, d, len1, len2;
+
+ dx1 = x1 - x0;
+ dy1 = y1 - y0;
+ dx2 = x2 - x1;
+ dy2 = y2 - y1;
+ d = dx1 * dx2 + dy1 * dy2;
+ len1 = dx1 * dx1 + dy1 * dy1;
+ len2 = dx2 * dx2 + dy2 * dy2;
+ return d > 0 && d * d > len1 * len2 * minCosSquaredJoinAngle;
+}
+
+// Returns true if (x1,y1) is sufficiently close to the segment
+// (x0,y0)-(x2,y2), looking at the perpendicular point-to-line
+// distance.
+static GBool pointCloseToSegment(SplashCoord x0, SplashCoord y0,
+ SplashCoord x1, SplashCoord y1,
+ SplashCoord x2, SplashCoord y2) {
+ SplashCoord t1, t2, dx, dy;
+
+ // compute the perpendicular distance from the point to the segment,
+ // i.e., the projection of (x0,y0)-(x1,y1) onto a unit normal to the
+ // segment (this actually computes the square of the distance)
+ dx = x2 - x0;
+ dy = y2 - y0;
+ t1 = dx*dx + dy*dy;
+ if (t1 < 0.0001) {
+ // degenerate case: (x0,y0) and (x2,y2) are (nearly) identical --
+ // just compute the distance to (x1,y1)
+ dx = x0 - x1;
+ dy = y0 - y1;
+ t2 = dx*dx + dy*dy;
+ return t2 < maxPointToLineDistanceSquared;
}
-#if USE_FIXEDPOINT
- if (y0 == y1 || x0 == x1 ||
- !FixedPoint::divCheck(x1 - x0, y1 - y0, &segs[length].dxdy) ||
- !FixedPoint::divCheck(y1 - y0, x1 - x0, &segs[length].dydx)) {
- segs[length].dxdy = 0;
- segs[length].dydx = 0;
+ t2 = x1 * dy - dx * y1 - x0 * y2 + x2 * y0;
+ // actual distance = t2 / sqrt(t1)
+ return t2 * t2 < t1 * maxPointToLineDistanceSquared;
+}
+
+// Attempt to simplify the path by merging sequences of consecutive
+// segments in [first] .. [length]-1.
+void SplashXPath::mergeSegments(int first) {
+ GBool horiz, vert;
+ int in, out, prev, i, j;
+
+ in = out = first;
+ while (in < length) {
+
+ // skip zero-length segments
+ if (segs[in].x0 == segs[in].x1 && segs[in].y0 == segs[in].y1) {
+ ++in;
+ continue;
+ }
+
+ horiz = segs[in].y0 == segs[in].y1;
+ vert = segs[in].x0 == segs[in].x1;
+
+ // check for a sequence of mergeable segments: in .. i
+ prev = in;
+ for (i = in + 1; i < length; ++i) {
+
+ // skip zero-length segments
+ if (segs[i].x0 == segs[i].x1 && segs[i].y0 == segs[i].y1) {
+ continue;
+ }
+
+ // check for a horizontal or vertical segment
+ if ((horiz && segs[in].y0 != segs[in].y1) ||
+ (vert && segs[in].x0 != segs[in].x1)) {
+ break;
+ }
+
+ // check the angle between segs i-1 and i
+ // (actually, we compare seg i to the previous non-zero-length
+ // segment, which may not be i-1)
+ if (!joinAngleIsFlat(segs[prev].x0, segs[prev].y0,
+ segs[i].x0, segs[i].y0,
+ segs[i].x1, segs[i].y1)) {
+ break;
+ }
+
+ // check the distances from the ends of segs in .. i-1 to the
+ // proposed new segment
+ for (j = in; j < i; ++j) {
+ if (!pointCloseToSegment(segs[in].x0, segs[in].y0,
+ segs[j].x1, segs[j].y1,
+ segs[i].x1, segs[i].y1)) {
+ break;
+ }
+ }
+ if (j < i) {
+ break;
+ }
+
+ prev = i;
+ }
+
+ // we can merge segs: in .. i-1
+ // (this may be the single segment: in)
+ segs[out].x0 = segs[in].x0;
+ segs[out].y0 = segs[in].y0;
+ segs[out].x1 = segs[i-1].x1;
+ segs[out].y1 = segs[i-1].y1;
+ in = i;
+ ++out;
}
+
+ length = out;
+}
+
+void SplashXPath::finishSegments() {
+ SplashXPathSeg *seg;
+ SplashCoord xMinFP, xMaxFP, yMinFP, yMaxFP, t;
+ int i;
+
+ xMinFP = yMinFP = xMaxFP = yMaxFP = 0;
+
+ for (i = 0; i < length; ++i) {
+ seg = &segs[i];
+
+ //--- compute the slopes
+ if (seg->y0 <= seg->y1) {
+ seg->count = 1;
+ } else {
+ t = seg->x0; seg->x0 = seg->x1; seg->x1 = t;
+ t = seg->y0; seg->y0 = seg->y1; seg->y1 = t;
+ seg->count = -1;
+ }
+#if USE_FIXEDPOINT
+ if (seg->y0 == seg->y1 || seg->x0 == seg->x1 ||
+ !FixedPoint::divCheck(seg->x1 - seg->x0, seg->y1 - seg->y0,
+ &seg->dxdy) ||
+ !FixedPoint::divCheck(seg->y1 - seg->y0, seg->x1 - seg->x0,
+ &seg->dydx)) {
+ seg->dxdy = 0;
+ seg->dydx = 0;
+ }
#else
- if (y0 == y1 || x0 == x1) {
- segs[length].dxdy = 0;
- segs[length].dydx = 0;
- } else {
- segs[length].dxdy = (x1 - x0) / (y1 - y0);
- if (segs[length].dxdy == 0) {
- segs[length].dydx = 0;
+ if (seg->y0 == seg->y1 || seg->x0 == seg->x1) {
+ seg->dxdy = 0;
+ seg->dydx = 0;
} else {
- segs[length].dydx = 1 / segs[length].dxdy;
+ seg->dxdy = (seg->x1 - seg->x0) / (seg->y1 - seg->y0);
+ if (seg->dxdy == 0) {
+ seg->dydx = 0;
+ } else {
+ seg->dydx = 1 / seg->dxdy;
+ }
}
- }
#endif
- ++length;
+
+ //--- update bbox
+ if (i == 0) {
+ if (seg->x0 <= seg->x1) {
+ xMinFP = seg->x0;
+ xMaxFP = seg->x1;
+ } else {
+ xMinFP = seg->x1;
+ xMaxFP = seg->x0;
+ }
+ yMinFP = seg->y0;
+ yMaxFP = seg->y1;
+ } else {
+ if (seg->x0 < xMinFP) {
+ xMinFP = seg->x0;
+ } else if (seg->x0 > xMaxFP) {
+ xMaxFP = seg->x0;
+ }
+ if (seg->x1 < xMinFP) {
+ xMinFP = seg->x1;
+ } else if (seg->x1 > xMaxFP) {
+ xMaxFP = seg->x1;
+ }
+ if (seg->y0 < yMinFP) {
+ yMinFP = seg->y0;
+ }
+ if (seg->y1 > yMaxFP) {
+ yMaxFP = seg->y1;
+ }
+ }
+ }
+
+ xMin = splashFloor(xMinFP);
+ yMin = splashFloor(yMinFP);
+ xMax = splashFloor(xMaxFP);
+ yMax = splashFloor(yMaxFP);
}
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.h
index 5bcec61cd25..82d7889c447 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.h
@@ -37,36 +37,48 @@ struct SplashXPathSeg {
int count; // EO/NZWN counter increment
//----- used by SplashXPathScanner
- SplashCoord xCur0, xCur1; // current x values
+ int iy;
+ SplashCoord sx0, sx1, mx;
+ SplashXPathSeg *prev, *next;
#if HAVE_STD_SORT
+
+ static bool cmpMX(const SplashXPathSeg &s0,
+ const SplashXPathSeg &s1) {
+ if (s0.iy != s1.iy) {
+ return s0.iy < s1.iy;
+ }
+ return s0.mx < s1.mx;
+ }
+
static bool cmpY(const SplashXPathSeg &seg0,
const SplashXPathSeg &seg1) {
return seg0.y0 < seg1.y0;
}
+
#else
- static int cmpY(const void *seg0, const void *seg1) {
+
+ static int cmpMX(const void *p0, const void *p1) {
+ SplashXPathSeg *s0 = (SplashXPathSeg *)p0;
+ SplashXPathSeg *s1 = (SplashXPathSeg *)p1;
SplashCoord cmp;
- cmp = ((SplashXPathSeg *)seg0)->y0
- - ((SplashXPathSeg *)seg1)->y0;
- return (cmp > 0) ? 1 : (cmp < 0) ? -1 : 0;
+ if (s0->iy != s1->iy) {
+ return s0->iy - s1->iy;
+ }
+ cmp = s0->mx - s1->mx;
+ return (cmp < 0) ? -1 : (cmp > 0) ? 1 : 0;
}
-#endif
- static int cmpX(SplashXPathSeg *seg0, SplashXPathSeg *seg1) {
+ static int cmpY(const void *seg0, const void *seg1) {
SplashCoord cmp;
- if ((cmp = seg0->xCur0 - seg1->xCur0) == 0) {
- cmp = seg0->dxdy - seg1->dxdy;
- }
+ cmp = ((SplashXPathSeg *)seg0)->y0
+ - ((SplashXPathSeg *)seg1)->y0;
return (cmp > 0) ? 1 : (cmp < 0) ? -1 : 0;
}
- static int cmpXi(const void *p0, const void *p1) {
- return cmpX(*(SplashXPathSeg **)p0, *(SplashXPathSeg **)p1);
- }
-
+#endif
};
//------------------------------------------------------------------------
@@ -81,7 +93,8 @@ public:
// space, via <matrix>. If <closeSubpaths> is true, closes all open
// subpaths.
SplashXPath(SplashPath *path, SplashCoord *matrix,
- SplashCoord flatness, GBool closeSubpaths);
+ SplashCoord flatness, GBool closeSubpaths,
+ GBool simplify, SplashStrokeAdjustMode strokeAdjMode);
// Copy an expanded path.
SplashXPath *copy() { return new SplashXPath(this); }
@@ -95,11 +108,13 @@ public:
private:
+ static void clampCoords(SplashCoord *x, SplashCoord *y);
SplashXPath(SplashXPath *xPath);
void transform(SplashCoord *matrix, SplashCoord xi, SplashCoord yi,
SplashCoord *xo, SplashCoord *yo);
- void strokeAdjust(SplashXPathPoint *pts,
- SplashPathHint *hints, int nHints);
+ GBool strokeAdjust(SplashXPathPoint *pts,
+ SplashPathHint *hints, int nHints,
+ SplashStrokeAdjustMode strokeAdjMode);
void grow(int nSegs);
void addCurve(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1,
@@ -107,14 +122,19 @@ private:
SplashCoord x3, SplashCoord y3,
SplashCoord flatness,
GBool first, GBool last, GBool end0, GBool end1);
+ void mergeSegments(int first);
void addSegment(SplashCoord x0, SplashCoord y0,
SplashCoord x1, SplashCoord y1);
+ void finishSegments();
SplashXPathSeg *segs;
int length, size; // length and size of segs array
int xMin, xMax;
int yMin, yMax;
+ GBool isRect;
+ SplashCoord rectX0, rectY0, rectX1, rectY1;
+
friend class SplashXPathScanner;
friend class SplashClip;
friend class Splash;
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.cc
index aee60cce61e..3f167b8b311 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.cc
@@ -18,6 +18,7 @@
#include <algorithm>
#endif
#include "gmem.h"
+#include "gmempp.h"
#include "GList.h"
#include "SplashMath.h"
#include "SplashXPath.h"
@@ -25,543 +26,595 @@
//------------------------------------------------------------------------
-#define minVertStep 0.05
+#if ANTIALIAS_256
+
+#define aaVert 15
+#define aaHoriz 17
+
+#else
+
+#define aaVert 4
+#define aaHoriz 4
+
+static Guchar map16to255[17] = {
+ 0,
+ 16,
+ 32,
+ 48,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 143,
+ 159,
+ 175,
+ 191,
+ 207,
+ 223,
+ 239,
+ 255
+};
+
+#endif
//------------------------------------------------------------------------
-SplashXPathScanner::SplashXPathScanner(SplashXPath *xPathA, GBool eoA,
+SplashXPathScanner::SplashXPathScanner(SplashXPath *xPathA, GBool eo,
int yMinA, int yMaxA) {
xPath = xPathA;
- eo = eoA;
+ eoMask = eo ? 1 : 0xffffffff;
yMin = yMinA;
yMax = yMaxA;
+ if (xPath->isRect) {
+ rectX0I = splashFloor(xPath->rectX0);
+ rectY0I = splashFloor(xPath->rectY0);
+ rectX1I = splashFloor(xPath->rectX1);
+ rectY1I = splashFloor(xPath->rectY1);
+ }
- activeSegs = new GList();
- nextSeg = 0;
- yNext = xPath->yMin;
+ pre = &preSeg;
+ post = &postSeg;
+ pre->mx = xPath->xMin - 1;
+ post->mx = xPath->xMax + 1;
+
+ resetDone = gFalse;
+ resetAA = gFalse;
}
SplashXPathScanner::~SplashXPathScanner() {
- delete activeSegs;
}
-void SplashXPathScanner::getSpan(Guchar *line, int y, int x0, int x1) {
- SplashXPathSeg *seg, *seg0;
- SplashCoord y0, y1, y1p;
- GBool intersect, last;
- int eoMask, state0, state1, count, i;
+void SplashXPathScanner::insertSegmentBefore(SplashXPathSeg *s,
+ SplashXPathSeg *sNext) {
+ SplashXPathSeg *sPrev;
- //--- clear the scan line buffer
- memset(line + x0, 0, x1 - x0 + 1);
+ sPrev = sNext->prev;
+ sPrev->next = s;
+ s->prev = sPrev;
+ s->next = sNext;
+ sNext->prev = s;
+}
+
+void SplashXPathScanner::removeSegment(SplashXPathSeg *s) {
+ SplashXPathSeg *sPrev, *sNext;
+
+ sPrev = s->prev;
+ sNext = s->next;
+ sPrev->next = sNext;
+ sNext->prev = sPrev;
+ s->prev = s->next = NULL;
+}
- //--- reset the path
- if (yNext != y) {
- delete activeSegs;
- activeSegs = new GList();
- nextSeg = 0;
- while (nextSeg < xPath->length) {
- seg = &xPath->segs[nextSeg];
- if (seg->y0 >= y) {
- break;
+void SplashXPathScanner::moveSegmentAfter(SplashXPathSeg *s,
+ SplashXPathSeg *sPrev) {
+ SplashXPathSeg *sNext;
+
+ s->prev->next = s->next;
+ s->next->prev = s->prev;
+
+ sNext = sPrev->next;
+ sPrev->next = s;
+ s->prev = sPrev;
+ s->next = sNext;
+ sNext->prev = s;
+}
+
+void SplashXPathScanner::reset(GBool aa, GBool aaChanged) {
+ SplashXPathSeg *seg;
+ SplashCoord y;
+ int i;
+
+ //--- initialize segment parameters
+ for (i = 0; i < xPath->length; ++i) {
+ seg = &xPath->segs[i];
+ if (aa) {
+ if (aaChanged) {
+ seg->iy = splashFloor(seg->y0 * aaVert);
}
- if (seg->y0 != seg->y1 && seg->y1 > y) {
- if (seg->y0 == y) {
- seg->xCur0 = seg->x0;
- } else {
- seg->xCur0 = seg->x0 + ((SplashCoord)y - seg->y0) * seg->dxdy;
- }
- activeSegs->append(seg);
+ y = (SplashCoord)(seg->iy + 1) / (SplashCoord)aaVert;
+ } else {
+ if (aaChanged) {
+ seg->iy = splashFloor(seg->y0);
}
- ++nextSeg;
+ y = (SplashCoord)(seg->iy + 1);
+ }
+ seg->sx0 = seg->x0;
+ if (seg->y1 <= y) {
+ seg->sx1 = seg->x1;
+ } else {
+ seg->sx1 = seg->x0 + (y - seg->y0) * seg->dxdy;
}
- activeSegs->sort(&SplashXPathSeg::cmpXi);
+ seg->mx = (seg->sx0 <= seg->sx1) ? seg->sx0 : seg->sx1;
+ seg->prev = seg->next = NULL;
}
- //--- process the scan line
- y0 = y;
- while (y0 < y + 1) {
+ //--- sort the inactive segments by iy, mx
+ if (aaChanged) {
+#if HAVE_STD_SORT
+ std::sort(xPath->segs, xPath->segs + xPath->length, &SplashXPathSeg::cmpMX);
+#else
+ qsort(xPath->segs, xPath->length, sizeof(SplashXPathSeg),
+ &SplashXPathSeg::cmpMX);
+#endif
+ }
- //--- delete finished segs
- i = 0;
- while (i < activeSegs->getLength()) {
- seg = (SplashXPathSeg *)activeSegs->get(i);
- if (seg->y1 <= y0) {
- activeSegs->del(i);
- } else {
- ++i;
- }
- }
+ //--- initialize the active list
+ pre->prev = NULL;
+ pre->next = post;
+ post->prev = pre;
+ post->next = NULL;
- //--- check for bottom of path
- if (!activeSegs->getLength() && nextSeg >= xPath->length) {
- break;
+ //--- initialize the scan state
+ nextSeg = 0;
+ if (xPath->length) {
+ yBottomI = xPath->segs[0].iy;
+ if (aa) {
+ yBottomI -= yBottomI % aaVert;
}
+ } else {
+ yBottomI = 0;
+ }
+ yTopI = yBottomI - 1;
+ if (aa) {
+ yTop = (SplashCoord)yTopI / (SplashCoord)aaVert;
+ yBottom = (SplashCoord)yBottomI / (SplashCoord)aaVert;
+ } else {
+ yTop = (SplashCoord)yTopI;
+ yBottom = (SplashCoord)yBottomI;
+ }
+
+ resetDone = gTrue;
+ resetAA = aa;
+}
- //--- sort activeSegs
- sortActiveSegs();
+void SplashXPathScanner::skip(int newYBottomI, GBool aa) {
+ SplashXPathSeg *s0, *s1,*s2;
+ int iy;
+
+ yTopI = newYBottomI - 1;
+ yBottomI = newYBottomI;
+ if (aa) {
+ yTop = (SplashCoord)yTopI / (SplashCoord)aaVert;
+ yBottom = (SplashCoord)yBottomI / (SplashCoord)aaVert;
+ } else {
+ yTop = (SplashCoord)yTopI;
+ yBottom = (SplashCoord)yBottomI;
+ }
- //--- add waiting segs
- while (nextSeg < xPath->length) {
- seg = &xPath->segs[nextSeg];
- if (seg->y0 > y0) {
- break;
+ //--- remove finished segments; update sx0, sx1, mx for active segments
+ s0 = pre->next;
+ while (s0 != post) {
+ s1 = s0->next;
+
+ // check for a finished segment
+ if (s0->y1 < yTop) {
+ removeSegment(s0);
+
+ // compute sx0, sx1, mx
+ } else {
+ if (s0->y0 >= yTop) {
+ s0->sx0 = s0->x0;
+ } else {
+ s0->sx0 = s0->x0 + (yTop - s0->y0) * s0->dxdy;
}
- if (seg->y0 != seg->y1) {
- seg->xCur0 = seg->x0;
- insertActiveSeg(seg);
+ if (s0->y1 <= yBottom) {
+ s0->sx1 = s0->x1;
+ } else {
+ s0->sx1 = s0->x0 + (yBottom - s0->y0) * s0->dxdy;
}
- ++nextSeg;
+ s0->mx = (s0->sx0 <= s0->sx1) ? s0->sx0 : s0->sx1;
}
- //--- get the next "interesting" y value
- y1 = y + 1;
- if (nextSeg < xPath->length && xPath->segs[nextSeg].y0 < y1) {
- y1 = xPath->segs[nextSeg].y0;
- }
- for (i = 0; i < activeSegs->getLength(); ++i) {
- seg = (SplashXPathSeg *)activeSegs->get(i);
- if (seg->y1 < y1) {
- y1 = seg->y1;
+ s0 = s1;
+ }
+
+ //--- check for intersections
+ s0 = pre->next;
+ if (s0 != post) {
+ s1 = s0->next;
+ while (s1 != post) {
+ if (s1->mx < s0->mx) {
+ for (s2 = s0->prev; s1->mx < s2->mx; s2 = s2->prev) ;
+ moveSegmentAfter(s1, s2);
+ } else {
+ s0 = s1;
}
+ s1 = s0->next;
}
+ }
- //--- compute xCur1 values, check for intersections
- seg0 = NULL;
- intersect = gFalse;
- for (i = 0; i < activeSegs->getLength(); ++i) {
- seg = (SplashXPathSeg *)activeSegs->get(i);
- if (seg->y1 == y1) {
- seg->xCur1 = seg->x1;
- } else {
- seg->xCur1 = seg->x0 + (y1 - seg->y0) * seg->dxdy;
+ //--- insert new segments with a merge sort
+ // - this has to be done one (sub)scanline at a time, because the
+ // inactive list is bin-sorted by (sub)scanline
+ while (nextSeg < xPath->length && xPath->segs[nextSeg].iy <= yTopI) {
+ // the first inactive segment determines the next scanline to process
+ iy = xPath->segs[nextSeg].iy;
+ s0 = pre->next;
+ do {
+ s1 = &xPath->segs[nextSeg];
+ ++nextSeg;
+ if (s1->y1 < yTop) {
+ continue;
}
- if (seg0 && seg0->xCur1 > seg->xCur1) {
- intersect = gTrue;
+ if (s1->y0 >= yTop) {
+ s1->sx0 = s1->x0;
+ } else {
+ s1->sx0 = s1->x0 + (yTop - s1->y0) * s1->dxdy;
}
- seg0 = seg;
- }
-
- //--- draw rectangles
- if (intersect) {
- for (; y0 < y1; y0 += minVertStep) {
- if ((y1p = y0 + minVertStep) >= y1) {
- y1p = y1;
- last = gTrue;
- } else {
- last = gFalse;
- }
- state0 = state1 = count = 0;
- seg0 = NULL;
- eoMask = eo ? 1 : 0xffffffff;
- for (i = 0; i < activeSegs->getLength(); ++i) {
- seg = (SplashXPathSeg *)activeSegs->get(i);
- if (last && seg->y1 == y1) {
- seg->xCur1 = seg->x1;
- } else {
- seg->xCur1 = seg->x0 + (y1p - seg->y0) * seg->dxdy;
- }
- count += seg->count;
- state1 = count & eoMask;
- if (!state0 && state1) {
- seg0 = seg;
- } else if (state0 && !state1) {
- drawRectangle(line, x0, x1, y0, y1p, seg0->xCur0, seg->xCur0);
- }
- state0 = state1;
- }
- for (i = 0; i < activeSegs->getLength(); ++i) {
- seg = (SplashXPathSeg *)activeSegs->get(i);
- seg->xCur0 = seg->xCur1;
- }
- sortActiveSegs();
+ if (s1->y1 <= yBottom) {
+ s1->sx1 = s1->x1;
+ } else {
+ s1->sx1 = s1->x0 + (yBottom - s1->y0) * s1->dxdy;
}
+ s1->mx = (s1->sx0 <= s1->sx1) ? s1->sx0 : s1->sx1;
+ insertSegmentBefore(s1, s0);
+ } while (nextSeg < xPath->length && xPath->segs[nextSeg].iy <= iy);
+ }
+}
- //--- draw trapezoids
- } else {
- state0 = state1 = count = 0;
- seg0 = NULL;
- eoMask = eo ? 1 : 0xffffffff;
- for (i = 0; i < activeSegs->getLength(); ++i) {
- seg = (SplashXPathSeg *)activeSegs->get(i);
- count += seg->count;
- state1 = count & eoMask;
- if (!state0 && state1) {
- seg0 = seg;
- } else if (state0 && !state1) {
- drawTrapezoid(line, x0, x1, y0, y1,
- seg0->xCur0, seg0->xCur1, seg0->dydx,
- seg->xCur0, seg->xCur1, seg->dydx);
- }
- state0 = state1;
- }
- for (i = 0; i < activeSegs->getLength(); ++i) {
- seg = (SplashXPathSeg *)activeSegs->get(i);
- seg->xCur0 = seg->xCur1;
- }
- }
+void SplashXPathScanner::advance(GBool aa) {
+ SplashXPathSeg *s, *sNext, *s1;
- //--- next slice
- y0 = y1;
+ yTopI = yBottomI;
+ yTop = yBottom;
+ yBottomI = yTopI + 1;
+ if (aa) {
+ yBottom = (SplashCoord)yBottomI / (SplashCoord)aaVert;
+ } else {
+ yBottom = (SplashCoord)yBottomI;
}
- yNext = y + 1;
-}
+ s = pre->next;
+ while (s != post) {
+ sNext = s->next;
-void SplashXPathScanner::getSpanBinary(Guchar *line, int y, int x0, int x1) {
- SplashXPathSeg *seg;
- int xx0, xx1, xx;
- int eoMask, state0, state1, count, i;
+ // check for a finished segment
+ if (s->y1 < yTop) {
+ removeSegment(s);
- //--- clear the scan line buffer
- memset(line + x0, 0, x1 - x0 + 1);
+ } else {
- //--- reset the path
- if (yNext != y) {
- delete activeSegs;
- activeSegs = new GList();
- nextSeg = 0;
- while (nextSeg < xPath->length) {
- seg = &xPath->segs[nextSeg];
- if (seg->y0 >= y) {
- break;
+ // compute sx0, sx1, mx
+ s->sx0 = s->sx1;
+ if (s->y1 <= yBottom) {
+ s->sx1 = s->x1;
+ } else {
+ s->sx1 = s->x0 + (yBottom - s->y0) * s->dxdy;
}
- if (seg->y1 > y) {
- if (seg->y0 == y) {
- seg->xCur0 = seg->x0;
- } else {
- seg->xCur0 = seg->x0 + ((SplashCoord)y - seg->y0) * seg->dxdy;
- }
- activeSegs->append(seg);
+ s->mx = (s->sx0 <= s->sx1) ? s->sx0 : s->sx1;
+
+ // check for intersection
+ if (s->mx < s->prev->mx) {
+ for (s1 = s->prev->prev; s->mx < s1->mx; s1 = s1->prev) ;
+ moveSegmentAfter(s, s1);
}
- ++nextSeg;
}
- activeSegs->sort(&SplashXPathSeg::cmpXi);
- }
- //--- delete finished segs
- i = 0;
- while (i < activeSegs->getLength()) {
- seg = (SplashXPathSeg *)activeSegs->get(i);
- if (seg->y1 <= y) {
- activeSegs->del(i);
- } else {
- ++i;
- }
+ s = sNext;
}
- //--- sort activeSegs
- sortActiveSegs();
-
- //--- add waiting segs
- while (nextSeg < xPath->length) {
- seg = &xPath->segs[nextSeg];
- if (seg->y0 >= y + 1) {
- break;
- }
- seg->xCur0 = seg->x0;
- insertActiveSeg(seg);
+ // insert new segments
+ s = pre->next;
+ while (nextSeg < xPath->length && xPath->segs[nextSeg].iy <= yTopI) {
+ s1 = &xPath->segs[nextSeg];
++nextSeg;
- }
-
- //--- compute xCur1 values
- for (i = 0; i < activeSegs->getLength(); ++i) {
- seg = (SplashXPathSeg *)activeSegs->get(i);
- if (seg->y1 <= y + 1) {
- seg->xCur1 = seg->x1;
- } else {
- seg->xCur1 = seg->x0 + ((SplashCoord)(y + 1) - seg->y0) * seg->dxdy;
+ while (s1->mx > s->mx) {
+ s = s->next;
}
+ insertSegmentBefore(s1, s);
}
+}
- //--- draw spans
- state0 = state1 = count = 0;
- eoMask = eo ? 1 : 0xffffffff;
- xx0 = xx1 = 0; // make gcc happy
- for (i = 0; i < activeSegs->getLength(); ++i) {
- seg = (SplashXPathSeg *)activeSegs->get(i);
- if (seg->y0 <= y && seg->y0 < seg->y1) {
- count += seg->count;
- state1 = count & eoMask;
- }
- if (state0) {
- xx = splashCeil(seg->xCur0) - 1;
- if (xx > xx1) {
- xx1 = xx;
- }
- xx = splashFloor(seg->xCur1);
- if (xx < xx0) {
- xx0 = xx;
- }
- xx = splashCeil(seg->xCur1) - 1;
- if (xx > xx1) {
- xx1 = xx;
- }
- } else {
- if (seg->xCur0 < seg->xCur1) {
- xx0 = splashFloor(seg->xCur0);
- xx1 = splashCeil(seg->xCur1) - 1;
- } else {
- xx0 = splashFloor(seg->xCur1);
- xx1 = splashCeil(seg->xCur0) - 1;
- }
+void SplashXPathScanner::generatePixels(int x0, int x1, Guchar *line,
+ int *xMin, int *xMax) {
+ SplashXPathSeg *s;
+ int fillCount, x, xEnd, ix0, ix1, t;
+
+ fillCount = 0;
+ x = x0 * aaHoriz;
+ xEnd = (x1 + 1) * aaHoriz;
+ for (s = pre->next; s != post && x < xEnd; s = s->next) {
+ ix0 = splashFloor(s->sx0 * aaHoriz);
+ ix1 = splashFloor(s->sx1 * aaHoriz);
+ if (ix0 > ix1) {
+ t = ix0; ix0 = ix1; ix1 = t;
}
- if (!state1) {
- if (xx0 < x0) {
- xx0 = x0;
- }
- if (xx1 > x1) {
- xx1 = x1;
- }
- for (xx = xx0; xx <= xx1; ++xx) {
- line[xx] = 0xff;
+ if (!(fillCount & eoMask)) {
+ if (ix0 > x) {
+ x = ix0;
}
}
- state0 = state1;
+ if (ix1 >= xEnd) {
+ ix1 = xEnd - 1;
+ }
+ if (x / aaHoriz < *xMin) {
+ *xMin = x / aaHoriz;
+ }
+ if (ix1 / aaHoriz > *xMax) {
+ *xMax = ix1 / aaHoriz;
+ }
+ for (; x <= ix1; ++x) {
+ ++line[x / aaHoriz];
+ }
+ if (s->y0 <= yTop && s->y1 > yTop) {
+ fillCount += s->count;
+ }
}
+}
- //--- update xCur0 values
- for (i = 0; i < activeSegs->getLength(); ++i) {
- seg = (SplashXPathSeg *)activeSegs->get(i);
- seg->xCur0 = seg->xCur1;
+void SplashXPathScanner::generatePixelsBinary(int x0, int x1, Guchar *line,
+ int *xMin, int *xMax) {
+ SplashXPathSeg *s;
+ int fillCount, x, xEnd, ix0, ix1, t;
+
+ fillCount = 0;
+ x = x0;
+ xEnd = x1 + 1;
+ for (s = pre->next; s != post && x < xEnd; s = s->next) {
+ ix0 = splashFloor(s->sx0);
+ ix1 = splashFloor(s->sx1);
+ if (ix0 > ix1) {
+ t = ix0; ix0 = ix1; ix1 = t;
+ }
+ if (!(fillCount & eoMask)) {
+ if (ix0 > x) {
+ x = ix0;
+ }
+ }
+ if (ix1 >= xEnd) {
+ ix1 = xEnd - 1;
+ }
+ if (x < *xMin) {
+ *xMin = x;
+ }
+ if (ix1 > *xMax) {
+ *xMax = ix1;
+ }
+ for (; x <= ix1; ++x) {
+ line[x] = 255;
+ }
+ if (s->y0 <= yTop && s->y1 > yTop) {
+ fillCount += s->count;
+ }
}
-
- yNext = y + 1;
}
-inline void SplashXPathScanner::addArea(Guchar *line, int x, SplashCoord a) {
- int a2, t;
+void SplashXPathScanner::drawRectangleSpan(Guchar *line, int y,
+ int x0, int x1,
+ int *xMin, int *xMax) {
+ SplashCoord edge;
+ Guchar pix;
+ int xe, x;
- a2 = splashRound(a * 255);
- if (a2 <= 0) {
+ if (rectX0I > x1 || rectX1I < x0) {
return;
}
- t = line[x] + a2;
- if (t > 255) {
- t = 255;
- }
- line[x] = t;
-}
-// Draw a trapezoid with edges:
-// top: (xa0, y0) - (xb0, y0)
-// left: (xa0, y0) - (xa1, y1)
-// right: (xb0, y0) - (xb1, y1)
-// bottom: (xa1, y1) - (xb1, y1)
-void SplashXPathScanner::drawTrapezoid(Guchar *line, int xMin, int xMax,
- SplashCoord y0, SplashCoord y1,
- SplashCoord xa0, SplashCoord xa1,
- SplashCoord dydxa,
- SplashCoord xb0, SplashCoord xb1,
- SplashCoord dydxb) {
- SplashCoord a, dy;
- int x0, x1, x2, x3, x;
-
- // check for a rectangle
- if (dydxa == 0 && dydxb == 0 && xa0 >= xMin && xb0 <= xMax) {
- x0 = splashFloor(xa0);
- x3 = splashFloor(xb0);
- dy = y1 - y0;
- if (x0 == x3) {
- addArea(line, x0, (xb0 - xa0) * dy);
+ *xMin = x0 <= rectX0I ? rectX0I : x0;
+ *xMax = rectX1I <= x1 ? rectX1I : x1;
+
+ //--- upper edge
+ if (y == rectY0I) {
+
+ // handle a rectangle less than one pixel high
+ if (rectY0I == rectY1I) {
+ edge = xPath->rectY1 - xPath->rectY0;
+ } else {
+ edge = (SplashCoord)1 - (xPath->rectY0 - rectY0I);
+ }
+
+ // upper left corner
+ if (x0 <= rectX0I) {
+ pix = (Guchar)splashCeil(edge
+ * ((SplashCoord)1 - (xPath->rectX0 - rectX0I))
+ * 255);
+ if (pix < 16) {
+ pix = 16;
+ }
+ line[rectX0I] = pix;
+ x = rectX0I + 1;
} else {
- addArea(line, x0, ((SplashCoord)1 - (xa0 - x0)) * dy);
- for (x = x0 + 1; x <= x3 - 1; ++x) {
- addArea(line, x, y1 - y0);
+ x = x0;
+ }
+
+ // upper right corner
+ if (rectX1I <= x1) {
+ pix = (Guchar)splashCeil(edge * (xPath->rectX1 - rectX1I) * 255);
+ if (pix < 16) {
+ pix = 16;
}
- addArea(line, x3, (xb0 - x3) * (y1 - y0));
+ line[rectX1I] = pix;
+ xe = rectX1I - 1;
+ } else {
+ xe = x1;
}
- return;
- }
- if (dydxa > 0) {
- x0 = splashFloor(xa0);
- x1 = splashFloor(xa1);
- } else {
- x0 = splashFloor(xa1);
- x1 = splashFloor(xa0);
- }
- if (x0 < xMin) {
- x0 = xMin;
- }
- if (dydxb > 0) {
- x2 = splashFloor(xb0);
- x3 = splashFloor(xb1);
- } else {
- x2 = splashFloor(xb1);
- x3 = splashFloor(xb0);
- }
- if (x3 > xMax) {
- x3 = xMax;
- }
- for (x = x0; x <= x3; ++x) {
- a = y1 - y0;
- if (x <= x1) {
- a -= areaLeft(x, xa0, y0, xa1, y1, dydxa);
+ // upper edge
+ pix = (Guchar)splashCeil(edge * 255);
+ if (pix < 16) {
+ pix = 16;
}
- if (x >= x2) {
- a -= areaRight(x, xb0, y0, xb1, y1, dydxb);
+ for (; x <= xe; ++x) {
+ line[x] = pix;
}
- addArea(line, x, a);
- }
-}
-// Compute area within a pixel slice ((xp,y0)-(xp+1,y1)) to the left
-// of a trapezoid edge ((x0,y0)-(x1,y1)).
-SplashCoord SplashXPathScanner::areaLeft(int xp,
- SplashCoord x0, SplashCoord y0,
- SplashCoord x1, SplashCoord y1,
- SplashCoord dydx) {
- SplashCoord a, ya, yb;
-
- if (dydx >= 0) {
- if (x0 >= xp) {
- if (x1 <= xp + 1) {
- a = ((x0 + x1) * 0.5 - xp) * (y1 - y0);
- } else {
- yb = y0 + ((SplashCoord)(xp + 1) - x0) * dydx;
- a = (y1 - y0) - ((SplashCoord)(xp + 1) - x0) * (yb - y0) * 0.5;
+ //--- lower edge
+ } else if (y == rectY1I) {
+ edge = xPath->rectY1 - rectY1I;
+
+ // lower left corner
+ if (x0 <= rectX0I) {
+ pix = (Guchar)splashCeil(edge
+ * ((SplashCoord)1 - (xPath->rectX0 - rectX0I))
+ * 255);
+ if (pix < 16) {
+ pix = 16;
}
+ line[rectX0I] = pix;
+ x = rectX0I + 1;
} else {
- if (x1 <= xp + 1) {
- ya = y0 + ((SplashCoord)xp - x0) * dydx;
- a = (x1 - xp) * (y1 - ya) * 0.5;
- } else {
- // ya = y1 - (x1 - xp - 0.5) * dydx;
- // a = y1 - ya;
- a = (x1 - xp - 0.5) * dydx;
- }
+ x = x0;
}
- } else {
- if (x0 <= xp + 1) {
- if (x1 >= xp) {
- a = ((x0 + x1) * 0.5 - xp) * (y1 - y0);
- } else {
- ya = y0 + ((SplashCoord)xp - x0) * dydx;
- a = (x0 - xp) * (ya - y0) * 0.5;
+
+ // lower right corner
+ if (rectX1I <= x1) {
+ pix = (Guchar)splashCeil(edge * (xPath->rectX1 - rectX1I) * 255);
+ if (pix < 16) {
+ pix = 16;
}
+ line[rectX1I] = pix;
+ xe = rectX1I - 1;
} else {
- if (x1 >= xp) {
- yb = y0 + ((SplashCoord)(xp + 1) - x0) * dydx;
- a = (y1 - y0) - ((SplashCoord)(xp + 1) - x1) * (y1 - yb) * 0.5;
- } else {
- // ya = y0 + (xp - x0 + 0.5) * dydx;
- // a = ya - y0;
- a = ((SplashCoord)xp - x0 + 0.5) * dydx;
- }
+ xe = x1;
}
- }
- return a;
-}
-// Compute area within a pixel slice ((xp,y0)-(xp+1,y1)) to the left
-// of a trapezoid edge ((x0,y0)-(x1,y1)).
-SplashCoord SplashXPathScanner::areaRight(int xp,
- SplashCoord x0, SplashCoord y0,
- SplashCoord x1, SplashCoord y1,
- SplashCoord dydx) {
- SplashCoord a, ya, yb;
-
- if (dydx >= 0) {
- if (x0 >= xp) {
- if (x1 <= xp + 1) {
- a = ((SplashCoord)(xp + 1) - (x0 + x1) * 0.5) * (y1 - y0);
- } else {
- yb = y0 + ((SplashCoord)(xp + 1) - x0) * dydx;
- a = ((SplashCoord)(xp + 1) - x0) * (yb - y0) * 0.5;
+ // lower edge
+ pix = (Guchar)splashCeil(edge * 255);
+ if (pix < 16) {
+ pix = 16;
+ }
+ for (; x <= xe; ++x) {
+ line[x] = pix;
+ }
+
+ //--- between the upper and lower edges
+ } else if (y > rectY0I && y < rectY1I) {
+
+ // left edge
+ if (x0 <= rectX0I) {
+ pix = (Guchar)splashCeil(((SplashCoord)1 - (xPath->rectX0 - rectX0I))
+ * 255);
+ if (pix < 16) {
+ pix = 16;
}
+ line[rectX0I] = pix;
+ x = rectX0I + 1;
} else {
- if (x1 <= xp + 1) {
- ya = y0 + ((SplashCoord)xp - x0) * dydx;
- a = (y1 - y0) - (x1 - xp) * (y1 - ya) * 0.5;
- } else {
- // ya = y0 + (xp - x0 + 0.5) * dydx;
- // a = ya - y0;
- a = ((SplashCoord)xp + 0.5 - x0) * dydx;
- }
+ x = x0;
}
- } else {
- if (x0 <= xp + 1) {
- if (x1 >= xp) {
- a = ((SplashCoord)(xp + 1) - (x0 + x1) * 0.5) * (y1 - y0);
- } else {
- ya = y0 + ((SplashCoord)xp - x0) * dydx;
- a = (y1 - y0) - (x0 - xp) * (ya - y0) * 0.5;
+
+ // right edge
+ if (rectX1I <= x1) {
+ pix = (Guchar)splashCeil((xPath->rectX1 - rectX1I) * 255);
+ if (pix < 16) {
+ pix = 16;
}
+ line[rectX1I] = pix;
+ xe = rectX1I - 1;
} else {
- if (x1 >= xp) {
- yb = y0 + ((SplashCoord)(xp + 1) - x0) * dydx;
- a = ((SplashCoord)(xp + 1) - x1) * (y1 - yb) * 0.5;
- } else {
- // ya = y1 - (x1 - xp - 0.5) * dydx;
- // a = y1 - ya;
- a = (x1 - xp - 0.5) * dydx;
- }
+ xe = x1;
+ }
+
+ // middle
+ for (; x <= xe; ++x) {
+ line[x] = 255;
}
}
- return a;
}
-void SplashXPathScanner::drawRectangle(Guchar *line, int xMin, int xMax,
- SplashCoord y0, SplashCoord y1,
- SplashCoord x0, SplashCoord x1) {
- SplashCoord dy, a;
- int xx0, xx1, x;
+void SplashXPathScanner::drawRectangleSpanBinary(Guchar *line, int y,
+ int x0, int x1,
+ int *xMin, int *xMax) {
+ int xe, x;
- xx0 = splashFloor(x0);
- if (xx0 < xMin) {
- xx0 = xMin;
- }
- xx1 = splashFloor(x1);
- if (xx1 > xMax) {
- xx1 = xMax;
- }
- dy = y1 - y0;
- for (x = xx0; x <= xx1; ++x) {
- a = dy;
- if ((SplashCoord)x < x0) {
- a -= (x0 - x) * dy;
+ if (y >= rectY0I && y <= rectY1I) {
+ if (x0 <= rectX0I) {
+ x = rectX0I;
+ } else {
+ x = x0;
}
- if ((SplashCoord)(x + 1) > x1) {
- a -= ((SplashCoord)(x + 1) - x1) * dy;
+ *xMin = x;
+ if (rectX1I <= x1) {
+ xe = rectX1I;
+ } else {
+ xe = x1;
+ }
+ *xMax = xe;
+ for (; x <= xe; ++x) {
+ line[x] = 255;
}
- addArea(line, x, a);
}
}
-void SplashXPathScanner::sortActiveSegs() {
- SplashXPathSeg *seg0, *seg1;
- int i, j, k;
+void SplashXPathScanner::getSpan(Guchar *line, int y, int x0, int x1,
+ int *xMin, int *xMax) {
+ int iy, x, k;
- if (activeSegs->getLength() < 2) {
+ iy = y * aaVert;
+ if (!resetDone || !resetAA) {
+ reset(gTrue, gTrue);
+ } else if (yBottomI > iy) {
+ reset(gTrue, gFalse);
+ }
+ memset(line + x0, 0, x1 - x0 + 1);
+
+ *xMin = x1 + 1;
+ *xMax = x0 - 1;
+
+ if (xPath->isRect) {
+ drawRectangleSpan(line, y, x0, x1, xMin, xMax);
return;
}
- seg0 = (SplashXPathSeg *)activeSegs->get(0);
- for (i = 1; i < activeSegs->getLength(); ++i) {
- seg1 = (SplashXPathSeg *)activeSegs->get(i);
- if (SplashXPathSeg::cmpX(seg0, seg1) > 0) {
- for (j = i - 1; j > 0; --j) {
- if (SplashXPathSeg::cmpX((SplashXPathSeg *)activeSegs->get(j - 1),
- seg1) <= 0) {
- break;
- }
- }
- for (k = i; k > j; --k) {
- activeSegs->put(k, activeSegs->get(k-1));
- }
- activeSegs->put(j, seg1);
- } else {
- seg0 = seg1;
- }
+
+ if (yBottomI < iy) {
+ skip(iy, gTrue);
+ }
+ for (k = 0; k < aaVert; ++k, ++iy) {
+ advance(gTrue);
+ generatePixels(x0, x1, line, xMin, xMax);
+ }
+
+#if !ANTIALIAS_256
+ for (x = *xMin; x <= *xMax; ++x) {
+ line[x] = map16to255[line[x]];
}
+#endif
}
-void SplashXPathScanner::insertActiveSeg(SplashXPathSeg *seg) {
- int i;
+void SplashXPathScanner::getSpanBinary(Guchar *line, int y, int x0, int x1,
+ int *xMin, int *xMax) {
+ int iy;
- for (i = 0; i < activeSegs->getLength(); ++i) {
- if (SplashXPathSeg::cmpX(seg, (SplashXPathSeg *)activeSegs->get(i)) < 0) {
- break;
- }
+ iy = y;
+ if (!resetDone || resetAA) {
+ reset(gFalse, gTrue);
+ } else if (yBottomI > iy) {
+ reset(gFalse, gFalse);
+ }
+ memset(line + x0, 0, x1 - x0 + 1);
+
+ *xMin = x1 + 1;
+ *xMax = x0 - 1;
+
+ if (xPath->isRect) {
+ drawRectangleSpanBinary(line, y, x0, x1, xMin, xMax);
+ return;
+ }
+
+ if (yBottomI < iy) {
+ skip(iy, gFalse);
}
- activeSegs->insert(i, seg);
+ advance(gFalse);
+ generatePixelsBinary(x0, x1, line, xMin, xMax);
}
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.h
index 519ff4dfcac..39cc0eb022a 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.h
@@ -16,9 +16,15 @@
#endif
#include "SplashTypes.h"
+#include "SplashXPath.h"
class GList;
-class SplashXPath;
+
+//------------------------------------------------------------------------
+
+// Set this to 0 for antialiasing with 16 levels of gray.
+// Set it to 1 for (much slower) antialiasing with 256 levels of gray.
+#define ANTIALIAS_256 0
//------------------------------------------------------------------------
// SplashXPathScanner
@@ -28,48 +34,51 @@ class SplashXPathScanner {
public:
// Create a new SplashXPathScanner object. <xPathA> must be sorted.
- SplashXPathScanner(SplashXPath *xPathA, GBool eoA,
+ SplashXPathScanner(SplashXPath *xPathA, GBool eo,
int yMinA, int yMaxA);
~SplashXPathScanner();
// Compute shape values for a scan line. Fills in line[] with shape
// values for one scan line: ([x0, x1], y). The values are in [0,
- // 255].
- void getSpan(Guchar *line, int y, int x0, int x1);
+ // 255]. Also returns the min/max x positions with non-zero shape
+ // values.
+ void getSpan(Guchar *line, int y, int x0, int x1, int *xMin, int *xMax);
// Like getSpan(), but uses the values 0 and 255 only. Writes 255
// for all pixels which include non-zero area inside the path.
- void getSpanBinary(Guchar *line, int y, int x0, int x1);
+ void getSpanBinary(Guchar *line, int y, int x0, int x1,
+ int *xMin, int *xMax);
private:
- inline void addArea(Guchar *line, int x, SplashCoord a);
- void drawTrapezoid(Guchar *line, int xMin, int xMax,
- SplashCoord y0, SplashCoord y1,
- SplashCoord xa0, SplashCoord xa1, SplashCoord dydxa,
- SplashCoord xb0, SplashCoord xb1, SplashCoord dydxb);
- SplashCoord areaLeft(int xp,
- SplashCoord x0, SplashCoord y0,
- SplashCoord x1, SplashCoord y1,
- SplashCoord dydx);
- SplashCoord areaRight(int xp,
- SplashCoord x0, SplashCoord y0,
- SplashCoord x1, SplashCoord y1,
- SplashCoord dydx);
- void drawRectangle(Guchar *line, int xMin, int xMax,
- SplashCoord y0, SplashCoord y1,
- SplashCoord x0, SplashCoord x1);
- void sortActiveSegs();
- void insertActiveSeg(SplashXPathSeg *seg);
+ void insertSegmentBefore(SplashXPathSeg *s, SplashXPathSeg *sNext);
+ void removeSegment(SplashXPathSeg *s);
+ void moveSegmentAfter(SplashXPathSeg *s, SplashXPathSeg *sPrev);
+ void reset(GBool aa, GBool aaChanged);
+ void skip(int newYBottomI, GBool aa);
+ void advance(GBool aa);
+ void generatePixels(int x0, int x1, Guchar *line, int *xMin, int *xMax);
+ void generatePixelsBinary(int x0, int x1, Guchar *line,
+ int *xMin, int *xMax);
+ void drawRectangleSpan(Guchar *line, int y, int x0, int x1,
+ int *xMin, int *xMax);
+ void drawRectangleSpanBinary(Guchar *line, int y, int x0, int x1,
+ int *xMin, int *xMax);
SplashXPath *xPath;
- GBool eo;
+ int eoMask;
int yMin, yMax;
+ int rectX0I, rectY0I, rectX1I, rectY1I;
+
+ SplashXPathSeg preSeg, postSeg;
+ SplashXPathSeg *pre, *post;
- GList *activeSegs; // [SplashXPathSeg]
+ GBool resetDone;
+ GBool resetAA;
int nextSeg;
- int yNext;
+ int yTopI, yBottomI;
+ SplashCoord yTop, yBottom;
};
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
index 86e70375c85..834841fd512 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc
@@ -15,6 +15,7 @@
#include <stdlib.h>
#include <math.h>
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "GList.h"
#include "Error.h"
@@ -79,33 +80,105 @@ public:
//------------------------------------------------------------------------
AcroForm *AcroForm::load(PDFDoc *docA, Catalog *catalog, Object *acroFormObjA) {
+ Object acroFormObj2;
AcroForm *acroForm;
- Object fieldsObj, obj1, obj2;
- int i;
+ AcroFormField *field;
+ Object fieldsObj, annotsObj, annotRef, annotObj, obj1, obj2;
+ int pageNum, i, j;
- acroForm = new AcroForm(docA, acroFormObjA);
+ // this is the normal case: acroFormObj is a dictionary, as expected
+ if (acroFormObjA->isDict()) {
+ acroForm = new AcroForm(docA, acroFormObjA);
- if (acroFormObjA->dictLookup("NeedAppearances", &obj1)->isBool()) {
- acroForm->needAppearances = obj1.getBool();
- }
- obj1.free();
+ if (acroFormObjA->dictLookup("NeedAppearances", &obj1)->isBool()) {
+ acroForm->needAppearances = obj1.getBool();
+ }
+ obj1.free();
- acroForm->buildAnnotPageList(catalog);
+ acroForm->buildAnnotPageList(catalog);
- if (!acroFormObjA->dictLookup("Fields", &obj1)->isArray()) {
- if (!obj1.isNull()) {
- error(errSyntaxError, -1, "AcroForm Fields entry is wrong type");
+ if (!acroFormObjA->dictLookup("Fields", &obj1)->isArray()) {
+ if (!obj1.isNull()) {
+ error(errSyntaxError, -1, "AcroForm Fields entry is wrong type");
+ }
+ obj1.free();
+ delete acroForm;
+ return NULL;
+ }
+ for (i = 0; i < obj1.arrayGetLength(); ++i) {
+ obj1.arrayGetNF(i, &obj2);
+ acroForm->scanField(&obj2);
+ obj2.free();
}
obj1.free();
- delete acroForm;
- return NULL;
- }
- for (i = 0; i < obj1.arrayGetLength(); ++i) {
- obj1.arrayGetNF(i, &obj2);
- acroForm->scanField(&obj2);
- obj2.free();
+
+ // scan the annotations, looking for Widget-type annots that are
+ // not attached to the AcroForm object
+ for (pageNum = 1; pageNum <= catalog->getNumPages(); ++pageNum) {
+ if (catalog->getPage(pageNum)->getAnnots(&annotsObj)->isArray()) {
+ for (i = 0; i < annotsObj.arrayGetLength(); ++i) {
+ if (annotsObj.arrayGetNF(i, &annotRef)->isRef()) {
+ for (j = 0; j < acroForm->fields->getLength(); ++j) {
+ field = (AcroFormField *)acroForm->fields->get(j);
+ if (field->fieldRef.isRef()) {
+ if (field->fieldRef.getRefNum() == annotRef.getRefNum() &&
+ field->fieldRef.getRefGen() == annotRef.getRefGen()) {
+ break;
+ }
+ }
+ }
+ if (j == acroForm->fields->getLength()) {
+ annotRef.fetch(acroForm->doc->getXRef(), &annotObj);
+ if (annotObj.isDict()) {
+ if (annotObj.dictLookup("Subtype", &obj1)->isName("Widget")) {
+ acroForm->scanField(&annotRef);
+ }
+ obj1.free();
+ }
+ annotObj.free();
+ }
+ }
+ annotRef.free();
+ }
+ }
+ annotsObj.free();
+ }
+
+ // if acroFormObjA is a null object, but there are Widget-type
+ // annots, we still create an AcroForm
+ } else {
+ // create an empty dict for acroFormObj
+ acroFormObj2.initDict(docA->getXRef());
+ acroForm = new AcroForm(docA, &acroFormObj2);
+ acroFormObj2.free();
+
+ acroForm->buildAnnotPageList(catalog);
+
+ // scan the annotations, looking for any Widget-type annots
+ for (pageNum = 1; pageNum <= catalog->getNumPages(); ++pageNum) {
+ if (catalog->getPage(pageNum)->getAnnots(&annotsObj)->isArray()) {
+ for (i = 0; i < annotsObj.arrayGetLength(); ++i) {
+ if (annotsObj.arrayGetNF(i, &annotRef)->isRef()) {
+ annotRef.fetch(acroForm->doc->getXRef(), &annotObj);
+ if (annotObj.isDict()) {
+ if (annotObj.dictLookup("Subtype", &obj1)->isName("Widget")) {
+ acroForm->scanField(&annotRef);
+ }
+ obj1.free();
+ }
+ annotObj.free();
+ }
+ annotRef.free();
+ }
+ }
+ annotsObj.free();
+ }
+
+ if (acroForm->fields->getLength() == 0) {
+ delete acroForm;
+ acroForm = NULL;
+ }
}
- obj1.free();
return acroForm;
}
@@ -235,7 +308,7 @@ AcroFormField *AcroFormField::load(AcroForm *acroFormA, Object *fieldRefA) {
GString *typeStr;
TextString *nameA;
Guint flagsA;
- GBool haveFlags;
+ GBool haveFlags, typeFromParentA;
Object fieldObjA, parentObj, parentObj2, obj1, obj2;
AcroFormFieldType typeA;
AcroFormField *field;
@@ -253,8 +326,10 @@ AcroFormField *AcroFormField::load(AcroForm *acroFormA, Object *fieldRefA) {
if (fieldObjA.dictLookup("FT", &obj1)->isName()) {
typeStr = new GString(obj1.getName());
+ typeFromParentA = gFalse;
} else {
typeStr = NULL;
+ typeFromParentA = gTrue;
}
obj1.free();
@@ -304,7 +379,19 @@ AcroFormField *AcroFormField::load(AcroForm *acroFormA, Object *fieldRefA) {
if (!typeStr) {
error(errSyntaxError, -1, "Missing type in AcroForm field");
goto err1;
- } else if (!typeStr->cmp("Btn")) {
+ }
+
+ //----- check for a radio button
+
+ // this is a kludge: if we see a Btn-type field with kids, and the
+ // Ff entry is missing, assume the kids are radio buttons
+ if (typeFromParentA && !typeStr->cmp("Btn") && !haveFlags) {
+ flagsA = acroFormFlagRadio;
+ }
+
+ //----- determine field type
+
+ if (!typeStr->cmp("Btn")) {
if (flagsA & acroFormFlagPushbutton) {
typeA = acroFormFieldPushbutton;
} else if (flagsA & acroFormFlagRadio) {
@@ -335,7 +422,7 @@ AcroFormField *AcroFormField::load(AcroForm *acroFormA, Object *fieldRefA) {
delete typeStr;
field = new AcroFormField(acroFormA, fieldRefA, &fieldObjA,
- typeA, nameA, flagsA);
+ typeA, nameA, flagsA, typeFromParentA);
fieldObjA.free();
return field;
@@ -349,13 +436,14 @@ AcroFormField *AcroFormField::load(AcroForm *acroFormA, Object *fieldRefA) {
AcroFormField::AcroFormField(AcroForm *acroFormA,
Object *fieldRefA, Object *fieldObjA,
AcroFormFieldType typeA, TextString *nameA,
- Guint flagsA) {
+ Guint flagsA, GBool typeFromParentA) {
acroForm = acroFormA;
fieldRefA->copy(&fieldRef);
fieldObjA->copy(&fieldObj);
type = typeA;
name = nameA;
flags = flagsA;
+ typeFromParent = typeFromParentA;
}
AcroFormField::~AcroFormField() {
@@ -364,6 +452,24 @@ AcroFormField::~AcroFormField() {
delete name;
}
+int AcroFormField::getPageNum() {
+ Object kidsObj, annotRef;
+ int pageNum;
+
+ pageNum = 0;
+ if (fieldObj.dictLookup("Kids", &kidsObj)->isArray()) {
+ if (kidsObj.arrayGetLength() > 0) {
+ kidsObj.arrayGetNF(0, &annotRef);
+ pageNum = acroForm->lookupAnnotPage(&annotRef);
+ annotRef.free();
+ }
+ } else {
+ pageNum = acroForm->lookupAnnotPage(&fieldRef);
+ }
+ kidsObj.free();
+ return pageNum;
+}
+
const char *AcroFormField::getType() {
switch (type) {
case acroFormFieldPushbutton: return "PushButton";
@@ -392,12 +498,16 @@ Unicode *AcroFormField::getName(int *length) {
}
Unicode *AcroFormField::getValue(int *length) {
- Object obj1;
+ Object obj1, obj2;
Unicode *u;
char *s;
TextString *ts;
+ GString *gs;
int n, i;
+ u = NULL;
+ *length = 0;
+
fieldLookup("V", &obj1);
if (obj1.isName()) {
s = obj1.getName();
@@ -407,7 +517,6 @@ Unicode *AcroFormField::getValue(int *length) {
u[i] = s[i] & 0xff;
}
*length = n;
- return u;
} else if (obj1.isString()) {
ts = new TextString(obj1.getString());
n = ts->getLength();
@@ -415,10 +524,198 @@ Unicode *AcroFormField::getValue(int *length) {
memcpy(u, ts->getUnicode(), n * sizeof(Unicode));
*length = n;
delete ts;
- return u;
+ } else if (obj1.isDict()) {
+ obj1.dictLookup("Contents", &obj2);
+ if (obj2.isString()) {
+ gs = obj2.getString();
+ n = gs->getLength();
+ u = (Unicode *)gmallocn(n, sizeof(Unicode));
+ for (i = 0; i < n; ++i) {
+ u[i] = gs->getChar(i) & 0xff;
+ }
+ *length = n;
+ }
+ obj2.free();
+ }
+ obj1.free();
+
+ return u;
+}
+
+void AcroFormField::getBBox(double *llx, double *lly,
+ double *urx, double *ury) {
+ Object annotObj, rectObj, numObj;
+ double t;
+
+ *llx = *lly = *urx = *ury = 0;
+
+ if (getAnnotObj(&annotObj)->isDict()) {
+ annotObj.dictLookup("Rect", &rectObj);
+ if (rectObj.isArray() && rectObj.arrayGetLength() == 4) {
+ rectObj.arrayGet(0, &numObj);
+ if (numObj.isNum()) {
+ *llx = numObj.getNum();
+ }
+ numObj.free();
+ rectObj.arrayGet(1, &numObj);
+ if (numObj.isNum()) {
+ *lly = numObj.getNum();
+ }
+ numObj.free();
+ rectObj.arrayGet(2, &numObj);
+ if (numObj.isNum()) {
+ *urx = numObj.getNum();
+ }
+ numObj.free();
+ rectObj.arrayGet(3, &numObj);
+ if (numObj.isNum()) {
+ *ury = numObj.getNum();
+ }
+ numObj.free();
+ }
+ rectObj.free();
+ }
+ annotObj.free();
+
+ if (*llx > *urx) {
+ t = *llx; *llx = *urx; *urx = t;
+ }
+ if (*lly > *ury) {
+ t = *lly; *lly = *ury; *ury = t;
+ }
+}
+
+void AcroFormField::getFont(Ref *fontID, double *fontSize) {
+ Object daObj;
+ GList *daToks;
+ char *fontTag;
+ double tfSize, m2, m3;
+ int tfPos, tmPos, i;
+
+ fontID->num = fontID->gen = -1;
+ *fontSize = 0;
+
+ if (fieldLookup("DA", &daObj)->isString()) {
+
+ // parse the default appearance string
+ daToks = tokenize(daObj.getString());
+ tfPos = tmPos = -1;
+ for (i = 2; i < daToks->getLength(); ++i) {
+ if (!((GString *)daToks->get(i))->cmp("Tf")) {
+ tfPos = i - 2;
+ } else if (i >= 6 && !((GString *)daToks->get(i))->cmp("Tm")) {
+ tmPos = i - 6;
+ }
+ }
+
+ // handle the Tf operator
+ if (tfPos >= 0) {
+ fontTag = ((GString *)daToks->get(tfPos))->getCString();
+ if (*fontTag == '/') {
+ ++fontTag;
+ }
+ *fontID = findFontName(fontTag);
+ tfSize = atof(((GString *)daToks->get(tfPos + 1))->getCString());
+ } else {
+ tfSize = 1;
+ }
+
+ // handle the Tm operator
+ if (tmPos >= 0) {
+ // transformed font size = sqrt(m[2]^2 + m[3]^2) * size
+ m2 = atof(((GString *)daToks->get(tfPos + 2))->getCString());
+ m3 = atof(((GString *)daToks->get(tfPos + 3))->getCString());
+ tfSize *= sqrt(m2*m2 + m3*m3);
+ }
+ *fontSize = tfSize;
+
+ deleteGList(daToks, GString);
+ }
+
+ daObj.free();
+}
+
+Ref AcroFormField::findFontName(char *fontTag) {
+ Object drObj, fontDictObj, fontObj, baseFontObj;
+ Ref fontID;
+ GBool found;
+
+ fontID.num = fontID.gen = -1;
+ found = gFalse;
+
+ if (fieldObj.dictLookup("DR", &drObj)->isDict()) {
+ if (drObj.dictLookup("Font", &fontDictObj)->isDict()) {
+ if (fontDictObj.dictLookupNF(fontTag, &fontObj)->isRef()) {
+ fontID = fontObj.getRef();
+ found = gTrue;
+ }
+ fontObj.free();
+ }
+ fontDictObj.free();
+ }
+ drObj.free();
+ if (found) {
+ return fontID;
+ }
+
+ if (acroForm->acroFormObj.dictLookup("DR", &drObj)->isDict()) {
+ if (drObj.dictLookup("Font", &fontDictObj)->isDict()) {
+ if (fontDictObj.dictLookupNF(fontTag, &fontObj)->isRef()) {
+ fontID = fontObj.getRef();
+ }
+ fontObj.free();
+ }
+ fontDictObj.free();
+ }
+ drObj.free();
+ return fontID;
+}
+
+void AcroFormField::getColor(double *red, double *green, double *blue) {
+ Object daObj;
+ GList *daToks;
+ int i;
+
+ *red = *green = *blue = 0;
+
+ if (fieldLookup("DA", &daObj)->isString()) {
+
+ // parse the default appearance string
+ daToks = tokenize(daObj.getString());
+ for (i = 1; i < daToks->getLength(); ++i) {
+
+ // handle the g operator
+ if (!((GString *)daToks->get(i))->cmp("g")) {
+ *red = *green = *blue =
+ atof(((GString *)daToks->get(i - 1))->getCString());
+ break;
+
+ // handle the rg operator
+ } else if (i >= 3 && !((GString *)daToks->get(i))->cmp("rg")) {
+ *red = atof(((GString *)daToks->get(i - 3))->getCString());
+ *green = atof(((GString *)daToks->get(i - 2))->getCString());
+ *blue = atof(((GString *)daToks->get(i - 1))->getCString());
+ break;
+ }
+ }
+
+ deleteGList(daToks, GString);
+ }
+
+ daObj.free();
+}
+
+int AcroFormField::getMaxLen() {
+ Object obj;
+ int len;
+
+ if (fieldLookup("MaxLen", &obj)->isInt()) {
+ len = obj.getInt();
} else {
- return NULL;
+ len = -1;
}
+ obj.free();
+ return len;
}
void AcroFormField::draw(int pageNum, Gfx *gfx, GBool printing) {
@@ -445,7 +742,7 @@ void AcroFormField::drawAnnot(int pageNum, Gfx *gfx, GBool printing,
Object obj1, obj2;
double xMin, yMin, xMax, yMax, t;
int annotFlags;
- GBool oc;
+ GBool oc, render;
if (!annotObj->isDict()) {
return;
@@ -518,7 +815,16 @@ void AcroFormField::drawAnnot(int pageNum, Gfx *gfx, GBool printing,
//----- draw it
+ render = gFalse;
if (acroForm->needAppearances) {
+ render = gTrue;
+ } else {
+ if (!annotObj->dictLookup("AP", &obj1)->isDict()) {
+ render = gTrue;
+ }
+ obj1.free();
+ }
+ if (render) {
drawNewAppearance(gfx, annotObj->getDict(),
xMin, yMin, xMax, yMax);
} else {
@@ -562,11 +868,13 @@ void AcroFormField::drawExistingAppearance(Gfx *gfx, Dict *annot,
}
}
-// Regenerate the appearnce for this field, and draw it.
+// Regenerate the appearance for this field, and draw it.
void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
double xMin, double yMin,
double xMax, double yMax) {
+ GString *appearBuf;
Object appearance, mkObj, ftObj, appearDict, drObj, apObj, asObj;
+ Object resources, fontResources, defaultFont, gfxStateDict;
Object obj1, obj2, obj3;
Dict *mkDict;
MemStream *appearStream;
@@ -595,7 +903,7 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
if (mkDict) {
if (mkDict->lookup("BG", &obj1)->isArray() &&
obj1.arrayGetLength() > 0) {
- setColor(obj1.getArray(), gTrue, 0);
+ setColor(obj1.getArray(), gTrue, 0, appearBuf);
appearBuf->appendf("0 0 {0:.4f} {1:.4f} re f\n",
xMax - xMin, yMax - yMin);
}
@@ -678,6 +986,7 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
if (borderWidth > 0) {
mkDict->lookup("BC", &obj1);
if (!(obj1.isArray() && obj1.arrayGetLength() > 0)) {
+ obj1.free();
mkDict->lookup("BG", &obj1);
}
if (obj1.isArray() && obj1.arrayGetLength() > 0) {
@@ -700,20 +1009,26 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
case annotBorderSolid:
case annotBorderUnderlined:
appearBuf->appendf("{0:.4f} w\n", borderWidth);
- setColor(obj1.getArray(), gFalse, 0);
- drawCircle(0.5 * dx, 0.5 * dy, r - 0.5 * borderWidth, "s");
+ setColor(obj1.getArray(), gFalse, 0, appearBuf);
+ drawCircle(0.5 * dx, 0.5 * dy, r - 0.5 * borderWidth, "s",
+ appearBuf);
break;
case annotBorderBeveled:
case annotBorderInset:
appearBuf->appendf("{0:.4f} w\n", 0.5 * borderWidth);
- setColor(obj1.getArray(), gFalse, 0);
- drawCircle(0.5 * dx, 0.5 * dy, r - 0.25 * borderWidth, "s");
+ setColor(obj1.getArray(), gFalse, 0, appearBuf);
+ drawCircle(0.5 * dx, 0.5 * dy, r - 0.25 * borderWidth, "s",
+ appearBuf);
setColor(obj1.getArray(), gFalse,
- borderType == annotBorderBeveled ? 1 : -1);
- drawCircleTopLeft(0.5 * dx, 0.5 * dy, r - 0.75 * borderWidth);
+ borderType == annotBorderBeveled ? 1 : -1,
+ appearBuf);
+ drawCircleTopLeft(0.5 * dx, 0.5 * dy, r - 0.75 * borderWidth,
+ appearBuf);
setColor(obj1.getArray(), gFalse,
- borderType == annotBorderBeveled ? -1 : 1);
- drawCircleBottomRight(0.5 * dx, 0.5 * dy, r - 0.75 * borderWidth);
+ borderType == annotBorderBeveled ? -1 : 1,
+ appearBuf);
+ drawCircleBottomRight(0.5 * dx, 0.5 * dy, r - 0.75 * borderWidth,
+ appearBuf);
break;
}
@@ -728,7 +1043,7 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
// fall through to the solid case
case annotBorderSolid:
appearBuf->appendf("{0:.4f} w\n", borderWidth);
- setColor(obj1.getArray(), gFalse, 0);
+ setColor(obj1.getArray(), gFalse, 0, appearBuf);
appearBuf->appendf("{0:.4f} {0:.4f} {1:.4f} {2:.4f} re s\n",
0.5 * borderWidth,
dx - borderWidth, dy - borderWidth);
@@ -736,7 +1051,8 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
case annotBorderBeveled:
case annotBorderInset:
setColor(obj1.getArray(), gTrue,
- borderType == annotBorderBeveled ? 1 : -1);
+ borderType == annotBorderBeveled ? 1 : -1,
+ appearBuf);
appearBuf->append("0 0 m\n");
appearBuf->appendf("0 {0:.4f} l\n", dy);
appearBuf->appendf("{0:.4f} {1:.4f} l\n", dx, dy);
@@ -747,7 +1063,8 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
appearBuf->appendf("{0:.4f} {0:.4f} l\n", borderWidth);
appearBuf->append("f\n");
setColor(obj1.getArray(), gTrue,
- borderType == annotBorderBeveled ? -1 : 1);
+ borderType == annotBorderBeveled ? -1 : 1,
+ appearBuf);
appearBuf->append("0 0 m\n");
appearBuf->appendf("{0:.4f} 0 l\n", dx);
appearBuf->appendf("{0:.4f} {1:.4f} l\n", dx, dy);
@@ -760,7 +1077,7 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
break;
case annotBorderUnderlined:
appearBuf->appendf("{0:.4f} w\n", borderWidth);
- setColor(obj1.getArray(), gFalse, 0);
+ setColor(obj1.getArray(), gFalse, 0, appearBuf);
appearBuf->appendf("0 0 m {0:.4f} 0 l s\n", dx);
break;
}
@@ -777,7 +1094,7 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
gfree(borderDash);
// get the resource dictionary
- fieldLookup("DR", &drObj);
+ buildDefaultResourceDict(&drObj);
// build the font dictionary
if (drObj.isDict() && drObj.dictLookup("Font", &obj1)->isDict()) {
@@ -839,15 +1156,17 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
->isName(appearanceState->getCString())) {
if (caption) {
drawText(caption, da, fontDict, gFalse, 0, acroFormQuadCenter,
- gFalse, gTrue, rot, xMin, yMin, xMax, yMax, borderWidth);
+ gFalse, gTrue, rot, xMin, yMin, xMax, yMax, borderWidth,
+ appearBuf);
} else {
if (mkDict) {
if (mkDict->lookup("BC", &obj2)->isArray() &&
obj2.arrayGetLength() > 0) {
dx = xMax - xMin;
dy = yMax - yMin;
- setColor(obj2.getArray(), gTrue, 0);
- drawCircle(0.5 * dx, 0.5 * dy, 0.2 * (dx < dy ? dx : dy), "f");
+ setColor(obj2.getArray(), gTrue, 0, appearBuf);
+ drawCircle(0.5 * dx, 0.5 * dy, 0.2 * (dx < dy ? dx : dy), "f",
+ appearBuf);
}
obj2.free();
}
@@ -858,17 +1177,21 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
} else if (flags & acroFormFlagPushbutton) {
if (caption) {
drawText(caption, da, fontDict, gFalse, 0, acroFormQuadCenter,
- gFalse, gFalse, rot, xMin, yMin, xMax, yMax, borderWidth);
+ gFalse, gFalse, rot, xMin, yMin, xMax, yMax, borderWidth,
+ appearBuf);
}
// checkbox
} else {
fieldLookup("V", &obj1);
- if (obj1.isName() && !obj1.isName("Off")) {
+ if (obj1.isName() && !(obj1.isName("Off") ||
+ obj1.isName("No") ||
+ obj1.isName(""))) {
if (!caption) {
caption = new GString("3"); // ZapfDingbats checkmark
}
drawText(caption, da, fontDict, gFalse, 0, acroFormQuadCenter,
- gFalse, gTrue, rot, xMin, yMin, xMax, yMax, borderWidth);
+ gFalse, gTrue, rot, xMin, yMin, xMax, yMax, borderWidth,
+ appearBuf);
}
obj1.free();
}
@@ -897,7 +1220,8 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
}
drawText(obj1.getString(), da, fontDict,
flags & acroFormFlagMultiline, comb, quadding,
- gTrue, gFalse, rot, xMin, yMin, xMax, yMax, borderWidth);
+ gTrue, gFalse, rot, xMin, yMin, xMax, yMax, borderWidth,
+ appearBuf);
}
obj1.free();
} else if (ftObj.isName("Ch")) {
@@ -913,7 +1237,7 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
if (fieldLookup("V", &obj1)->isString()) {
drawText(obj1.getString(), da, fontDict,
gFalse, 0, quadding, gTrue, gFalse, rot,
- xMin, yMin, xMax, yMax, borderWidth);
+ xMin, yMin, xMax, yMax, borderWidth, appearBuf);
//~ Acrobat draws a popup icon on the right side
}
obj1.free();
@@ -969,7 +1293,7 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
obj2.free();
// draw the text
drawListBox(text, selection, nOptions, topIdx, da, fontDict, quadding,
- xMin, yMin, xMax, yMax, borderWidth);
+ xMin, yMin, xMax, yMax, borderWidth, appearBuf);
for (i = 0; i < nOptions; ++i) {
delete text[i];
}
@@ -979,7 +1303,22 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
obj1.free();
}
} else if (ftObj.isName("Sig")) {
- //~unimp
+ //~ check to see if background is already drawn
+ gfxStateDict.initDict(acroForm->doc->getXRef());
+ obj1.initReal(0.5);
+ gfxStateDict.dictAdd(copyString("ca"), &obj1);
+ appearBuf->append("/GS1 gs\n");
+ appearBuf->appendf("0.7 0.7 1 rg 0 0 {0:.2f} {1:.2f} re f\n",
+ xMax - xMin, yMax - yMin);
+ caption = new GString("SIGN HERE");
+ if (da) {
+ delete da;
+ }
+ da = new GString("/Helv 10 Tf 1 0 0 rg");
+ drawText(caption, da, fontDict,
+ gFalse, 0, acroFormQuadLeft, gFalse, gFalse, rot,
+ xMin, yMin, xMax, yMax, borderWidth, appearBuf);
+ delete caption;
} else {
error(errSyntaxError, -1, "Unknown field type");
}
@@ -1001,11 +1340,34 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
obj1.arrayAdd(obj2.initReal(yMax - yMin));
appearDict.dictAdd(copyString("BBox"), &obj1);
- // set the resource dictionary
+ // set the resource dictionary; add a default font
if (drObj.isDict()) {
- appearDict.dictAdd(copyString("Resources"), drObj.copy(&obj1));
+ drObj.copy(&resources);
+ } else {
+ resources.initDict(acroForm->doc->getXRef());
}
drObj.free();
+ fontResources.initDict(acroForm->doc->getXRef());
+ if (resources.dictLookup("Font", &obj1)->isDict()) {
+ for (i = 0; i < obj1.dictGetLength(); ++i) {
+ obj1.dictGetValNF(i, &obj2);
+ fontResources.dictAdd(copyString(obj1.dictGetKey(i)), &obj2);
+ }
+ }
+ obj1.free();
+ defaultFont.initDict(acroForm->doc->getXRef());
+ defaultFont.dictAdd(copyString("Type"), obj1.initName("Font"));
+ defaultFont.dictAdd(copyString("Subtype"), obj1.initName("Type1"));
+ defaultFont.dictAdd(copyString("BaseFont"), obj1.initName("Helvetica"));
+ defaultFont.dictAdd(copyString("Encoding"), obj1.initName("WinAnsiEncoding"));
+ fontResources.dictAdd(copyString("xpdf_default_font"), &defaultFont);
+ resources.dictAdd(copyString("Font"), &fontResources);
+ if (gfxStateDict.isDict()) {
+ obj1.initDict(acroForm->doc->getXRef());
+ obj1.dictAdd(copyString("GS1"), &gfxStateDict);
+ resources.dictAdd(copyString("ExtGState"), &obj1);
+ }
+ appearDict.dictAdd(copyString("Resources"), &resources);
// build the appearance stream
appearStream = new MemStream(appearBuf->getCString(), 0,
@@ -1029,7 +1391,8 @@ void AcroFormField::drawNewAppearance(Gfx *gfx, Dict *annot,
// have 1, 3, or 4 elements). If <adjust> is +1, color is brightened;
// if <adjust> is -1, color is darkened; otherwise color is not
// modified.
-void AcroFormField::setColor(Array *a, GBool fill, int adjust) {
+void AcroFormField::setColor(Array *a, GBool fill, int adjust,
+ GString *appearBuf) {
Object obj1;
double color[4];
int nComps, i;
@@ -1078,7 +1441,7 @@ void AcroFormField::drawText(GString *text, GString *da, GfxFontDict *fontDict,
GBool multiline, int comb, int quadding,
GBool txField, GBool forceZapfDingbats, int rot,
double xMin, double yMin, double xMax, double yMax,
- double border) {
+ double border, GString *appearBuf) {
GString *text2;
GList *daToks;
GString *tok;
@@ -1111,20 +1474,7 @@ void AcroFormField::drawText(GString *text, GString *da, GfxFontDict *fontDict,
// parse the default appearance string
tfPos = tmPos = -1;
if (da) {
- daToks = new GList();
- i = 0;
- while (i < da->getLength()) {
- while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {
- ++i;
- }
- if (i < da->getLength()) {
- for (j = i + 1;
- j < da->getLength() && !Lexer::isSpace(da->getChar(j));
- ++j) ;
- daToks->append(new GString(da, i, j - i));
- i = j;
- }
- }
+ daToks = tokenize(da);
for (i = 2; i < daToks->getLength(); ++i) {
if (i >= 2 && !((GString *)daToks->get(i))->cmp("Tf")) {
tfPos = i - 2;
@@ -1156,6 +1506,8 @@ void AcroFormField::drawText(GString *text, GString *da, GfxFontDict *fontDict,
if (tok->getLength() >= 1 && tok->getChar(0) == '/') {
if (!fontDict || !(font = fontDict->lookup(tok->getCString() + 1))) {
error(errSyntaxError, -1, "Unknown font in field's DA string");
+ tok->clear();
+ tok->append("/xpdf_default_font");
}
} else {
error(errSyntaxError, -1,
@@ -1477,7 +1829,8 @@ void AcroFormField::drawListBox(GString **text, GBool *selection,
int nOptions, int topIdx,
GString *da, GfxFontDict *fontDict,
GBool quadding, double xMin, double yMin,
- double xMax, double yMax, double border) {
+ double xMax, double yMax, double border,
+ GString *appearBuf) {
GList *daToks;
GString *tok;
GfxFont *font;
@@ -1491,20 +1844,7 @@ void AcroFormField::drawListBox(GString **text, GBool *selection,
// parse the default appearance string
tfPos = tmPos = -1;
if (da) {
- daToks = new GList();
- i = 0;
- while (i < da->getLength()) {
- while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {
- ++i;
- }
- if (i < da->getLength()) {
- for (j = i + 1;
- j < da->getLength() && !Lexer::isSpace(da->getChar(j));
- ++j) ;
- daToks->append(new GString(da, i, j - i));
- i = j;
- }
- }
+ daToks = tokenize(da);
for (i = 2; i < daToks->getLength(); ++i) {
if (i >= 2 && !((GString *)daToks->get(i))->cmp("Tf")) {
tfPos = i - 2;
@@ -1524,6 +1864,8 @@ void AcroFormField::drawListBox(GString **text, GBool *selection,
if (tok->getLength() >= 1 && tok->getChar(0) == '/') {
if (!fontDict || !(font = fontDict->lookup(tok->getCString() + 1))) {
error(errSyntaxError, -1, "Unknown font in field's DA string");
+ tok->clear();
+ tok->append("/xpdf_default_font");
}
} else {
error(errSyntaxError, -1,
@@ -1735,7 +2077,7 @@ void AcroFormField::getNextLine(GString *text, int start,
// Draw an (approximate) circle of radius <r> centered at (<cx>, <cy>).
// <cmd> is used to draw the circle ("f", "s", or "b").
void AcroFormField::drawCircle(double cx, double cy, double r,
- const char *cmd) {
+ const char *cmd, GString *appearBuf) {
appearBuf->appendf("{0:.4f} {1:.4f} m\n",
cx + r, cy);
appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} {4:.4f} {5:.4f} c\n",
@@ -1759,7 +2101,8 @@ void AcroFormField::drawCircle(double cx, double cy, double r,
// Draw the top-left half of an (approximate) circle of radius <r>
// centered at (<cx>, <cy>).
-void AcroFormField::drawCircleTopLeft(double cx, double cy, double r) {
+void AcroFormField::drawCircleTopLeft(double cx, double cy, double r,
+ GString *appearBuf) {
double r2;
r2 = r / sqrt(2.0);
@@ -1784,7 +2127,8 @@ void AcroFormField::drawCircleTopLeft(double cx, double cy, double r) {
// Draw the bottom-right half of an (approximate) circle of radius <r>
// centered at (<cx>, <cy>).
-void AcroFormField::drawCircleBottomRight(double cx, double cy, double r) {
+void AcroFormField::drawCircleBottomRight(double cx, double cy, double r,
+ GString *appearBuf) {
double r2;
r2 = r / sqrt(2.0);
@@ -1807,6 +2151,27 @@ void AcroFormField::drawCircleBottomRight(double cx, double cy, double r) {
appearBuf->append("S\n");
}
+GList *AcroFormField::tokenize(GString *s) {
+ GList *toks;
+ int i, j;
+
+ toks = new GList();
+ i = 0;
+ while (i < s->getLength()) {
+ while (i < s->getLength() && Lexer::isSpace(s->getChar(i))) {
+ ++i;
+ }
+ if (i < s->getLength()) {
+ for (j = i + 1;
+ j < s->getLength() && !Lexer::isSpace(s->getChar(j));
+ ++j) ;
+ toks->append(new GString(s, i, j - i));
+ i = j;
+ }
+ }
+ return toks;
+}
+
Object *AcroFormField::getResources(Object *res) {
Object kidsObj, annotObj, obj1;
int i;
@@ -1841,6 +2206,35 @@ Object *AcroFormField::getResources(Object *res) {
return res;
}
+Object *AcroFormField::getFieldRef(Object *ref) {
+ return fieldRef.copy(ref);
+}
+
+Object *AcroFormField::getValueObj(Object *val) {
+ return fieldLookup("V", val);
+}
+
+Object *AcroFormField::getParentRef(Object *parent) {
+ return fieldObj.dictLookupNF("Parent", parent);
+}
+
+// Get the first annotation object associated with this field.
+Object *AcroFormField::getAnnotObj(Object *annotObj) {
+ Object kidsObj;
+
+ if (fieldObj.dictLookup("Kids", &kidsObj)->isArray()) {
+ if (kidsObj.arrayGetLength() > 0) {
+ kidsObj.arrayGet(0, annotObj);
+ } else {
+ annotObj->initNull();
+ }
+ } else {
+ fieldObj.copy(annotObj);
+ }
+ kidsObj.free();
+ return annotObj;
+}
+
Object *AcroFormField::getAnnotResources(Dict *annot, Object *res) {
Object apObj, asObj, appearance, obj1;
@@ -1873,6 +2267,60 @@ Object *AcroFormField::getAnnotResources(Dict *annot, Object *res) {
return res;
}
+// Merge the field and AcroForm DR objects.
+void AcroFormField::buildDefaultResourceDict(Object *dr) {
+ Object formDR, fieldDR, resDict, newResDict, resObj;
+ char *resType, *resName;
+ int i, j;
+
+ // NB: we need to deep-copy the dictionaries here, because multiple
+ // threads can be sharing these objects.
+
+ dr->initDict(acroForm->doc->getXRef());
+
+ acroForm->acroFormObj.dictLookup("DR", &formDR);
+ if (formDR.isDict()) {
+ for (i = 0; i < formDR.dictGetLength(); ++i) {
+ resType = formDR.dictGetKey(i);
+ formDR.dictGetVal(i, &resDict);
+ if (resDict.isDict()) {
+ newResDict.initDict(acroForm->doc->getXRef());
+ dr->dictAdd(copyString(resType), &newResDict);
+ for (j = 0; j < resDict.dictGetLength(); ++j) {
+ resName = resDict.dictGetKey(j);
+ resDict.dictGetValNF(j, &resObj);
+ newResDict.dictAdd(copyString(resName), &resObj);
+ }
+ }
+ resDict.free();
+ }
+ }
+ formDR.free();
+
+ fieldObj.dictLookup("DR", &fieldDR);
+ if (fieldDR.isDict()) {
+ for (i = 0; i < fieldDR.dictGetLength(); ++i) {
+ resType = fieldDR.dictGetKey(i);
+ fieldDR.dictGetVal(i, &resDict);
+ if (resDict.isDict()) {
+ dr->dictLookup(resType, &newResDict);
+ if (!newResDict.isDict()) {
+ newResDict.free();
+ newResDict.initDict(acroForm->doc->getXRef());
+ }
+ dr->dictAdd(copyString(resType), &newResDict);
+ for (j = 0; j < resDict.dictGetLength(); ++j) {
+ resName = resDict.dictGetKey(j);
+ resDict.dictGetValNF(j, &resObj);
+ newResDict.dictAdd(copyString(resName), &resObj);
+ }
+ }
+ resDict.free();
+ }
+ }
+ fieldDR.free();
+}
+
// Look up an inheritable field dictionary entry.
Object *AcroFormField::fieldLookup(const char *key, Object *obj) {
return fieldLookup(fieldObj.getDict(), key, obj);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h
index 8e0075a858c..a92979a3e2f 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.h
@@ -73,17 +73,29 @@ public:
virtual ~AcroFormField();
+ virtual int getPageNum();
virtual const char *getType();
virtual Unicode *getName(int *length);
virtual Unicode *getValue(int *length);
+ virtual void getBBox(double *llx, double *lly, double *urx, double *ury);
+ virtual void getFont(Ref *fontID, double *fontSize);
+ virtual void getColor(double *red, double *green, double *blue);
+ int getMaxLen();
virtual Object *getResources(Object *res);
+ AcroFormFieldType getAcroFormFieldType() { return type; }
+ Object *getFieldRef(Object *ref);
+ Object *getValueObj(Object *val);
+ Object *getParentRef(Object *parent);
+ GBool getTypeFromParent() { return typeFromParent; }
+
private:
AcroFormField(AcroForm *acroFormA, Object *fieldRefA, Object *fieldObjA,
AcroFormFieldType typeA, TextString *nameA,
- Guint flagsA);
+ Guint flagsA, GBool typeFromParentA);
+ Ref findFontName(char *fontTag);
void draw(int pageNum, Gfx *gfx, GBool printing);
void drawAnnot(int pageNum, Gfx *gfx, GBool printing,
Object *annotRef, Object *annotObj);
@@ -93,24 +105,31 @@ private:
void drawNewAppearance(Gfx *gfx, Dict *annot,
double xMin, double yMin,
double xMax, double yMax);
- void setColor(Array *a, GBool fill, int adjust);
+ void setColor(Array *a, GBool fill, int adjust, GString *appearBuf);
void drawText(GString *text, GString *da, GfxFontDict *fontDict,
GBool multiline, int comb, int quadding,
GBool txField, GBool forceZapfDingbats, int rot,
double xMin, double yMin, double xMax, double yMax,
- double border);
+ double border, GString *appearBuf);
void drawListBox(GString **text, GBool *selection,
int nOptions, int topIdx,
GString *da, GfxFontDict *fontDict,
GBool quadding, double xMin, double yMin,
- double xMax, double yMax, double border);
+ double xMax, double yMax, double border,
+ GString *appearBuf);
void getNextLine(GString *text, int start,
GfxFont *font, double fontSize, double wMax,
int *end, double *width, int *next);
- void drawCircle(double cx, double cy, double r, const char *cmd);
- void drawCircleTopLeft(double cx, double cy, double r);
- void drawCircleBottomRight(double cx, double cy, double r);
+ void drawCircle(double cx, double cy, double r, const char *cmd,
+ GString *appearBuf);
+ void drawCircleTopLeft(double cx, double cy, double r,
+ GString *appearBuf);
+ void drawCircleBottomRight(double cx, double cy, double r,
+ GString *appearBuf);
+ GList *tokenize(GString *s);
+ Object *getAnnotObj(Object *annotObj);
Object *getAnnotResources(Dict *annot, Object *res);
+ void buildDefaultResourceDict(Object *dr);
Object *fieldLookup(const char *key, Object *obj);
Object *fieldLookup(Dict *dict, const char *key, Object *obj);
@@ -120,7 +139,7 @@ private:
AcroFormFieldType type;
TextString *name;
Guint flags;
- GString *appearBuf;
+ GBool typeFromParent;
friend class AcroForm;
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
index ff1e37648da..f2075feaea2 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.cc
@@ -15,6 +15,7 @@
#include <stdlib.h>
#include <math.h>
#include "gmem.h"
+#include "gmempp.h"
#include "GList.h"
#include "Error.h"
#include "Object.h"
@@ -25,6 +26,8 @@
#include "PDFDoc.h"
#include "OptionalContent.h"
#include "Form.h"
+#include "BuiltinFontTables.h"
+#include "FontEncodingTables.h"
#include "Annot.h"
// the MSVC math.h doesn't define this
@@ -310,6 +313,8 @@ void Annot::generateAnnotAppearance() {
generatePolyLineAppearance();
} else if (!type->cmp("Polygon")) {
generatePolygonAppearance();
+ } else if (!type->cmp("FreeText")) {
+ generateFreeTextAppearance();
}
}
}
@@ -690,6 +695,107 @@ void Annot::generatePolygonAppearance() {
annotObj.free();
}
+//~ this doesn't handle rich text
+//~ this doesn't handle the callout
+//~ this doesn't handle the RD field
+void Annot::generateFreeTextAppearance() {
+ Object annotObj, gfxStateDict, appearDict, obj1, obj2;
+ Object resources, gsResources, fontResources, defaultFont;
+ GString *text, *da;
+ double lineWidth;
+ int quadding, rot;
+ MemStream *appearStream;
+
+ if (!getObject(&annotObj)->isDict()) {
+ annotObj.free();
+ return;
+ }
+
+ appearBuf = new GString();
+
+ //----- check for transparency
+ if (annotObj.dictLookup("CA", &obj1)->isNum()) {
+ gfxStateDict.initDict(doc->getXRef());
+ gfxStateDict.dictAdd(copyString("ca"), obj1.copy(&obj2));
+ appearBuf->append("/GS1 gs\n");
+ }
+ obj1.free();
+
+ //----- draw the text
+ if (annotObj.dictLookup("Contents", &obj1)->isString()) {
+ text = obj1.getString()->copy();
+ } else {
+ text = new GString();
+ }
+ obj1.free();
+ if (annotObj.dictLookup("Q", &obj1)->isInt()) {
+ quadding = obj1.getInt();
+ } else {
+ quadding = 0;
+ }
+ obj1.free();
+ if (annotObj.dictLookup("DA", &obj1)->isString()) {
+ da = obj1.getString()->copy();
+ } else {
+ da = new GString();
+ }
+ obj1.free();
+ // the "Rotate" field is not defined in the PDF spec, but Acrobat
+ // looks at it
+ if (annotObj.dictLookup("Rotate", &obj1)->isInt()) {
+ rot = obj1.getInt();
+ } else {
+ rot = 0;
+ }
+ obj1.free();
+ drawText(text, da, quadding, 0, rot);
+ delete text;
+ delete da;
+
+ //----- draw the border
+ if (borderStyle->getWidth() != 0) {
+ setLineStyle(borderStyle, &lineWidth);
+ appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} re s\n",
+ 0.5 * lineWidth, 0.5 * lineWidth,
+ xMax - xMin - lineWidth, yMax - yMin - lineWidth);
+ }
+
+ //----- build the appearance stream dictionary
+ appearDict.initDict(doc->getXRef());
+ appearDict.dictAdd(copyString("Length"),
+ obj1.initInt(appearBuf->getLength()));
+ appearDict.dictAdd(copyString("Subtype"), obj1.initName("Form"));
+ obj1.initArray(doc->getXRef());
+ obj1.arrayAdd(obj2.initReal(0));
+ obj1.arrayAdd(obj2.initReal(0));
+ obj1.arrayAdd(obj2.initReal(xMax - xMin));
+ obj1.arrayAdd(obj2.initReal(yMax - yMin));
+ appearDict.dictAdd(copyString("BBox"), &obj1);
+ resources.initDict(doc->getXRef());
+ defaultFont.initDict(doc->getXRef());
+ defaultFont.dictAdd(copyString("Type"), obj1.initName("Font"));
+ defaultFont.dictAdd(copyString("Subtype"), obj1.initName("Type1"));
+ defaultFont.dictAdd(copyString("BaseFont"), obj1.initName("Helvetica"));
+ defaultFont.dictAdd(copyString("Encoding"), obj1.initName("WinAnsiEncoding"));
+ fontResources.initDict(doc->getXRef());
+ fontResources.dictAdd(copyString("xpdf_default_font"), &defaultFont);
+ resources.dictAdd(copyString("Font"), &fontResources);
+ if (gfxStateDict.isDict()) {
+ gsResources.initDict(doc->getXRef());
+ gsResources.dictAdd(copyString("GS1"), &gfxStateDict);
+ resources.dictAdd(copyString("ExtGState"), &gsResources);
+ }
+ appearDict.dictAdd(copyString("Resources"), &resources);
+
+ //----- build the appearance stream
+ appearStream = new MemStream(appearBuf->getCString(), 0,
+ appearBuf->getLength(), &appearDict);
+ appearance.free();
+ appearance.initStream(appearStream);
+
+ annotObj.free();
+}
+
void Annot::setLineStyle(AnnotBorderStyle *bs, double *lineWidth) {
double *dash;
double w;
@@ -1018,6 +1124,190 @@ void Annot::drawCircleBottomRight(double cx, double cy, double r) {
appearBuf->append("S\n");
}
+void Annot::drawText(GString *text, GString *da, int quadding, double margin,
+ int rot) {
+ GString *text2, *tok;
+ GList *daToks;
+ const char *charName;
+ double dx, dy, fontSize, fontSize2, x, y, w;
+ Gushort charWidth;
+ int tfPos, tmPos, i, j, c;
+
+ // check for a Unicode string
+ //~ this currently drops all non-Latin1 characters
+ if (text->getLength() >= 2 &&
+ text->getChar(0) == '\xfe' && text->getChar(1) == '\xff') {
+ text2 = new GString();
+ for (i = 2; i+1 < text->getLength(); i += 2) {
+ c = ((text->getChar(i) & 0xff) << 8) + (text->getChar(i+1) & 0xff);
+ if (c <= 0xff) {
+ text2->append((char)c);
+ } else {
+ text2->append('?');
+ }
+ }
+ } else {
+ text2 = text;
+ }
+
+ // parse the default appearance string
+ tfPos = tmPos = -1;
+ if (da) {
+ daToks = new GList();
+ i = 0;
+ while (i < da->getLength()) {
+ while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {
+ ++i;
+ }
+ if (i < da->getLength()) {
+ for (j = i + 1;
+ j < da->getLength() && !Lexer::isSpace(da->getChar(j));
+ ++j) ;
+ daToks->append(new GString(da, i, j - i));
+ i = j;
+ }
+ }
+ for (i = 2; i < daToks->getLength(); ++i) {
+ if (i >= 2 && !((GString *)daToks->get(i))->cmp("Tf")) {
+ tfPos = i - 2;
+ } else if (i >= 6 && !((GString *)daToks->get(i))->cmp("Tm")) {
+ tmPos = i - 6;
+ }
+ }
+ } else {
+ daToks = NULL;
+ }
+
+ // get the font and font size
+ fontSize = 0;
+ if (tfPos >= 0) {
+ //~ where do we look up the font?
+ tok = (GString *)daToks->get(tfPos);
+ tok->clear();
+ tok->append("/xpdf_default_font");
+ tok = (GString *)daToks->get(tfPos + 1);
+ fontSize = atof(tok->getCString());
+ } else {
+ error(errSyntaxError, -1,
+ "Missing 'Tf' operator in annotation's DA string");
+ daToks->append(new GString("/xpdf_default_font"));
+ daToks->append(new GString("10"));
+ daToks->append(new GString("Tf"));
+ }
+
+ // setup
+ appearBuf->append("q\n");
+ if (rot == 90) {
+ appearBuf->appendf("0 1 -1 0 {0:.4f} 0 cm\n", xMax - xMin);
+ dx = yMax - yMin;
+ dy = xMax - xMin;
+ } else if (rot == 180) {
+ appearBuf->appendf("-1 0 0 -1 {0:.4f} {1:.4f} cm\n",
+ xMax - xMin, yMax - yMin);
+ dx = xMax - yMax;
+ dy = yMax - yMin;
+ } else if (rot == 270) {
+ appearBuf->appendf("0 -1 1 0 0 {0:.4f} cm\n", yMax - yMin);
+ dx = yMax - yMin;
+ dy = xMax - xMin;
+ } else { // assume rot == 0
+ dx = xMax - xMin;
+ dy = yMax - yMin;
+ }
+ appearBuf->append("BT\n");
+
+ // compute string width
+ //~ this assumes we're substituting Helvetica/WinAnsiEncoding for everything
+ w = 0;
+ for (i = 0; i < text2->getLength(); ++i) {
+ charName = winAnsiEncoding[text->getChar(i) & 0xff];
+ if (charName && builtinFonts[4].widths->getWidth(charName, &charWidth)) {
+ w += charWidth;
+ } else {
+ w += 0.5;
+ }
+ }
+
+ // compute font autosize
+ if (fontSize == 0) {
+ fontSize = dy - 2 * margin;
+ fontSize2 = (dx - 2 * margin) / w;
+ if (fontSize2 < fontSize) {
+ fontSize = fontSize2;
+ }
+ fontSize = floor(fontSize);
+ if (tfPos >= 0) {
+ tok = (GString *)daToks->get(tfPos + 1);
+ tok->clear();
+ tok->appendf("{0:.4f}", fontSize);
+ }
+ }
+
+ // compute text start position
+ w *= fontSize;
+ switch (quadding) {
+ case 0:
+ default:
+ x = margin + 2;
+ break;
+ case 1:
+ x = (dx - w) / 2;
+ break;
+ case 2:
+ x = dx - margin - 2 - w;
+ break;
+ }
+ y = 0.5 * dy - 0.4 * fontSize;
+
+ // set the font matrix
+ if (tmPos >= 0) {
+ tok = (GString *)daToks->get(tmPos + 4);
+ tok->clear();
+ tok->appendf("{0:.4f}", x);
+ tok = (GString *)daToks->get(tmPos + 5);
+ tok->clear();
+ tok->appendf("{0:.4f}", y);
+ }
+
+ // write the DA string
+ if (daToks) {
+ for (i = 0; i < daToks->getLength(); ++i) {
+ appearBuf->append((GString *)daToks->get(i))->append(' ');
+ }
+ }
+
+ // write the font matrix (if not part of the DA string)
+ if (tmPos < 0) {
+ appearBuf->appendf("1 0 0 1 {0:.4f} {1:.4f} Tm\n", x, y);
+ }
+
+ // write the text string
+ appearBuf->append('(');
+ for (i = 0; i < text2->getLength(); ++i) {
+ c = text2->getChar(i) & 0xff;
+ if (c == '(' || c == ')' || c == '\\') {
+ appearBuf->append('\\');
+ appearBuf->append(c);
+ } else if (c < 0x20 || c >= 0x80) {
+ appearBuf->appendf("\\{0:03o}", c);
+ } else {
+ appearBuf->append(c);
+ }
+ }
+ appearBuf->append(") Tj\n");
+
+ // cleanup
+ appearBuf->append("ET\n");
+ appearBuf->append("Q\n");
+
+ if (daToks) {
+ deleteGList(daToks, GString);
+ }
+ if (text2 != text) {
+ delete text2;
+ }
+}
+
void Annot::draw(Gfx *gfx, GBool printing) {
GBool oc, isLink;
@@ -1111,6 +1401,28 @@ Annots::~Annots() {
gfree(annots);
}
+Annot *Annots::find(double x, double y) {
+ int i;
+
+ for (i = nAnnots - 1; i >= 0; --i) {
+ if (annots[i]->inRect(x, y)) {
+ return annots[i];
+ }
+ }
+ return NULL;
+}
+
+int Annots::findIdx(double x, double y) {
+ int i;
+
+ for (i = nAnnots - 1; i >= 0; --i) {
+ if (annots[i]->inRect(x, y)) {
+ return i;
+ }
+ }
+ return -1;
+}
+
void Annots::generateAnnotAppearances() {
int i;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h
index 6f52ac45670..6ba5ff490da 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Annot.h
@@ -93,6 +93,10 @@ public:
double getYMax() { return yMax; }
Object *getObject(Object *obj);
+ // Check if point is inside the annotation rectangle.
+ GBool inRect(double x, double y)
+ { return xMin <= x && x <= xMax && yMin <= y && y <= yMax; }
+
// Get appearance object.
Object *getAppearance(Object *obj) { return appearance.fetch(xref, obj); }
@@ -108,6 +112,7 @@ private:
void generateLineAppearance();
void generatePolyLineAppearance();
void generatePolygonAppearance();
+ void generateFreeTextAppearance();
void setLineStyle(AnnotBorderStyle *bs, double *lineWidth);
void setStrokeColor(double *color, int nComps);
GBool setFillColor(Object *colorObj);
@@ -121,6 +126,8 @@ private:
void drawCircle(double cx, double cy, double r, const char *cmd);
void drawCircleTopLeft(double cx, double cy, double r);
void drawCircleBottomRight(double cx, double cy, double r);
+ void drawText(GString *text, GString *da, int quadding, double margin,
+ int rot);
PDFDoc *doc;
XRef *xref; // the xref table for this PDF file
@@ -154,6 +161,11 @@ public:
int getNumAnnots() { return nAnnots; }
Annot *getAnnot(int i) { return annots[i]; }
+ // If point <x>,<y> is in an annotation, return the associated
+ // annotation; else return NULL.
+ Annot *find(double x, double y);
+ int findIdx(double x, double y);
+
// Generate an appearance stream for any non-form-field annotation
// that is missing it.
void generateAnnotAppearances();
@@ -162,6 +174,7 @@ private:
void scanFieldAppearances(Dict *node, Ref *ref, Dict *parent,
Dict *acroForm);
+
Annot *findAnnot(Ref *ref);
PDFDoc *doc;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc
index 10ded148db6..9fe902d1fe5 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Array.cc
@@ -15,6 +15,7 @@
#include <stdlib.h>
#include <stddef.h>
#include "gmem.h"
+#include "gmempp.h"
#include "Object.h"
#include "Array.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Array.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Array.h
index 20ae05f2970..45bfa8b07bd 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Array.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Array.h
@@ -15,6 +15,9 @@
#pragma interface
#endif
+#if MULTITHREADED
+#include "GMutex.h"
+#endif
#include "Object.h"
class XRef;
@@ -33,8 +36,13 @@ public:
~Array();
// Reference counting.
+#if MULTITHREADED
+ int incRef() { return gAtomicIncrement(&ref); }
+ int decRef() { return gAtomicDecrement(&ref); }
+#else
int incRef() { return ++ref; }
int decRef() { return --ref; }
+#endif
// Get number of elements.
int getLength() { return length; }
@@ -52,7 +60,11 @@ private:
Object *elems; // array of elements
int size; // size of <elems> array
int length; // number of elements in array
+#if MULTITHREADED
+ GAtomicCounter ref; // reference count
+#else
int ref; // reference count
+#endif
};
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc
index 33c9fa5e11e..01dbd110dca 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFont.cc
@@ -15,6 +15,7 @@
#include <stdlib.h>
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "FontEncodingTables.h"
#include "BuiltinFont.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFontTables.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFontTables.cc
index 9c362389c1b..a210a6fc674 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFontTables.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/BuiltinFontTables.cc
@@ -8,6 +8,7 @@
#include <aconf.h>
#include <stdlib.h>
+#include "gmempp.h"
#include "FontEncodingTables.h"
#include "BuiltinFontTables.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt
new file mode 100644
index 00000000000..4cffd39e0c5
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CMakeLists.txt
@@ -0,0 +1,228 @@
+#========================================================================
+#
+# xpdf/cmake-xpdf.txt
+#
+# CMake script for the Xpdf tools.
+#
+# Copyright 2015 Glyph & Cog, LLC
+#
+#========================================================================
+
+include_directories("${PROJECT_SOURCE_DIR}")
+include_directories("${PROJECT_BINARY_DIR}")
+include_directories("${PROJECT_SOURCE_DIR}/goo")
+include_directories("${PROJECT_SOURCE_DIR}/fofi")
+include_directories("${PROJECT_SOURCE_DIR}/splash")
+if (PNG_FOUND)
+ include_directories("${PNG_INCLUDE_DIRS}")
+ add_definitions("${PNG_DEFINITIONS}")
+endif ()
+if (HAVE_LCMS)
+ include_directories("${LCMS_INCLUDE_DIR}")
+ set(COLOR_MANAGER_SOURCE "ColorManager.cc")
+else ()
+ set(COLOR_MANAGER_SOURCE "")
+endif ()
+
+add_library(xpdf_objs OBJECT
+ AcroForm.cc
+ Annot.cc
+ Array.cc
+ BuiltinFont.cc
+ BuiltinFontTables.cc
+ Catalog.cc
+ CharCodeToUnicode.cc
+ CMap.cc
+ ${COLOR_MANAGER_SOURCE}
+ Decrypt.cc
+ Dict.cc
+ Error.cc
+ FontEncodingTables.cc
+ Form.cc
+ Function.cc
+ Gfx.cc
+ GfxFont.cc
+ GfxState.cc
+ GlobalParams.cc
+ JArithmeticDecoder.cc
+ JBIG2Stream.cc
+ JPXStream.cc
+ Lexer.cc
+ Link.cc
+ NameToCharCode.cc
+ Object.cc
+ OptionalContent.cc
+ Outline.cc
+ OutputDev.cc
+ Page.cc
+ Parser.cc
+ PDFDoc.cc
+ PDFDocEncoding.cc
+ PSTokenizer.cc
+ SecurityHandler.cc
+ Stream.cc
+ TextString.cc
+ UnicodeMap.cc
+ UnicodeTypeTable.cc
+ UTF8.cc
+ XFAForm.cc
+ XRef.cc
+ Zoox.cc
+)
+
+#--- object files needed by XpdfWidget
+
+if ((QT4_FOUND OR Qt5Widgets_FOUND)
+ AND HAVE_SPLASH AND MULTITHREADED AND USE_EXCEPTIONS)
+
+ if (HIGHLIGHTED_REGIONS)
+ set(HIGHLIGHT_SRC "HighlightFile.cc")
+ else ()
+ set(HIGHLIGHT_SRC "")
+ endif ()
+
+ add_library(xpdf_widget_objs OBJECT
+ DisplayState.cc
+ PDFCore.cc
+ PreScanOutputDev.cc
+ PSOutputDev.cc
+ SplashOutputDev.cc
+ TextOutputDev.cc
+ TileCache.cc
+ TileCompositor.cc
+ TileMap.cc
+ ${HIGHLIGHT_SRC}
+ )
+endif ()
+
+#--- pdftops
+
+if (HAVE_SPLASH)
+ add_executable(pdftops
+ $<TARGET_OBJECTS:xpdf_objs>
+ PreScanOutputDev.cc
+ PSOutputDev.cc
+ SplashOutputDev.cc
+ pdftops.cc
+ )
+ target_link_libraries(pdftops goo fofi splash
+ ${FREETYPE_LIBRARY} ${FREETYPE_OTHER_LIBS}
+ ${DTYPE_LIBRARY}
+ ${LCMS_LIBRARY})
+else ()
+ add_executable(pdftops
+ $<TARGET_OBJECTS:xpdf_objs>
+ PreScanOutputDev.cc
+ PSOutputDev.cc
+ pdftops.cc
+ )
+ target_link_libraries(pdftops goo fofi ${LCMS_LIBRARY})
+endif ()
+install(TARGETS pdftops RUNTIME DESTINATION bin)
+install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftops.1 DESTINATION man/man1)
+
+#--- pdftotext
+
+add_executable(pdftotext
+ $<TARGET_OBJECTS:xpdf_objs>
+ TextOutputDev.cc
+ pdftotext.cc
+)
+target_link_libraries(pdftotext goo fofi ${LCMS_LIBRARY})
+install(TARGETS pdftotext RUNTIME DESTINATION bin)
+install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftotext.1 DESTINATION man/man1)
+
+#--- pdftohtml
+
+if (HAVE_SPLASH AND PNG_FOUND)
+ add_executable(pdftohtml
+ $<TARGET_OBJECTS:xpdf_objs>
+ HTMLGen.cc
+ SplashOutputDev.cc
+ TextOutputDev.cc
+ pdftohtml.cc
+ )
+ target_link_libraries(pdftohtml goo fofi splash
+ ${FREETYPE_LIBRARY} ${FREETYPE_OTHER_LIBS}
+ ${DTYPE_LIBRARY}
+ ${LCMS_LIBRARY} ${PNG_LIBRARIES})
+ install(TARGETS pdftohtml RUNTIME DESTINATION bin)
+ install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftohtml.1 DESTINATION man/man1)
+endif ()
+
+#--- pdfinfo
+
+add_executable(pdfinfo
+ $<TARGET_OBJECTS:xpdf_objs>
+ pdfinfo.cc
+)
+target_link_libraries(pdfinfo goo fofi ${LCMS_LIBRARY})
+install(TARGETS pdfinfo RUNTIME DESTINATION bin)
+install(FILES ${PROJECT_SOURCE_DIR}/doc/pdfinfo.1 DESTINATION man/man1)
+
+#--- pdffonts
+
+add_executable(pdffonts
+ $<TARGET_OBJECTS:xpdf_objs>
+ pdffonts.cc
+)
+target_link_libraries(pdffonts goo fofi ${LCMS_LIBRARY})
+install(TARGETS pdffonts RUNTIME DESTINATION bin)
+install(FILES ${PROJECT_SOURCE_DIR}/doc/pdffonts.1 DESTINATION man/man1)
+
+#--- pdfdetach
+
+add_executable(pdfdetach
+ $<TARGET_OBJECTS:xpdf_objs>
+ pdfdetach.cc
+)
+target_link_libraries(pdfdetach goo fofi ${LCMS_LIBRARY})
+install(TARGETS pdfdetach RUNTIME DESTINATION bin)
+install(FILES ${PROJECT_SOURCE_DIR}/doc/pdfdetach.1 DESTINATION man/man1)
+
+#--- pdftoppm
+
+if (HAVE_SPLASH)
+ add_executable(pdftoppm
+ $<TARGET_OBJECTS:xpdf_objs>
+ SplashOutputDev.cc
+ pdftoppm.cc
+ )
+ target_link_libraries(pdftoppm goo fofi splash
+ ${FREETYPE_LIBRARY} ${FREETYPE_OTHER_LIBS}
+ ${DTYPE_LIBRARY}
+ ${LCMS_LIBRARY})
+ install(TARGETS pdftoppm RUNTIME DESTINATION bin)
+ install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftoppm.1 DESTINATION man/man1)
+endif ()
+
+#--- pdftopng
+
+if (HAVE_SPLASH AND PNG_FOUND)
+ add_executable(pdftopng
+ $<TARGET_OBJECTS:xpdf_objs>
+ SplashOutputDev.cc
+ pdftopng.cc
+ )
+ target_link_libraries(pdftopng goo fofi splash
+ ${FREETYPE_LIBRARY} ${FREETYPE_OTHER_LIBS}
+ ${DTYPE_LIBRARY}
+ ${LCMS_LIBRARY} ${PNG_LIBRARIES})
+ install(TARGETS pdftopng RUNTIME DESTINATION bin)
+ install(FILES ${PROJECT_SOURCE_DIR}/doc/pdftopng.1 DESTINATION man/man1)
+endif ()
+
+#--- pdfimages
+
+add_executable(pdfimages
+ $<TARGET_OBJECTS:xpdf_objs>
+ ImageOutputDev.cc
+ pdfimages.cc
+)
+target_link_libraries(pdfimages goo fofi ${LCMS_LIBRARY})
+install(TARGETS pdfimages RUNTIME DESTINATION bin)
+install(FILES ${PROJECT_SOURCE_DIR}/doc/pdfimages.1 DESTINATION man/man1)
+
+#--- xpdfrc man page
+
+install(FILES ${PROJECT_SOURCE_DIR}/doc/xpdfrc.5 DESTINATION man/man5)
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc
index affdf931df9..12632c5992c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.cc
@@ -17,6 +17,7 @@
#include <string.h>
#include <ctype.h>
#include "gmem.h"
+#include "gmempp.h"
#include "gfile.h"
#include "GString.h"
#include "Error.h"
@@ -200,9 +201,6 @@ CMap::CMap(GString *collectionA, GString *cMapNameA) {
vector[i].cid = 0;
}
refCnt = 1;
-#if MULTITHREADED
- gInitMutex(&mutex);
-#endif
}
CMap::CMap(GString *collectionA, GString *cMapNameA, int wModeA) {
@@ -212,9 +210,6 @@ CMap::CMap(GString *collectionA, GString *cMapNameA, int wModeA) {
wMode = wModeA;
vector = NULL;
refCnt = 1;
-#if MULTITHREADED
- gInitMutex(&mutex);
-#endif
}
void CMap::useCMap(CMapCache *cache, char *useName) {
@@ -324,9 +319,6 @@ CMap::~CMap() {
if (vector) {
freeCMapVector(vector);
}
-#if MULTITHREADED
- gDestroyMutex(&mutex);
-#endif
}
void CMap::freeCMapVector(CMapVectorEntry *vec) {
@@ -342,11 +334,9 @@ void CMap::freeCMapVector(CMapVectorEntry *vec) {
void CMap::incRefCnt() {
#if MULTITHREADED
- gLockMutex(&mutex);
-#endif
+ gAtomicIncrement(&refCnt);
+#else
++refCnt;
-#if MULTITHREADED
- gUnlockMutex(&mutex);
#endif
}
@@ -354,11 +344,9 @@ void CMap::decRefCnt() {
GBool done;
#if MULTITHREADED
- gLockMutex(&mutex);
-#endif
+ done = gAtomicDecrement(&refCnt) == 0;
+#else
done = --refCnt == 0;
-#if MULTITHREADED
- gUnlockMutex(&mutex);
#endif
if (done) {
delete this;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h b/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h
index f21b800c2b3..55692b4f337 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CMap.h
@@ -84,9 +84,10 @@ private:
int wMode; // writing mode (0=horizontal, 1=vertical)
CMapVectorEntry *vector; // vector for first byte (NULL for
// identity CMap)
- int refCnt;
#if MULTITHREADED
- GMutex mutex;
+ GAtomicCounter refCnt;
+#else
+ int refCnt;
#endif
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
index e2e2a8747d4..e1b8be98936 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.cc
@@ -16,6 +16,7 @@
#include <stddef.h>
#include <limits.h>
#include "gmem.h"
+#include "gmempp.h"
#include "gfile.h"
#include "GList.h"
#include "Object.h"
@@ -105,6 +106,9 @@ Catalog::Catalog(PDFDoc *docA) {
baseURI = NULL;
form = NULL;
embeddedFiles = NULL;
+#if MULTITHREADED
+ gInitMutex(&pageMutex);
+#endif
xref->getCatalog(&catDict);
if (!catDict.isDict()) {
@@ -164,9 +168,16 @@ Catalog::Catalog(PDFDoc *docA) {
// get the AcroForm dictionary
catDict.dictLookup("AcroForm", &acroForm);
- if (!acroForm.isNull()) {
- form = Form::load(doc, this, &acroForm);
- }
+ // get the NeedsRendering flag
+ // NB: Form::load() uses this value
+ needsRendering = catDict.dictLookup("NeedsRendering", &obj)->isBool() &&
+ obj.getBool();
+ obj.free();
+
+ // create the Form
+ // (if acroForm is a null object, this will still create an AcroForm
+ // if there are unattached Widget-type annots)
+ form = Form::load(doc, this, &acroForm);
// get the OCProperties dictionary
catDict.dictLookup("OCProperties", &ocProperties);
@@ -199,6 +210,9 @@ Catalog::~Catalog() {
gfree(pages);
gfree(pageRefs);
}
+#if MULTITHREADED
+ gDestroyMutex(&pageMutex);
+#endif
dests.free();
nameTree.free();
if (baseURI) {
@@ -218,24 +232,48 @@ Catalog::~Catalog() {
}
Page *Catalog::getPage(int i) {
+ Page *page;
+
+#if MULTITHREADED
+ gLockMutex(&pageMutex);
+#endif
if (!pages[i-1]) {
loadPage(i);
}
- return pages[i-1];
+ page = pages[i-1];
+#if MULTITHREADED
+ gUnlockMutex(&pageMutex);
+#endif
+ return page;
}
Ref *Catalog::getPageRef(int i) {
+ Ref *pageRef;
+
+#if MULTITHREADED
+ gLockMutex(&pageMutex);
+#endif
if (!pages[i-1]) {
loadPage(i);
}
- return &pageRefs[i-1];
+ pageRef = &pageRefs[i-1];
+#if MULTITHREADED
+ gUnlockMutex(&pageMutex);
+#endif
+ return pageRef;
}
void Catalog::doneWithPage(int i) {
+#if MULTITHREADED
+ gLockMutex(&pageMutex);
+#endif
if (pages[i-1]) {
delete pages[i-1];
pages[i-1] = NULL;
}
+#if MULTITHREADED
+ gUnlockMutex(&pageMutex);
+#endif
}
GString *Catalog::readMetadata() {
@@ -266,13 +304,23 @@ GString *Catalog::readMetadata() {
int Catalog::findPage(int num, int gen) {
int i;
+#if MULTITHREADED
+ gLockMutex(&pageMutex);
+#endif
for (i = 0; i < numPages; ++i) {
if (!pages[i]) {
loadPage(i+1);
}
- if (pageRefs[i].num == num && pageRefs[i].gen == gen)
+ if (pageRefs[i].num == num && pageRefs[i].gen == gen) {
+#if MULTITHREADED
+ gUnlockMutex(&pageMutex);
+#endif
return i + 1;
+ }
}
+#if MULTITHREADED
+ gUnlockMutex(&pageMutex);
+#endif
return 0;
}
@@ -284,29 +332,33 @@ LinkDest *Catalog::findDest(GString *name) {
// try named destination dictionary then name tree
found = gFalse;
if (dests.isDict()) {
- if (!dests.dictLookup(name->getCString(), &obj1)->isNull())
+ if (!dests.dictLookup(name->getCString(), &obj1)->isNull()) {
found = gTrue;
- else
+ } else {
obj1.free();
+ }
}
if (!found && nameTree.isDict()) {
- if (!findDestInTree(&nameTree, name, &obj1)->isNull())
+ if (!findDestInTree(&nameTree, name, &obj1)->isNull()) {
found = gTrue;
- else
+ } else {
obj1.free();
+ }
}
- if (!found)
+ if (!found) {
return NULL;
+ }
// construct LinkDest
dest = NULL;
if (obj1.isArray()) {
dest = new LinkDest(obj1.getArray());
} else if (obj1.isDict()) {
- if (obj1.dictLookup("D", &obj2)->isArray())
+ if (obj1.dictLookup("D", &obj2)->isArray()) {
dest = new LinkDest(obj2.getArray());
- else
+ } else {
error(errSyntaxWarning, -1, "Bad named destination value");
+ }
obj2.free();
} else {
error(errSyntaxWarning, -1, "Bad named destination value");
@@ -343,8 +395,9 @@ Object *Catalog::findDestInTree(Object *tree, GString *name, Object *obj) {
name1.free();
}
names.free();
- if (!found)
+ if (!found) {
obj->initNull();
+ }
return obj;
}
names.free();
@@ -374,8 +427,9 @@ Object *Catalog::findDestInTree(Object *tree, GString *name, Object *obj) {
kids.free();
// name was outside of ranges of all kids
- if (!done)
+ if (!done) {
obj->initNull();
+ }
return obj;
}
@@ -569,6 +623,46 @@ void Catalog::loadPage2(int pg, int relPg, PageTreeNode *node) {
}
}
+Object *Catalog::getDestOutputProfile(Object *destOutProf) {
+ Object catDict, intents, intent, subtype;
+ int i;
+
+ if (!xref->getCatalog(&catDict)->isDict()) {
+ goto err1;
+ }
+ if (!catDict.dictLookup("OutputIntents", &intents)->isArray()) {
+ goto err2;
+ }
+ for (i = 0; i < intents.arrayGetLength(); ++i) {
+ intents.arrayGet(i, &intent);
+ if (!intent.isDict()) {
+ intent.free();
+ continue;
+ }
+ if (!intent.dictLookup("S", &subtype)->isName("GTS_PDFX")) {
+ subtype.free();
+ intent.free();
+ continue;
+ }
+ subtype.free();
+ if (!intent.dictLookup("DestOutputProfile", destOutProf)->isStream()) {
+ destOutProf->free();
+ intent.free();
+ goto err2;
+ }
+ intent.free();
+ intents.free();
+ catDict.free();
+ return destOutProf;
+ }
+
+ err2:
+ intents.free();
+ err1:
+ catDict.free();
+ return NULL;
+}
+
void Catalog::readEmbeddedFileList(Dict *catDict) {
Object obj1, obj2;
char *touchedObjs;
@@ -733,3 +827,193 @@ 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;
+ }
+
+ label = NULL;
+ catDict.dictLookup("PageLabels", &node);
+ if (findPageLabel(&node, pageNum - 1, &pageLabelObj, &firstPageIndex)) {
+ if (pageLabelObj.isDict()) {
+ if (pageLabelObj.dictLookup("P", &prefix)->isString()) {
+ label = prefix.getString()->copy();
+ } else {
+ label = new GString();
+ }
+ prefix.free();
+
+ pageRangeNum = pageNum - firstPageIndex;
+ if (pageLabelObj.dictLookup("St", &start)->isInt()) {
+ pageRangeNum += start.getInt() - 1;
+ }
+ start.free();
+
+ if (pageLabelObj.dictLookup("S", &style)->isName()) {
+ if (style.isName("D")) {
+ label->appendf("{0:d}", pageRangeNum);
+ } else if (style.isName("R")) {
+ s = makeRomanNumeral(pageRangeNum, gTrue);
+ label->append(s);
+ delete s;
+ } else if (style.isName("r")) {
+ s = makeRomanNumeral(pageRangeNum, gFalse);
+ label->append(s);
+ delete s;
+ } else if (style.isName("A")) {
+ s = makeLetterLabel(pageRangeNum, gTrue);
+ label->append(s);
+ delete s;
+ } else if (style.isName("a")) {
+ s = makeLetterLabel(pageRangeNum, gFalse);
+ label->append(s);
+ delete s;
+ }
+ }
+ style.free();
+ }
+ pageLabelObj.free();
+ }
+ node.free();
+ catDict.free();
+
+ ts = new TextString(label);
+ delete label;
+ return ts;
+}
+
+GBool Catalog::findPageLabel(Object *node, int pageIndex,
+ Object *pageLabelObj, int *firstPageIndex) {
+ Object limits, limit, nums, num, 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();
+ }
+ 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;
+ }
+ } else {
+ error(errSyntaxError, -1, "Invalid key in page label number tree");
+ num.free();
+ nums.free();
+ return gFalse;
+ }
+ num.free();
+ }
+ }
+ 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;
+ }
+ }
+ kid.free();
+ }
+ }
+ kids.free();
+
+ return gFalse;
+}
+
+GString *Catalog::makeRomanNumeral(int num, GBool uppercase) {
+ GString *s;
+
+ s = new GString();
+ while (num >= 1000) {
+ s->append(uppercase ? 'M' : 'm');
+ num -= 1000;
+ }
+ if (num >= 900) {
+ s->append(uppercase ? "CM" : "cm");
+ num -= 900;
+ } else if (num >= 500) {
+ s->append(uppercase ? 'D' : 'd');
+ num -= 500;
+ } else if (num >= 400) {
+ s->append(uppercase ? "CD" : "cd");
+ num -= 400;
+ }
+ while (num >= 100) {
+ s->append(uppercase ? 'C' : 'c');
+ num -= 100;
+ }
+ if (num >= 90) {
+ s->append(uppercase ? "XC" : "xc");
+ num -= 90;
+ } else if (num >= 50) {
+ s->append(uppercase ? 'L' : 'l');
+ num -= 50;
+ } else if (num >= 40) {
+ s->append(uppercase ? "XL" : "xl");
+ num -= 40;
+ }
+ while (num >= 10) {
+ s->append(uppercase ? 'X' : 'x');
+ num -= 10;
+ }
+ if (num >= 9) {
+ s->append(uppercase ? "IX" : "ix");
+ num -= 9;
+ } else if (num >= 5) {
+ s->append(uppercase ? 'V' : 'v');
+ num -= 5;
+ } else if (num >= 4) {
+ s->append(uppercase ? "IV" : "iv");
+ num -= 4;
+ }
+ while (num >= 1) {
+ s->append(uppercase ? 'I' : 'i');
+ num -= 1;
+ }
+ return s;
+}
+
+GString *Catalog::makeLetterLabel(int num, GBool uppercase) {
+ GString *s;
+ int m, n, i;
+
+ m = (num - 1) / 26 + 1;
+ n = (num - 1) % 26;
+ s = new GString();
+ for (i = 0; i < m; ++i) {
+ s->append((char)((uppercase ? 'A' : 'a') + n));
+ }
+ return s;
+}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h
index 7f064aac849..803550d7f96 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Catalog.h
@@ -15,6 +15,9 @@
#pragma interface
#endif
+#if MULTITHREADED
+#include "GMutex.h"
+#endif
#include "CharTypes.h"
class GList;
@@ -27,6 +30,7 @@ struct Ref;
class LinkDest;
class PageTreeNode;
class Form;
+class TextString;
//------------------------------------------------------------------------
// Catalog
@@ -85,8 +89,13 @@ public:
Form *getForm() { return form; }
+ GBool getNeedsRendering() { return needsRendering; }
+
Object *getOCProperties() { return &ocProperties; }
+ // Return the DestOutputProfile stream, or NULL if there isn't one.
+ Object *getDestOutputProfile(Object *destOutProf);
+
// Get the list of embedded files.
int getNumEmbeddedFiles();
Unicode *getEmbeddedFileName(int idx);
@@ -94,6 +103,10 @@ public:
Object *getEmbeddedFileStreamRef(int idx);
Object *getEmbeddedFileStreamObj(int idx, Object *strObj);
+ // Get the page label for page number [pageNum]. Returns NULL if
+ // the PDF file doesn't have page labels.
+ TextString *getPageLabel(int pageNum);
+
private:
PDFDoc *doc;
@@ -101,8 +114,10 @@ private:
PageTreeNode *pageTree; // the page tree
Page **pages; // array of pages
Ref *pageRefs; // object ID for each page
+#if MULTITHREADED
+ GMutex pageMutex;
+#endif
int numPages; // number of pages
- int pagesSize; // size of pages array
Object dests; // named destination dictionary
Object nameTree; // name tree
GString *baseURI; // base URI for URI-type links
@@ -110,6 +125,7 @@ private:
Object structTreeRoot; // structure tree root dictionary
Object outline; // outline dictionary
Object acroForm; // AcroForm dictionary
+ GBool needsRendering; // NeedsRendering flag
Form *form; // parsed form
Object ocProperties; // OCProperties dictionary
GList *embeddedFiles; // embedded file list [EmbeddedFile]
@@ -125,6 +141,10 @@ private:
void readFileAttachmentAnnots(Object *pageNodeRef,
char *touchedObjs);
void readEmbeddedFile(Object *fileSpec, Object *name1);
+ GBool findPageLabel(Object *node, int pageIndex,
+ Object *pageLabelObj, int *firstPageIndex);
+ GString *makeRomanNumeral(int num, GBool uppercase);
+ GString *makeLetterLabel(int num, GBool uppercase);
};
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
index 674b992434c..0d064cff379 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.cc
@@ -15,6 +15,7 @@
#include <stdio.h>
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "gfile.h"
#include "GString.h"
#include "Error.h"
@@ -34,18 +35,17 @@ struct CharCodeToUnicodeString {
//------------------------------------------------------------------------
-static int getCharFromString(void *data) {
- char *p;
- int c;
+struct GStringIndex {
+ GString *s;
+ int i;
+};
- p = *(char **)data;
- if (*p) {
- c = *p++;
- *(char **)data = p;
- } else {
- c = EOF;
+static int getCharFromGString(void *data) {
+ GStringIndex *idx = (GStringIndex *)data;
+ if (idx->i >= idx->s->getLength()) {
+ return EOF;
}
- return c;
+ return idx->s->getChar(idx->i++) & 0xff;
}
static int getCharFromFile(void *data) {
@@ -234,23 +234,28 @@ CharCodeToUnicode *CharCodeToUnicode::make8BitToUnicode(Unicode *toUnicode) {
CharCodeToUnicode *CharCodeToUnicode::parseCMap(GString *buf, int nBits) {
CharCodeToUnicode *ctu;
- char *p;
+ GStringIndex idx;
ctu = new CharCodeToUnicode(NULL);
- p = buf->getCString();
- ctu->parseCMap1(&getCharFromString, &p, nBits);
+ idx.s = buf;
+ idx.i = 0;
+ if (!ctu->parseCMap1(&getCharFromGString, &idx, nBits)) {
+ delete ctu;
+ return NULL;
+ }
return ctu;
}
void CharCodeToUnicode::mergeCMap(GString *buf, int nBits) {
- char *p;
+ GStringIndex idx;
- p = buf->getCString();
- parseCMap1(&getCharFromString, &p, nBits);
+ idx.s = buf;
+ idx.i = 0;
+ parseCMap1(&getCharFromGString, &idx, nBits);
}
-void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
- int nBits) {
+GBool CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
+ int nBits) {
PSTokenizer *pst;
char tok1[256], tok2[256], tok3[256];
int n1, n2, n3;
@@ -258,7 +263,9 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
CharCode maxCode, code1, code2;
GString *name;
FILE *f;
+ GBool ok;
+ ok = gFalse;
maxCode = (nBits == 8) ? 0xff : (nBits == 16) ? 0xffff : 0xffffffff;
pst = new PSTokenizer(getCharFunc, data);
pst->getToken(tok1, sizeof(tok1), &n1);
@@ -267,7 +274,9 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
if (tok1[0] == '/') {
name = new GString(tok1 + 1);
if ((f = globalParams->findToUnicodeFile(name))) {
- parseCMap1(&getCharFromFile, f, nBits);
+ if (parseCMap1(&getCharFromFile, f, nBits)) {
+ ok = gTrue;
+ }
fclose(f);
} else {
error(errSyntaxError, -1,
@@ -305,6 +314,7 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
"Invalid entry in bfchar block in ToUnicode CMap");
}
addMapping(code1, tok2 + 1, n2 - 2, 0);
+ ok = gTrue;
}
pst->getToken(tok1, sizeof(tok1), &n1);
} else if (!strcmp(tok2, "beginbfrange")) {
@@ -350,6 +360,7 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
if (code1 + i <= code2) {
tok1[n1 - 1] = '\0';
addMapping(code1 + i, tok1 + 1, n1 - 2, 0);
+ ok = gTrue;
}
} else {
error(errSyntaxWarning, -1,
@@ -361,19 +372,99 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
tok3[n3 - 1] = '\0';
for (i = 0; code1 <= code2; ++code1, ++i) {
addMapping(code1, tok3 + 1, n3 - 2, i);
+ ok = gTrue;
}
-
} else {
error(errSyntaxWarning, -1,
"Illegal entry in bfrange block in ToUnicode CMap");
}
}
pst->getToken(tok1, sizeof(tok1), &n1);
+ } else if (!strcmp(tok2, "begincidchar")) {
+ // the begincidchar operator is not allowed in ToUnicode CMaps,
+ // but some buggy PDF generators incorrectly use
+ // code-to-CID-type CMaps here
+ error(errSyntaxWarning, -1,
+ "Invalid 'begincidchar' operator in ToUnicode CMap");
+ while (pst->getToken(tok1, sizeof(tok1), &n1)) {
+ if (!strcmp(tok1, "endcidchar")) {
+ break;
+ }
+ if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
+ !strcmp(tok2, "endcidchar")) {
+ error(errSyntaxWarning, -1,
+ "Illegal entry in cidchar block in ToUnicode CMap");
+ break;
+ }
+ if (!(tok1[0] == '<' && tok1[n1 - 1] == '>')) {
+ error(errSyntaxWarning, -1,
+ "Illegal entry in cidchar block in ToUnicode CMap");
+ continue;
+ }
+ tok1[n1 - 1] = '\0';
+ if (!parseHex(tok1 + 1, n1 - 2, &code1)) {
+ error(errSyntaxWarning, -1,
+ "Illegal entry in cidchar block in ToUnicode CMap");
+ continue;
+ }
+ if (code1 > maxCode) {
+ error(errSyntaxWarning, -1,
+ "Invalid entry in cidchar block in ToUnicode CMap");
+ }
+ addMappingInt(code1, atoi(tok2));
+ ok = gTrue;
+ }
+ pst->getToken(tok1, sizeof(tok1), &n1);
+ } else if (!strcmp(tok2, "begincidrange")) {
+ // the begincidrange operator is not allowed in ToUnicode CMaps,
+ // but some buggy PDF generators incorrectly use
+ // code-to-CID-type CMaps here
+ error(errSyntaxWarning, -1,
+ "Invalid 'begincidrange' operator in ToUnicode CMap");
+ while (pst->getToken(tok1, sizeof(tok1), &n1)) {
+ if (!strcmp(tok1, "endcidrange")) {
+ break;
+ }
+ if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
+ !strcmp(tok2, "endcidrange") ||
+ !pst->getToken(tok3, sizeof(tok3), &n3) ||
+ !strcmp(tok3, "endcidrange")) {
+ error(errSyntaxWarning, -1,
+ "Illegal entry in cidrange block in ToUnicode CMap");
+ break;
+ }
+ if (!(tok1[0] == '<' && tok1[n1 - 1] == '>' &&
+ tok2[0] == '<' && tok2[n2 - 1] == '>')) {
+ error(errSyntaxWarning,
+ -1, "Illegal entry in cidrange block in ToUnicode CMap");
+ continue;
+ }
+ tok1[n1 - 1] = tok2[n2 - 1] = '\0';
+ if (!parseHex(tok1 + 1, n1 - 2, &code1) ||
+ !parseHex(tok2 + 1, n2 - 2, &code2)) {
+ error(errSyntaxWarning, -1,
+ "Illegal entry in cidrange block in ToUnicode CMap");
+ continue;
+ }
+ if (code1 > maxCode || code2 > maxCode) {
+ error(errSyntaxWarning, -1,
+ "Invalid entry in cidrange block in ToUnicode CMap");
+ if (code2 > maxCode) {
+ code2 = maxCode;
+ }
+ }
+ for (i = atoi(tok3); code1 <= code2; ++code1, ++i) {
+ addMappingInt(code1, i);
+ ok = gTrue;
+ }
+ }
+ pst->getToken(tok1, sizeof(tok1), &n1);
} else {
strcpy(tok1, tok2);
}
}
delete pst;
+ return ok;
}
void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n,
@@ -426,6 +517,28 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n,
}
}
+void CharCodeToUnicode::addMappingInt(CharCode code, Unicode u) {
+ CharCode oldLen, i;
+
+ if (code > 0xffffff) {
+ // This is an arbitrary limit to avoid integer overflow issues.
+ // (I've seen CMaps with mappings for <ffffffff>.)
+ return;
+ }
+ if (code >= mapLen) {
+ oldLen = mapLen;
+ mapLen = mapLen ? 2 * mapLen : 256;
+ if (code >= mapLen) {
+ mapLen = (code + 256) & ~255;
+ }
+ map = (Unicode *)greallocn(map, mapLen, sizeof(Unicode));
+ for (i = oldLen; i < mapLen; ++i) {
+ map[i] = 0;
+ }
+ }
+ map[code] = u;
+}
+
CharCodeToUnicode::CharCodeToUnicode() {
tag = NULL;
map = NULL;
@@ -433,9 +546,6 @@ CharCodeToUnicode::CharCodeToUnicode() {
sMap = NULL;
sMapLen = sMapSize = 0;
refCnt = 1;
-#if MULTITHREADED
- gInitMutex(&mutex);
-#endif
}
CharCodeToUnicode::CharCodeToUnicode(GString *tagA) {
@@ -450,9 +560,6 @@ CharCodeToUnicode::CharCodeToUnicode(GString *tagA) {
sMap = NULL;
sMapLen = sMapSize = 0;
refCnt = 1;
-#if MULTITHREADED
- gInitMutex(&mutex);
-#endif
}
CharCodeToUnicode::CharCodeToUnicode(GString *tagA, Unicode *mapA,
@@ -471,9 +578,6 @@ CharCodeToUnicode::CharCodeToUnicode(GString *tagA, Unicode *mapA,
sMapLen = sMapLenA;
sMapSize = sMapSizeA;
refCnt = 1;
-#if MULTITHREADED
- gInitMutex(&mutex);
-#endif
}
CharCodeToUnicode::~CharCodeToUnicode() {
@@ -482,18 +586,13 @@ CharCodeToUnicode::~CharCodeToUnicode() {
}
gfree(map);
gfree(sMap);
-#if MULTITHREADED
- gDestroyMutex(&mutex);
-#endif
}
void CharCodeToUnicode::incRefCnt() {
#if MULTITHREADED
- gLockMutex(&mutex);
-#endif
+ gAtomicIncrement(&refCnt);
+#else
++refCnt;
-#if MULTITHREADED
- gUnlockMutex(&mutex);
#endif
}
@@ -501,11 +600,9 @@ void CharCodeToUnicode::decRefCnt() {
GBool done;
#if MULTITHREADED
- gLockMutex(&mutex);
-#endif
+ done = gAtomicDecrement(&refCnt) == 0;
+#else
done = --refCnt == 0;
-#if MULTITHREADED
- gUnlockMutex(&mutex);
#endif
if (done) {
delete this;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h
index 1b870efe8d0..5d7bea5b057 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/CharCodeToUnicode.h
@@ -78,8 +78,9 @@ public:
private:
- void parseCMap1(int (*getCharFunc)(void *), void *data, int nBits);
+ GBool parseCMap1(int (*getCharFunc)(void *), void *data, int nBits);
void addMapping(CharCode code, char *uStr, int n, int offset);
+ void addMappingInt(CharCode code, Unicode u);
CharCodeToUnicode();
CharCodeToUnicode(GString *tagA);
CharCodeToUnicode(GString *tagA, Unicode *mapA,
@@ -92,9 +93,10 @@ private:
CharCode mapLen;
CharCodeToUnicodeString *sMap;
int sMapLen, sMapSize;
- int refCnt;
#if MULTITHREADED
- GMutex mutex;
+ GAtomicCounter refCnt;
+#else
+ int refCnt;
#endif
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CoreOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/CoreOutputDev.cc
deleted file mode 100644
index 78751102430..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CoreOutputDev.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-//========================================================================
-//
-// CoreOutputDev.cc
-//
-// Copyright 2004 Glyph & Cog, LLC
-//
-//========================================================================
-
-#include <aconf.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
-#include "Object.h"
-#include "TextOutputDev.h"
-#include "CoreOutputDev.h"
-
-//------------------------------------------------------------------------
-// CoreOutputDev
-//------------------------------------------------------------------------
-
-CoreOutputDev::CoreOutputDev(SplashColorMode colorModeA, int bitmapRowPadA,
- GBool reverseVideoA, SplashColorPtr paperColorA,
- GBool incrementalUpdateA,
- CoreOutRedrawCbk redrawCbkA,
- void *redrawCbkDataA):
- SplashOutputDev(colorModeA, bitmapRowPadA, reverseVideoA, paperColorA)
-{
- incrementalUpdate = incrementalUpdateA;
- redrawCbk = redrawCbkA;
- redrawCbkData = redrawCbkDataA;
-}
-
-CoreOutputDev::~CoreOutputDev() {
-}
-
-void CoreOutputDev::endPage() {
- SplashOutputDev::endPage();
- if (!incrementalUpdate) {
- (*redrawCbk)(redrawCbkData, 0, 0, getBitmapWidth(), getBitmapHeight(),
- gTrue);
- }
-}
-
-void CoreOutputDev::dump() {
- int x0, y0, x1, y1;
-
- if (incrementalUpdate) {
- getModRegion(&x0, &y0, &x1, &y1);
- clearModRegion();
- if (x1 >= x0 && y1 >= y0) {
- (*redrawCbk)(redrawCbkData, x0, y0, x1, y1, gFalse);
- }
- }
-}
-
-void CoreOutputDev::clear() {
- startDoc(NULL);
- startPage(0, NULL);
-}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/CoreOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/CoreOutputDev.h
deleted file mode 100644
index 006d3517f4d..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/CoreOutputDev.h
+++ /dev/null
@@ -1,61 +0,0 @@
-//========================================================================
-//
-// CoreOutputDev.h
-//
-// Copyright 2004 Glyph & Cog, LLC
-//
-//========================================================================
-
-#ifndef COREOUTPUTDEV_H
-#define COREOUTPUTDEV_H
-
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
-#include "SplashTypes.h"
-#include "SplashOutputDev.h"
-
-class TextPage;
-
-//------------------------------------------------------------------------
-
-typedef void (*CoreOutRedrawCbk)(void *data, int x0, int y0, int x1, int y1,
- GBool composited);
-
-//------------------------------------------------------------------------
-// CoreOutputDev
-//------------------------------------------------------------------------
-
-class CoreOutputDev: public SplashOutputDev {
-public:
-
- CoreOutputDev(SplashColorMode colorModeA, int bitmapRowPadA,
- GBool reverseVideoA, SplashColorPtr paperColorA,
- GBool incrementalUpdateA,
- CoreOutRedrawCbk redrawCbkA,
- void *redrawCbkDataA);
-
- virtual ~CoreOutputDev();
-
- //----- initialization and control
-
- // End a page.
- virtual void endPage();
-
- // Dump page contents to display.
- virtual void dump();
-
- //----- special access
-
- // Clear out the document (used when displaying an empty window).
- void clear();
-
-private:
-
- GBool incrementalUpdate; // incrementally update the display?
- CoreOutRedrawCbk redrawCbk;
- void *redrawCbkData;
-};
-
-#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc
index bf0bfb7007c..2d28399d655 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.cc
@@ -14,6 +14,7 @@
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "Decrypt.h"
static void aes256KeyExpansion(DecryptAES256State *s,
@@ -328,14 +329,18 @@ GBool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength,
// DecryptStream
//------------------------------------------------------------------------
-DecryptStream::DecryptStream(Stream *strA, Guchar *fileKey,
- CryptAlgorithm algoA, int keyLength,
- int objNum, int objGen):
+DecryptStream::DecryptStream(Stream *strA, Guchar *fileKeyA,
+ CryptAlgorithm algoA, int keyLengthA,
+ int objNumA, int objGenA):
FilterStream(strA)
{
int i;
+ memcpy(fileKey, fileKeyA, keyLengthA);
algo = algoA;
+ keyLength = keyLengthA;
+ objNum = objNumA;
+ objGen = objGenA;
// construct object key
for (i = 0; i < keyLength; ++i) {
@@ -378,6 +383,11 @@ DecryptStream::~DecryptStream() {
delete str;
}
+Stream *DecryptStream::copy() {
+ return new DecryptStream(str->copy(), fileKey, algo, keyLength,
+ objNum, objGen);
+}
+
void DecryptStream::reset() {
str->reset();
switch (algo) {
@@ -1349,46 +1359,46 @@ static void sha256(Guchar *msg, int msgLen, Guchar *hash) {
typedef unsigned long long SHA512Uint64;
static SHA512Uint64 sha512K[80] = {
- 0x428a2f98d728ae22LL, 0x7137449123ef65cdLL,
- 0xb5c0fbcfec4d3b2fLL, 0xe9b5dba58189dbbcLL,
- 0x3956c25bf348b538LL, 0x59f111f1b605d019LL,
- 0x923f82a4af194f9bLL, 0xab1c5ed5da6d8118LL,
- 0xd807aa98a3030242LL, 0x12835b0145706fbeLL,
- 0x243185be4ee4b28cLL, 0x550c7dc3d5ffb4e2LL,
- 0x72be5d74f27b896fLL, 0x80deb1fe3b1696b1LL,
- 0x9bdc06a725c71235LL, 0xc19bf174cf692694LL,
- 0xe49b69c19ef14ad2LL, 0xefbe4786384f25e3LL,
- 0x0fc19dc68b8cd5b5LL, 0x240ca1cc77ac9c65LL,
- 0x2de92c6f592b0275LL, 0x4a7484aa6ea6e483LL,
- 0x5cb0a9dcbd41fbd4LL, 0x76f988da831153b5LL,
- 0x983e5152ee66dfabLL, 0xa831c66d2db43210LL,
- 0xb00327c898fb213fLL, 0xbf597fc7beef0ee4LL,
- 0xc6e00bf33da88fc2LL, 0xd5a79147930aa725LL,
- 0x06ca6351e003826fLL, 0x142929670a0e6e70LL,
- 0x27b70a8546d22ffcLL, 0x2e1b21385c26c926LL,
- 0x4d2c6dfc5ac42aedLL, 0x53380d139d95b3dfLL,
- 0x650a73548baf63deLL, 0x766a0abb3c77b2a8LL,
- 0x81c2c92e47edaee6LL, 0x92722c851482353bLL,
- 0xa2bfe8a14cf10364LL, 0xa81a664bbc423001LL,
- 0xc24b8b70d0f89791LL, 0xc76c51a30654be30LL,
- 0xd192e819d6ef5218LL, 0xd69906245565a910LL,
- 0xf40e35855771202aLL, 0x106aa07032bbd1b8LL,
- 0x19a4c116b8d2d0c8LL, 0x1e376c085141ab53LL,
- 0x2748774cdf8eeb99LL, 0x34b0bcb5e19b48a8LL,
- 0x391c0cb3c5c95a63LL, 0x4ed8aa4ae3418acbLL,
- 0x5b9cca4f7763e373LL, 0x682e6ff3d6b2b8a3LL,
- 0x748f82ee5defb2fcLL, 0x78a5636f43172f60LL,
- 0x84c87814a1f0ab72LL, 0x8cc702081a6439ecLL,
- 0x90befffa23631e28LL, 0xa4506cebde82bde9LL,
- 0xbef9a3f7b2c67915LL, 0xc67178f2e372532bLL,
- 0xca273eceea26619cLL, 0xd186b8c721c0c207LL,
- 0xeada7dd6cde0eb1eLL, 0xf57d4f7fee6ed178LL,
- 0x06f067aa72176fbaLL, 0x0a637dc5a2c898a6LL,
- 0x113f9804bef90daeLL, 0x1b710b35131c471bLL,
- 0x28db77f523047d84LL, 0x32caab7b40c72493LL,
- 0x3c9ebe0a15c9bebcLL, 0x431d67c49c100d4cLL,
- 0x4cc5d4becb3e42b6LL, 0x597f299cfc657e2aLL,
- 0x5fcb6fab3ad6faecLL, 0x6c44198c4a475817LL
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+ 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+ 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+ 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+ 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+ 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+ 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+ 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+ 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+ 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+ 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+ 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+ 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+ 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+ 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+ 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+ 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+ 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+ 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+ 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+ 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+ 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+ 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+ 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+ 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+ 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+ 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
};
static inline SHA512Uint64 rotr64(SHA512Uint64 x, Guint n) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h
index 5ddcfc8ad7b..2b10abd050b 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Decrypt.h
@@ -80,10 +80,11 @@ struct DecryptAES256State {
class DecryptStream: public FilterStream {
public:
- DecryptStream(Stream *strA, Guchar *fileKey,
- CryptAlgorithm algoA, int keyLength,
- int objNum, int objGen);
+ DecryptStream(Stream *strA, Guchar *fileKeyA,
+ CryptAlgorithm algoA, int keyLengthA,
+ int objNumA, int objGenA);
virtual ~DecryptStream();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strWeird; }
virtual void reset();
virtual int getChar();
@@ -93,7 +94,10 @@ public:
private:
+ Guchar fileKey[32];
CryptAlgorithm algo;
+ int keyLength;
+ int objNum, objGen;
int objKeyLength;
Guchar objKey[32];
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc
index 7e33fff1921..c8c29736fe9 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.cc
@@ -15,6 +15,7 @@
#include <stddef.h>
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "Object.h"
#include "XRef.h"
#include "Dict.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h
index 301d0b860d3..514c3ae8d6e 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Dict.h
@@ -15,6 +15,9 @@
#pragma interface
#endif
+#if MULTITHREADED
+#include "GMutex.h"
+#endif
#include "Object.h"
struct DictEntry;
@@ -33,8 +36,13 @@ public:
~Dict();
// Reference counting.
+#if MULTITHREADED
+ int incRef() { return gAtomicIncrement(&ref); }
+ int decRef() { return gAtomicDecrement(&ref); }
+#else
int incRef() { return ++ref; }
int decRef() { return --ref; }
+#endif
// Get number of entries.
int getLength() { return length; }
@@ -67,7 +75,11 @@ private:
DictEntry **hashTab; // hash table pointers
int size; // size of <entries> array
int length; // number of entries in dictionary
+#if MULTITHREADED
+ GAtomicCounter ref; // reference count
+#else
int ref; // reference count
+#endif
DictEntry *find(const char *key);
void expand();
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.cc
new file mode 100644
index 00000000000..e0d306857ca
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.cc
@@ -0,0 +1,223 @@
+//========================================================================
+//
+// DisplayState.cc
+//
+// Copyright 2014 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include <stdlib.h>
+#include "gmempp.h"
+#include "GString.h"
+#include "GList.h"
+#include "TileMap.h"
+#include "TileCache.h"
+#include "TileCompositor.h"
+#include "DisplayState.h"
+
+
+//------------------------------------------------------------------------
+// DisplayState
+//------------------------------------------------------------------------
+
+DisplayState::DisplayState(int maxTileWidthA, int maxTileHeightA,
+ int tileCacheSizeA, int nWorkerThreadsA,
+ SplashColorMode colorModeA, int bitmapRowPadA) {
+ int i;
+
+ maxTileWidth = maxTileWidthA;
+ maxTileHeight = maxTileHeightA;
+ tileCacheSize = tileCacheSizeA;
+ nWorkerThreads = nWorkerThreadsA;
+ colorMode = colorModeA;
+ bitmapRowPad = bitmapRowPadA;
+
+ tileMap = NULL;
+ tileCache = NULL;
+ tileCompositor = NULL;
+
+ for (i = 0; i < splashColorModeNComps[colorMode]; ++i) {
+ paperColor[i] = 0xff;
+ matteColor[i] = 0x80;
+ }
+ if (colorMode == splashModeRGB8 || colorMode == splashModeBGR8) {
+ selectColor[0] = 0x80;
+ selectColor[1] = 0x80;
+ selectColor[2] = 0xff;
+ } else {
+ for (i = 0; i < splashColorModeNComps[colorMode]; ++i) {
+ selectColor[i] = 0xa0;
+ }
+ }
+ reverseVideo = gFalse;
+
+ doc = NULL;
+
+ winW = winH = 100;
+ displayMode = displayContinuous;
+ zoom = 100;
+ rotate = 0;
+ scrollPage = 0;
+ scrollX = scrollY = 0;
+
+ selectRects = NULL;
+
+
+}
+
+DisplayState::~DisplayState() {
+ if (selectRects) {
+ deleteGList(selectRects, SelectRect);
+ }
+}
+
+void DisplayState::setPaperColor(SplashColorPtr paperColorA) {
+ splashColorCopy(paperColor, paperColorA);
+ tileCache->paperColorChanged();
+ tileCompositor->paperColorChanged();
+}
+
+void DisplayState::setMatteColor(SplashColorPtr matteColorA) {
+ splashColorCopy(matteColor, matteColorA);
+ tileCompositor->matteColorChanged();
+}
+
+void DisplayState::setSelectColor(SplashColorPtr selectColorA) {
+ splashColorCopy(selectColor, selectColorA);
+ tileCompositor->selectColorChanged();
+}
+
+void DisplayState::setReverseVideo(GBool reverseVideoA) {
+ if (reverseVideo != reverseVideoA) {
+ reverseVideo = reverseVideoA;
+ tileCache->reverseVideoChanged();
+ tileCompositor->reverseVideoChanged();
+ }
+}
+
+void DisplayState::setDoc(PDFDoc *docA) {
+ doc = docA;
+ tileMap->docChanged();
+ tileCache->docChanged();
+ tileCompositor->docChanged();
+}
+
+void DisplayState::setWindowSize(int winWA, int winHA) {
+ if (winW != winWA || winH != winHA) {
+ winW = winWA;
+ winH = winHA;
+ tileMap->windowSizeChanged();
+ tileCompositor->windowSizeChanged();
+ }
+}
+
+void DisplayState::setDisplayMode(DisplayMode displayModeA) {
+ if (displayMode != displayModeA) {
+ displayMode = displayModeA;
+ tileMap->displayModeChanged();
+ tileCompositor->displayModeChanged();
+ }
+}
+
+void DisplayState::setZoom(double zoomA) {
+ if (zoom != zoomA) {
+ zoom = zoomA;
+ tileMap->zoomChanged();
+ tileCompositor->zoomChanged();
+ }
+}
+
+void DisplayState::setRotate(int rotateA) {
+ if (rotate != rotateA) {
+ rotate = rotateA;
+ tileMap->rotateChanged();
+ tileCompositor->rotateChanged();
+ }
+}
+
+void DisplayState::setScrollPosition(int scrollPageA,
+ int scrollXA, int scrollYA) {
+ if (scrollPage != scrollPageA ||
+ scrollX != scrollXA ||
+ scrollY != scrollYA) {
+ scrollPage = scrollPageA;
+ scrollX = scrollXA;
+ scrollY = scrollYA;
+ tileMap->scrollPositionChanged();
+ tileCompositor->scrollPositionChanged();
+ }
+}
+
+void DisplayState::setSelection(int selectPage,
+ double selectX0, double selectY0,
+ double selectX1, double selectY1) {
+ GList *rects;
+ SelectRect *rect;
+
+ rect = new SelectRect(selectPage, selectX0, selectY0, selectX1, selectY1);
+ rects = new GList();
+ rects->append(rect);
+ setSelection(rects);
+}
+
+void DisplayState::setSelection(GList *selectRectsA) {
+ SelectRect *rect, *rectA;
+ int i;
+
+ if (!selectRects && !selectRectsA) {
+ return;
+ }
+ if (selectRects && selectRectsA &&
+ selectRects->getLength() == selectRectsA->getLength()) {
+ for (i = 0; i < selectRects->getLength(); ++i) {
+ rect = (SelectRect *)selectRects->get(i);
+ rectA = (SelectRect *)selectRectsA->get(i);
+ if (*rect != *rectA) {
+ break;
+ }
+ }
+ if (i == selectRects->getLength()) {
+ deleteGList(selectRectsA, SelectRect);
+ return;
+ }
+ }
+ if (selectRects) {
+ deleteGList(selectRects, SelectRect);
+ }
+ selectRects = selectRectsA;
+ tileCompositor->selectionChanged();
+}
+
+void DisplayState::clearSelection() {
+ setSelection(NULL);
+}
+
+int DisplayState::getNumSelectRects() {
+ if (!selectRects) {
+ return 0;
+ }
+ return selectRects->getLength();
+}
+
+SelectRect *DisplayState::getSelectRect(int idx) {
+ return (SelectRect *)selectRects->get(idx);
+}
+
+void DisplayState::optionalContentChanged() {
+ tileCache->optionalContentChanged();
+ tileCompositor->optionalContentChanged();
+}
+
+
+
+void DisplayState::forceRedraw() {
+ tileMap->forceRedraw();
+ tileCache->forceRedraw();
+ tileCompositor->forceRedraw();
+}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.h b/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.h
new file mode 100644
index 00000000000..12c8170f0b3
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/DisplayState.h
@@ -0,0 +1,173 @@
+//========================================================================
+//
+// DisplayState.h
+//
+// Copyright 2014 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef DISPLAYSTATE_H
+#define DISPLAYSTATE_H
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include "gtypes.h"
+#include "SplashTypes.h"
+
+class GString;
+class GList;
+class PDFDoc;
+class TileMap;
+class TileCache;
+class TileCompositor;
+
+//------------------------------------------------------------------------
+// zoom level
+//------------------------------------------------------------------------
+
+// positive zoom levels are percentage of 72 dpi
+// (e.g., 50 means 36dpi, 100 means 72dpi, 150 means 108 dpi)
+
+#define zoomPage -1
+#define zoomWidth -2
+#define zoomHeight -3
+
+//------------------------------------------------------------------------
+// display mode
+//------------------------------------------------------------------------
+
+enum DisplayMode {
+ displaySingle,
+ displayContinuous,
+ displaySideBySideSingle,
+ displaySideBySideContinuous,
+ displayHorizontalContinuous
+};
+
+//------------------------------------------------------------------------
+// SelectRect
+//------------------------------------------------------------------------
+
+class SelectRect {
+public:
+
+ SelectRect(int pageA, double x0A, double y0A, double x1A, double y1A):
+ page(pageA), x0(x0A), y0(y0A), x1(x1A), y1(y1A) {}
+ int operator==(SelectRect r)
+ { return page == r.page && x0 == r.x0 && y0 == r.y0 &&
+ x1 == r.x1 && y1 == r.y1; }
+ int operator!=(SelectRect r)
+ { return page != r.page || x0 != r.x0 || y0 != r.y0 ||
+ x1 != r.x1 || y1 != r.y1; }
+
+ int page;
+ double x0, y0, x1, y1; // user coords
+};
+
+
+//------------------------------------------------------------------------
+// DisplayState
+//------------------------------------------------------------------------
+
+class DisplayState {
+public:
+
+ DisplayState(int maxTileWidthA, int maxTileHeightA,
+ int tileCacheSizeA, int nWorkerThreadsA,
+ SplashColorMode colorModeA, int bitmapRowPadA);
+ ~DisplayState();
+
+ void setTileMap(TileMap *tileMapA)
+ { tileMap = tileMapA; }
+ void setTileCache(TileCache *tileCacheA)
+ { tileCache = tileCacheA; }
+ void setTileCompositor(TileCompositor *tileCompositorA)
+ { tileCompositor = tileCompositorA; }
+
+ void setPaperColor(SplashColorPtr paperColorA);
+ void setMatteColor(SplashColorPtr matteColorA);
+ void setSelectColor(SplashColorPtr selectColorA);
+ void setReverseVideo(GBool reverseVideoA);
+ void setDoc(PDFDoc *docA);
+ void setWindowSize(int winWA, int winHA);
+ void setDisplayMode(DisplayMode displayModeA);
+ void setZoom(double zoomA);
+ void setRotate(int rotateA);
+ void setScrollPosition(int scrollPageA, int scrollXA, int scrollYA);
+ void setSelection(int selectPage, double selectX0, double selectY0,
+ double selectX1, double selectY1);
+ void setSelection(GList *selectRectsA);
+ void clearSelection();
+ void forceRedraw();
+
+ int getMaxTileWidth() { return maxTileWidth; }
+ int getMaxTileHeight() { return maxTileHeight; }
+ int getTileCacheSize() { return tileCacheSize; }
+ int getNWorkerThreads() { return nWorkerThreads; }
+ SplashColorMode getColorMode() { return colorMode; }
+ int getBitmapRowPad() { return bitmapRowPad; }
+ SplashColorPtr getPaperColor() { return paperColor; }
+ SplashColorPtr getMatteColor() { return matteColor; }
+ SplashColorPtr getSelectColor() { return selectColor; }
+ GBool getReverseVideo() { return reverseVideo; }
+ PDFDoc *getDoc() { return doc; }
+ int getWinW() { return winW; }
+ int getWinH() { return winH; }
+ DisplayMode getDisplayMode() { return displayMode; }
+ GBool displayModeIsContinuous()
+ { return displayMode == displayContinuous ||
+ displayMode == displaySideBySideContinuous ||
+ displayMode == displayHorizontalContinuous; }
+ GBool displayModeIsSideBySide()
+ { return displayMode == displaySideBySideSingle ||
+ displayMode == displaySideBySideContinuous; }
+ double getZoom() { return zoom; }
+ int getRotate() { return rotate; }
+ int getScrollPage() { return scrollPage; }
+ int getScrollX() { return scrollX; }
+ int getScrollY() { return scrollY; }
+ GBool hasSelection() { return selectRects != NULL; }
+ GList *getSelectRects() { return selectRects; }
+ int getNumSelectRects();
+ SelectRect *getSelectRect(int idx);
+ void optionalContentChanged();
+
+private:
+
+ int maxTileWidth, maxTileHeight;
+ int tileCacheSize;
+ int nWorkerThreads;
+
+ SplashColorMode colorMode;
+ int bitmapRowPad;
+
+ TileMap *tileMap;
+ TileCache *tileCache;
+ TileCompositor *tileCompositor;
+
+ SplashColor paperColor;
+ SplashColor matteColor;
+ SplashColor selectColor;
+ GBool reverseVideo;
+
+ PDFDoc *doc;
+
+ int winW, winH; // window (draw area) size
+ DisplayMode displayMode;
+ double zoom; // zoom level (see zoom* defines, above)
+ int rotate; // rotation (0, 90, 180, or 270)
+ int scrollPage; // scroll page - only used in
+ // non-continuous modes
+ int scrollX, scrollY;
+
+ GList *selectRects; // selection rectangles [SelectRect]
+ // (NULL if there is no selection)
+
+
+};
+
+#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc
index 600442e0091..5a97505ed84 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Error.cc
@@ -15,11 +15,12 @@
#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>
+#include "gmempp.h"
#include "GString.h"
#include "GlobalParams.h"
#include "Error.h"
-static const char *errorCategoryNames[] = {
+const char *errorCategoryNames[] = {
"Syntax Warning",
"Syntax Error",
"Config Error",
@@ -41,6 +42,10 @@ void setErrorCallback(void (*cbk)(void *data, ErrorCategory category,
errorCbkData = data;
}
+void *getErrorCallbackData() {
+ return errorCbkData;
+}
+
void CDECL error(ErrorCategory category, GFileOffset pos,
const char *msg, ...) {
va_list args;
@@ -71,6 +76,7 @@ void CDECL error(ErrorCategory category, GFileOffset pos,
if (errorCbk) {
(*errorCbk)(errorCbkData, category, (int)pos, sanitized->getCString());
} else {
+ fflush(stdout);
if (pos >= 0) {
fprintf(stderr, "%s (%d): %s\n",
errorCategoryNames[category], (int)pos, sanitized->getCString());
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Error.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Error.h
index 6c6afe33f36..39e7613e4e6 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Error.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Error.h
@@ -34,10 +34,14 @@ enum ErrorCategory {
errInternal // internal error - malfunction within the Xpdf code
};
+extern const char *errorCategoryNames[];
+
extern void setErrorCallback(void (*cbk)(void *data, ErrorCategory category,
int pos, char *msg),
void *data);
+extern void *getErrorCallbackData();
+
extern void CDECL error(ErrorCategory category, GFileOffset pos,
const char *msg, ...);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/FontEncodingTables.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/FontEncodingTables.cc
index bf04b5b190f..d4b18ab68c5 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/FontEncodingTables.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/FontEncodingTables.cc
@@ -8,6 +8,7 @@
#include <aconf.h>
#include <stdlib.h>
+#include "gmempp.h"
#include "FontEncodingTables.h"
const char *macRomanEncoding[256] = {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Form.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Form.cc
index f65a1e27541..681401ad5de 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Form.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Form.cc
@@ -12,6 +12,7 @@
#pragma implementation
#endif
+#include "gmempp.h"
#include "GlobalParams.h"
#include "Error.h"
#include "Object.h"
@@ -26,27 +27,24 @@
Form *Form::load(PDFDoc *docA, Catalog *catalog, Object *acroFormObj) {
Form *form;
- Object xfaObj, catDict, needsRenderingObj;
+ Object xfaObj;
- if (!acroFormObj->isDict()) {
- error(errSyntaxError, -1, "AcroForm object is wrong type");
- return NULL;
+ if (acroFormObj->isDict()) {
+ //~ temporary: create an XFAForm only for XFAF, not for dynamic XFA
+ acroFormObj->dictLookup("XFA", &xfaObj);
+ if (globalParams->getEnableXFA() &&
+ !xfaObj.isNull() &&
+ !catalog->getNeedsRendering()) {
+ form = XFAForm::load(docA, catalog, acroFormObj, &xfaObj);
+ xfaObj.free();
+ return form;
+ }
+ xfaObj.free();
}
- //~ temporary: create an XFAForm only for XFAF, not for dynamic XFA
- acroFormObj->dictLookup("XFA", &xfaObj);
- docA->getXRef()->getCatalog(&catDict);
- catDict.dictLookup("NeedsRendering", &needsRenderingObj);
- catDict.free();
- if (globalParams->getEnableXFA() &&
- !xfaObj.isNull() &&
- !(needsRenderingObj.isBool() && needsRenderingObj.getBool())) {
- form = XFAForm::load(docA, acroFormObj, &xfaObj);
- } else {
- form = AcroForm::load(docA, catalog, acroFormObj);
- }
- xfaObj.free();
- needsRenderingObj.free();
- return form;
+
+ // if acroFormObj is a null object, this will still create an
+ // AcroForm if there are unattached Widget-type annots
+ return AcroForm::load(docA, catalog, acroFormObj);
}
Form::Form(PDFDoc *docA) {
@@ -56,6 +54,40 @@ Form::Form(PDFDoc *docA) {
Form::~Form() {
}
+FormField *Form::findField(int pg, double x, double y) {
+ FormField *field;
+ double llx, lly, urx, ury;
+ int i;
+
+ for (i = 0; i < getNumFields(); ++i) {
+ field = getField(i);
+ if (field->getPageNum() == pg) {
+ field->getBBox(&llx, &lly, &urx, &ury);
+ if (llx <= x && x <= urx && lly <= y && y <= ury) {
+ return field;
+ }
+ }
+ }
+ return NULL;
+}
+
+int Form::findFieldIdx(int pg, double x, double y) {
+ FormField *field;
+ double llx, lly, urx, ury;
+ int i;
+
+ for (i = 0; i < getNumFields(); ++i) {
+ field = getField(i);
+ if (field->getPageNum() == pg) {
+ field->getBBox(&llx, &lly, &urx, &ury);
+ if (llx <= x && x <= urx && lly <= y && y <= ury) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
//------------------------------------------------------------------------
// FormField
//------------------------------------------------------------------------
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Form.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Form.h
index 50c0f478a51..0e851fe16e0 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Form.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Form.h
@@ -36,6 +36,9 @@ public:
virtual int getNumFields() = 0;
virtual FormField *getField(int idx) = 0;
+ FormField *findField(int pg, double x, double y);
+ int findFieldIdx(int pg, double x, double y);
+
protected:
Form(PDFDoc *docA);
@@ -51,10 +54,20 @@ public:
FormField();
virtual ~FormField();
+ virtual int getPageNum() = 0;
virtual const char *getType() = 0;
+
+ // Return the field name. This never returns NULL.
virtual Unicode *getName(int *length) = 0;
+
+ // Return the field value. This returns NULL if the field does not
+ // have a value.
virtual Unicode *getValue(int *length) = 0;
+ virtual void getBBox(double *llx, double *lly, double *urx, double *ury) = 0;
+ virtual void getFont(Ref *fontID, double *fontSize) = 0;
+ virtual void getColor(double *red, double *green, double *blue) = 0;
+
// Return the resource dictionaries used to draw this field. The
// returned object must be either a dictionary or an array of
// dictonaries.
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc
index a06d10dab71..c50e9b8e551 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Function.cc
@@ -17,6 +17,7 @@
#include <ctype.h>
#include <math.h>
#include "gmem.h"
+#include "gmempp.h"
#include "GList.h"
#include "Object.h"
#include "Dict.h"
@@ -407,7 +408,7 @@ SampledFunction::~SampledFunction() {
}
SampledFunction::SampledFunction(SampledFunction *func) {
- memcpy(this, func, sizeof(SampledFunction));
+ memcpy((void *)this, (void *)func, sizeof(SampledFunction));
idxOffset = (int *)gmallocn(1 << m, sizeof(int));
memcpy(idxOffset, func->idxOffset, (1 << m) * (int)sizeof(int));
samples = (double *)gmallocn(nSamples, sizeof(double));
@@ -518,6 +519,12 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
goto err2;
}
n = obj1.arrayGetLength();
+ if (n > funcMaxOutputs) {
+ error(errSyntaxError, -1,
+ "Functions with more than {0:d} outputs are unsupported",
+ funcMaxOutputs);
+ goto err2;
+ }
for (i = 0; i < n; ++i) {
obj1.arrayGet(i, &obj2);
if (!obj2.isNum()) {
@@ -584,7 +591,7 @@ ExponentialFunction::~ExponentialFunction() {
}
ExponentialFunction::ExponentialFunction(ExponentialFunction *func) {
- memcpy(this, func, sizeof(ExponentialFunction));
+ memcpy((void *)this, (void *)func, sizeof(ExponentialFunction));
}
void ExponentialFunction::transform(double *in, double *out) {
@@ -725,7 +732,7 @@ StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict,
StitchingFunction::StitchingFunction(StitchingFunction *func) {
int i;
- memcpy(this, func, sizeof(StitchingFunction));
+ memcpy((void *)this, (void *)func, sizeof(StitchingFunction));
funcs = (Function **)gmallocn(k, sizeof(Function *));
for (i = 0; i < k; ++i) {
funcs[i] = func->funcs[i]->copy();
@@ -781,6 +788,8 @@ void StitchingFunction::transform(double *in, double *out) {
// This is not an enum, because we can't foreward-declare the enum
// type in Function.h
+//
+// NB: This must be kept in sync with psOpNames[] below.
#define psOpAbs 0
#define psOpAdd 1
#define psOpAnd 2
@@ -821,15 +830,17 @@ void StitchingFunction::transform(double *in, double *out) {
#define psOpTrue 37
#define psOpTruncate 38
#define psOpXor 39
+// the push/j/jz ops are used internally (and are not listed in psOpNames[])
#define psOpPush 40
#define psOpJ 41
#define psOpJz 42
-#define nPSOps 43
+#define nPSOps (sizeof(psOpNames) / sizeof(const char *))
// Note: 'if' and 'ifelse' are parsed separately.
// The rest are listed here in alphabetical order.
-// The index in this table is equivalent to the psOpXXX defines.
+//
+// NB: This must be kept in sync with the psOpXXX defines above.
static const char *psOpNames[] = {
"abs",
"add",
@@ -923,7 +934,7 @@ PostScriptFunction::PostScriptFunction(Object *funcObj, Dict *dict) {
//----- parse the function
if (tokens->getLength() < 1 ||
((GString *)tokens->get(0))->cmp("{")) {
- error(errSyntaxError, -1, "Expected '{' at start of PostScript function");
+ error(errSyntaxError, -1, "Expected '{{' at start of PostScript function");
goto err2;
}
tokPtr = 1;
@@ -949,7 +960,7 @@ PostScriptFunction::PostScriptFunction(Object *funcObj, Dict *dict) {
}
PostScriptFunction::PostScriptFunction(PostScriptFunction *func) {
- memcpy(this, func, sizeof(PostScriptFunction));
+ memcpy((void *)this, (void *)func, sizeof(PostScriptFunction));
codeString = func->codeString->copy();
code = (PSCode *)gmallocn(codeSize, sizeof(PSCode));
memcpy(code, func->code, codeSize * sizeof(PSCode));
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
index 0fa48f8c8af..1f77bf48319 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.cc
@@ -2,7 +2,7 @@
//
// Gfx.cc
//
-// Copyright 1996-2013 Glyph & Cog, LLC
+// Copyright 1996-2016 Glyph & Cog, LLC
//
//========================================================================
@@ -18,6 +18,7 @@
#include <string.h>
#include <math.h>
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "GList.h"
#include "GlobalParams.h"
@@ -54,8 +55,8 @@
// Max delta allowed in any color component for a function shading fill.
#define functionColorDelta (dblToCol(1 / 256.0))
-// Max number of splits along the t axis for an axial shading fill.
-#define axialMaxSplits 256
+// Number of splits along the t axis for an axial shading fill.
+#define axialSplits 256
// Max delta allowed in any color component for an axial shading fill.
#define axialColorDelta (dblToCol(1 / 256.0))
@@ -520,7 +521,6 @@ Gfx::Gfx(PDFDoc *docA, OutputDev *outA, int pageNum, Dict *resDict,
baseMatrix[i] = state->getCTM()[i];
}
formDepth = 0;
- textClipBBoxEmpty = gTrue;
markedContentStack = new GList();
ocState = gTrue;
parser = NULL;
@@ -565,7 +565,6 @@ Gfx::Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict,
baseMatrix[i] = state->getCTM()[i];
}
formDepth = 0;
- textClipBBoxEmpty = gTrue;
markedContentStack = new GList();
ocState = gTrue;
parser = NULL;
@@ -684,17 +683,28 @@ GBool Gfx::checkForContentStreamLoop(Object *ref) {
void Gfx::go(GBool topLevel) {
Object obj;
Object args[maxArgs];
+ GBool aborted;
int numArgs, i;
- int lastAbortCheck, errCount;
+ int errCount;
// scan a sequence of objects
- updateLevel = 1; // make sure even empty pages trigger a call to dump()
- lastAbortCheck = 0;
+ opCounter = 0;
+ aborted = gFalse;
errCount = 0;
numArgs = 0;
parser->getObj(&obj);
while (!obj.isEOF()) {
+ // check for an abort
+ ++opCounter;
+ if (abortCheckCbk && opCounter > 100) {
+ if ((*abortCheckCbk)(abortCheckCbkData)) {
+ aborted = gTrue;
+ break;
+ }
+ opCounter = 0;
+ }
+
// got a command - execute it
if (obj.isCmd()) {
if (printCommands) {
@@ -714,22 +724,6 @@ void Gfx::go(GBool topLevel) {
args[i].free();
numArgs = 0;
- // periodically update display
- if (++updateLevel >= 20000) {
- out->dump();
- updateLevel = 0;
- }
-
- // check for an abort
- if (abortCheckCbk) {
- if (updateLevel - lastAbortCheck > 10) {
- if ((*abortCheckCbk)(abortCheckCbkData)) {
- break;
- }
- lastAbortCheck = updateLevel;
- }
- }
-
// check for too many errors
if (errCount > contentStreamErrorLimit) {
error(errSyntaxError, -1,
@@ -760,23 +754,21 @@ void Gfx::go(GBool topLevel) {
// args at end with no command
if (numArgs > 0) {
- error(errSyntaxError, getPos(), "Leftover args in content stream");
- if (printCommands) {
- printf("%d leftovers:", numArgs);
- for (i = 0; i < numArgs; ++i) {
- printf(" ");
- args[i].print(stdout);
+ if (!aborted) {
+ error(errSyntaxError, getPos(), "Leftover args in content stream");
+ if (printCommands) {
+ printf("%d leftovers:", numArgs);
+ for (i = 0; i < numArgs; ++i) {
+ printf(" ");
+ args[i].print(stdout);
+ }
+ printf("\n");
+ fflush(stdout);
}
- printf("\n");
- fflush(stdout);
}
- for (i = 0; i < numArgs; ++i)
+ for (i = 0; i < numArgs; ++i) {
args[i].free();
- }
-
- // update display
- if (topLevel && updateLevel > 0) {
- out->dump();
+ }
}
}
@@ -1006,6 +998,10 @@ void Gfx::opSetExtGState(Object args[], int numArgs) {
opSetFlat(&obj2, 1);
}
obj2.free();
+ if (obj1.dictLookup("RI", &obj2)->isName()) {
+ opSetRenderingIntent(&obj2, 1);
+ }
+ obj2.free();
// font
if (obj1.dictLookup("Font", &obj2)->isArray() &&
@@ -1270,6 +1266,24 @@ void Gfx::doSoftMask(Object *str, Object *strRef, GBool alpha,
}
void Gfx::opSetRenderingIntent(Object args[], int numArgs) {
+ GfxRenderingIntent ri;
+
+ ri = parseRenderingIntent(args[0].getName());
+ state->setRenderingIntent(ri);
+ out->updateRenderingIntent(state);
+}
+
+GfxRenderingIntent Gfx::parseRenderingIntent(const char *name) {
+ if (!strcmp(name, "AbsoluteColorimetric")) {
+ return gfxRenderingIntentAbsoluteColorimetric;
+ }
+ if (!strcmp(name, "Saturation")) {
+ return gfxRenderingIntentSaturation;
+ }
+ if (!strcmp(name, "Perceptual")) {
+ return gfxRenderingIntentPerceptual;
+ }
+ return gfxRenderingIntentRelativeColorimetric;
}
//------------------------------------------------------------------------
@@ -1887,6 +1901,7 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
GBool stroke, GBool eoFill, GBool text) {
GfxPatternColorSpace *patCS;
GfxColorSpace *cs;
+ GfxColor color;
GfxState *savedState;
double xMin, yMin, xMax, yMax, x, y, x1, y1, t;
double cxMin, cyMin, cxMax, cyMax;
@@ -1895,7 +1910,7 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
double bbox[4], m[6], ictm[6], m1[6], imb[6];
double det;
double xstep, ystep;
- int i;
+ int abortCheckCounter, i;
// get color space
patCS = (GfxPatternColorSpace *)(stroke ? state->getStrokeColorSpace()
@@ -1907,7 +1922,7 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
ptm = tPat->getMatrix();
// iCTM = invert CTM
det = ctm[0] * ctm[3] - ctm[1] * ctm[2];
- if (fabs(det) < 0.000001) {
+ if (fabs(det) <= 1e-10) {
error(errSyntaxError, getPos(), "Singular matrix in tiling pattern fill");
return;
}
@@ -1935,7 +1950,7 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
// construct a (device space) -> (pattern space) transform matrix
det = m1[0] * m1[3] - m1[1] * m1[2];
- if (fabs(det) < 0.000001) {
+ if (fabs(det) <= 1e-10) {
error(errSyntaxError, getPos(), "Singular matrix in tiling pattern fill");
return;
}
@@ -1966,12 +1981,20 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
} else {
state->setFillColorSpace(GfxColorSpace::create(csDeviceGray));
out->updateFillColorSpace(state);
+ state->getFillColorSpace()->getDefaultColor(&color);
+ state->setFillColor(&color);
+ out->updateFillColor(state);
state->setStrokeColorSpace(GfxColorSpace::create(csDeviceGray));
out->updateStrokeColorSpace(state);
+ state->getStrokeColorSpace()->getDefaultColor(&color);
+ state->setStrokeColor(&color);
+ out->updateStrokeColor(state);
}
if (!stroke) {
state->setLineWidth(0);
out->updateLineWidth(state);
+ state->setLineDash(NULL, 0, 0);
+ out->updateLineDash(state);
}
// clip to current path
@@ -2060,12 +2083,23 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
m1[4] = m[4];
m1[5] = m[5];
out->tilingPatternFill(state, this, tPat->getContentStreamRef(),
- tPat->getPaintType(), tPat->getResDict(),
+ tPat->getPaintType(), tPat->getTilingType(),
+ tPat->getResDict(),
m1, bbox,
xi0, yi0, xi1, yi1, xstep, ystep);
} else {
+ abortCheckCounter = 0;
for (yi = yi0; yi < yi1; ++yi) {
for (xi = xi0; xi < xi1; ++xi) {
+ if (abortCheckCbk) {
+ ++abortCheckCounter;
+ if (abortCheckCounter > 100) {
+ if ((*abortCheckCbk)(abortCheckCbkData)) {
+ goto err;
+ }
+ abortCheckCounter = 0;
+ }
+ }
x = xi * xstep;
y = yi * ystep;
m1[4] = x * m[0] + y * m[2] + m[4];
@@ -2115,7 +2149,7 @@ void Gfx::doShadingPatternFill(GfxShadingPattern *sPat,
ptm = sPat->getMatrix();
// iCTM = invert CTM
det = ctm[0] * ctm[3] - ctm[1] * ctm[2];
- if (fabs(det) < 0.000001) {
+ if (fabs(det) <= 1e-10) {
error(errSyntaxError, getPos(), "Singular matrix in shading pattern fill");
return;
}
@@ -2412,15 +2446,12 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
double x0, y0, x1, y1;
double dx, dy, mul;
GBool dxdyZero, horiz;
- double tMin, tMax, t, tx, ty;
+ double tMin, tMax, tMinExt, tMaxExt, t, tx, ty;
double sMin, sMax, tmp;
double ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1;
double t0, t1, tt;
- double ta[axialMaxSplits + 1];
- int next[axialMaxSplits + 1];
- GfxColor color0, color1;
- int nComps;
- int i, j, k;
+ GfxColor colors[axialSplits];
+ int abortCheckCounter, nComps, i, j, k;
if (out->useShadedFills() &&
out->axialShadedFill(state, shading)) {
@@ -2435,37 +2466,44 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
shading->getCoords(&x0, &y0, &x1, &y1);
dx = x1 - x0;
dy = y1 - y0;
- dxdyZero = fabs(dx) < 0.01 && fabs(dy) < 0.01;
+ dxdyZero = fabs(dx) < 0.0001 && fabs(dy) < 0.0001;
horiz = fabs(dy) < fabs(dx);
if (dxdyZero) {
+ tMinExt = tMaxExt = 0;
tMin = tMax = 0;
} else {
mul = 1 / (dx * dx + dy * dy);
- tMin = tMax = ((xMin - x0) * dx + (yMin - y0) * dy) * mul;
+ tMinExt = tMaxExt = ((xMin - x0) * dx + (yMin - y0) * dy) * mul;
t = ((xMin - x0) * dx + (yMax - y0) * dy) * mul;
- if (t < tMin) {
- tMin = t;
- } else if (t > tMax) {
- tMax = t;
+ if (t < tMinExt) {
+ tMinExt = t;
+ } else if (t > tMaxExt) {
+ tMaxExt = t;
}
t = ((xMax - x0) * dx + (yMin - y0) * dy) * mul;
- if (t < tMin) {
- tMin = t;
- } else if (t > tMax) {
- tMax = t;
+ if (t < tMinExt) {
+ tMinExt = t;
+ } else if (t > tMaxExt) {
+ tMaxExt = t;
}
t = ((xMax - x0) * dx + (yMax - y0) * dy) * mul;
- if (t < tMin) {
- tMin = t;
- } else if (t > tMax) {
- tMax = t;
+ if (t < tMinExt) {
+ tMinExt = t;
+ } else if (t > tMaxExt) {
+ tMaxExt = t;
}
- if (tMin < 0 && !shading->getExtend0()) {
+ if ((tMin = tMinExt) < 0) {
tMin = 0;
}
- if (tMax > 1 && !shading->getExtend1()) {
+ if (!shading->getExtend0()) {
+ tMinExt = tMin;
+ }
+ if ((tMax = tMaxExt) > 1) {
tMax = 1;
}
+ if (!shading->getExtend1()) {
+ tMaxExt = tMax;
+ }
}
// get the function domain
@@ -2499,22 +2537,6 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
// difference across a region is small enough, and then the region
// is painted with a single color.
- // set up
- nComps = shading->getColorSpace()->getNComps();
- ta[0] = tMin;
- next[0] = axialMaxSplits;
- ta[axialMaxSplits] = tMax;
-
- // compute the color at t = tMin
- if (tMin < 0) {
- tt = t0;
- } else if (tMin > 1) {
- tt = t1;
- } else {
- tt = t0 + (t1 - t0) * tMin;
- }
- shading->getColor(tt, &color0);
-
// compute the coordinates of the point on the t axis at t = tMin;
// then compute the intersection of the perpendicular line with the
// bounding box
@@ -2539,50 +2561,94 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
vx0 = tx - sMax * dy;
vy0 = ty + sMax * dx;
- i = 0;
- while (i < axialMaxSplits) {
-
- // bisect until color difference is small enough or we hit the
- // bisection limit
- j = next[i];
- while (j > i + 1) {
- if (ta[j] < 0) {
- tt = t0;
- } else if (ta[j] > 1) {
- tt = t1;
+ // fill the extension at t0
+ if (shading->getExtend0() && tMinExt < tMin) {
+
+ // compute the color at t0
+ shading->getColor(t0, &colors[0]);
+
+ // compute the coordinates of the point on the t axis at t =
+ // tMinExt; then compute the intersection of the perpendicular
+ // line with the bounding box
+ tx = x0 + tMinExt * dx;
+ ty = y0 + tMinExt * dy;
+ if (dxdyZero) {
+ sMin = sMax = 0;
+ } else {
+ if (horiz) {
+ sMin = (yMin - ty) / dx;
+ sMax = (yMax - ty) / dx;
} else {
- tt = t0 + (t1 - t0) * ta[j];
+ sMin = (xMin - tx) / -dy;
+ sMax = (xMax - tx) / -dy;
}
- // require at least two splits (to avoid problems where the
- // color doesn't change smoothly along the t axis)
- if (j - i <= axialMaxSplits / 4) {
- shading->getColor(tt, &color1);
- for (k = 0; k < nComps; ++k) {
- if (abs(color1.c[k] - color0.c[k]) > axialColorDelta) {
- break;
- }
- }
- if (k == nComps) {
- break;
- }
+ if (sMin > sMax) {
+ tmp = sMin; sMin = sMax; sMax = tmp;
}
- k = (i + j) / 2;
- ta[k] = 0.5 * (ta[i] + ta[j]);
- next[i] = k;
- next[k] = j;
- j = k;
}
+ ux1 = tx - sMin * dy;
+ uy1 = ty + sMin * dx;
+ vx1 = tx - sMax * dy;
+ vy1 = ty + sMax * dx;
- // use the average of the colors of the two sides of the region
- for (k = 0; k < nComps; ++k) {
- color0.c[k] = (color0.c[k] + color1.c[k]) / 2;
+ // set the color
+ state->setFillColor(&colors[0]);
+ out->updateFillColor(state);
+
+ // fill the region
+ state->moveTo(ux1, uy1);
+ state->lineTo(vx1, vy1);
+ state->lineTo(vx0, vy0);
+ state->lineTo(ux0, uy0);
+ state->closePath();
+ out->fill(state);
+ state->clearPath();
+ }
+
+ // traverse the t axis, splitting [tMin, tMax] into axialSplits regions
+
+ // compute the color in the center of each region
+ for (i = 0; i < axialSplits; ++i) {
+ t = tMin + (tMax - tMin) * (i + 0.5) / axialSplits;
+ tt = t0 + (t1 - t0) * t;
+ shading->getColor(tt, &colors[i]);
+ }
+
+ // each iteration draws one or more regions, starting at i --
+ // if the colors are similar, it will combine regions i, i+1, ...
+ nComps = shading->getColorSpace()->getNComps();
+ abortCheckCounter = 0;
+ i = 0;
+ while (i < axialSplits) {
+
+ if (abortCheckCbk) {
+ ++abortCheckCounter;
+ if (abortCheckCounter > 100) {
+ if ((*abortCheckCbk)(abortCheckCbkData)) {
+ break;
+ }
+ abortCheckCounter = 0;
+ }
+ }
+
+ // check for similar colors
+ for (j = i + 1; j < axialSplits; ++j) {
+ for (k = 0; k < nComps; ++k) {
+ if (abs(colors[j].c[k] - colors[i].c[k]) > axialColorDelta) {
+ break;
+ }
+ }
+ if (k < nComps) {
+ break;
+ }
}
// compute the coordinates of the point on the t axis; then
// compute the intersection of the perpendicular line with the
// bounding box
- tx = x0 + ta[j] * dx;
- ty = y0 + ta[j] * dy;
+ t = tMin + (tMax - tMin) * (double)j / axialSplits;
+ tx = x0 + t * dx;
+ ty = y0 + t * dy;
if (dxdyZero) {
sMin = sMax = 0;
} else {
@@ -2603,7 +2669,7 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
vy1 = ty + sMax * dx;
// set the color
- state->setFillColor(&color0);
+ state->setFillColor(&colors[i]);
out->updateFillColor(state);
// fill the region
@@ -2620,11 +2686,62 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
uy0 = uy1;
vx0 = vx1;
vy0 = vy1;
- color0 = color1;
- i = next[i];
+
+ i = j;
+ }
+
+ // fill the extension at t1
+ if (shading->getExtend1() && tMaxExt > tMax) {
+
+ // compute the color at t1
+ shading->getColor(t1, &colors[0]);
+
+ // compute the coordinates of the point on the t axis at t =
+ // tMaxExt; then compute the intersection of the perpendicular
+ // line with the bounding box
+ tx = x0 + tMaxExt * dx;
+ ty = y0 + tMaxExt * dy;
+ if (dxdyZero) {
+ sMin = sMax = 0;
+ } else {
+ if (horiz) {
+ sMin = (yMin - ty) / dx;
+ sMax = (yMax - ty) / dx;
+ } else {
+ sMin = (xMin - tx) / -dy;
+ sMax = (xMax - tx) / -dy;
+ }
+ if (sMin > sMax) {
+ tmp = sMin; sMin = sMax; sMax = tmp;
+ }
+ }
+ ux1 = tx - sMin * dy;
+ uy1 = ty + sMin * dx;
+ vx1 = tx - sMax * dy;
+ vy1 = ty + sMax * dx;
+
+ // set the color
+ state->setFillColor(&colors[0]);
+ out->updateFillColor(state);
+
+ // fill the region
+ state->moveTo(ux0, uy0);
+ state->lineTo(vx0, vy0);
+ state->lineTo(vx1, vy1);
+ state->lineTo(ux1, uy1);
+ state->closePath();
+ out->fill(state);
+ state->clearPath();
}
}
+#if defined(__GNUC__) && !defined(__clang__)
+// this function makes a lot of sin()/cos() calls, which are slow
+// with glibc 2.16 and newer on x86; accuracy isn't terribly
+// important here, so tell gcc to use the fast version
+#pragma GCC optimize ("fast-math")
+#endif
+
void Gfx::doRadialShFill(GfxRadialShading *shading) {
double xMin, yMin, xMax, yMax;
double x0, y0, r0, x1, y1, r1, t0, t1;
@@ -2637,9 +2754,9 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) {
GBool haveSLeft, haveSRight, haveSTop, haveSBottom, haveSZero;
GBool haveSMin, haveSMax;
GBool enclosed;
- int ia, ib, k, n;
double *ctm;
double theta, alpha, angle, t;
+ int abortCheckCounter, ia, ib, k, n;
if (out->useShadedFills() &&
out->radialShadedFill(state, shading)) {
@@ -2826,8 +2943,19 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) {
}
// fill the circles
+ abortCheckCounter = 0;
while (ia < radialMaxSplits) {
+ if (abortCheckCbk) {
+ ++abortCheckCounter;
+ if (abortCheckCounter > 100) {
+ if ((*abortCheckCbk)(abortCheckCbkData)) {
+ break;
+ }
+ abortCheckCounter = 0;
+ }
+ }
+
// go as far along the t axis (toward t1) as we can, such that the
// color difference is within the tolerance (radialColorDelta) --
// this uses bisection (between the current value, t, and t1),
@@ -3004,14 +3132,28 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) {
}
}
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC reset_options
+#endif
+
void Gfx::doGouraudTriangleShFill(GfxGouraudTriangleShading *shading) {
double x0, y0, x1, y1, x2, y2;
double color0[gfxColorMaxComps];
double color1[gfxColorMaxComps];
double color2[gfxColorMaxComps];
- int i;
+ int abortCheckCounter, i;
+ abortCheckCounter = 0;
for (i = 0; i < shading->getNTriangles(); ++i) {
+ if (abortCheckCbk) {
+ ++abortCheckCounter;
+ if (abortCheckCounter > 25) {
+ if ((*abortCheckCbk)(abortCheckCbkData)) {
+ break;
+ }
+ abortCheckCounter = 0;
+ }
+ }
shading->getTriangle(i, &x0, &y0, color0,
&x1, &y1, color1,
&x2, &y2, color2);
@@ -3087,7 +3229,7 @@ void Gfx::gouraudFillTriangle(double x0, double y0, double *color0,
}
void Gfx::doPatchMeshShFill(GfxPatchMeshShading *shading) {
- int start, i;
+ int start, abortCheckCounter, i;
if (shading->getNPatches() > 128) {
start = 3;
@@ -3098,7 +3240,17 @@ void Gfx::doPatchMeshShFill(GfxPatchMeshShading *shading) {
} else {
start = 0;
}
+ abortCheckCounter = 0;
for (i = 0; i < shading->getNPatches(); ++i) {
+ if (abortCheckCbk) {
+ ++abortCheckCounter;
+ if (abortCheckCounter > 25) {
+ if ((*abortCheckCbk)(abortCheckCbkData)) {
+ break;
+ }
+ abortCheckCounter = 0;
+ }
+ }
fillPatch(shading->getPatch(i), shading, start);
}
}
@@ -3107,23 +3259,67 @@ void Gfx::fillPatch(GfxPatch *patch, GfxPatchMeshShading *shading, int depth) {
GfxPatch patch00, patch01, patch10, patch11;
GfxColor c00, c01, c10, c11;
double xx[4][8], yy[4][8];
- double xxm, yym;
- int nComps, i;
+ double x, y, xMin, yMin, xMax, yMax, xxm, yym;
+ int nComps, i, j;
+ GBool stop;
- nComps = shading->getColorSpace()->getNComps();
shading->getColor(patch->color[0][0], &c00);
- shading->getColor(patch->color[0][1], &c01);
- shading->getColor(patch->color[1][0], &c10);
- shading->getColor(patch->color[1][1], &c11);
- for (i = 0; i < nComps; ++i) {
- if (abs(c00.c[i] - c01.c[i]) > patchColorDelta ||
- abs(c01.c[i] - c11.c[i]) > patchColorDelta ||
- abs(c11.c[i] - c10.c[i]) > patchColorDelta ||
- abs(c10.c[i] - c00.c[i]) > patchColorDelta) {
- break;
+ stop = gFalse;
+
+ // stop subdivision at max depth
+ if (depth == patchMaxDepth) {
+ stop = gTrue;
+ }
+
+ // stop subdivision if colors are close enough
+ if (!stop) {
+ nComps = shading->getColorSpace()->getNComps();
+ shading->getColor(patch->color[0][1], &c01);
+ shading->getColor(patch->color[1][0], &c10);
+ shading->getColor(patch->color[1][1], &c11);
+ for (i = 0; i < nComps; ++i) {
+ if (abs(c00.c[i] - c01.c[i]) > patchColorDelta ||
+ abs(c01.c[i] - c11.c[i]) > patchColorDelta ||
+ abs(c11.c[i] - c10.c[i]) > patchColorDelta ||
+ abs(c10.c[i] - c00.c[i]) > patchColorDelta) {
+ break;
+ }
+ }
+ if (i == nComps) {
+ stop = gTrue;
}
}
- if (i == nComps || depth == patchMaxDepth) {
+
+ // stop subdivision if patch is small enough
+ if (!stop) {
+ xMin = yMin = xMax = yMax = 0;
+ for (j = 0; j < 4; ++j) {
+ for (i = 0; i < 4; ++i) {
+ state->transformDelta(patch->x[i][j], patch->y[i][j], &x, &y);
+ if (i == 0 && j == 0) {
+ xMin = xMax = x;
+ yMin = yMax = y;
+ } else {
+ if (x < xMin) {
+ xMin = x;
+ } else if (x > xMax) {
+ xMax = x;
+ }
+ if (y < yMin) {
+ yMin = y;
+ } else if (y > yMax) {
+ yMax = y;
+ }
+ }
+ }
+ }
+ if (xMax - xMin < 1 && yMax - yMin < 1) {
+ stop = gTrue;
+ }
+ }
+
+ // draw the patch
+ if (stop) {
state->setFillColor(&c00);
out->updateFillColor(state);
state->moveTo(patch->x[0][0], patch->y[0][0]);
@@ -3142,6 +3338,8 @@ void Gfx::fillPatch(GfxPatch *patch, GfxPatchMeshShading *shading, int depth) {
state->closePath();
out->fill(state);
state->clearPath();
+
+ // subdivide the patch
} else {
for (i = 0; i < 4; ++i) {
xx[i][0] = patch->x[i][0];
@@ -3266,7 +3464,6 @@ void Gfx::opBeginText(Object args[], int numArgs) {
out->updateTextMat(state);
out->updateTextPos(state);
fontChanged = gTrue;
- textClipBBoxEmpty = gTrue;
}
void Gfx::opEndText(Object args[], int numArgs) {
@@ -3724,7 +3921,7 @@ void Gfx::doShowText(GString *s) {
out->restoreTextPos(state);
}
- updateLevel += 10 * s->getLength();
+ opCounter += 10 * s->getLength();
}
// NB: this is only called when ocState is false.
@@ -3741,6 +3938,7 @@ void Gfx::doIncCharCount(GString *s) {
void Gfx::opXObject(Object args[], int numArgs) {
char *name;
Object obj1, obj2, obj3, refObj;
+ GBool ocSaved, oc;
#if OPI_SUPPORT
Object opiDict;
#endif
@@ -3757,6 +3955,15 @@ void Gfx::opXObject(Object args[], int numArgs) {
obj1.free();
return;
}
+
+ // check for optional content key
+ ocSaved = ocState;
+ obj1.streamGetDict()->lookupNF("OC", &obj2);
+ if (doc->getOptionalContent()->evalOCObject(&obj2, &oc)) {
+ ocState &= oc;
+ }
+ obj2.free();
+
#if USE_EXCEPTIONS
try {
#endif
@@ -3776,15 +3983,19 @@ void Gfx::opXObject(Object args[], int numArgs) {
} else if (obj2.isName("Form")) {
res->lookupXObjectNF(name, &refObj);
if (out->useDrawForm() && refObj.isRef()) {
- out->drawForm(refObj.getRef());
+ if (ocState) {
+ out->drawForm(refObj.getRef());
+ }
} else {
doForm(&refObj, &obj1);
}
refObj.free();
} else if (obj2.isName("PS")) {
- obj1.streamGetDict()->lookup("Level1", &obj3);
- out->psXObject(obj1.getStream(),
- obj3.isStream() ? obj3.getStream() : (Stream *)NULL);
+ if (ocState) {
+ obj1.streamGetDict()->lookup("Level1", &obj3);
+ out->psXObject(obj1.getStream(),
+ obj3.isStream() ? obj3.getStream() : (Stream *)NULL);
+ }
} else if (obj2.isName()) {
error(errSyntaxError, getPos(),
"Unknown XObject subtype '{0:s}'", obj2.getName());
@@ -3806,6 +4017,8 @@ void Gfx::opXObject(Object args[], int numArgs) {
}
#endif
obj1.free();
+
+ ocState = ocSaved;
}
void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
@@ -3813,20 +4026,26 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
int width, height;
int bits, maskBits;
StreamColorSpaceMode csMode;
- GBool mask;
- GBool invert;
+ GBool mask, invert;
GfxColorSpace *colorSpace, *maskColorSpace;
GfxImageColorMap *colorMap, *maskColorMap;
Object maskObj, smaskObj;
- GBool haveColorKeyMask, haveExplicitMask, haveSoftMask;
+ GBool haveColorKeyMask, haveExplicitMask, haveSoftMask, haveMatte;
int maskColors[2*gfxColorMaxComps];
int maskWidth, maskHeight;
GBool maskInvert;
Stream *maskStr;
+ double matte[gfxColorMaxComps];
GBool interpolate;
+ GfxRenderingIntent riSaved;
Object obj1, obj2;
int i, n;
+ // check for optional content
+ if (!ocState && !inlineImg) {
+ return;
+ }
+
// get info from the stream
bits = 0;
csMode = streamCSNone;
@@ -3835,6 +4054,9 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
// get stream dict
dict = str->getDict();
+ // save the current rendering intent
+ riSaved = state->getRenderingIntent();
+
// get size
dict->lookup("Width", &obj1);
if (obj1.isNull()) {
@@ -3948,6 +4170,12 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
} else {
+ // rendering intent
+ if (dict->lookup("Intent", &obj1)->isName()) {
+ opSetRenderingIntent(&obj1, 1);
+ }
+ obj1.free();
+
// get color space and color map
dict->lookup("ColorSpace", &obj1);
if (obj1.isNull()) {
@@ -3992,7 +4220,7 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
}
// get the mask
- haveColorKeyMask = haveExplicitMask = haveSoftMask = gFalse;
+ haveColorKeyMask = haveExplicitMask = haveSoftMask = haveMatte = gFalse;
maskStr = NULL; // make gcc happy
maskWidth = maskHeight = 0; // make gcc happy
maskInvert = gFalse; // make gcc happy
@@ -4002,6 +4230,9 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
if (smaskObj.isStream()) {
// soft mask
if (inlineImg) {
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
goto err1;
}
maskStr = smaskObj.getStream();
@@ -4012,6 +4243,9 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
maskDict->lookup("W", &obj1);
}
if (!obj1.isInt()) {
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
goto err2;
}
maskWidth = obj1.getInt();
@@ -4022,6 +4256,9 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
maskDict->lookup("H", &obj1);
}
if (!obj1.isInt()) {
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
goto err2;
}
maskHeight = obj1.getInt();
@@ -4032,6 +4269,9 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
maskDict->lookup("BPC", &obj1);
}
if (!obj1.isInt()) {
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
goto err2;
}
maskBits = obj1.getInt();
@@ -4050,12 +4290,14 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
obj2.free();
}
}
- maskColorSpace = GfxColorSpace::parse(&obj1
- );
- obj1.free();
- if (!maskColorSpace || maskColorSpace->getMode() != csDeviceGray) {
+ if (!obj1.isName("DeviceGray")) {
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
goto err1;
}
+ maskColorSpace = new GfxDeviceGrayColorSpace();
+ obj1.free();
maskDict->lookup("Decode", &obj1);
if (obj1.isNull()) {
obj1.free();
@@ -4065,9 +4307,29 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
obj1.free();
if (!maskColorMap->isOk()) {
delete maskColorMap;
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
goto err1;
}
- //~ handle the Matte entry
+ if (maskDict->lookup("Matte", &obj1)->isArray()) {
+ if (obj1.arrayGetLength() == colorSpace->getNComps()) {
+ for (i = 0; i < obj1.arrayGetLength(); ++i) {
+ if (obj1.arrayGet(i, &obj2)->isNum()) {
+ matte[i] = obj2.getNum();
+ } else {
+ error(errSyntaxError, getPos(),
+ "Invalid Matte entry in soft mask");
+ matte[i] = 0;
+ }
+ obj2.free();
+ }
+ haveMatte = gTrue;
+ } else {
+ error(errSyntaxError, getPos(), "Invalid Matte entry in soft mask");
+ }
+ }
+ obj1.free();
haveSoftMask = gTrue;
} else if (maskObj.isArray()) {
// color key mask
@@ -4104,6 +4366,9 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
} else if (maskObj.isStream()) {
// explicit mask
if (inlineImg) {
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
goto err1;
}
maskStr = maskObj.getStream();
@@ -4114,6 +4379,9 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
maskDict->lookup("W", &obj1);
}
if (!obj1.isInt()) {
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
goto err2;
}
maskWidth = obj1.getInt();
@@ -4124,6 +4392,9 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
maskDict->lookup("H", &obj1);
}
if (!obj1.isInt()) {
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
goto err2;
}
maskHeight = obj1.getInt();
@@ -4134,6 +4405,9 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
maskDict->lookup("IM", &obj1);
}
if (!obj1.isBool() || !obj1.getBool()) {
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
goto err2;
}
obj1.free();
@@ -4148,6 +4422,9 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
maskInvert = obj2.isNum() && obj2.getNum() == 1;
obj2.free();
} else if (!obj1.isNull()) {
+ delete colorMap;
+ maskObj.free();
+ smaskObj.free();
goto err2;
}
obj1.free();
@@ -4169,6 +4446,7 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
if (haveSoftMask) {
out->drawSoftMaskedImage(state, ref, str, width, height, colorMap,
maskStr, maskWidth, maskHeight, maskColorMap,
+ haveMatte ? matte : (double *)NULL,
interpolate);
delete maskColorMap;
} else if (haveExplicitMask) {
@@ -4187,10 +4465,16 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
smaskObj.free();
}
+ // restore rendering intent
+ if (state->getRenderingIntent() != riSaved) {
+ state->setRenderingIntent(riSaved);
+ out->updateRenderingIntent(state);
+ }
+
if ((i = width * height) > 1000) {
i = 1000;
}
- updateLevel += i;
+ opCounter += i;
return;
@@ -4198,6 +4482,12 @@ void Gfx::doImage(Object *ref, Stream *str, GBool inlineImg) {
obj1.free();
err1:
error(errSyntaxError, getPos(), "Bad image parameters");
+
+ // restore rendering intent
+ if (state->getRenderingIntent() != riSaved) {
+ state->setRenderingIntent(riSaved);
+ out->updateRenderingIntent(state);
+ }
}
void Gfx::doForm(Object *strRef, Object *str) {
@@ -4208,7 +4498,6 @@ void Gfx::doForm(Object *strRef, Object *str) {
double m[6], bbox[4];
Object resObj;
Dict *resDict;
- GBool oc, ocSaved;
Object obj1, obj2, obj3;
int i;
@@ -4217,6 +4506,11 @@ void Gfx::doForm(Object *strRef, Object *str) {
return;
}
+ // check for optional content
+ if (!ocState && !out->needCharCount()) {
+ return;
+ }
+
// get stream dict
dict = str->streamGetDict();
@@ -4227,25 +4521,11 @@ void Gfx::doForm(Object *strRef, Object *str) {
}
obj1.free();
- // check for optional content key
- ocSaved = ocState;
- dict->lookupNF("OC", &obj1);
- if (doc->getOptionalContent()->evalOCObject(&obj1, &oc) && !oc) {
- obj1.free();
- if (out->needCharCount()) {
- ocState = gFalse;
- } else {
- return;
- }
- }
- obj1.free();
-
// get bounding box
dict->lookup("BBox", &bboxObj);
if (!bboxObj.isArray()) {
bboxObj.free();
error(errSyntaxError, getPos(), "Bad form bounding box");
- ocState = ocSaved;
return;
}
for (i = 0; i < 4; ++i) {
@@ -4308,8 +4588,6 @@ void Gfx::doForm(Object *strRef, Object *str) {
delete blendingColorSpace;
}
resObj.free();
-
- ocState = ocSaved;
}
void Gfx::drawForm(Object *strRef, Dict *resDict,
@@ -4328,7 +4606,7 @@ void Gfx::drawForm(Object *strRef, Dict *resDict,
pushResources(resDict);
// save current graphics state
- savedState = saveStateStack();
+ saveState();
// kill any pre-existing path
state->clearPath();
@@ -4376,9 +4654,15 @@ void Gfx::drawForm(Object *strRef, Dict *resDict,
baseMatrix[i] = state->getCTM()[i];
}
+ // save the state stack -- this handles the case where the form
+ // contents have unbalanced q/Q operators
+ savedState = saveStateStack();
+
// draw the form
display(strRef, gFalse);
+ restoreStateStack(savedState);
+
if (softMask || transpGroup) {
out->endTransparencyGroup(state);
}
@@ -4392,7 +4676,7 @@ void Gfx::drawForm(Object *strRef, Dict *resDict,
parser = oldParser;
// restore graphics state
- restoreStateStack(savedState);
+ restoreState();
// pop resource stack
popResources();
@@ -4410,41 +4694,69 @@ void Gfx::takeContentStreamStack(Gfx *oldGfx) {
contentStreamStack->append(oldGfx->contentStreamStack);
}
+void Gfx::endOfPage() {
+ while (state->hasSaves()) {
+ restoreState();
+ }
+ while (markedContentStack->getLength() > 0) {
+ opEndMarkedContent(NULL, 0);
+ }
+}
+
//------------------------------------------------------------------------
// in-line image operators
//------------------------------------------------------------------------
void Gfx::opBeginImage(Object args[], int numArgs) {
Stream *str;
+ GBool haveLength;
int c1, c2, c3;
// NB: this function is run even if ocState is false -- doImage() is
// responsible for skipping over the inline image data
// build dict/stream
- str = buildImageStream();
+ str = buildImageStream(&haveLength);
// display the image
if (str) {
doImage(NULL, str, gTrue);
- // skip 'EI' tag
- c1 = str->getUndecodedStream()->getChar();
- c2 = str->getUndecodedStream()->getChar();
- c3 = str->getUndecodedStream()->lookChar();
- while (!(c1 == 'E' && c2 == 'I' && Lexer::isSpace(c3)) && c3 != EOF) {
- c1 = c2;
+ // if we have the stream length, skip to end-of-stream and then
+ // skip 'EI' in the original stream
+ if (haveLength) {
+ while ((c1 = str->getChar()) != EOF) ;
+ delete str;
+ str = parser->getStream();
+ c1 = str->getChar();
+ c2 = str->getChar();
+ c3 = str->lookChar();
+ while (!(c1 == 'E' && c2 == 'I' && Lexer::isSpace(c3)) && c3 != EOF) {
+ c1 = c2;
+ c2 = str->getChar();
+ c3 = str->lookChar();
+ }
+
+ // else, look for the 'EI' tag and skip it
+ } else {
+ c1 = str->getUndecodedStream()->getChar();
c2 = str->getUndecodedStream()->getChar();
c3 = str->getUndecodedStream()->lookChar();
+ while (!(c1 == 'E' && c2 == 'I' && Lexer::isSpace(c3)) && c3 != EOF) {
+ c1 = c2;
+ c2 = str->getUndecodedStream()->getChar();
+ c3 = str->getUndecodedStream()->lookChar();
+ }
+ delete str;
}
- delete str;
}
}
-Stream *Gfx::buildImageStream() {
+Stream *Gfx::buildImageStream(GBool *haveLength) {
Object dict;
- Object obj;
+ Object obj, lengthObj;
char *key;
+ int length;
Stream *str;
// build dictionary
@@ -4475,13 +4787,26 @@ Stream *Gfx::buildImageStream() {
}
obj.free();
+ // check for length field
+ length = 0;
+ *haveLength = gFalse;
+ if (!dict.dictLookup("Length", &lengthObj)->isInt()) {
+ lengthObj.free();
+ dict.dictLookup("L", &lengthObj);
+ }
+ if (lengthObj.isInt()) {
+ length = lengthObj.getInt();
+ *haveLength = gTrue;
+ }
+ lengthObj.free();
+
// make stream
if (!(str = parser->getStream())) {
error(errSyntaxError, getPos(), "Invalid inline image data");
dict.free();
return NULL;
}
- str = new EmbedStream(str, &dict, gFalse, 0);
+ str = new EmbedStream(str, &dict, *haveLength, (GFileOffset)length);
str = str->addFilters(&dict);
return str;
@@ -4545,7 +4870,7 @@ void Gfx::opBeginMarkedContent(Object args[], int numArgs) {
if (args[0].isName("OC") && numArgs == 2 && args[1].isName() &&
res->lookupPropertiesNF(args[1].getName(), &obj)) {
if (doc->getOptionalContent()->evalOCObject(&obj, &ocStateNew)) {
- ocState = ocStateNew;
+ ocState &= ocStateNew;
}
obj.free();
mcKind = gfxMCOptionalContent;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
index b7347771861..9d175825f97 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Gfx.h
@@ -2,7 +2,7 @@
//
// Gfx.h
//
-// Copyright 1996-2003 Glyph & Cog, LLC
+// Copyright 1996-2016 Glyph & Cog, LLC
//
//========================================================================
@@ -17,6 +17,7 @@
#include "gtypes.h"
#include "gfile.h"
+#include "GfxState.h"
class GString;
class GList;
@@ -30,19 +31,6 @@ class Function;
class OutputDev;
class GfxFontDict;
class GfxFont;
-class GfxPattern;
-class GfxTilingPattern;
-class GfxShadingPattern;
-class GfxShading;
-class GfxFunctionShading;
-class GfxAxialShading;
-class GfxRadialShading;
-class GfxGouraudTriangleShading;
-class GfxPatchMeshShading;
-struct GfxPatch;
-class GfxState;
-struct GfxColor;
-class GfxColorSpace;
class Gfx;
class PDFRectangle;
class AnnotBorderStyle;
@@ -189,6 +177,9 @@ public:
// the new Gfx object.
void takeContentStreamStack(Gfx *oldGfx);
+ // Clear the state stack and the marked content stack.
+ void endOfPage();
+
private:
PDFDoc *doc;
@@ -197,7 +188,8 @@ private:
GBool subPage; // is this a sub-page object?
GBool printCommands; // print the drawing commands (for debugging)
GfxResources *res; // resource stack
- int updateLevel;
+ int opCounter; // operation counter (used to decide when
+ // to check for an abort)
GfxState *state; // current graphics state
GBool fontChanged; // set if font or text matrix has changed
@@ -206,9 +198,6 @@ private:
double baseMatrix[6]; // default matrix for most recent
// page/form/pattern
int formDepth;
- double textClipBBox[4]; // text clipping bounding box
- GBool textClipBBoxEmpty; // true if textClipBBox has not been
- // initialized yet
GBool ocState; // true if drawing is enabled, false if
// disabled
GList *markedContentStack; // BMC/BDC/EMC stack [GfxMarkedContent]
@@ -246,6 +235,7 @@ private:
GBool isolated, GBool knockout,
Function *transferFunc, GfxColor *backdropColor);
void opSetRenderingIntent(Object args[], int numArgs);
+ GfxRenderingIntent parseRenderingIntent(const char *name);
// color operators
void opSetFillGray(Object args[], int numArgs);
@@ -345,7 +335,7 @@ private:
// in-line image operators
void opBeginImage(Object args[], int numArgs);
- Stream *buildImageStream();
+ Stream *buildImageStream(GBool *haveLength);
void opImageData(Object args[], int numArgs);
void opEndImage(Object args[], int numArgs);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
index 0ebb5b95cc8..201f609adbf 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.cc
@@ -18,10 +18,10 @@
#include <ctype.h>
#include <math.h>
#include <limits.h>
-#if HAVE_STD_SORT
-#include <algorithm>
-#endif
#include "gmem.h"
+#include "gmempp.h"
+#include "GList.h"
+#include "GHash.h"
#include "Error.h"
#include "Object.h"
#include "Dict.h"
@@ -206,6 +206,7 @@ GfxFont::GfxFont(char *tagA, Ref idA, GString *nameA,
type = typeA;
embFontID = embFontIDA;
embFontName = NULL;
+ hasToUnicode = gFalse;
}
GfxFont::~GfxFont() {
@@ -414,7 +415,7 @@ GfxFontType GfxFont::getFontType(XRef *xref, Dict *fontDict, Ref *embID) {
void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
Object obj1, obj2, obj3, obj4;
- double t;
+ double t, t2;
int i;
// assume Times-Roman by default (for substitution purposes)
@@ -444,13 +445,33 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
}
obj2.free();
- // get Ascent and Descent
+ // get Ascent
+ // (CapHeight is a little more reliable - so use it if present)
obj1.dictLookup("Ascent", &obj2);
- if (obj2.isNum()) {
- t = 0.001 * obj2.getNum();
- // some broken font descriptors specify a negative ascent
- if (t < 0) {
- t = -t;
+ obj1.dictLookup("CapHeight", &obj3);
+ if (obj2.isNum() || obj3.isNum()) {
+ if (obj2.isNum()) {
+ t = 0.001 * obj2.getNum();
+ // some broken font descriptors specify a negative ascent
+ if (t < 0) {
+ t = -t;
+ }
+ } else {
+ t = 0;
+ }
+ if (obj3.isNum()) {
+ t2 = 0.001 * obj3.getNum();
+ // some broken font descriptors specify a negative ascent
+ if (t2 < 0) {
+ t2 = -t2;
+ }
+ } else {
+ t2 = 0;
+ }
+ // if both Ascent and CapHeight are set, use the smaller one
+ // (because the most common problem is that Ascent is too large)
+ if (t2 != 0 && (t == 0 || t2 < t)) {
+ t = t2;
}
// some broken font descriptors set ascent and descent to 0;
// others set it to ridiculous values (e.g., 32768)
@@ -459,6 +480,9 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
}
}
obj2.free();
+ obj3.free();
+
+ // get Descent
obj1.dictLookup("Descent", &obj2);
if (obj2.isNum()) {
t = 0.001 * obj2.getNum();
@@ -512,6 +536,7 @@ CharCodeToUnicode *GfxFont::readToUnicodeCMap(Dict *fontDict, int nBits,
ctu = CharCodeToUnicode::parseCMap(buf, nBits);
}
delete buf;
+ hasToUnicode = gTrue;
return ctu;
}
@@ -847,7 +872,6 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
GString *name2;
BuiltinFont *builtinFont;
const char **baseEnc;
- GBool baseEncFromFontFile;
char *buf;
int len;
FoFiType1 *ffT1;
@@ -924,9 +948,9 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
// get info from font descriptor
readFontDescriptor(xref, fontDict);
- // for non-embedded fonts, don't trust the ascent/descent/bbox
- // values from the font descriptor
- if (builtinFont && embFontID.num < 0) {
+ // for Base-14 fonts (even if embedded), don't trust the
+ // ascent/descent/bbox values from the font descriptor
+ if (builtinFont) {
ascent = 0.001 * builtinFont->ascent;
descent = 0.001 * builtinFont->descent;
fontBBox[0] = 0.001 * builtinFont->bbox[0];
@@ -1137,14 +1161,14 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
// name that looks like 'Axx' or 'xx', where 'A' is any letter
// and 'xx' is two hex digits
if ((strlen(charName) == 3 &&
- isalpha(charName[0]) &&
- isxdigit(charName[1]) && isxdigit(charName[2]) &&
+ isalpha(charName[0] & 0xff) &&
+ isxdigit(charName[1] & 0xff) && isxdigit(charName[2] & 0xff) &&
((charName[1] >= 'a' && charName[1] <= 'f') ||
(charName[1] >= 'A' && charName[1] <= 'F') ||
(charName[2] >= 'a' && charName[2] <= 'f') ||
(charName[2] >= 'A' && charName[2] <= 'F'))) ||
(strlen(charName) == 2 &&
- isxdigit(charName[0]) && isxdigit(charName[1]) &&
+ isxdigit(charName[0] & 0xff) && isxdigit(charName[1] & 0xff) &&
((charName[0] >= 'a' && charName[0] <= 'f') ||
(charName[0] >= 'A' && charName[0] <= 'F') ||
(charName[1] >= 'a' && charName[1] <= 'f') ||
@@ -1169,35 +1193,40 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
// use 'uni0628.medi', etc.)
// where 'A' and 'B' are any letters, 'xx' is two hex digits, 'xxxx'
// is four hex digits, and 'nn' is 2-4 decimal digits
+ usedNumericHeuristic = gFalse;
if (missing && globalParams->getMapNumericCharNames()) {
for (code = 0; code < 256; ++code) {
if ((charName = enc[code]) && !toUnicode[code] &&
strcmp(charName, ".notdef")) {
n = (int)strlen(charName);
code2 = -1;
- if (hex && n == 3 && isalpha(charName[0]) &&
- isxdigit(charName[1]) && isxdigit(charName[2])) {
+ if (hex && n == 3 && isalpha(charName[0] & 0xff) &&
+ isxdigit(charName[1] & 0xff) && isxdigit(charName[2] & 0xff)) {
sscanf(charName+1, "%x", &code2);
} else if (hex && n == 2 &&
- isxdigit(charName[0]) && isxdigit(charName[1])) {
+ isxdigit(charName[0] & 0xff) &&
+ isxdigit(charName[1] & 0xff)) {
sscanf(charName, "%x", &code2);
} else if (!hex && n >= 2 && n <= 4 &&
- isdigit(charName[0]) && isdigit(charName[1])) {
+ isdigit(charName[0] & 0xff) && isdigit(charName[1] & 0xff)) {
code2 = atoi(charName);
} else if (n >= 3 && n <= 5 &&
- isdigit(charName[1]) && isdigit(charName[2])) {
+ isdigit(charName[1] & 0xff) && isdigit(charName[2] & 0xff)) {
code2 = atoi(charName+1);
} else if (n >= 4 && n <= 6 &&
- isdigit(charName[2]) && isdigit(charName[3])) {
+ isdigit(charName[2] & 0xff) && isdigit(charName[3] & 0xff)) {
code2 = atoi(charName+2);
} else if (n >= 7 && charName[0] == 'u' && charName[1] == 'n' &&
charName[2] == 'i' &&
- isxdigit(charName[3]) && isxdigit(charName[4]) &&
- isxdigit(charName[5]) && isxdigit(charName[6])) {
+ isxdigit(charName[3] & 0xff) &&
+ isxdigit(charName[4] & 0xff) &&
+ isxdigit(charName[5] & 0xff) &&
+ isxdigit(charName[6] & 0xff)) {
sscanf(charName + 3, "%x", &code2);
}
if (code2 >= 0 && code2 <= 0xffff) {
toUnicode[code] = (Unicode)code2;
+ usedNumericHeuristic = gTrue;
}
}
}
@@ -1406,7 +1435,7 @@ int *Gfx8BitFont::getCodeToGIDMap(FoFiTrueType *ff) {
cmapPlatform = ff->getCmapPlatform(i);
cmapEncoding = ff->getCmapEncoding(i);
if ((cmapPlatform == 3 && cmapEncoding == 1) ||
- cmapPlatform == 0) {
+ (cmapPlatform == 0 && cmapEncoding <= 4)) {
unicodeCmap = i;
} else if (cmapPlatform == 1 && cmapEncoding == 0) {
macRomanCmap = i;
@@ -1512,39 +1541,64 @@ Dict *Gfx8BitFont::getResources() {
return resources.isDict() ? resources.getDict() : (Dict *)NULL;
}
-//------------------------------------------------------------------------
-// GfxCIDFont
-//------------------------------------------------------------------------
-
-#if HAVE_STD_SORT
+GBool Gfx8BitFont::problematicForUnicode() {
+ GString *nameLC;
+ GBool symbolic;
+
+ // potential inputs:
+ // - font is embedded (GfxFont.embFontID.num >= 0)
+ // - font name (GfxFont.name)
+ // - font type (GfxFont.type)
+ // - Base-14 font (Gfx8BitFont.base14 != NULL)
+ // - symbolic (GfxFont.flags & fontSymbolic)
+ // - has Encoding array (Gfx8BitFont.hasEncoding)
+ // - extracted base encoding from embedded font file
+ // (Gfx8BitFont.baseEncFromFontFile)
+ // - has a ToUnicode map (GfxFont.hasToUnicode)
+ // - used the numeric glyph name heuristic
+ // (Gfx8BitFont.usedNumericHeuristic)
-struct cmpWidthExcepFunctor {
- bool operator()(const GfxFontCIDWidthExcep &w1,
- const GfxFontCIDWidthExcep &w2) {
- return w1.first < w2.first;
+ if (name) {
+ nameLC = name->copy();
+ nameLC->lowerCase();
+ symbolic = strstr(nameLC->getCString(), "dingbat") ||
+ strstr(nameLC->getCString(), "wingding") ||
+ strstr(nameLC->getCString(), "commpi");
+ delete nameLC;
+ if (symbolic) {
+ return gFalse;
+ }
}
-};
-struct cmpWidthExcepVFunctor {
- bool operator()(const GfxFontCIDWidthExcepV &w1,
- const GfxFontCIDWidthExcepV &w2) {
- return w1.first < w2.first;
- }
-};
+ if (embFontID.num >= 0) {
+ switch (type) {
+ case fontType1:
+ case fontType1C:
+ case fontType1COT:
+ return !hasToUnicode && (!hasEncoding || usedNumericHeuristic);
-#else // HAVE_STD_SORT
+ case fontType3:
+ return !hasToUnicode && !hasEncoding;
-static int CDECL cmpWidthExcep(const void *w1, const void *w2) {
- return ((GfxFontCIDWidthExcep *)w1)->first -
- ((GfxFontCIDWidthExcep *)w2)->first;
-}
+ case fontTrueType:
+ case fontTrueTypeOT:
+ return !hasToUnicode && !hasEncoding;
-static int CDECL cmpWidthExcepV(const void *w1, const void *w2) {
- return ((GfxFontCIDWidthExcepV *)w1)->first -
- ((GfxFontCIDWidthExcepV *)w2)->first;
+ default:
+ return !hasToUnicode;
+ }
+
+ } else {
+ // NB: type will be fontTypeUnknown if the PDF specifies an
+ // invalid font type -- which is ok, if we have a ToUnicode map or
+ // an encoding
+ return !hasToUnicode && !hasEncoding;
+ }
}
-#endif
+//------------------------------------------------------------------------
+// GfxCIDFont
+//------------------------------------------------------------------------
GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
GfxFontType typeA, Ref embFontIDA, Dict *fontDict):
@@ -1615,6 +1669,7 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
obj1.free();
// look for a ToUnicode CMap
+ hasKnownCollection = gFalse;
if (!(ctu = readToUnicodeCMap(fontDict, 16, NULL))) {
ctuUsesCharCode = gFalse;
@@ -1625,25 +1680,36 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
ctu = CharCodeToUnicode::makeIdentityMapping();
// look for a user-supplied .cidToUnicode file
- } else if (!(ctu = globalParams->getCIDToUnicode(collection))) {
+ } else if ((ctu = globalParams->getCIDToUnicode(collection))) {
+ hasKnownCollection = gTrue;
+
+ } else {
error(errSyntaxError, -1,
"Unknown character collection '{0:t}'", collection);
+
+ // fall back to an identity mapping
+ ctu = CharCodeToUnicode::makeIdentityMapping();
}
}
// look for a Unicode-to-Unicode mapping
if (name && (utu = globalParams->getUnicodeToUnicode(name))) {
if (ctu) {
- for (c = 0; c < ctu->getLength(); ++c) {
- n = ctu->mapToUnicode(c, uBuf, 8);
- if (n >= 1) {
- n = utu->mapToUnicode((CharCode)uBuf[0], uBuf, 8);
+ if (ctu->isIdentity()) {
+ ctu->decRefCnt();
+ ctu = utu;
+ } else {
+ for (c = 0; c < ctu->getLength(); ++c) {
+ n = ctu->mapToUnicode(c, uBuf, 8);
if (n >= 1) {
- ctu->setMapping(c, uBuf, n);
+ n = utu->mapToUnicode((CharCode)uBuf[0], uBuf, 8);
+ if (n >= 1) {
+ ctu->setMapping(c, uBuf, n);
+ }
}
}
+ utu->decRefCnt();
}
- utu->decRefCnt();
} else {
ctu = utu;
}
@@ -1660,29 +1726,31 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
obj1.free();
// CIDToGIDMap
- // (the PDF spec only allows these for TrueType fonts, but Acrobat
- // apparently also allows them for OpenType CFF fonts)
- if (type == fontCIDType2 || type == fontCIDType0COT) {
- desFontDict->lookup("CIDToGIDMap", &obj1);
- if (obj1.isStream()) {
- cidToGIDLen = 0;
- i = 64;
- cidToGID = (int *)gmallocn(i, sizeof(int));
- obj1.streamReset();
- while ((c1 = obj1.streamGetChar()) != EOF &&
- (c2 = obj1.streamGetChar()) != EOF) {
- if (cidToGIDLen == i) {
- i *= 2;
- cidToGID = (int *)greallocn(cidToGID, i, sizeof(int));
- }
- cidToGID[cidToGIDLen++] = (c1 << 8) + c2;
+ // (the PDF 1.7 spec only allows these for TrueType fonts, but
+ // Acrobat apparently also allows them for OpenType CFF fonts -- and
+ // the PDF 2.0 spec has removed the prohibition)
+ hasIdentityCIDToGID = gFalse;
+ desFontDict->lookup("CIDToGIDMap", &obj1);
+ if (obj1.isStream()) {
+ cidToGIDLen = 0;
+ i = 64;
+ cidToGID = (int *)gmallocn(i, sizeof(int));
+ obj1.streamReset();
+ while ((c1 = obj1.streamGetChar()) != EOF &&
+ (c2 = obj1.streamGetChar()) != EOF) {
+ if (cidToGIDLen == i) {
+ i *= 2;
+ cidToGID = (int *)greallocn(cidToGID, i, sizeof(int));
}
- obj1.streamClose();
- } else if (!obj1.isName("Identity") && !obj1.isNull()) {
- error(errSyntaxError, -1, "Invalid CIDToGIDMap entry in CID font");
+ cidToGID[cidToGIDLen++] = (c1 << 8) + c2;
}
- obj1.free();
+ obj1.streamClose();
+ } else if (obj1.isName("Identity")) {
+ hasIdentityCIDToGID = gTrue;
+ } else if (!obj1.isNull()) {
+ error(errSyntaxError, -1, "Invalid CIDToGIDMap entry in CID font");
}
+ obj1.free();
//----- character metrics -----
@@ -1744,13 +1812,6 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
obj3.free();
obj2.free();
}
-#if HAVE_STD_SORT
- std::sort(widths.exceps, widths.exceps + widths.nExceps,
- cmpWidthExcepFunctor());
-#else
- qsort(widths.exceps, widths.nExceps, sizeof(GfxFontCIDWidthExcep),
- &cmpWidthExcep);
-#endif
}
obj1.free();
@@ -1833,13 +1894,6 @@ GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
obj3.free();
obj2.free();
}
-#if HAVE_STD_SORT
- std::sort(widths.excepsV, widths.excepsV + widths.nExcepsV,
- cmpWidthExcepVFunctor());
-#else
- qsort(widths.excepsV, widths.nExcepsV, sizeof(GfxFontCIDWidthExcepV),
- &cmpWidthExcepV);
-#endif
}
obj1.free();
@@ -1879,8 +1933,7 @@ int GfxCIDFont::getNextChar(char *s, int len, CharCode *code,
double *dx, double *dy, double *ox, double *oy) {
CID cid;
CharCode c;
- double w, h, vx, vy;
- int n, a, b, m;
+ int n;
if (!cMap) {
*code = 0;
@@ -1902,59 +1955,54 @@ int GfxCIDFont::getNextChar(char *s, int len, CharCode *code,
// horizontal
if (cMap->getWMode() == 0) {
- w = widths.defWidth;
- h = vx = vy = 0;
- if (widths.nExceps > 0 && cid >= widths.exceps[0].first) {
- a = 0;
- b = widths.nExceps;
- // invariant: widths.exceps[a].first <= cid < widths.exceps[b].first
- while (b - a > 1) {
- m = (a + b) / 2;
- if (widths.exceps[m].first <= cid) {
- a = m;
- } else {
- b = m;
- }
- }
- if (cid <= widths.exceps[a].last) {
- w = widths.exceps[a].width;
- }
- }
+ getHorizontalMetrics(cid, dx);
+ *dy = *ox = *oy = 0;
// vertical
} else {
- w = 0;
- h = widths.defHeight;
- vx = widths.defWidth / 2;
- vy = widths.defVY;
- if (widths.nExcepsV > 0 && cid >= widths.excepsV[0].first) {
- a = 0;
- b = widths.nExcepsV;
- // invariant: widths.excepsV[a].first <= cid < widths.excepsV[b].first
- while (b - a > 1) {
- m = (a + b) / 2;
- if (widths.excepsV[m].last <= cid) {
- a = m;
- } else {
- b = m;
- }
- }
- if (cid <= widths.excepsV[a].last) {
- h = widths.excepsV[a].height;
- vx = widths.excepsV[a].vx;
- vy = widths.excepsV[a].vy;
- }
- }
+ getVerticalMetrics(cid, dy, ox, oy);
+ *dx = 0;
}
- *dx = w;
- *dy = h;
- *ox = vx;
- *oy = vy;
-
return n;
}
+// NB: Section 9.7.4.3 in the PDF 2.0 spec says that, in the case of
+// duplicate entries in the metrics, the first entry should be used.
+// This means we need to leave the metrics in the original order and
+// perform a linear search. (Or use a more complex data structure.)
+void GfxCIDFont::getHorizontalMetrics(CID cid, double *w) {
+ int i;
+ for (i = 0; i < widths.nExceps; ++i) {
+ if (widths.exceps[i].first <= cid && cid <= widths.exceps[i].last) {
+ *w = widths.exceps[i].width;
+ return;
+ }
+ }
+ *w = widths.defWidth;
+}
+
+// NB: Section 9.7.4.3 in the PDF 2.0 spec says that, in the case of
+// duplicate entries in the metrics, the first entry should be used.
+// This means we need to leave the metrics in the original order and
+// perform a linear search. (Or use a more complex data structure.)
+void GfxCIDFont::getVerticalMetrics(CID cid, double *h,
+ double *vx, double *vy) {
+ int i;
+ for (i = 0; i < widths.nExcepsV; ++i) {
+ if (widths.excepsV[i].first <= cid && cid <= widths.excepsV[i].last) {
+ *h = widths.excepsV[i].height;
+ *vx = widths.excepsV[i].vx;
+ *vy = widths.excepsV[i].vy;
+ return;
+ }
+ }
+ *h = widths.defHeight;
+ getHorizontalMetrics(cid, vx);
+ *vx /= 2;
+ *vy = widths.defVY;
+}
+
int GfxCIDFont::getWMode() {
return cMap ? cMap->getWMode() : 0;
}
@@ -1970,43 +2018,97 @@ GString *GfxCIDFont::getCollection() {
return cMap ? cMap->getCollection() : (GString *)NULL;
}
+GBool GfxCIDFont::problematicForUnicode() {
+ GString *nameLC;
+ GBool symbolic;
+
+ // potential inputs:
+ // - font is embedded (GfxFont.embFontID.num >= 0)
+ // - font name (GfxFont.name)
+ // - font type (GfxFont.type)
+ // - symbolic (GfxFont.flags & fontSymbolic)
+ // - has a ToUnicode map (GfxFont.hasToUnicode)
+ // - collection is Adobe-Identity or Adobe-UCS
+ // (GfxCIDFont.collection - compare string)
+ // - collection is known AdobeCJK (GfxCIDFont.hasKnownCollection)
+ // - has non-Identity CIDToGIDMap (GfxCIDFont.cidToGID != NULL)
+ // - has Identity CIDToGIDMap (GfxCIDFont.hasIdentityCIDToGID)
+
+ if (name) {
+ nameLC = name->copy();
+ nameLC->lowerCase();
+ symbolic = strstr(nameLC->getCString(), "dingbat") ||
+ strstr(nameLC->getCString(), "wingding") ||
+ strstr(nameLC->getCString(), "commpi");
+ delete nameLC;
+ if (symbolic) {
+ return gFalse;
+ }
+ }
+
+ if (embFontID.num >= 0) {
+ switch (type) {
+ case fontCIDType0:
+ case fontCIDType0C:
+ case fontCIDType0COT:
+ return !hasToUnicode && !hasKnownCollection;
+
+ case fontCIDType2:
+ case fontCIDType2OT:
+ return !hasToUnicode && !hasKnownCollection;
+
+ default:
+ return !hasToUnicode;
+ }
+
+ } else {
+ return !hasToUnicode;
+ }
+}
+
//------------------------------------------------------------------------
// GfxFontDict
//------------------------------------------------------------------------
GfxFontDict::GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict) {
- int i;
+ GfxFont *font;
+ char *tag;
Object obj1, obj2;
Ref r;
+ int i;
- numFonts = fontDict->getLength();
- fonts = (GfxFont **)gmallocn(numFonts, sizeof(GfxFont *));
- for (i = 0; i < numFonts; ++i) {
+ fonts = new GHash(gTrue);
+ uniqueFonts = new GList();
+ for (i = 0; i < fontDict->getLength(); ++i) {
+ tag = fontDict->getKey(i);
fontDict->getValNF(i, &obj1);
obj1.fetch(xref, &obj2);
- if (obj2.isDict()) {
+ if (!obj2.isDict()) {
+ error(errSyntaxError, -1, "font resource is not a dictionary");
+ } else if (obj1.isRef() && (font = lookupByRef(obj1.getRef()))) {
+ fonts->add(new GString(tag), font);
+ } else {
if (obj1.isRef()) {
r = obj1.getRef();
- } else {
- // no indirect reference for this font, so invent a unique one
- // (legal generation numbers are five digits, so any 6-digit
- // number would be safe)
+ } else if (fontDictRef) {
+ // legal generation numbers are five digits, so we use a
+ // 6-digit number here
+ r.gen = 100000 + fontDictRef->num;
r.num = i;
- if (fontDictRef) {
- r.gen = 100000 + fontDictRef->num;
+ } else {
+ // no indirect reference for this font, or for the containing
+ // font dict, so hash the font and use that
+ r.gen = 100000;
+ r.num = hashFontObject(&obj2);
+ }
+ if ((font = GfxFont::makeFont(xref, tag, r, obj2.getDict()))) {
+ if (!font->isOk()) {
+ delete font;
} else {
- r.gen = 999999;
+ uniqueFonts->append(font);
+ fonts->add(new GString(tag), font);
}
}
- fonts[i] = GfxFont::makeFont(xref, fontDict->getKey(i),
- r, obj2.getDict());
- if (fonts[i] && !fonts[i]->isOk()) {
- delete fonts[i];
- fonts[i] = NULL;
- }
- } else {
- error(errSyntaxError, -1, "font resource is not a dictionary");
- fonts[i] = NULL;
}
obj1.free();
obj2.free();
@@ -2014,36 +2116,141 @@ GfxFontDict::GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict) {
}
GfxFontDict::~GfxFontDict() {
- int i;
-
- for (i = 0; i < numFonts; ++i) {
- if (fonts[i]) {
- delete fonts[i];
- }
- }
- gfree(fonts);
+ deleteGList(uniqueFonts, GfxFont);
+ delete fonts;
}
GfxFont *GfxFontDict::lookup(char *tag) {
+ return (GfxFont *)fonts->lookup(tag);
+}
+
+GfxFont *GfxFontDict::lookupByRef(Ref ref) {
+ GfxFont *font;
int i;
- for (i = 0; i < numFonts; ++i) {
- if (fonts[i] && fonts[i]->matches(tag)) {
- return fonts[i];
+ for (i = 0; i < uniqueFonts->getLength(); ++i) {
+ font = (GfxFont *)uniqueFonts->get(i);
+ if (font->getID()->num == ref.num &&
+ font->getID()->gen == ref.gen) {
+ return font;
}
}
return NULL;
}
-GfxFont *GfxFontDict::lookupByRef(Ref ref) {
- int i;
+int GfxFontDict::getNumFonts() {
+ return uniqueFonts->getLength();
+}
- for (i = 0; i < numFonts; ++i) {
- if (fonts[i] &&
- fonts[i]->getID()->num == ref.num &&
- fonts[i]->getID()->gen == ref.gen) {
- return fonts[i];
+GfxFont *GfxFontDict::getFont(int i) {
+ return (GfxFont *)uniqueFonts->get(i);
+}
+
+// FNV-1a hash
+class FNVHash {
+public:
+
+ FNVHash() {
+ h = 2166136261U;
+ }
+
+ void hash(char c) {
+ h ^= c & 0xff;
+ h *= 16777619;
+ }
+
+ void hash(char *p, int n) {
+ int i;
+ for (i = 0; i < n; ++i) {
+ hash(p[i]);
}
}
- return NULL;
+
+ int get31() {
+ return (h ^ (h >> 31)) & 0x7fffffff;
+ }
+
+private:
+
+ Guint h;
+};
+
+int GfxFontDict::hashFontObject(Object *obj) {
+ FNVHash h;
+
+ hashFontObject1(obj, &h);
+ return h.get31();
+}
+
+void GfxFontDict::hashFontObject1(Object *obj, FNVHash *h) {
+ Object obj2;
+ GString *s;
+ char *p;
+ double r;
+ int n, i;
+
+ switch (obj->getType()) {
+ case objBool:
+ h->hash('b');
+ h->hash(obj->getBool() ? 1 : 0);
+ break;
+ case objInt:
+ h->hash('i');
+ n = obj->getInt();
+ h->hash((char *)&n, sizeof(int));
+ break;
+ case objReal:
+ h->hash('r');
+ r = obj->getReal();
+ h->hash((char *)&r, sizeof(double));
+ break;
+ case objString:
+ h->hash('s');
+ s = obj->getString();
+ h->hash(s->getCString(), s->getLength());
+ break;
+ case objName:
+ h->hash('n');
+ p = obj->getName();
+ h->hash(p, (int)strlen(p));
+ break;
+ case objNull:
+ h->hash('z');
+ break;
+ case objArray:
+ h->hash('a');
+ n = obj->arrayGetLength();
+ h->hash((char *)&n, sizeof(int));
+ for (i = 0; i < n; ++i) {
+ obj->arrayGetNF(i, &obj2);
+ hashFontObject1(&obj2, h);
+ obj2.free();
+ }
+ break;
+ case objDict:
+ h->hash('d');
+ n = obj->dictGetLength();
+ h->hash((char *)&n, sizeof(int));
+ for (i = 0; i < n; ++i) {
+ p = obj->dictGetKey(i);
+ h->hash(p, (int)strlen(p));
+ obj->dictGetValNF(i, &obj2);
+ hashFontObject1(&obj2, h);
+ obj2.free();
+ }
+ break;
+ case objStream:
+ // this should never happen - streams must be indirect refs
+ break;
+ case objRef:
+ h->hash('f');
+ n = obj->getRefNum();
+ h->hash((char *)&n, sizeof(int));
+ n = obj->getRefGen();
+ h->hash((char *)&n, sizeof(int));
+ break;
+ default:
+ h->hash('u');
+ break;
+ }
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
index 1ec46ec5bf1..fd90ce4f040 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxFont.h
@@ -20,12 +20,15 @@
#include "Object.h"
#include "CharTypes.h"
+class GList;
+class GHash;
class Dict;
class CMap;
class CharCodeToUnicode;
class FoFiTrueType;
struct GfxFontCIDWidths;
struct Base14FontMapEntry;
+class FNVHash;
//------------------------------------------------------------------------
// GfxFontType
@@ -204,6 +207,10 @@ public:
Unicode *u, int uSize, int *uLen,
double *dx, double *dy, double *ox, double *oy) = 0;
+ // Returns true if this font is likely to be problematic when
+ // converting text to Unicode.
+ virtual GBool problematicForUnicode() = 0;
+
protected:
static GfxFontType getFontType(XRef *xref, Dict *fontDict, Ref *embID);
@@ -225,6 +232,7 @@ protected:
double missingWidth; // "default" width
double ascent; // max height above baseline
double descent; // max depth below baseline
+ GBool hasToUnicode; // true if the font has a ToUnicode map
GBool ok;
};
@@ -276,6 +284,8 @@ public:
// Return the Type 3 Resources dictionary, or NULL if none.
Dict *getResources();
+ virtual GBool problematicForUnicode();
+
private:
Base14FontMapEntry *base14; // for Base-14 fonts only; NULL otherwise
@@ -285,6 +295,8 @@ private:
CharCodeToUnicode *ctu; // char code --> Unicode
GBool hasEncoding;
GBool usesMacRomanEnc;
+ GBool baseEncFromFontFile;
+ GBool usedNumericHeuristic;
double widths[256]; // character widths
Object charProcs; // Type 3 CharProcs dictionary
Object resources; // Type 3 Resources dictionary
@@ -324,8 +336,14 @@ public:
int *getCIDToGID() { return cidToGID; }
int getCIDToGIDLen() { return cidToGIDLen; }
+ virtual GBool problematicForUnicode();
+
private:
+ void getHorizontalMetrics(CID cid, double *w);
+ void getVerticalMetrics(CID cid, double *h,
+ double *vx, double *vy);
+
GString *collection; // collection name
CMap *cMap; // char code --> CID
CharCodeToUnicode *ctu; // CID/char code --> Unicode
@@ -335,6 +353,8 @@ private:
int *cidToGID; // CID --> GID mapping (for embedded
// TrueType fonts)
int cidToGIDLen;
+ GBool hasKnownCollection;
+ GBool hasIdentityCIDToGID;
};
//------------------------------------------------------------------------
@@ -355,13 +375,18 @@ public:
GfxFont *lookupByRef(Ref ref);
// Iterative access.
- int getNumFonts() { return numFonts; }
- GfxFont *getFont(int i) { return fonts[i]; }
+ int getNumFonts();
+ GfxFont *getFont(int i);
private:
- GfxFont **fonts; // list of fonts
- int numFonts; // number of fonts
+ int hashFontObject(Object *obj);
+ void hashFontObject1(Object *obj, FNVHash *h);
+
+ GHash *fonts; // hash table of fonts -- this may
+ // include duplicates, i.e., when
+ // two tags map to the same font
+ GList *uniqueFonts; // list of all unique font objects (no dups)
};
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
index bdaa5e6a72f..b1c650a586f 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.cc
@@ -2,7 +2,7 @@
//
// GfxState.cc
//
-// Copyright 1996-2003 Glyph & Cog, LLC
+// Copyright 1996-2016 Glyph & Cog, LLC
//
//========================================================================
@@ -16,7 +16,9 @@
#include <math.h>
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "Error.h"
+#include "GlobalParams.h"
#include "Object.h"
#include "Array.h"
#include "Page.h"
@@ -29,6 +31,7 @@
// loops in the color space object structure.
#define colorSpaceRecursionLimit 8
+
//------------------------------------------------------------------------
static inline GfxColorComp clip01(GfxColorComp x) {
@@ -90,6 +93,7 @@ static const char *gfxColorSpaceModeNames[] = {
#define nGfxColorSpaceModes ((sizeof(gfxColorSpaceModeNames) / sizeof(char *)))
+
//------------------------------------------------------------------------
// GfxColorSpace
//------------------------------------------------------------------------
@@ -212,15 +216,18 @@ GfxColorSpace *GfxDeviceGrayColorSpace::copy() {
}
-void GfxDeviceGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) {
+void GfxDeviceGrayColorSpace::getGray(GfxColor *color, GfxGray *gray,
+ GfxRenderingIntent ri) {
*gray = clip01(color->c[0]);
}
-void GfxDeviceGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+void GfxDeviceGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb,
+ GfxRenderingIntent ri) {
rgb->r = rgb->g = rgb->b = clip01(color->c[0]);
}
-void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk,
+ GfxRenderingIntent ri) {
cmyk->c = cmyk->m = cmyk->y = 0;
cmyk->k = clip01(gfxColorComp1 - color->c[0]);
}
@@ -307,15 +314,18 @@ GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr, int recursion) {
return cs;
}
-void GfxCalGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) {
+void GfxCalGrayColorSpace::getGray(GfxColor *color, GfxGray *gray,
+ GfxRenderingIntent ri) {
*gray = clip01(color->c[0]);
}
-void GfxCalGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+ void GfxCalGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb,
+ GfxRenderingIntent ri) {
rgb->r = rgb->g = rgb->b = clip01(color->c[0]);
}
-void GfxCalGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+void GfxCalGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk,
+ GfxRenderingIntent ri) {
cmyk->c = cmyk->m = cmyk->y = 0;
cmyk->k = clip01(gfxColorComp1 - color->c[0]);
}
@@ -343,19 +353,22 @@ GfxColorSpace *GfxDeviceRGBColorSpace::copy() {
}
-void GfxDeviceRGBColorSpace::getGray(GfxColor *color, GfxGray *gray) {
+void GfxDeviceRGBColorSpace::getGray(GfxColor *color, GfxGray *gray,
+ GfxRenderingIntent ri) {
*gray = clip01((GfxColorComp)(0.3 * color->c[0] +
0.59 * color->c[1] +
0.11 * color->c[2] + 0.5));
}
-void GfxDeviceRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+void GfxDeviceRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb,
+ GfxRenderingIntent ri) {
rgb->r = clip01(color->c[0]);
rgb->g = clip01(color->c[1]);
rgb->b = clip01(color->c[2]);
}
-void GfxDeviceRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+void GfxDeviceRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk,
+ GfxRenderingIntent ri) {
GfxColorComp c, m, y, k;
c = clip01(gfxColorComp1 - color->c[0]);
@@ -486,19 +499,22 @@ GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr, int recursion) {
}
-void GfxCalRGBColorSpace::getGray(GfxColor *color, GfxGray *gray) {
+void GfxCalRGBColorSpace::getGray(GfxColor *color, GfxGray *gray,
+ GfxRenderingIntent ri) {
*gray = clip01((GfxColorComp)(0.299 * color->c[0] +
0.587 * color->c[1] +
0.114 * color->c[2] + 0.5));
}
-void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb,
+ GfxRenderingIntent ri) {
rgb->r = clip01(color->c[0]);
rgb->g = clip01(color->c[1]);
rgb->b = clip01(color->c[2]);
}
-void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk,
+ GfxRenderingIntent ri) {
GfxColorComp c, m, y, k;
c = clip01(gfxColorComp1 - color->c[0]);
@@ -542,14 +558,16 @@ GfxColorSpace *GfxDeviceCMYKColorSpace::copy() {
}
-void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, GfxGray *gray) {
+void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, GfxGray *gray,
+ GfxRenderingIntent ri) {
*gray = clip01((GfxColorComp)(gfxColorComp1 - color->c[3]
- 0.3 * color->c[0]
- 0.59 * color->c[1]
- 0.11 * color->c[2] + 0.5));
}
-void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb,
+ GfxRenderingIntent ri) {
double c, m, y, k, c1, m1, y1, k1, r, g, b, x;
c = colToDbl(color->c[0]);
@@ -611,7 +629,8 @@ void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
rgb->b = clip01(dblToCol(b));
}
-void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk,
+ GfxRenderingIntent ri) {
cmyk->c = clip01(color->c[0]);
cmyk->m = clip01(color->c[1]);
cmyk->y = clip01(color->c[2]);
@@ -626,6 +645,7 @@ void GfxDeviceCMYKColorSpace::getDefaultColor(GfxColor *color) {
color->c[3] = gfxColorComp1;
}
+
//------------------------------------------------------------------------
// GfxLabColorSpace
//------------------------------------------------------------------------
@@ -741,16 +761,18 @@ GfxColorSpace *GfxLabColorSpace::parse(Array *arr, int recursion) {
}
-void GfxLabColorSpace::getGray(GfxColor *color, GfxGray *gray) {
+void GfxLabColorSpace::getGray(GfxColor *color, GfxGray *gray,
+ GfxRenderingIntent ri) {
GfxRGB rgb;
- getRGB(color, &rgb);
+ getRGB(color, &rgb, ri);
*gray = clip01((GfxColorComp)(0.299 * rgb.r +
0.587 * rgb.g +
0.114 * rgb.b + 0.5));
}
-void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb,
+ GfxRenderingIntent ri) {
double X, Y, Z;
double t1, t2;
double r, g, b;
@@ -788,12 +810,13 @@ void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
rgb->b = dblToCol(pow(clip01(b * kb), 0.5));
}
-void GfxLabColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+void GfxLabColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk,
+ GfxRenderingIntent ri) {
GfxRGB rgb;
GfxColorComp c, m, y, k;
- getRGB(color, &rgb);
+ getRGB(color, &rgb, ri);
c = clip01(gfxColorComp1 - rgb.r);
m = clip01(gfxColorComp1 - rgb.g);
y = clip01(gfxColorComp1 - rgb.b);
@@ -950,16 +973,19 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr,
}
-void GfxICCBasedColorSpace::getGray(GfxColor *color, GfxGray *gray) {
- alt->getGray(color, gray);
+void GfxICCBasedColorSpace::getGray(GfxColor *color, GfxGray *gray,
+ GfxRenderingIntent ri) {
+ alt->getGray(color, gray, ri);
}
-void GfxICCBasedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
- alt->getRGB(color, rgb);
+void GfxICCBasedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb,
+ GfxRenderingIntent ri) {
+ alt->getRGB(color, rgb, ri);
}
-void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
- alt->getCMYK(color, cmyk);
+void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk,
+ GfxRenderingIntent ri) {
+ alt->getCMYK(color, cmyk, ri);
}
@@ -994,6 +1020,7 @@ void GfxICCBasedColorSpace::getDefaultRanges(double *decodeLow,
#endif
}
+
//------------------------------------------------------------------------
// GfxIndexedColorSpace
//------------------------------------------------------------------------
@@ -1107,33 +1134,42 @@ GfxColor *GfxIndexedColorSpace::mapColorToBase(GfxColor *color,
GfxColor *baseColor) {
Guchar *p;
double low[gfxColorMaxComps], range[gfxColorMaxComps];
- int n, i;
+ int n, i, k;
n = base->getNComps();
base->getDefaultRanges(low, range, indexHigh);
- p = &lookup[(int)(colToDbl(color->c[0]) + 0.5) * n];
+ k = (int)(colToDbl(color->c[0]) + 0.5);
+ if (k < 0) {
+ k = 0;
+ } else if (k > indexHigh) {
+ k = indexHigh;
+ }
+ p = &lookup[k * n];
for (i = 0; i < n; ++i) {
baseColor->c[i] = dblToCol(low[i] + (p[i] / 255.0) * range[i]);
}
return baseColor;
}
-void GfxIndexedColorSpace::getGray(GfxColor *color, GfxGray *gray) {
+void GfxIndexedColorSpace::getGray(GfxColor *color, GfxGray *gray,
+ GfxRenderingIntent ri) {
GfxColor color2;
- base->getGray(mapColorToBase(color, &color2), gray);
+ base->getGray(mapColorToBase(color, &color2), gray, ri);
}
-void GfxIndexedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+void GfxIndexedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb,
+ GfxRenderingIntent ri) {
GfxColor color2;
- base->getRGB(mapColorToBase(color, &color2), rgb);
+ base->getRGB(mapColorToBase(color, &color2), rgb, ri);
}
-void GfxIndexedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+void GfxIndexedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk,
+ GfxRenderingIntent ri) {
GfxColor color2;
- base->getCMYK(mapColorToBase(color, &color2), cmyk);
+ base->getCMYK(mapColorToBase(color, &color2), cmyk, ri);
}
@@ -1196,7 +1232,6 @@ GfxColorSpace *GfxSeparationColorSpace::copy() {
return cs;
}
-//~ handle the 'All' and 'None' colorants
GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr,
int recursion) {
GfxSeparationColorSpace *cs;
@@ -1242,7 +1277,8 @@ GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr,
}
-void GfxSeparationColorSpace::getGray(GfxColor *color, GfxGray *gray) {
+void GfxSeparationColorSpace::getGray(GfxColor *color, GfxGray *gray,
+ GfxRenderingIntent ri) {
double x;
double c[gfxColorMaxComps];
GfxColor color2;
@@ -1253,10 +1289,11 @@ void GfxSeparationColorSpace::getGray(GfxColor *color, GfxGray *gray) {
for (i = 0; i < alt->getNComps(); ++i) {
color2.c[i] = dblToCol(c[i]);
}
- alt->getGray(&color2, gray);
+ alt->getGray(&color2, gray, ri);
}
-void GfxSeparationColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+void GfxSeparationColorSpace::getRGB(GfxColor *color, GfxRGB *rgb,
+ GfxRenderingIntent ri) {
double x;
double c[gfxColorMaxComps];
GfxColor color2;
@@ -1267,10 +1304,11 @@ void GfxSeparationColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
for (i = 0; i < alt->getNComps(); ++i) {
color2.c[i] = dblToCol(c[i]);
}
- alt->getRGB(&color2, rgb);
+ alt->getRGB(&color2, rgb, ri);
}
-void GfxSeparationColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+void GfxSeparationColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk,
+ GfxRenderingIntent ri) {
double x;
double c[gfxColorMaxComps];
GfxColor color2;
@@ -1281,7 +1319,7 @@ void GfxSeparationColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
for (i = 0; i < alt->getNComps(); ++i) {
color2.c[i] = dblToCol(c[i]);
}
- alt->getCMYK(&color2, cmyk);
+ alt->getCMYK(&color2, cmyk, ri);
}
@@ -1296,12 +1334,14 @@ void GfxSeparationColorSpace::getDefaultColor(GfxColor *color) {
GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nCompsA,
GString **namesA,
GfxColorSpace *altA,
- Function *funcA) {
+ Function *funcA,
+ Object *attrsA) {
int i;
nComps = nCompsA;
alt = altA;
func = funcA;
+ attrsA->copy(&attrs);
nonMarking = gTrue;
overprintMask = 0;
for (i = 0; i < nComps; ++i) {
@@ -1327,6 +1367,7 @@ GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nCompsA,
GString **namesA,
GfxColorSpace *altA,
Function *funcA,
+ Object *attrsA,
GBool nonMarkingA,
Guint overprintMaskA) {
int i;
@@ -1334,6 +1375,7 @@ GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nCompsA,
nComps = nCompsA;
alt = altA;
func = funcA;
+ attrsA->copy(&attrs);
nonMarking = nonMarkingA;
overprintMask = overprintMaskA;
for (i = 0; i < nComps; ++i) {
@@ -1349,17 +1391,17 @@ GfxDeviceNColorSpace::~GfxDeviceNColorSpace() {
}
delete alt;
delete func;
+ attrs.free();
}
GfxColorSpace *GfxDeviceNColorSpace::copy() {
GfxDeviceNColorSpace *cs;
cs = new GfxDeviceNColorSpace(nComps, names, alt->copy(), func->copy(),
- nonMarking, overprintMask);
+ &attrs, nonMarking, overprintMask);
return cs;
}
-//~ handle the 'None' colorant
GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr,
int recursion) {
GfxDeviceNColorSpace *cs;
@@ -1367,7 +1409,7 @@ GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr,
GString *namesA[gfxColorMaxComps];
GfxColorSpace *altA;
Function *funcA;
- Object obj1, obj2;
+ Object attrsA, obj1, obj2;
int i;
if (arr->getLength() != 4 && arr->getLength() != 5) {
@@ -1408,7 +1450,13 @@ GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr,
goto err4;
}
obj1.free();
- cs = new GfxDeviceNColorSpace(nCompsA, namesA, altA, funcA);
+ if (arr->getLength() == 5) {
+ arr->get(4, &attrsA);
+ } else {
+ attrsA.initNull();
+ }
+ cs = new GfxDeviceNColorSpace(nCompsA, namesA, altA, funcA, &attrsA);
+ attrsA.free();
return cs;
err4:
@@ -1424,7 +1472,8 @@ GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr,
}
-void GfxDeviceNColorSpace::getGray(GfxColor *color, GfxGray *gray) {
+void GfxDeviceNColorSpace::getGray(GfxColor *color, GfxGray *gray,
+ GfxRenderingIntent ri) {
double x[gfxColorMaxComps], c[gfxColorMaxComps];
GfxColor color2;
int i;
@@ -1436,10 +1485,11 @@ void GfxDeviceNColorSpace::getGray(GfxColor *color, GfxGray *gray) {
for (i = 0; i < alt->getNComps(); ++i) {
color2.c[i] = dblToCol(c[i]);
}
- alt->getGray(&color2, gray);
+ alt->getGray(&color2, gray, ri);
}
-void GfxDeviceNColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+void GfxDeviceNColorSpace::getRGB(GfxColor *color, GfxRGB *rgb,
+ GfxRenderingIntent ri) {
double x[gfxColorMaxComps], c[gfxColorMaxComps];
GfxColor color2;
int i;
@@ -1451,10 +1501,11 @@ void GfxDeviceNColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
for (i = 0; i < alt->getNComps(); ++i) {
color2.c[i] = dblToCol(c[i]);
}
- alt->getRGB(&color2, rgb);
+ alt->getRGB(&color2, rgb, ri);
}
-void GfxDeviceNColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+void GfxDeviceNColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk,
+ GfxRenderingIntent ri) {
double x[gfxColorMaxComps], c[gfxColorMaxComps];
GfxColor color2;
int i;
@@ -1466,7 +1517,7 @@ void GfxDeviceNColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
for (i = 0; i < alt->getNComps(); ++i) {
color2.c[i] = dblToCol(c[i]);
}
- alt->getCMYK(&color2, cmyk);
+ alt->getCMYK(&color2, cmyk, ri);
}
@@ -1527,15 +1578,18 @@ GfxColorSpace *GfxPatternColorSpace::parse(Array *arr,
}
-void GfxPatternColorSpace::getGray(GfxColor *color, GfxGray *gray) {
+void GfxPatternColorSpace::getGray(GfxColor *color, GfxGray *gray,
+ GfxRenderingIntent ri) {
*gray = 0;
}
-void GfxPatternColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
+void GfxPatternColorSpace::getRGB(GfxColor *color, GfxRGB *rgb,
+ GfxRenderingIntent ri) {
rgb->r = rgb->g = rgb->b = 0;
}
-void GfxPatternColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
+void GfxPatternColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk,
+ GfxRenderingIntent ri) {
cmyk->c = cmyk->m = cmyk->y = 0;
cmyk->k = 1;
}
@@ -2162,6 +2216,7 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict
} else {
error(errSyntaxError, -1,
"Missing or invalid Coords in shading dictionary");
+ obj1.free();
goto err1;
}
obj1.free();
@@ -3129,7 +3184,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict,
p->x[1][0] = x[7];
p->y[1][0] = y[7];
for (j = 0; j < nCompsA; ++j) {
- p->color[0][1][j] = patchesA[nPatchesA-1].color[1][0][j];
+ p->color[0][0][j] = patchesA[nPatchesA-1].color[1][0][j];
p->color[0][1][j] = patchesA[nPatchesA-1].color[0][0][j];
p->color[1][1][j] = c[0][j];
p->color[1][0][j] = c[1][j];
@@ -3572,7 +3627,8 @@ GfxImageColorMap::~GfxImageColorMap() {
}
}
-void GfxImageColorMap::getGray(Guchar *x, GfxGray *gray) {
+void GfxImageColorMap::getGray(Guchar *x, GfxGray *gray,
+ GfxRenderingIntent ri) {
GfxColor color;
int i;
@@ -3580,16 +3636,16 @@ void GfxImageColorMap::getGray(Guchar *x, GfxGray *gray) {
for (i = 0; i < nComps2; ++i) {
color.c[i] = lookup2[i][x[0]];
}
- colorSpace2->getGray(&color, gray);
+ colorSpace2->getGray(&color, gray, ri);
} else {
for (i = 0; i < nComps; ++i) {
color.c[i] = lookup[i][x[i]];
}
- colorSpace->getGray(&color, gray);
+ colorSpace->getGray(&color, gray, ri);
}
}
-void GfxImageColorMap::getRGB(Guchar *x, GfxRGB *rgb) {
+void GfxImageColorMap::getRGB(Guchar *x, GfxRGB *rgb, GfxRenderingIntent ri) {
GfxColor color;
int i;
@@ -3597,16 +3653,17 @@ void GfxImageColorMap::getRGB(Guchar *x, GfxRGB *rgb) {
for (i = 0; i < nComps2; ++i) {
color.c[i] = lookup2[i][x[0]];
}
- colorSpace2->getRGB(&color, rgb);
+ colorSpace2->getRGB(&color, rgb, ri);
} else {
for (i = 0; i < nComps; ++i) {
color.c[i] = lookup[i][x[i]];
}
- colorSpace->getRGB(&color, rgb);
+ colorSpace->getRGB(&color, rgb, ri);
}
}
-void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) {
+void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk,
+ GfxRenderingIntent ri) {
GfxColor color;
int i;
@@ -3614,12 +3671,12 @@ void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) {
for (i = 0; i < nComps2; ++i) {
color.c[i] = lookup2[i][x[0]];
}
- colorSpace2->getCMYK(&color, cmyk);
+ colorSpace2->getCMYK(&color, cmyk, ri);
} else {
for (i = 0; i < nComps; ++i) {
color.c[i] = lookup[i][x[i]];
}
- colorSpace->getCMYK(&color, cmyk);
+ colorSpace->getCMYK(&color, cmyk, ri);
}
}
@@ -3637,7 +3694,8 @@ void GfxImageColorMap::getColor(Guchar *x, GfxColor *color) {
}
}
-void GfxImageColorMap::getGrayByteLine(Guchar *in, Guchar *out, int n) {
+void GfxImageColorMap::getGrayByteLine(Guchar *in, Guchar *out, int n,
+ GfxRenderingIntent ri) {
GfxColor color;
GfxGray gray;
int i, j;
@@ -3647,7 +3705,7 @@ void GfxImageColorMap::getGrayByteLine(Guchar *in, Guchar *out, int n) {
for (i = 0; i < nComps2; ++i) {
color.c[i] = lookup2[i][in[j]];
}
- colorSpace2->getGray(&color, &gray);
+ colorSpace2->getGray(&color, &gray, ri);
out[j] = colToByte(gray);
}
} else {
@@ -3655,13 +3713,14 @@ void GfxImageColorMap::getGrayByteLine(Guchar *in, Guchar *out, int n) {
for (i = 0; i < nComps; ++i) {
color.c[i] = lookup[i][in[j * nComps + i]];
}
- colorSpace->getGray(&color, &gray);
+ colorSpace->getGray(&color, &gray, ri);
out[j] = colToByte(gray);
}
}
}
-void GfxImageColorMap::getRGBByteLine(Guchar *in, Guchar *out, int n) {
+void GfxImageColorMap::getRGBByteLine(Guchar *in, Guchar *out, int n,
+ GfxRenderingIntent ri) {
GfxColor color;
GfxRGB rgb;
int i, j;
@@ -3671,7 +3730,7 @@ void GfxImageColorMap::getRGBByteLine(Guchar *in, Guchar *out, int n) {
for (i = 0; i < nComps2; ++i) {
color.c[i] = lookup2[i][in[j]];
}
- colorSpace2->getRGB(&color, &rgb);
+ colorSpace2->getRGB(&color, &rgb, ri);
out[j*3] = colToByte(rgb.r);
out[j*3 + 1] = colToByte(rgb.g);
out[j*3 + 2] = colToByte(rgb.b);
@@ -3681,7 +3740,7 @@ void GfxImageColorMap::getRGBByteLine(Guchar *in, Guchar *out, int n) {
for (i = 0; i < nComps; ++i) {
color.c[i] = lookup[i][in[j * nComps + i]];
}
- colorSpace->getRGB(&color, &rgb);
+ colorSpace->getRGB(&color, &rgb, ri);
out[j*3] = colToByte(rgb.r);
out[j*3 + 1] = colToByte(rgb.g);
out[j*3 + 2] = colToByte(rgb.b);
@@ -3689,7 +3748,8 @@ void GfxImageColorMap::getRGBByteLine(Guchar *in, Guchar *out, int n) {
}
}
-void GfxImageColorMap::getCMYKByteLine(Guchar *in, Guchar *out, int n) {
+void GfxImageColorMap::getCMYKByteLine(Guchar *in, Guchar *out, int n,
+ GfxRenderingIntent ri) {
GfxColor color;
GfxCMYK cmyk;
int i, j;
@@ -3699,7 +3759,7 @@ void GfxImageColorMap::getCMYKByteLine(Guchar *in, Guchar *out, int n) {
for (i = 0; i < nComps2; ++i) {
color.c[i] = lookup2[i][in[j]];
}
- colorSpace2->getCMYK(&color, &cmyk);
+ colorSpace2->getCMYK(&color, &cmyk, ri);
out[j*4] = colToByte(cmyk.c);
out[j*4 + 1] = colToByte(cmyk.m);
out[j*4 + 2] = colToByte(cmyk.y);
@@ -3710,7 +3770,7 @@ void GfxImageColorMap::getCMYKByteLine(Guchar *in, Guchar *out, int n) {
for (i = 0; i < nComps; ++i) {
color.c[i] = lookup[i][in[j * nComps + i]];
}
- colorSpace->getCMYK(&color, &cmyk);
+ colorSpace->getCMYK(&color, &cmyk, ri);
out[j*4] = colToByte(cmyk.c);
out[j*4 + 1] = colToByte(cmyk.m);
out[j*4 + 2] = colToByte(cmyk.y);
@@ -3983,6 +4043,7 @@ GfxState::GfxState(double hDPIA, double vDPIA, PDFRectangle *pageBox,
strokeOpacity = 1;
fillOverprint = gFalse;
strokeOverprint = gFalse;
+ renderingIntent = gfxRenderingIntentRelativeColorimetric;
overprintMode = 0;
transfer[0] = transfer[1] = transfer[2] = transfer[3] = NULL;
@@ -4165,8 +4226,8 @@ double GfxState::getTransformedFontSize() {
void GfxState::getFontTransMat(double *m11, double *m12,
double *m21, double *m22) {
- *m11 = (textMat[0] * ctm[0] + textMat[1] * ctm[2]) * fontSize;
- *m12 = (textMat[0] * ctm[1] + textMat[1] * ctm[3]) * fontSize;
+ *m11 = (textMat[0] * ctm[0] + textMat[1] * ctm[2]) * fontSize * horizScaling;
+ *m12 = (textMat[0] * ctm[1] + textMat[1] * ctm[3]) * fontSize * horizScaling;
*m21 = (textMat[2] * ctm[0] + textMat[3] * ctm[2]) * fontSize;
*m22 = (textMat[2] * ctm[1] + textMat[3] * ctm[3]) * fontSize;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
index 74ab5eb1c51..7cf92b69700 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GfxState.h
@@ -2,7 +2,7 @@
//
// GfxState.h
//
-// Copyright 1996-2003 Glyph & Cog, LLC
+// Copyright 1996-2016 Glyph & Cog, LLC
//
//========================================================================
@@ -23,6 +23,7 @@ class Array;
class GfxFont;
class PDFRectangle;
class GfxShading;
+class GfxState;
//------------------------------------------------------------------------
// GfxBlendMode
@@ -48,6 +49,19 @@ enum GfxBlendMode {
};
//------------------------------------------------------------------------
+// GfxRenderingIntent
+//------------------------------------------------------------------------
+
+enum GfxRenderingIntent {
+ gfxRenderingIntentAbsoluteColorimetric,
+ gfxRenderingIntentRelativeColorimetric,
+ gfxRenderingIntentSaturation,
+ gfxRenderingIntentPerceptual
+};
+
+#define gfxNumRenderingIntents 4
+
+//------------------------------------------------------------------------
// GfxColorComp
//------------------------------------------------------------------------
@@ -111,6 +125,7 @@ struct GfxCMYK {
+
//------------------------------------------------------------------------
// GfxColorSpace
//------------------------------------------------------------------------
@@ -149,9 +164,12 @@ public:
// Convert to gray, RGB, or CMYK.
- virtual void getGray(GfxColor *color, GfxGray *gray) = 0;
- virtual void getRGB(GfxColor *color, GfxRGB *rgb) = 0;
- virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk) = 0;
+ virtual void getGray(GfxColor *color, GfxGray *gray,
+ GfxRenderingIntent ri) = 0;
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb,
+ GfxRenderingIntent ri) = 0;
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk,
+ GfxRenderingIntent ri) = 0;
// Return the number of color components.
virtual int getNComps() = 0;
@@ -168,6 +186,7 @@ public:
// mark the page (e.g., the "None" colorant).
virtual GBool isNonMarking() { return gFalse; }
+
// Return the color space's overprint mask.
Guint getOverprintMask() { return overprintMask; }
@@ -194,9 +213,9 @@ public:
virtual GfxColorSpace *copy();
virtual GfxColorSpaceMode getMode() { return csDeviceGray; }
- virtual void getGray(GfxColor *color, GfxGray *gray);
- virtual void getRGB(GfxColor *color, GfxRGB *rgb);
- virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+ virtual void getGray(GfxColor *color, GfxGray *gray, GfxRenderingIntent ri);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb, GfxRenderingIntent ri);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk, GfxRenderingIntent ri);
virtual int getNComps() { return 1; }
virtual void getDefaultColor(GfxColor *color);
@@ -219,9 +238,9 @@ public:
// Construct a CalGray color space. Returns NULL if unsuccessful.
static GfxColorSpace *parse(Array *arr, int recursion);
- virtual void getGray(GfxColor *color, GfxGray *gray);
- virtual void getRGB(GfxColor *color, GfxRGB *rgb);
- virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+ virtual void getGray(GfxColor *color, GfxGray *gray, GfxRenderingIntent ri);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb, GfxRenderingIntent ri);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk, GfxRenderingIntent ri);
virtual int getNComps() { return 1; }
virtual void getDefaultColor(GfxColor *color);
@@ -254,9 +273,9 @@ public:
virtual GfxColorSpace *copy();
virtual GfxColorSpaceMode getMode() { return csDeviceRGB; }
- virtual void getGray(GfxColor *color, GfxGray *gray);
- virtual void getRGB(GfxColor *color, GfxRGB *rgb);
- virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+ virtual void getGray(GfxColor *color, GfxGray *gray, GfxRenderingIntent ri);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb, GfxRenderingIntent ri);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk, GfxRenderingIntent ri);
virtual int getNComps() { return 3; }
virtual void getDefaultColor(GfxColor *color);
@@ -279,9 +298,9 @@ public:
// Construct a CalRGB color space. Returns NULL if unsuccessful.
static GfxColorSpace *parse(Array *arr, int recursion);
- virtual void getGray(GfxColor *color, GfxGray *gray);
- virtual void getRGB(GfxColor *color, GfxRGB *rgb);
- virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+ virtual void getGray(GfxColor *color, GfxGray *gray, GfxRenderingIntent ri);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb, GfxRenderingIntent ri);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk, GfxRenderingIntent ri);
virtual int getNComps() { return 3; }
virtual void getDefaultColor(GfxColor *color);
@@ -318,13 +337,14 @@ public:
virtual GfxColorSpace *copy();
virtual GfxColorSpaceMode getMode() { return csDeviceCMYK; }
- virtual void getGray(GfxColor *color, GfxGray *gray);
- virtual void getRGB(GfxColor *color, GfxRGB *rgb);
- virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+ virtual void getGray(GfxColor *color, GfxGray *gray, GfxRenderingIntent ri);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb, GfxRenderingIntent ri);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk, GfxRenderingIntent ri);
virtual int getNComps() { return 4; }
virtual void getDefaultColor(GfxColor *color);
+
private:
};
@@ -343,9 +363,9 @@ public:
// Construct a Lab color space. Returns NULL if unsuccessful.
static GfxColorSpace *parse(Array *arr, int recursion);
- virtual void getGray(GfxColor *color, GfxGray *gray);
- virtual void getRGB(GfxColor *color, GfxRGB *rgb);
- virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+ virtual void getGray(GfxColor *color, GfxGray *gray, GfxRenderingIntent ri);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb, GfxRenderingIntent ri);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk, GfxRenderingIntent ri);
virtual int getNComps() { return 3; }
virtual void getDefaultColor(GfxColor *color);
@@ -390,9 +410,9 @@ public:
static GfxColorSpace *parse(Array *arr,
int recursion);
- virtual void getGray(GfxColor *color, GfxGray *gray);
- virtual void getRGB(GfxColor *color, GfxRGB *rgb);
- virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+ virtual void getGray(GfxColor *color, GfxGray *gray, GfxRenderingIntent ri);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb, GfxRenderingIntent ri);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk, GfxRenderingIntent ri);
virtual int getNComps() { return nComps; }
virtual void getDefaultColor(GfxColor *color);
@@ -400,8 +420,10 @@ public:
virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
int maxImgPixel);
+
// ICCBased-specific access.
GfxColorSpace *getAlt() { return alt; }
+ Ref getICCProfileStreamRef() { return iccProfileStream; }
private:
@@ -428,9 +450,9 @@ public:
static GfxColorSpace *parse(Array *arr,
int recursion);
- virtual void getGray(GfxColor *color, GfxGray *gray);
- virtual void getRGB(GfxColor *color, GfxRGB *rgb);
- virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+ virtual void getGray(GfxColor *color, GfxGray *gray, GfxRenderingIntent ri);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb, GfxRenderingIntent ri);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk, GfxRenderingIntent ri);
virtual int getNComps() { return 1; }
virtual void getDefaultColor(GfxColor *color);
@@ -468,9 +490,9 @@ public:
static GfxColorSpace *parse(Array *arr,
int recursion);
- virtual void getGray(GfxColor *color, GfxGray *gray);
- virtual void getRGB(GfxColor *color, GfxRGB *rgb);
- virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+ virtual void getGray(GfxColor *color, GfxGray *gray, GfxRenderingIntent ri);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb, GfxRenderingIntent ri);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk, GfxRenderingIntent ri);
virtual int getNComps() { return 1; }
virtual void getDefaultColor(GfxColor *color);
@@ -502,7 +524,8 @@ class GfxDeviceNColorSpace: public GfxColorSpace {
public:
GfxDeviceNColorSpace(int nCompsA, GString **namesA,
- GfxColorSpace *alt, Function *func);
+ GfxColorSpace *alt, Function *func,
+ Object *attrsA);
virtual ~GfxDeviceNColorSpace();
virtual GfxColorSpace *copy();
virtual GfxColorSpaceMode getMode() { return csDeviceN; }
@@ -511,9 +534,9 @@ public:
static GfxColorSpace *parse(Array *arr,
int recursion);
- virtual void getGray(GfxColor *color, GfxGray *gray);
- virtual void getRGB(GfxColor *color, GfxRGB *rgb);
- virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+ virtual void getGray(GfxColor *color, GfxGray *gray, GfxRenderingIntent ri);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb, GfxRenderingIntent ri);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk, GfxRenderingIntent ri);
virtual int getNComps() { return nComps; }
virtual void getDefaultColor(GfxColor *color);
@@ -524,11 +547,13 @@ public:
GString *getColorantName(int i) { return names[i]; }
GfxColorSpace *getAlt() { return alt; }
Function *getTintTransformFunc() { return func; }
+ Object *getAttrs() { return &attrs; }
private:
GfxDeviceNColorSpace(int nCompsA, GString **namesA,
GfxColorSpace *alt, Function *func,
+ Object *attrsA,
GBool nonMarkingA, Guint overprintMaskA);
int nComps; // number of components
@@ -536,6 +561,7 @@ private:
*names[gfxColorMaxComps];
GfxColorSpace *alt; // alternate color space
Function *func; // tint transform (into alternate color space)
+ Object attrs;
GBool nonMarking;
};
@@ -555,9 +581,9 @@ public:
static GfxColorSpace *parse(Array *arr,
int recursion);
- virtual void getGray(GfxColor *color, GfxGray *gray);
- virtual void getRGB(GfxColor *color, GfxRGB *rgb);
- virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+ virtual void getGray(GfxColor *color, GfxGray *gray, GfxRenderingIntent ri);
+ virtual void getRGB(GfxColor *color, GfxRGB *rgb, GfxRenderingIntent ri);
+ virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk, GfxRenderingIntent ri);
virtual int getNComps() { return 0; }
virtual void getDefaultColor(GfxColor *color);
@@ -915,15 +941,15 @@ public:
double getDecodeHigh(int i) { return decodeLow[i] + decodeRange[i]; }
// Convert an image pixel to a color.
- void getGray(Guchar *x, GfxGray *gray);
- void getRGB(Guchar *x, GfxRGB *rgb);
- void getCMYK(Guchar *x, GfxCMYK *cmyk);
+ void getGray(Guchar *x, GfxGray *gray, GfxRenderingIntent ri);
+ void getRGB(Guchar *x, GfxRGB *rgb, GfxRenderingIntent ri);
+ void getCMYK(Guchar *x, GfxCMYK *cmyk, GfxRenderingIntent ri);
void getColor(Guchar *x, GfxColor *color);
// Convert a line of <n> pixels to 8-bit colors.
- void getGrayByteLine(Guchar *in, Guchar *out, int n);
- void getRGBByteLine(Guchar *in, Guchar *out, int n);
- void getCMYKByteLine(Guchar *in, Guchar *out, int n);
+ void getGrayByteLine(Guchar *in, Guchar *out, int n, GfxRenderingIntent ri);
+ void getRGBByteLine(Guchar *in, Guchar *out, int n, GfxRenderingIntent ri);
+ void getCMYKByteLine(Guchar *in, Guchar *out, int n, GfxRenderingIntent ri);
private:
@@ -1090,17 +1116,17 @@ public:
GfxColor *getFillColor() { return &fillColor; }
GfxColor *getStrokeColor() { return &strokeColor; }
void getFillGray(GfxGray *gray)
- { fillColorSpace->getGray(&fillColor, gray); }
+ { fillColorSpace->getGray(&fillColor, gray, renderingIntent); }
void getStrokeGray(GfxGray *gray)
- { strokeColorSpace->getGray(&strokeColor, gray); }
+ { strokeColorSpace->getGray(&strokeColor, gray, renderingIntent); }
void getFillRGB(GfxRGB *rgb)
- { fillColorSpace->getRGB(&fillColor, rgb); }
+ { fillColorSpace->getRGB(&fillColor, rgb, renderingIntent); }
void getStrokeRGB(GfxRGB *rgb)
- { strokeColorSpace->getRGB(&strokeColor, rgb); }
+ { strokeColorSpace->getRGB(&strokeColor, rgb, renderingIntent); }
void getFillCMYK(GfxCMYK *cmyk)
- { fillColorSpace->getCMYK(&fillColor, cmyk); }
+ { fillColorSpace->getCMYK(&fillColor, cmyk, renderingIntent); }
void getStrokeCMYK(GfxCMYK *cmyk)
- { strokeColorSpace->getCMYK(&strokeColor, cmyk); }
+ { strokeColorSpace->getCMYK(&strokeColor, cmyk, renderingIntent); }
GfxColorSpace *getFillColorSpace() { return fillColorSpace; }
GfxColorSpace *getStrokeColorSpace() { return strokeColorSpace; }
GfxPattern *getFillPattern() { return fillPattern; }
@@ -1111,11 +1137,12 @@ public:
GBool getFillOverprint() { return fillOverprint; }
GBool getStrokeOverprint() { return strokeOverprint; }
int getOverprintMode() { return overprintMode; }
+ GfxRenderingIntent getRenderingIntent() { return renderingIntent; }
Function **getTransfer() { return transfer; }
double getLineWidth() { return lineWidth; }
void getLineDash(double **dash, int *length, double *start)
{ *dash = lineDash; *length = lineDashLength; *start = lineDashStart; }
- int getFlatness() { return flatness; }
+ double getFlatness() { return flatness; }
int getLineJoin() { return lineJoin; }
int getLineCap() { return lineCap; }
double getMiterLimit() { return miterLimit; }
@@ -1180,10 +1207,11 @@ public:
void setFillOverprint(GBool op) { fillOverprint = op; }
void setStrokeOverprint(GBool op) { strokeOverprint = op; }
void setOverprintMode(int opm) { overprintMode = opm; }
+ void setRenderingIntent(GfxRenderingIntent ri) { renderingIntent = ri; }
void setTransfer(Function **funcs);
void setLineWidth(double width) { lineWidth = width; }
void setLineDash(double *dash, int length, double start);
- void setFlatness(int flatness1) { flatness = flatness1; }
+ void setFlatness(double flatness1) { flatness = flatness1; }
void setLineJoin(int lineJoin1) { lineJoin = lineJoin1; }
void setLineCap(int lineCap1) { lineCap = lineCap1; }
void setMiterLimit(double limit) { miterLimit = limit; }
@@ -1223,6 +1251,8 @@ public:
void clip();
void clipToStrokePath();
void clipToRect(double xMin, double yMin, double xMax, double yMax);
+ void resetDevClipRect(double xMin, double yMin, double xMax, double yMax)
+ { clipXMin = xMin; clipYMin = yMin; clipXMax = xMax; clipYMax = yMax; }
// Text position.
void textSetPos(double tx, double ty) { lineX = tx; lineY = ty; }
@@ -1259,6 +1289,7 @@ private:
GBool fillOverprint; // fill overprint
GBool strokeOverprint; // stroke overprint
int overprintMode; // overprint mode ("OPM")
+ GfxRenderingIntent renderingIntent; // rendering intent
Function *transfer[4]; // transfer function (entries may be: all
// NULL = identity; last three NULL =
// single function; all four non-NULL =
@@ -1268,7 +1299,7 @@ private:
double *lineDash; // line dash
int lineDashLength;
double lineDashStart;
- int flatness; // curve flatness
+ double flatness; // curve flatness
int lineJoin; // line join style
int lineCap; // line cap style
double miterLimit; // line miter limit
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
index 8938b75e4af..974102c73f5 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.cc
@@ -15,20 +15,9 @@
#pragma implementation
#endif
-#ifdef _WIN32
-# ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0500 // for GetSystemWindowsDirectory
-# endif
-# include <windows.h>
-#endif
#include <string.h>
#include <stdio.h>
#include <ctype.h>
-#ifdef ENABLE_PLUGINS
-# ifndef _WIN32
-# include <dlfcn.h>
-# endif
-#endif
#ifdef _WIN32
# include <shlobj.h>
#endif
@@ -36,6 +25,7 @@
#include <paper.h>
#endif
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "GList.h"
#include "GHash.h"
@@ -48,9 +38,6 @@
#include "CMap.h"
#include "BuiltinFontTables.h"
#include "FontEncodingTables.h"
-#ifdef ENABLE_PLUGINS
-# include "XpdfPluginAPI.h"
-#endif
#include "GlobalParams.h"
#ifdef _WIN32
@@ -82,12 +69,6 @@
#include "UnicodeMapTables.h"
#include "UTF8.h"
-#ifdef ENABLE_PLUGINS
-# ifdef _WIN32
-extern XpdfPluginVecTable xpdfPluginVecTable;
-# endif
-#endif
-
//------------------------------------------------------------------------
#define cidToUnicodeCacheSize 4
@@ -362,7 +343,7 @@ SysFontInfo *SysFontList::find(GString *name) {
#ifdef _WIN32
void SysFontList::scanWindowsFonts(char *winFontDir) {
OSVERSIONINFO version;
- char *path;
+ const char *path;
DWORD idx, valNameLen, dataLen, type;
HKEY regKey;
char valName[1024], data[1024];
@@ -513,146 +494,20 @@ KeyBinding::~KeyBinding() {
deleteGList(cmds, GString);
}
-#ifdef ENABLE_PLUGINS
//------------------------------------------------------------------------
-// Plugin
+// PopupMenuCmd
//------------------------------------------------------------------------
-class Plugin {
-public:
-
- static Plugin *load(char *type, char *name);
- ~Plugin();
-
-private:
-
-#ifdef _WIN32
- Plugin(HMODULE libA);
- HMODULE lib;
-#else
- Plugin(void *dlA);
- void *dl;
-#endif
-};
-
-Plugin *Plugin::load(char *type, char *name) {
- GString *path;
- Plugin *plugin;
- XpdfPluginVecTable *vt;
- XpdfBool (*xpdfInitPlugin)(void);
-#ifdef _WIN32
- HMODULE libA;
-#else
- void *dlA;
-#endif
-
- path = globalParams->getBaseDir();
- appendToPath(path, "plugins");
- appendToPath(path, type);
- appendToPath(path, name);
-
-#ifdef _WIN32
- path->append(".dll");
- if (!(libA = LoadLibraryA(path->getCString()))) {
- error(errIO, -1, "Failed to load plugin '{0:t}'", path);
- goto err1;
- }
- if (!(vt = (XpdfPluginVecTable *)
- GetProcAddress(libA, "xpdfPluginVecTable"))) {
- error(errIO, -1, "Failed to find xpdfPluginVecTable in plugin '{0:t}'",
- path);
- goto err2;
- }
-#else
- //~ need to deal with other extensions here
- path->append(".so");
- if (!(dlA = dlopen(path->getCString(), RTLD_NOW))) {
- error(errIO, -1, "Failed to load plugin '{0:t}': {1:s}",
- path, dlerror());
- goto err1;
- }
- if (!(vt = (XpdfPluginVecTable *)dlsym(dlA, "xpdfPluginVecTable"))) {
- error(errIO, -1, "Failed to find xpdfPluginVecTable in plugin '{0:t}'",
- path);
- goto err2;
- }
-#endif
-
- if (vt->version != xpdfPluginVecTable.version) {
- error(errIO, -1, "Plugin '{0:t}' is wrong version", path);
- goto err2;
- }
- memcpy(vt, &xpdfPluginVecTable, sizeof(xpdfPluginVecTable));
-
-#ifdef _WIN32
- if (!(xpdfInitPlugin = (XpdfBool (*)(void))
- GetProcAddress(libA, "xpdfInitPlugin"))) {
- error(errIO, -1, "Failed to find xpdfInitPlugin in plugin '{0:t}'",
- path);
- goto err2;
- }
-#else
- if (!(xpdfInitPlugin = (XpdfBool (*)(void))dlsym(dlA, "xpdfInitPlugin"))) {
- error(errIO, -1, "Failed to find xpdfInitPlugin in plugin '{0:t}'",
- path);
- goto err2;
- }
-#endif
-
- if (!(*xpdfInitPlugin)()) {
- error(errIO, -1, "Initialization of plugin '{0:t}' failed", path);
- goto err2;
- }
-
-#ifdef _WIN32
- plugin = new Plugin(libA);
-#else
- plugin = new Plugin(dlA);
-#endif
-
- delete path;
- return plugin;
-
- err2:
-#ifdef _WIN32
- FreeLibrary(libA);
-#else
- dlclose(dlA);
-#endif
- err1:
- delete path;
- return NULL;
-}
-
-#ifdef _WIN32
-Plugin::Plugin(HMODULE libA) {
- lib = libA;
-}
-#else
-Plugin::Plugin(void *dlA) {
- dl = dlA;
+PopupMenuCmd::PopupMenuCmd(GString *labelA, GList *cmdsA) {
+ label = labelA;
+ cmds = cmdsA;
}
-#endif
-
-Plugin::~Plugin() {
- void (*xpdfFreePlugin)(void);
-#ifdef _WIN32
- if ((xpdfFreePlugin = (void (*)(void))
- GetProcAddress(lib, "xpdfFreePlugin"))) {
- (*xpdfFreePlugin)();
- }
- FreeLibrary(lib);
-#else
- if ((xpdfFreePlugin = (void (*)(void))dlsym(dl, "xpdfFreePlugin"))) {
- (*xpdfFreePlugin)();
- }
- dlclose(dl);
-#endif
+PopupMenuCmd::~PopupMenuCmd() {
+ delete label;
+ deleteGList(cmds, GString);
}
-#endif // ENABLE_PLUGINS
-
//------------------------------------------------------------------------
// parsing
//------------------------------------------------------------------------
@@ -669,6 +524,10 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
gInitMutex(&cMapCacheMutex);
#endif
+#ifdef _WIN32
+ tlsWin32ErrorInfo = TlsAlloc();
+#endif
+
initBuiltinFontTables();
// scan the encoding in reverse because we want the lowest-numbered
@@ -745,24 +604,28 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
psRasterMono = gFalse;
psRasterSliceSize = 20000000;
psAlwaysRasterize = gFalse;
+ psNeverRasterize = gFalse;
textEncoding = new GString("Latin1");
#if defined(_WIN32)
textEOL = eolDOS;
-#elif defined(MACOS)
- textEOL = eolMac;
#else
textEOL = eolUnix;
#endif
textPageBreaks = gTrue;
textKeepTinyChars = gTrue;
initialZoom = new GString("125");
- continuousView = gFalse;
+ defaultFitZoom = 0;
+ initialSidebarState = gTrue;
+ maxTileWidth = 1500;
+ maxTileHeight = 1500;
+ tileCacheSize = 10;
+ workerThreads = 1;
enableFreeType = gTrue;
disableFreeTypeHinting = gFalse;
antialias = gTrue;
vectorAntialias = gTrue;
antialiasPrinting = gFalse;
- strokeAdjust = gTrue;
+ strokeAdjust = strokeAdjustNormal;
screenType = screenUnset;
screenSize = -1;
screenDotRadius = -1;
@@ -770,16 +633,21 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
screenBlackThreshold = 0.0;
screenWhiteThreshold = 1.0;
minLineWidth = 0.0;
+ enablePathSimplification = gFalse;
drawAnnotations = gTrue;
+ drawFormFields = gTrue;
overprintPreview = gFalse;
+ paperColor = new GString("#ffffff");
+ matteColor = new GString("#808080");
+ fullScreenMatteColor = new GString("#000000");
launchCommand = NULL;
- urlCommand = NULL;
movieCommand = NULL;
mapNumericCharNames = gTrue;
mapUnknownCharNames = gFalse;
mapExtTrueTypeFontsViaUnicode = gTrue;
enableXFA = gTrue;
createDefaultKeyBindings();
+ popupMenuCmds = new GList();
printCommands = gFalse;
errQuiet = gFalse;
@@ -789,11 +657,6 @@ GlobalParams::GlobalParams(const char *cfgFileName) {
unicodeMapCache = new UnicodeMapCache();
cMapCache = new CMapCache();
-#ifdef ENABLE_PLUGINS
- plugins = new GList();
- securityHandlers = new GList();
-#endif
-
// set up the initial nameToUnicode table
for (i = 0; nameToUnicodeTab[i].name; ++i) {
nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u);
@@ -865,8 +728,12 @@ void GlobalParams::createDefaultKeyBindings() {
keyBindings->append(new KeyBinding(xpdfKeyCodeMousePress1, xpdfKeyModNone,
xpdfKeyContextAny, "startSelection"));
keyBindings->append(new KeyBinding(xpdfKeyCodeMouseRelease1, xpdfKeyModNone,
- xpdfKeyContextAny, "endSelection",
- "followLinkNoSel"));
+ xpdfKeyContextAny, "endSelection"));
+ keyBindings->append(new KeyBinding(xpdfKeyCodeMouseClick1, xpdfKeyModNone,
+ xpdfKeyContextAny, "followLinkNoSel"));
+ keyBindings->append(new KeyBinding(xpdfKeyCodeMouseClick2, xpdfKeyModNone,
+ xpdfKeyContextOverLink,
+ "followLinkInNewTab"));
keyBindings->append(new KeyBinding(xpdfKeyCodeMousePress2, xpdfKeyModNone,
xpdfKeyContextAny, "startPan"));
keyBindings->append(new KeyBinding(xpdfKeyCodeMouseRelease2, xpdfKeyModNone,
@@ -884,7 +751,52 @@ void GlobalParams::createDefaultKeyBindings() {
keyBindings->append(new KeyBinding(xpdfKeyCodeMousePress7, xpdfKeyModNone,
xpdfKeyContextAny, "scrollRight(16)"));
- //----- keys
+ //----- control keys
+ keyBindings->append(new KeyBinding('o', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "open"));
+ keyBindings->append(new KeyBinding('r', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "reload"));
+ keyBindings->append(new KeyBinding('f', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "find"));
+ keyBindings->append(new KeyBinding('g', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "findNext"));
+ keyBindings->append(new KeyBinding('c', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "copy"));
+ keyBindings->append(new KeyBinding('p', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "print"));
+ keyBindings->append(new KeyBinding('0', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "zoomPercent(125)"));
+ keyBindings->append(new KeyBinding('+', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "zoomIn"));
+ keyBindings->append(new KeyBinding('=', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "zoomIn"));
+ keyBindings->append(new KeyBinding('-', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "zoomOut"));
+ keyBindings->append(new KeyBinding('s', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "saveAs"));
+ keyBindings->append(new KeyBinding('t', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "newTab"));
+ keyBindings->append(new KeyBinding('n', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "newWindow"));
+ keyBindings->append(new KeyBinding('w', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "closeTabOrQuit"));
+ keyBindings->append(new KeyBinding('q', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "quit"));
+ keyBindings->append(new KeyBinding(xpdfKeyCodeTab, xpdfKeyModCtrl,
+ xpdfKeyContextAny, "nextTab"));
+ keyBindings->append(new KeyBinding(xpdfKeyCodeTab,
+ xpdfKeyModShift | xpdfKeyModCtrl,
+ xpdfKeyContextAny, "prevTab"));
+ keyBindings->append(new KeyBinding('?', xpdfKeyModCtrl,
+ xpdfKeyContextAny, "help"));
+
+ //----- alt keys
+ keyBindings->append(new KeyBinding(xpdfKeyCodeLeft, xpdfKeyModAlt,
+ xpdfKeyContextAny, "goBackward"));
+ keyBindings->append(new KeyBinding(xpdfKeyCodeRight, xpdfKeyModAlt,
+ xpdfKeyContextAny, "goForward"));
+
+ //----- home/end keys
keyBindings->append(new KeyBinding(xpdfKeyCodeHome, xpdfKeyModCtrl,
xpdfKeyContextAny, "gotoPage(1)"));
keyBindings->append(new KeyBinding(xpdfKeyCodeHome, xpdfKeyModNone,
@@ -894,16 +806,29 @@ void GlobalParams::createDefaultKeyBindings() {
keyBindings->append(new KeyBinding(xpdfKeyCodeEnd, xpdfKeyModNone,
xpdfKeyContextAny,
"scrollToBottomRight"));
+
+ //----- pgup/pgdn keys
keyBindings->append(new KeyBinding(xpdfKeyCodePgUp, xpdfKeyModNone,
xpdfKeyContextAny, "pageUp"));
- keyBindings->append(new KeyBinding(xpdfKeyCodeBackspace, xpdfKeyModNone,
- xpdfKeyContextAny, "pageUp"));
- keyBindings->append(new KeyBinding(xpdfKeyCodeDelete, xpdfKeyModNone,
- xpdfKeyContextAny, "pageUp"));
keyBindings->append(new KeyBinding(xpdfKeyCodePgDn, xpdfKeyModNone,
xpdfKeyContextAny, "pageDown"));
- keyBindings->append(new KeyBinding(' ', xpdfKeyModNone,
- xpdfKeyContextAny, "pageDown"));
+ keyBindings->append(new KeyBinding(xpdfKeyCodePgUp, xpdfKeyModCtrl,
+ xpdfKeyContextAny, "prevPage"));
+ keyBindings->append(new KeyBinding(xpdfKeyCodePgDn, xpdfKeyModCtrl,
+ xpdfKeyContextAny, "nextPage"));
+ keyBindings->append(new KeyBinding(xpdfKeyCodePgUp, xpdfKeyModCtrl,
+ xpdfKeyContextScrLockOn,
+ "prevPageNoScroll"));
+ keyBindings->append(new KeyBinding(xpdfKeyCodePgDn, xpdfKeyModCtrl,
+ xpdfKeyContextScrLockOn,
+ "nextPageNoScroll"));
+
+ //----- esc key
+ keyBindings->append(new KeyBinding(xpdfKeyCodeEsc, xpdfKeyModNone,
+ xpdfKeyContextFullScreen,
+ "windowMode"));
+
+ //----- arrow keys
keyBindings->append(new KeyBinding(xpdfKeyCodeLeft, xpdfKeyModNone,
xpdfKeyContextAny, "scrollLeft(16)"));
keyBindings->append(new KeyBinding(xpdfKeyCodeRight, xpdfKeyModNone,
@@ -912,73 +837,26 @@ void GlobalParams::createDefaultKeyBindings() {
xpdfKeyContextAny, "scrollUp(16)"));
keyBindings->append(new KeyBinding(xpdfKeyCodeDown, xpdfKeyModNone,
xpdfKeyContextAny, "scrollDown(16)"));
- keyBindings->append(new KeyBinding('o', xpdfKeyModNone,
- xpdfKeyContextAny, "open"));
- keyBindings->append(new KeyBinding('O', xpdfKeyModNone,
- xpdfKeyContextAny, "open"));
- keyBindings->append(new KeyBinding('r', xpdfKeyModNone,
- xpdfKeyContextAny, "reload"));
- keyBindings->append(new KeyBinding('R', xpdfKeyModNone,
- xpdfKeyContextAny, "reload"));
- keyBindings->append(new KeyBinding('f', xpdfKeyModNone,
- xpdfKeyContextAny, "find"));
- keyBindings->append(new KeyBinding('F', xpdfKeyModNone,
- xpdfKeyContextAny, "find"));
- keyBindings->append(new KeyBinding('f', xpdfKeyModCtrl,
- xpdfKeyContextAny, "find"));
- keyBindings->append(new KeyBinding('g', xpdfKeyModCtrl,
- xpdfKeyContextAny, "findNext"));
- keyBindings->append(new KeyBinding('p', xpdfKeyModCtrl,
- xpdfKeyContextAny, "print"));
- keyBindings->append(new KeyBinding('n', xpdfKeyModNone,
- xpdfKeyContextScrLockOff, "nextPage"));
- keyBindings->append(new KeyBinding('N', xpdfKeyModNone,
- xpdfKeyContextScrLockOff, "nextPage"));
- keyBindings->append(new KeyBinding('n', xpdfKeyModNone,
- xpdfKeyContextScrLockOn,
- "nextPageNoScroll"));
- keyBindings->append(new KeyBinding('N', xpdfKeyModNone,
- xpdfKeyContextScrLockOn,
- "nextPageNoScroll"));
- keyBindings->append(new KeyBinding('p', xpdfKeyModNone,
- xpdfKeyContextScrLockOff, "prevPage"));
- keyBindings->append(new KeyBinding('P', xpdfKeyModNone,
- xpdfKeyContextScrLockOff, "prevPage"));
- keyBindings->append(new KeyBinding('p', xpdfKeyModNone,
+ keyBindings->append(new KeyBinding(xpdfKeyCodeUp, xpdfKeyModCtrl,
+ xpdfKeyContextAny, "prevPage"));
+ keyBindings->append(new KeyBinding(xpdfKeyCodeDown, xpdfKeyModCtrl,
+ xpdfKeyContextAny, "nextPage"));
+ keyBindings->append(new KeyBinding(xpdfKeyCodeUp, xpdfKeyModCtrl,
xpdfKeyContextScrLockOn,
"prevPageNoScroll"));
- keyBindings->append(new KeyBinding('P', xpdfKeyModNone,
+ keyBindings->append(new KeyBinding(xpdfKeyCodeDown, xpdfKeyModCtrl,
xpdfKeyContextScrLockOn,
- "prevPageNoScroll"));
- keyBindings->append(new KeyBinding('v', xpdfKeyModNone,
- xpdfKeyContextAny, "goForward"));
- keyBindings->append(new KeyBinding('b', xpdfKeyModNone,
- xpdfKeyContextAny, "goBackward"));
+ "nextPageNoScroll"));
+
+ //----- letter keys
+ keyBindings->append(new KeyBinding(' ', xpdfKeyModNone,
+ xpdfKeyContextAny, "pageDown"));
keyBindings->append(new KeyBinding('g', xpdfKeyModNone,
xpdfKeyContextAny, "focusToPageNum"));
- keyBindings->append(new KeyBinding('0', xpdfKeyModNone,
- xpdfKeyContextAny, "zoomPercent(125)"));
- keyBindings->append(new KeyBinding('+', xpdfKeyModNone,
- xpdfKeyContextAny, "zoomIn"));
- keyBindings->append(new KeyBinding('-', xpdfKeyModNone,
- xpdfKeyContextAny, "zoomOut"));
keyBindings->append(new KeyBinding('z', xpdfKeyModNone,
xpdfKeyContextAny, "zoomFitPage"));
keyBindings->append(new KeyBinding('w', xpdfKeyModNone,
xpdfKeyContextAny, "zoomFitWidth"));
- keyBindings->append(new KeyBinding('f', xpdfKeyModAlt,
- xpdfKeyContextAny,
- "toggleFullScreenMode"));
- keyBindings->append(new KeyBinding('l', xpdfKeyModCtrl,
- xpdfKeyContextAny, "redraw"));
- keyBindings->append(new KeyBinding('w', xpdfKeyModCtrl,
- xpdfKeyContextAny, "closeWindowOrQuit"));
- keyBindings->append(new KeyBinding('?', xpdfKeyModNone,
- xpdfKeyContextAny, "about"));
- keyBindings->append(new KeyBinding('q', xpdfKeyModNone,
- xpdfKeyContextAny, "quit"));
- keyBindings->append(new KeyBinding('Q', xpdfKeyModNone,
- xpdfKeyContextAny, "quit"));
}
void GlobalParams::parseFile(GString *fileName, FILE *f) {
@@ -1120,6 +998,9 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
} else if (!cmd->cmp("psAlwaysRasterize")) {
parseYesNo("psAlwaysRasterize", &psAlwaysRasterize,
tokens, fileName, line);
+ } else if (!cmd->cmp("psNeverRasterize")) {
+ parseYesNo("psNeverRasterize", &psNeverRasterize,
+ tokens, fileName, line);
} else if (!cmd->cmp("textEncoding")) {
parseTextEncoding(tokens, fileName, line);
} else if (!cmd->cmp("textEOL")) {
@@ -1132,8 +1013,19 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
tokens, fileName, line);
} else if (!cmd->cmp("initialZoom")) {
parseInitialZoom(tokens, fileName, line);
- } else if (!cmd->cmp("continuousView")) {
- parseYesNo("continuousView", &continuousView, tokens, fileName, line);
+ } else if (!cmd->cmp("defaultFitZoom")) {
+ parseInteger("defaultFitZoom", &defaultFitZoom, tokens, fileName, line);
+ } else if (!cmd->cmp("initialSidebarState")) {
+ parseYesNo("initialSidebarState", &initialSidebarState,
+ tokens, fileName, line);
+ } else if (!cmd->cmp("maxTileWidth")) {
+ parseInteger("maxTileWidth", &maxTileWidth, tokens, fileName, line);
+ } else if (!cmd->cmp("maxTileHeight")) {
+ parseInteger("maxTileHeight", &maxTileHeight, tokens, fileName, line);
+ } else if (!cmd->cmp("tileCacheSize")) {
+ parseInteger("tileCacheSize", &tileCacheSize, tokens, fileName, line);
+ } else if (!cmd->cmp("workerThreads")) {
+ parseInteger("workerThreads", &workerThreads, tokens, fileName, line);
} else if (!cmd->cmp("enableFreeType")) {
parseYesNo("enableFreeType", &enableFreeType, tokens, fileName, line);
} else if (!cmd->cmp("disableFreeTypeHinting")) {
@@ -1148,7 +1040,7 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
parseYesNo("antialiasPrinting", &antialiasPrinting,
tokens, fileName, line);
} else if (!cmd->cmp("strokeAdjust")) {
- parseYesNo("strokeAdjust", &strokeAdjust, tokens, fileName, line);
+ parseStrokeAdjust(tokens, fileName, line);
} else if (!cmd->cmp("screenType")) {
parseScreenType(tokens, fileName, line);
} else if (!cmd->cmp("screenSize")) {
@@ -1168,16 +1060,27 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
} else if (!cmd->cmp("minLineWidth")) {
parseFloat("minLineWidth", &minLineWidth,
tokens, fileName, line);
+ } else if (!cmd->cmp("enablePathSimplification")) {
+ parseYesNo("enablePathSimplification", &enablePathSimplification,
+ tokens, fileName, line);
} else if (!cmd->cmp("drawAnnotations")) {
parseYesNo("drawAnnotations", &drawAnnotations,
tokens, fileName, line);
+ } else if (!cmd->cmp("drawFormFields")) {
+ parseYesNo("drawFormFields", &drawFormFields,
+ tokens, fileName, line);
} else if (!cmd->cmp("overprintPreview")) {
parseYesNo("overprintPreview", &overprintPreview,
tokens, fileName, line);
+ } else if (!cmd->cmp("paperColor")) {
+ parseColor("paperColor", &paperColor, tokens, fileName, line);
+ } else if (!cmd->cmp("matteColor")) {
+ parseColor("matteColor", &matteColor, tokens, fileName, line);
+ } else if (!cmd->cmp("fullScreenMatteColor")) {
+ parseColor("fullScreenMatteColor", &fullScreenMatteColor,
+ tokens, fileName, line);
} else if (!cmd->cmp("launchCommand")) {
parseCommand("launchCommand", &launchCommand, tokens, fileName, line);
- } else if (!cmd->cmp("urlCommand")) {
- parseCommand("urlCommand", &urlCommand, tokens, fileName, line);
} else if (!cmd->cmp("movieCommand")) {
parseCommand("movieCommand", &movieCommand, tokens, fileName, line);
} else if (!cmd->cmp("mapNumericCharNames")) {
@@ -1196,6 +1099,8 @@ void GlobalParams::parseLine(char *buf, GString *fileName, int line) {
parseBind(tokens, fileName, line);
} else if (!cmd->cmp("unbind")) {
parseUnbind(tokens, fileName, line);
+ } else if (!cmd->cmp("popupMenuCmd")) {
+ parsePopupMenuCmd(tokens, fileName, line);
} else if (!cmd->cmp("printCommands")) {
parseYesNo("printCommands", &printCommands, tokens, fileName, line);
} else if (!cmd->cmp("errQuiet")) {
@@ -1436,10 +1341,14 @@ void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
psLevel = psLevel1Sep;
} else if (!tok->cmp("level2")) {
psLevel = psLevel2;
+ } else if (!tok->cmp("level2gray")) {
+ psLevel = psLevel2Gray;
} else if (!tok->cmp("level2sep")) {
psLevel = psLevel2Sep;
} else if (!tok->cmp("level3")) {
psLevel = psLevel3;
+ } else if (!tok->cmp("level3gray")) {
+ psLevel = psLevel3Gray;
} else if (!tok->cmp("level3Sep")) {
psLevel = psLevel3Sep;
} else {
@@ -1559,6 +1468,30 @@ void GlobalParams::parseInitialZoom(GList *tokens,
initialZoom = ((GString *)tokens->get(1))->copy();
}
+void GlobalParams::parseStrokeAdjust(GList *tokens, GString *fileName,
+ int line) {
+ GString *tok;
+
+ if (tokens->getLength() != 2) {
+ error(errConfig, -1,
+ "Bad 'strokeAdjust' config file command ({0:t}:{1:d})",
+ fileName, line);
+ return;
+ }
+ tok = (GString *)tokens->get(1);
+ if (!tok->cmp("no")) {
+ strokeAdjust = strokeAdjustOff;
+ } else if (!tok->cmp("yes")) {
+ strokeAdjust = strokeAdjustNormal;
+ } else if (!tok->cmp("cad")) {
+ strokeAdjust = strokeAdjustCAD;
+ } else {
+ error(errConfig, -1,
+ "Bad 'strokeAdjust' config file command ({0:t}:{1:d})",
+ fileName, line);
+ }
+}
+
void GlobalParams::parseScreenType(GList *tokens, GString *fileName,
int line) {
GString *tok;
@@ -1692,6 +1625,8 @@ GBool GlobalParams::parseKey(GString *modKeyStr, GString *contextStr,
*code = xpdfKeyCodeUp;
} else if (!strcmp(p0, "down")) {
*code = xpdfKeyCodeDown;
+ } else if (!strcmp(p0, "esc")) {
+ *code = xpdfKeyCodeEsc;
} else if (p0[0] == 'f' && p0[1] >= '1' && p0[1] <= '9' && !p0[2]) {
*code = xpdfKeyCodeF1 + (p0[1] - '1');
} else if (p0[0] == 'f' &&
@@ -1709,6 +1644,11 @@ GBool GlobalParams::parseKey(GString *modKeyStr, GString *contextStr,
(!p0[13] || (p0[13] >= '0' && p0[13] <= '9' && !p0[14])) &&
(btn = atoi(p0 + 12)) >= 1 && btn <= 32) {
*code = xpdfKeyCodeMouseRelease1 + btn - 1;
+ } else if (!strncmp(p0, "mouseClick", 10) &&
+ p0[10] >= '0' && p0[10] <= '9' &&
+ (!p0[11] || (p0[11] >= '0' && p0[11] <= '9' && !p0[12])) &&
+ (btn = atoi(p0 + 10)) >= 1 && btn <= 32) {
+ *code = xpdfKeyCodeMouseClick1 + btn - 1;
} else if (*p0 >= 0x20 && *p0 <= 0x7e && !p0[1]) {
*code = (int)*p0;
} else {
@@ -1776,6 +1716,25 @@ GBool GlobalParams::parseKey(GString *modKeyStr, GString *contextStr,
return gTrue;
}
+void GlobalParams::parsePopupMenuCmd(GList *tokens,
+ GString *fileName, int line) {
+ GList *cmds;
+ int i;
+
+ if (tokens->getLength() < 3) {
+ error(errConfig, -1,
+ "Bad 'popupMenuCmd' config file command ({0:t}:{1:d})",
+ fileName, line);
+ return;
+ }
+ cmds = new GList();
+ for (i = 2; i < tokens->getLength(); ++i) {
+ cmds->append(((GString *)tokens->get(i))->copy());
+ }
+ popupMenuCmds->append(new PopupMenuCmd(((GString *)tokens->get(1))->copy(),
+ cmds));
+}
+
void GlobalParams::parseCommand(const char *cmdName, GString **val,
GList *tokens, GString *fileName, int line) {
if (tokens->getLength() != 2) {
@@ -1816,6 +1775,19 @@ GBool GlobalParams::parseYesNo2(char *token, GBool *flag) {
return gTrue;
}
+void GlobalParams::parseColor(const char *cmdName, GString **val,
+ GList *tokens, GString *fileName, int line) {
+ if (tokens->getLength() != 2) {
+ error(errConfig, -1, "Bad '{0:s}' config file command ({1:t}:{2:d})",
+ cmdName, fileName, line);
+ return;
+ }
+ if (*val) {
+ delete *val;
+ }
+ *val = ((GString *)tokens->get(1))->copy();
+}
+
void GlobalParams::parseInteger(const char *cmdName, int *val,
GList *tokens, GString *fileName, int line) {
GString *tok;
@@ -1908,16 +1880,23 @@ GlobalParams::~GlobalParams() {
deleteGList(psResidentFontsCC, PSFontParam16);
delete textEncoding;
delete initialZoom;
+ if (paperColor) {
+ delete paperColor;
+ }
+ if (matteColor) {
+ delete matteColor;
+ }
+ if (fullScreenMatteColor) {
+ delete fullScreenMatteColor;
+ }
if (launchCommand) {
delete launchCommand;
}
- if (urlCommand) {
- delete urlCommand;
- }
if (movieCommand) {
delete movieCommand;
}
deleteGList(keyBindings, KeyBinding);
+ deleteGList(popupMenuCmds, PopupMenuCmd);
cMapDirs->startIter(&iter);
while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
@@ -1930,11 +1909,6 @@ GlobalParams::~GlobalParams() {
delete unicodeMapCache;
delete cMapCache;
-#ifdef ENABLE_PLUGINS
- delete securityHandlers;
- deleteGList(plugins, Plugin);
-#endif
-
#if MULTITHREADED
gDestroyMutex(&mutex);
gDestroyMutex(&unicodeMapCacheMutex);
@@ -1944,7 +1918,7 @@ GlobalParams::~GlobalParams() {
//------------------------------------------------------------------------
-void GlobalParams::setBaseDir(char *dir) {
+void GlobalParams::setBaseDir(const char *dir) {
delete baseDir;
baseDir = new GString(dir);
}
@@ -1997,7 +1971,7 @@ static void getWinFontDir(char *winFontDir) {
}
#endif
-void GlobalParams::setupBaseFonts(char *dir) {
+void GlobalParams::setupBaseFonts(const char *dir) {
GString *fontName;
GString *fileName;
int fontNum;
@@ -2634,6 +2608,15 @@ GBool GlobalParams::getPSAlwaysRasterize() {
return rast;
}
+GBool GlobalParams::getPSNeverRasterize() {
+ GBool rast;
+
+ lockGlobalParams;
+ rast = psNeverRasterize;
+ unlockGlobalParams;
+ return rast;
+}
+
GString *GlobalParams::getTextEncodingName() {
GString *s;
@@ -2679,13 +2662,58 @@ GString *GlobalParams::getInitialZoom() {
return s;
}
-GBool GlobalParams::getContinuousView() {
- GBool f;
+int GlobalParams::getDefaultFitZoom() {
+ int z;
lockGlobalParams;
- f = continuousView;
+ z = defaultFitZoom;
unlockGlobalParams;
- return f;
+ return z;
+}
+
+GBool GlobalParams::getInitialSidebarState() {
+ GBool state;
+
+ lockGlobalParams;
+ state = initialSidebarState;
+ unlockGlobalParams;
+ return state;
+}
+
+int GlobalParams::getMaxTileWidth() {
+ int w;
+
+ lockGlobalParams;
+ w = maxTileWidth;
+ unlockGlobalParams;
+ return w;
+}
+
+int GlobalParams::getMaxTileHeight() {
+ int h;
+
+ lockGlobalParams;
+ h = maxTileHeight;
+ unlockGlobalParams;
+ return h;
+}
+
+int GlobalParams::getTileCacheSize() {
+ int n;
+
+ lockGlobalParams;
+ n = tileCacheSize;
+ unlockGlobalParams;
+ return n;
+}
+
+int GlobalParams::getWorkerThreads() {
+ int n;
+
+ lockGlobalParams;
+ n = workerThreads;
+ unlockGlobalParams;
+ return n;
}
GBool GlobalParams::getEnableFreeType() {
@@ -2734,13 +2762,13 @@ GBool GlobalParams::getAntialiasPrinting() {
return f;
}
-GBool GlobalParams::getStrokeAdjust() {
- GBool f;
+StrokeAdjustMode GlobalParams::getStrokeAdjust() {
+ StrokeAdjustMode mode;
lockGlobalParams;
- f = strokeAdjust;
+ mode = strokeAdjust;
unlockGlobalParams;
- return f;
+ return mode;
}
ScreenType GlobalParams::getScreenType() {
@@ -2806,6 +2834,15 @@ double GlobalParams::getMinLineWidth() {
return w;
}
+GBool GlobalParams::getEnablePathSimplification() {
+ GBool en;
+
+ lockGlobalParams;
+ en = enablePathSimplification;
+ unlockGlobalParams;
+ return en;
+}
+
GBool GlobalParams::getDrawAnnotations() {
GBool draw;
@@ -2815,6 +2852,43 @@ GBool GlobalParams::getDrawAnnotations() {
return draw;
}
+GBool GlobalParams::getDrawFormFields() {
+ GBool draw;
+
+ lockGlobalParams;
+ draw = drawFormFields;
+ unlockGlobalParams;
+ return draw;
+}
+
+
+
+GString *GlobalParams::getPaperColor() {
+ GString *s;
+
+ lockGlobalParams;
+ s = paperColor->copy();
+ unlockGlobalParams;
+ return s;
+}
+
+GString *GlobalParams::getMatteColor() {
+ GString *s;
+
+ lockGlobalParams;
+ s = matteColor->copy();
+ unlockGlobalParams;
+ return s;
+}
+
+GString *GlobalParams::getFullScreenMatteColor() {
+ GString *s;
+
+ lockGlobalParams;
+ s = fullScreenMatteColor->copy();
+ unlockGlobalParams;
+ return s;
+}
GBool GlobalParams::getMapNumericCharNames() {
GBool map;
@@ -2861,7 +2935,7 @@ GList *GlobalParams::getKeyBinding(int code, int mods, int context) {
lockGlobalParams;
cmds = NULL;
// for ASCII chars, ignore the shift modifier
- modMask = code <= 0xff ? ~xpdfKeyModShift : ~0;
+ modMask = (code >= 0x21 && code <= 0xff) ? ~xpdfKeyModShift : ~0;
for (i = 0; i < keyBindings->getLength(); ++i) {
binding = (KeyBinding *)keyBindings->get(i);
if (binding->code == code &&
@@ -2878,6 +2952,28 @@ GList *GlobalParams::getKeyBinding(int code, int mods, int context) {
return cmds;
}
+int GlobalParams::getNumPopupMenuCmds() {
+ int n;
+
+ lockGlobalParams;
+ n = popupMenuCmds->getLength();
+ unlockGlobalParams;
+ return n;
+}
+
+PopupMenuCmd *GlobalParams::getPopupMenuCmd(int idx) {
+ PopupMenuCmd *cmd;
+
+ lockGlobalParams;
+ if (idx < popupMenuCmds->getLength()) {
+ cmd = (PopupMenuCmd *)popupMenuCmds->get(idx);
+ } else {
+ cmd = NULL;
+ }
+ unlockGlobalParams;
+ return cmd;
+}
+
GBool GlobalParams::getPrintCommands() {
GBool p;
@@ -3167,12 +3263,6 @@ void GlobalParams::setInitialZoom(char *s) {
unlockGlobalParams;
}
-void GlobalParams::setContinuousView(GBool cont) {
- lockGlobalParams;
- continuousView = cont;
- unlockGlobalParams;
-}
-
GBool GlobalParams::setEnableFreeType(char *s) {
GBool ok;
@@ -3237,6 +3327,20 @@ void GlobalParams::setScreenWhiteThreshold(double thresh) {
unlockGlobalParams;
}
+void GlobalParams::setDrawFormFields(GBool draw) {
+ lockGlobalParams;
+ drawFormFields = draw;
+ unlockGlobalParams;
+}
+
+void GlobalParams::setOverprintPreview(GBool preview) {
+ lockGlobalParams;
+ overprintPreview = preview;
+ unlockGlobalParams;
+}
+
+
+
void GlobalParams::setMapNumericCharNames(GBool map) {
lockGlobalParams;
mapNumericCharNames = map;
@@ -3273,62 +3377,35 @@ void GlobalParams::setErrQuiet(GBool errQuietA) {
unlockGlobalParams;
}
-void GlobalParams::addSecurityHandler(XpdfSecurityHandler *handler) {
-#ifdef ENABLE_PLUGINS
- lockGlobalParams;
- securityHandlers->append(handler);
- unlockGlobalParams;
-#endif
-}
-
-XpdfSecurityHandler *GlobalParams::getSecurityHandler(char *name) {
-#ifdef ENABLE_PLUGINS
- XpdfSecurityHandler *hdlr;
- int i;
+#ifdef _WIN32
+void GlobalParams::setWin32ErrorInfo(const char *func, DWORD code) {
+ XpdfWin32ErrorInfo *errorInfo;
- lockGlobalParams;
- for (i = 0; i < securityHandlers->getLength(); ++i) {
- hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
- if (!strcasecmp(hdlr->name, name)) {
- unlockGlobalParams;
- return hdlr;
- }
+ if (tlsWin32ErrorInfo == TLS_OUT_OF_INDEXES) {
+ return;
}
- unlockGlobalParams;
-
- if (!loadPlugin("security", name)) {
- return NULL;
+ errorInfo = (XpdfWin32ErrorInfo *)TlsGetValue(tlsWin32ErrorInfo);
+ if (!errorInfo) {
+ errorInfo = new XpdfWin32ErrorInfo();
+ TlsSetValue(tlsWin32ErrorInfo, errorInfo);
}
-
- lockGlobalParams;
- for (i = 0; i < securityHandlers->getLength(); ++i) {
- hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
- if (!strcmp(hdlr->name, name)) {
- unlockGlobalParams;
- return hdlr;
- }
- }
- unlockGlobalParams;
-#endif
-
- return NULL;
+ errorInfo->func = func;
+ errorInfo->code = code;
}
-#ifdef ENABLE_PLUGINS
-//------------------------------------------------------------------------
-// plugins
-//------------------------------------------------------------------------
+XpdfWin32ErrorInfo *GlobalParams::getWin32ErrorInfo() {
+ XpdfWin32ErrorInfo *errorInfo;
-GBool GlobalParams::loadPlugin(char *type, char *name) {
- Plugin *plugin;
-
- if (!(plugin = Plugin::load(type, name))) {
- return gFalse;
+ if (tlsWin32ErrorInfo == TLS_OUT_OF_INDEXES) {
+ return NULL;
}
- lockGlobalParams;
- plugins->append(plugin);
- unlockGlobalParams;
- return gTrue;
+ errorInfo = (XpdfWin32ErrorInfo *)TlsGetValue(tlsWin32ErrorInfo);
+ if (!errorInfo) {
+ errorInfo = new XpdfWin32ErrorInfo();
+ TlsSetValue(tlsWin32ErrorInfo, errorInfo);
+ errorInfo->func = NULL;
+ errorInfo->code = 0;
+ }
+ return errorInfo;
}
-
-#endif // ENABLE_PLUGINS
+#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
index 6764d8431bf..69367cc4ca0 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/GlobalParams.h
@@ -19,6 +19,9 @@
#endif
#include <stdio.h>
+#ifdef _WIN32
+# include <windows.h>
+#endif
#include "gtypes.h"
#include "CharTypes.h"
@@ -76,9 +79,11 @@ enum PSLevel {
psLevel1,
psLevel1Sep,
psLevel2,
+ psLevel2Gray,
psLevel2Sep,
psLevel3,
- psLevel3Sep
+ psLevel3Gray,
+ psLevel3Sep,
};
//------------------------------------------------------------------------
@@ -91,6 +96,14 @@ enum EndOfLineKind {
//------------------------------------------------------------------------
+enum StrokeAdjustMode {
+ strokeAdjustOff,
+ strokeAdjustNormal,
+ strokeAdjustCAD
+};
+
+//------------------------------------------------------------------------
+
enum ScreenType {
screenUnset,
screenDispersed,
@@ -123,16 +136,17 @@ public:
#define xpdfKeyCodeReturn 0x1001
#define xpdfKeyCodeEnter 0x1002
#define xpdfKeyCodeBackspace 0x1003
-#define xpdfKeyCodeInsert 0x1004
-#define xpdfKeyCodeDelete 0x1005
-#define xpdfKeyCodeHome 0x1006
-#define xpdfKeyCodeEnd 0x1007
-#define xpdfKeyCodePgUp 0x1008
-#define xpdfKeyCodePgDn 0x1009
-#define xpdfKeyCodeLeft 0x100a
-#define xpdfKeyCodeRight 0x100b
-#define xpdfKeyCodeUp 0x100c
-#define xpdfKeyCodeDown 0x100d
+#define xpdfKeyCodeEsc 0x1004
+#define xpdfKeyCodeInsert 0x1005
+#define xpdfKeyCodeDelete 0x1006
+#define xpdfKeyCodeHome 0x1007
+#define xpdfKeyCodeEnd 0x1008
+#define xpdfKeyCodePgUp 0x1009
+#define xpdfKeyCodePgDn 0x100a
+#define xpdfKeyCodeLeft 0x100b
+#define xpdfKeyCodeRight 0x100c
+#define xpdfKeyCodeUp 0x100d
+#define xpdfKeyCodeDown 0x100e
#define xpdfKeyCodeF1 0x1100
#define xpdfKeyCodeF35 0x1122
#define xpdfKeyCodeMousePress1 0x2001
@@ -153,6 +167,15 @@ public:
#define xpdfKeyCodeMouseRelease7 0x2107
// ...
#define xpdfKeyCodeMouseRelease32 0x2120
+#define xpdfKeyCodeMouseClick1 0x2201
+#define xpdfKeyCodeMouseClick2 0x2202
+#define xpdfKeyCodeMouseClick3 0x2203
+#define xpdfKeyCodeMouseClick4 0x2204
+#define xpdfKeyCodeMouseClick5 0x2205
+#define xpdfKeyCodeMouseClick6 0x2206
+#define xpdfKeyCodeMouseClick7 0x2207
+// ...
+#define xpdfKeyCodeMouseClick32 0x2220
#define xpdfKeyModNone 0
#define xpdfKeyModShift (1 << 0)
#define xpdfKeyModCtrl (1 << 1)
@@ -171,6 +194,27 @@ public:
//------------------------------------------------------------------------
+class PopupMenuCmd {
+public:
+
+ GString *label; // label for display in the menu
+ GList *cmds; // list of commands [GString]
+
+ PopupMenuCmd(GString *labelA, GList *cmdsA);
+ ~PopupMenuCmd();
+};
+
+//------------------------------------------------------------------------
+
+#ifdef _WIN32
+struct XpdfWin32ErrorInfo {
+ const char *func; // last Win32 API function call to fail
+ DWORD code; // error code returned by that function
+};
+#endif
+
+//------------------------------------------------------------------------
+
class GlobalParams {
public:
@@ -180,8 +224,8 @@ public:
~GlobalParams();
- void setBaseDir(char *dir);
- void setupBaseFonts(char *dir);
+ void setBaseDir(const char *dir);
+ void setupBaseFonts(const char *dir);
void parseLine(char *buf, GString *fileName, int line);
@@ -231,18 +275,24 @@ public:
GBool getPSRasterMono();
int getPSRasterSliceSize();
GBool getPSAlwaysRasterize();
+ GBool getPSNeverRasterize();
GString *getTextEncodingName();
EndOfLineKind getTextEOL();
GBool getTextPageBreaks();
GBool getTextKeepTinyChars();
GString *getInitialZoom();
- GBool getContinuousView();
+ int getDefaultFitZoom();
+ GBool getInitialSidebarState();
+ int getMaxTileWidth();
+ int getMaxTileHeight();
+ int getTileCacheSize();
+ int getWorkerThreads();
GBool getEnableFreeType();
GBool getDisableFreeTypeHinting();
GBool getAntialias();
GBool getVectorAntialias();
GBool getAntialiasPrinting();
- GBool getStrokeAdjust();
+ StrokeAdjustMode getStrokeAdjust();
ScreenType getScreenType();
int getScreenSize();
int getScreenDotRadius();
@@ -250,16 +300,22 @@ public:
double getScreenBlackThreshold();
double getScreenWhiteThreshold();
double getMinLineWidth();
+ GBool getEnablePathSimplification();
GBool getDrawAnnotations();
+ GBool getDrawFormFields();
GBool getOverprintPreview() { return overprintPreview; }
+ GString *getPaperColor();
+ GString *getMatteColor();
+ GString *getFullScreenMatteColor();
GString *getLaunchCommand() { return launchCommand; }
- GString *getURLCommand() { return urlCommand; }
GString *getMovieCommand() { return movieCommand; }
GBool getMapNumericCharNames();
GBool getMapUnknownCharNames();
GBool getMapExtTrueTypeFontsViaUnicode();
GBool getEnableXFA();
GList *getKeyBinding(int code, int mods, int context);
+ int getNumPopupMenuCmds();
+ PopupMenuCmd *getPopupMenuCmd(int idx);
GBool getPrintCommands();
GBool getErrQuiet();
@@ -297,7 +353,6 @@ public:
void setTextPageBreaks(GBool pageBreaks);
void setTextKeepTinyChars(GBool keep);
void setInitialZoom(char *s);
- void setContinuousView(GBool cont);
GBool setEnableFreeType(char *s);
GBool setAntialias(char *s);
GBool setVectorAntialias(char *s);
@@ -307,6 +362,8 @@ public:
void setScreenGamma(double gamma);
void setScreenBlackThreshold(double thresh);
void setScreenWhiteThreshold(double thresh);
+ void setDrawFormFields(GBool draw);
+ void setOverprintPreview(GBool preview);
void setMapNumericCharNames(GBool map);
void setMapUnknownCharNames(GBool map);
void setMapExtTrueTypeFontsViaUnicode(GBool map);
@@ -314,10 +371,10 @@ public:
void setPrintCommands(GBool printCommandsA);
void setErrQuiet(GBool errQuietA);
- //----- security handlers
-
- void addSecurityHandler(XpdfSecurityHandler *handler);
- XpdfSecurityHandler *getSecurityHandler(char *name);
+#ifdef _WIN32
+ void setWin32ErrorInfo(const char *func, DWORD code);
+ XpdfWin32ErrorInfo *getWin32ErrorInfo();
+#endif
private:
@@ -343,6 +400,7 @@ private:
void parseTextEncoding(GList *tokens, GString *fileName, int line);
void parseTextEOL(GList *tokens, GString *fileName, int line);
void parseInitialZoom(GList *tokens, GString *fileName, int line);
+ void parseStrokeAdjust(GList *tokens, GString *fileName, int line);
void parseScreenType(GList *tokens, GString *fileName, int line);
void parseBind(GList *tokens, GString *fileName, int line);
void parseUnbind(GList *tokens, GString *fileName, int line);
@@ -350,19 +408,19 @@ private:
int *code, int *mods, int *context,
const char *cmdName,
GList *tokens, GString *fileName, int line);
+ void parsePopupMenuCmd(GList *tokens, GString *fileName, int line);
void parseCommand(const char *cmdName, GString **val,
GList *tokens, GString *fileName, int line);
void parseYesNo(const char *cmdName, GBool *flag,
GList *tokens, GString *fileName, int line);
GBool parseYesNo2(char *token, GBool *flag);
+ void parseColor(const char *cmdName, GString **val,
+ GList *tokens, GString *fileName, int line);
void parseInteger(const char *cmdName, int *val,
GList *tokens, GString *fileName, int line);
void parseFloat(const char *cmdName, double *val,
GList *tokens, GString *fileName, int line);
UnicodeMap *getUnicodeMap2(GString *encodingName);
-#ifdef ENABLE_PLUGINS
- GBool loadPlugin(char *type, char *name);
-#endif
//----- static tables
@@ -436,6 +494,7 @@ private:
int psRasterSliceSize; // maximum size (pixels) of PostScript
// rasterization slice
GBool psAlwaysRasterize; // force PostScript rasterization
+ GBool psNeverRasterize; // prevent PostScript rasterization
GString *textEncoding; // encoding (unicodeMap) to use for text
// output
EndOfLineKind textEOL; // type of EOL marker to use for text
@@ -443,13 +502,20 @@ private:
GBool textPageBreaks; // insert end-of-page markers?
GBool textKeepTinyChars; // keep all characters in text output
GString *initialZoom; // initial zoom level
- GBool continuousView; // continuous view mode
+ int defaultFitZoom; // default zoom factor if initialZoom is
+ // 'page' or 'width'.
+ GBool initialSidebarState; // initial sidebar state - open (true)
+ // or closed (false)
+ int maxTileWidth; // maximum rasterization tile width
+ int maxTileHeight; // maximum rasterization tile height
+ int tileCacheSize; // number of rasterization tiles in cache
+ int workerThreads; // number of rasterization worker threads
GBool enableFreeType; // FreeType enable flag
GBool disableFreeTypeHinting; // FreeType hinting disable flag
GBool antialias; // font anti-aliasing enable flag
GBool vectorAntialias; // vector anti-aliasing enable flag
GBool antialiasPrinting; // allow anti-aliasing when printing
- GBool strokeAdjust; // stroke adjustment enable flag
+ StrokeAdjustMode strokeAdjust; // stroke adjustment mode
ScreenType screenType; // halftone screen type
int screenSize; // screen matrix size
int screenDotRadius; // screen dot radius
@@ -457,10 +523,15 @@ private:
double screenBlackThreshold; // screen black clamping threshold
double screenWhiteThreshold; // screen white clamping threshold
double minLineWidth; // minimum line width
+ GBool // enable path simplification
+ enablePathSimplification;
GBool drawAnnotations; // draw annotations or not
+ GBool drawFormFields; // draw form fields or not
GBool overprintPreview; // enable overprint preview
+ GString *paperColor; // paper (page background) color
+ GString *matteColor; // matte (background outside of page) color
+ GString *fullScreenMatteColor; // matte color in full-screen mode
GString *launchCommand; // command executed for 'launch' links
- GString *urlCommand; // command executed for URL links
GString *movieCommand; // command executed for movie annotations
GBool mapNumericCharNames; // map numeric char names (from font subsets)?
GBool mapUnknownCharNames; // map unknown char names?
@@ -468,6 +539,7 @@ private:
// for external TrueType fonts?
GBool enableXFA; // enable XFA form rendering
GList *keyBindings; // key & mouse button bindings [KeyBinding]
+ GList *popupMenuCmds; // popup menu commands [PopupMenuCmd]
GBool printCommands; // print the drawing commands
GBool errQuiet; // suppress error messages?
@@ -476,17 +548,14 @@ private:
UnicodeMapCache *unicodeMapCache;
CMapCache *cMapCache;
-#ifdef ENABLE_PLUGINS
- GList *plugins; // list of plugins [Plugin]
- GList *securityHandlers; // list of loaded security handlers
- // [XpdfSecurityHandler]
-#endif
-
#if MULTITHREADED
GMutex mutex;
GMutex unicodeMapCacheMutex;
GMutex cMapCacheMutex;
#endif
+#ifdef _WIN32
+ DWORD tlsWin32ErrorInfo; // TLS index for error info
+#endif
};
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
index 6372e131e54..cfa15fe9edc 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.cc
@@ -29,6 +29,7 @@
#include <stdlib.h>
#include <png.h>
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "GList.h"
#include "SplashBitmap.h"
@@ -36,12 +37,6 @@
#include "TextOutputDev.h"
#include "SplashOutputDev.h"
#include "ErrorCodes.h"
-#if EVAL_MODE
-# include "SplashMath.h"
-# include "Splash.h"
-# include "BuiltinFontTables.h"
-# include "FontEncodingTables.h"
-#endif
#include "HTMLGen.h"
#ifdef _WIN32
@@ -74,6 +69,7 @@ static FontStyleTagInfo fontStyleTags[] = {
{"Bold", 4, gTrue, gFalse},
{"Italic", 6, gFalse, gTrue},
{"Oblique", 7, gFalse, gTrue},
+ {"Light", 5, gFalse, gFalse},
{NULL, 0, gFalse, gFalse}
};
@@ -159,69 +155,22 @@ privateUnicodeMap[privateUnicodeMapEnd - privateUnicodeMapStart + 1] = {
0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x0178
};
-//------------------------------------------------------------------------
-
-#if EVAL_MODE
-
-#define EVAL_MODE_MSG "XpdfHTML evaluation - www.glyphandcog.com"
+enum VerticalAlignment {
+ vertAlignBaseline,
+ vertAlignSub,
+ vertAlignSuper,
+ vertAlignTop
+};
-static void drawEvalModeMsg(SplashOutputDev *out) {
- BuiltinFont *bf;
- SplashFont *font;
- GString *fontName;
- char *msg;
- SplashCoord mat[4], ident[6];
- SplashCoord diag, size, textW, x, y;
- Gushort cw;
- int w, h, n, i;
-
- // get the Helvetica font info
- bf = builtinFontSubst[4];
-
- msg = EVAL_MODE_MSG;
- n = strlen(msg);
-
- w = out->getBitmap()->getWidth();
- h = out->getBitmap()->getHeight();
-
- ident[0] = 1; ident[1] = 0;
- ident[2] = 0; ident[3] = -1;
- ident[4] = 0; ident[5] = h;
- out->getSplash()->setMatrix(ident);
-
- diag = splashSqrt((SplashCoord)(w*w + h*h));
- size = diag / (0.67 * n);
- if (size < 8) {
- size = 8;
- }
- mat[0] = size * (SplashCoord)w / diag;
- mat[3] = mat[0];
- mat[1] = size * (SplashCoord)h / diag;
- mat[2] = -mat[1];
- fontName = new GString(bf->name);
- font = out->getFont(fontName, mat);
- delete fontName;
- if (!font) {
- return;
- }
+static const char *vertAlignNames[] = {
+ "baseline",
+ "sub",
+ "super",
+ "top"
+};
- textW = 0;
- for (i = 0; i < n; ++i) {
- bf->widths->getWidth(winAnsiEncoding[msg[i] & 0xff], &cw);
- textW += size * cw * 0.001;
- }
+//------------------------------------------------------------------------
- out->setFillColor(255, 0, 0);
- x = 0.5 * (diag - textW) * (SplashCoord)w / diag;
- y = 0.5 * (diag - textW) * (SplashCoord)h / diag;
- for (i = 0; i < n; ++i) {
- out->getSplash()->fillChar(x, y, msg[i], font);
- bf->widths->getWidth(winAnsiEncoding[msg[i] & 0xff], &cw);
- x += mat[0] * cw * 0.001;
- y += mat[1] * cw * 0.001;
- }
-}
-#endif
//------------------------------------------------------------------------
@@ -232,7 +181,9 @@ HTMLGen::HTMLGen(double backgroundResolutionA) {
ok = gTrue;
backgroundResolution = backgroundResolutionA;
+ zoom = 1.0;
drawInvisibleText = gTrue;
+ allTextInvisible = gFalse;
// set up the TextOutputDev
textOutControl.mode = textOutReadingOrder;
@@ -245,7 +196,6 @@ HTMLGen::HTMLGen(double backgroundResolutionA) {
// set up the SplashOutputDev
paperColor[0] = paperColor[1] = paperColor[2] = 0xff;
splashOut = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor);
- splashOut->setSkipText(gTrue, gFalse);
}
HTMLGen::~HTMLGen() {
@@ -302,26 +252,21 @@ int HTMLGen::convertPage(
Guchar *p;
double pageW, pageH;
TextPage *text;
- GList *fonts, *cols, *pars, *lines, *words;
- double *fontScales;
+ GList *cols, *pars, *lines, *words;
TextFontInfo *font;
TextColumn *col;
TextParagraph *par;
TextLine *line;
- TextWord *word0, *word1;
GString *s;
- double base, base1;
- int subSuper0, subSuper1;
- double r0, g0, b0, r1, g1, b1;
- int colIdx, parIdx, lineIdx, wordIdx;
- int y, i, u;
+ double base;
+ int primaryDir, spanDir;
+ int colIdx, parIdx, lineIdx, firstWordIdx, lastWordIdx;
+ int y, i;
// generate the background bitmap
+ splashOut->setSkipText(!allTextInvisible, gFalse);
doc->displayPage(splashOut, pg, backgroundResolution, backgroundResolution,
0, gFalse, gTrue, gFalse);
-#if EVAL_MODE
- drawEvalModeMsg(splashOut);
-#endif
bitmap = splashOut->getBitmap();
if (!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL)) ||
@@ -354,6 +299,7 @@ int HTMLGen::convertPage(
doc->displayPage(textOut, pg, 72, 72, 0, gFalse, gTrue, gFalse);
doc->processLinks(textOut, pg);
text = textOut->takeText();
+ primaryDir = text->primaryDirectionIsLR() ? 1 : -1;
// HTML header
pr(writeHTML, htmlStream, "<html>\n");
@@ -371,9 +317,18 @@ int HTMLGen::convertPage(
}
pr(writeHTML, htmlStream, "</style>\n");
pr(writeHTML, htmlStream, "</head>\n");
- pr(writeHTML, htmlStream, "<body onload=\"start()\">\n");
- pf(writeHTML, htmlStream, "<img id=\"background\" style=\"position:absolute; left:0px; top:0px;\" width=\"{0:d}\" height=\"{1:d}\" src=\"{2:s}\">\n",
- (int)pageW, (int)pageH, pngURL);
+ if (primaryDir >= 0) {
+ pr(writeHTML, htmlStream, "<body>\n");
+ } else {
+ pr(writeHTML, htmlStream, "<body dir=\"rtl\">\n");
+ }
+ if (primaryDir >= 0) {
+ pf(writeHTML, htmlStream, "<img id=\"background\" style=\"position:absolute; left:0px; top:0px;\" width=\"{0:d}\" height=\"{1:d}\" src=\"{2:s}\">\n",
+ (int)(pageW * zoom), (int)(pageH * zoom), pngURL);
+ } else {
+ pf(writeHTML, htmlStream, "<img id=\"background\" style=\"position:absolute; right:0px; top:0px;\" width=\"{0:d}\" height=\"{1:d}\" src=\"{2:s}\">\n",
+ (int)(pageW * zoom), (int)(pageH * zoom), pngURL);
+ }
// generate the HTML text
cols = text->makeColumns();
@@ -389,101 +344,32 @@ int HTMLGen::convertPage(
continue;
}
words = line->getWords();
- base = line->getBaseline();
+ if (lineIdx == 0 && par->hasDropCap() && words->getLength() >= 2) {
+ base = ((TextWord *)words->get(1))->getBaseline();
+ } else {
+ base = line->getBaseline();
+ }
s = new GString();
- word0 = NULL;
- subSuper0 = 0; // make gcc happy
- r0 = g0 = b0 = 0; // make gcc happy
- for (wordIdx = 0; wordIdx < words->getLength(); ++wordIdx) {
- word1 = (TextWord *)words->get(wordIdx);
- if (!drawInvisibleText && word1->isInvisible()) {
- continue;
- }
- word1->getColor(&r1, &g1, &b1);
- base1 = word1->getBaseline();
- if (base1 - base < -1) {
- subSuper1 = -1; // superscript
- } else if (base1 - base > 1) {
- subSuper1 = 1; // subscript
- } else {
- subSuper1 = 0;
- }
- if (!word0 ||
- word1->getFontInfo() != word0->getFontInfo() ||
- word1->getFontSize() != word0->getFontSize() ||
- subSuper1 != subSuper0 ||
- r1 != r0 || g1 != g0 || b1 != b0) {
- if (word0) {
- s->append("</span>");
- }
- for (i = 0; i < fonts->getLength(); ++i) {
- if (word1->getFontInfo() == (TextFontInfo *)fonts->get(i)) {
- break;
- }
- }
- s->appendf("<span id=\"f{0:d}\" style=\"font-size:{1:d}px;vertical-align:{2:s};color:#{3:02x}{4:02x}{5:02x};\">",
- i, (int)(fontScales[i] * word1->getFontSize()),
- subSuper1 < 0 ? "super"
- : subSuper1 > 0 ? "sub"
- : "baseline",
- (int)(r1 * 255), (int)(g1 * 255), (int)(b1 * 255));
- }
- for (i = 0; i < word1->getLength(); ++i) {
- u = word1->getChar(i);
- if (u >= privateUnicodeMapStart &&
- u <= privateUnicodeMapEnd &&
- privateUnicodeMap[u - privateUnicodeMapStart]) {
- u = privateUnicodeMap[u - privateUnicodeMapStart];
- }
- if (u <= 0x7f) {
- if (u == '&') {
- s->append("&amp;");
- } else if (u == '<') {
- s->append("&lt;");
- } else if (u == '>') {
- s->append("&gt;");
- } else {
- s->append((char)u);
- }
- } else if (u <= 0x7ff) {
- s->append((char)(0xc0 + (u >> 6)));
- s->append((char)(0x80 + (u & 0x3f)));
- } else if (u <= 0xffff) {
- s->append((char)0xe0 + (u >> 12));
- s->append((char)0x80 + ((u >> 6) & 0x3f));
- s->append((char)0x80 + (u & 0x3f));
- } else if (u <= 0x1fffff) {
- s->append((char)0xf0 + (u >> 18));
- s->append((char)0x80 + ((u >> 12) & 0x3f));
- s->append((char)0x80 + ((u >> 6) & 0x3f));
- s->append((char)0x80 + (u & 0x3f));
- } else if (u <= 0x3ffffff) {
- s->append((char)0xf8 + (u >> 24));
- s->append((char)0x80 + ((u >> 18) & 0x3f));
- s->append((char)0x80 + ((u >> 12) & 0x3f));
- s->append((char)0x80 + ((u >> 6) & 0x3f));
- s->append((char)0x80 + (u & 0x3f));
- } else if (u <= 0x7fffffff) {
- s->append((char)0xfc + (u >> 30));
- s->append((char)0x80 + ((u >> 24) & 0x3f));
- s->append((char)0x80 + ((u >> 18) & 0x3f));
- s->append((char)0x80 + ((u >> 12) & 0x3f));
- s->append((char)0x80 + ((u >> 6) & 0x3f));
- s->append((char)0x80 + (u & 0x3f));
- }
- }
- if (word1->getSpaceAfter()) {
- s->append(' ');
- }
- word0 = word1;
- subSuper0 = subSuper1;
- r0 = r1;
- g0 = g1;
- b0 = b1;
+ for (firstWordIdx = (primaryDir >= 0) ? 0 : words->getLength() - 1;
+ (primaryDir >= 0) ? firstWordIdx < words->getLength()
+ : firstWordIdx >= 0;
+ firstWordIdx = lastWordIdx + primaryDir) {
+ lastWordIdx = findDirSpan(words, firstWordIdx,
+ primaryDir, &spanDir);
+ appendSpans(words, firstWordIdx, lastWordIdx,
+ primaryDir, spanDir,
+ base, lineIdx == 0 && par->hasDropCap(),
+ s);
+ }
+ if (primaryDir >= 0) {
+ pf(writeHTML, htmlStream, "<div class=\"txt\" style=\"position:absolute; left:{0:d}px; top:{1:d}px;\">{2:t}</div>\n",
+ (int)(line->getXMin() * zoom),
+ (int)(line->getYMin() * zoom), s);
+ } else {
+ pf(writeHTML, htmlStream, "<div class=\"txt\" style=\"position:absolute; right:{0:d}px; top:{1:d}px;\">{2:t}</div>\n",
+ (int)((pageW - line->getXMax()) * zoom),
+ (int)(line->getYMin() * zoom), s);
}
- s->append("</span>");
- pf(writeHTML, htmlStream, "<div class=\"txt\" style=\"position:absolute; left:{0:d}px; top:{1:d}px;\">{2:t}</div>\n",
- (int)line->getXMin(), (int)line->getYMin(), s);
delete s;
}
}
@@ -499,6 +385,208 @@ int HTMLGen::convertPage(
return errNone;
}
+// Find a sequence of words, starting at <firstWordIdx>, that have the
+// same writing direction. Returns the index of the last word, and
+// sets *<spanDir> to the span direction.
+int HTMLGen::findDirSpan(GList *words, int firstWordIdx, int primaryDir,
+ int *spanDir) {
+ int dir0, dir1, nextWordIdx;
+
+ dir0 = ((TextWord *)words->get(firstWordIdx))->getDirection();
+ for (nextWordIdx = firstWordIdx + primaryDir;
+ (primaryDir >= 0) ? nextWordIdx < words->getLength()
+ : nextWordIdx >= 0;
+ nextWordIdx += primaryDir) {
+ dir1 = ((TextWord *)words->get(nextWordIdx))->getDirection();
+ if (dir0 == 0) {
+ dir0 = dir1;
+ } else if (dir1 != 0 && dir1 != dir0) {
+ break;
+ }
+ }
+
+ if (dir0 == 0) {
+ *spanDir = primaryDir;
+ } else {
+ *spanDir = dir0;
+ }
+
+ return nextWordIdx - primaryDir;
+}
+
+// Create HTML spans for words <firstWordIdx> .. <lastWordIdx>, and
+// append them to <s>.
+void HTMLGen::appendSpans(GList *words, int firstWordIdx, int lastWordIdx,
+ int primaryDir, int spanDir,
+ double base, GBool dropCapLine, GString *s) {
+ TextWord *word0, *word1;
+ VerticalAlignment vertAlign0, vertAlign1;
+ const char *dirTag;
+ Unicode u;
+ GBool invisible, sp;
+ double r0, g0, b0, r1, g1, b1;
+ double base1;
+ int wordIdx, t, i;
+
+ if (spanDir != primaryDir) {
+ t = firstWordIdx;
+ firstWordIdx = lastWordIdx;
+ lastWordIdx = t;
+ }
+
+ word0 = NULL;
+ vertAlign0 = vertAlignBaseline; // make gcc happy
+ r0 = g0 = b0 = 0; // make gcc happy
+ for (wordIdx = firstWordIdx;
+ (spanDir >= 0) ? wordIdx <= lastWordIdx : wordIdx >= lastWordIdx;
+ wordIdx += spanDir) {
+ word1 = (TextWord *)words->get(wordIdx);
+ invisible = allTextInvisible || word1->isInvisible();
+ if (!drawInvisibleText && invisible) {
+ continue;
+ }
+ word1->getColor(&r1, &g1, &b1);
+ base1 = word1->getBaseline();
+ if (dropCapLine) {
+ //~ this will fail if there are subscripts or superscripts in
+ //~ the first line of a paragraph with a drop cap
+ vertAlign1 = vertAlignTop;
+ } else if (base1 - base < -1) {
+ vertAlign1 = vertAlignSuper;
+ } else if (base1 - base > 1) {
+ vertAlign1 = vertAlignSub;
+ } else {
+ vertAlign1 = vertAlignBaseline;
+ }
+ if (!word0 ||
+ word1->getFontInfo() != word0->getFontInfo() ||
+ word1->getFontSize() != word0->getFontSize() ||
+ word1->isInvisible() != word0->isInvisible() ||
+ vertAlign1 != vertAlign0 ||
+ r1 != r0 || g1 != g0 || b1 != b0) {
+ if (word0) {
+ s->append("</span>");
+ }
+ for (i = 0; i < fonts->getLength(); ++i) {
+ if (word1->getFontInfo() == (TextFontInfo *)fonts->get(i)) {
+ break;
+ }
+ }
+ // we force spans to be LTR or RTL; this is a kludge, but it's
+ // far easier than implementing the full Unicode bidi algorithm
+ if (spanDir == primaryDir) {
+ dirTag = "";
+ } else if (spanDir < 0) {
+ dirTag = " dir=\"rtl\"";
+ } else {
+ dirTag = " dir=\"ltr\"";
+ }
+ s->appendf("<span id=\"f{0:d}\"{1:s} style=\"font-size:{2:d}px;vertical-align:{3:s};{4:s}color:rgba({5:d},{6:d},{7:d},{8:d});\">",
+ i,
+ dirTag,
+ (int)(fontScales[i] * word1->getFontSize() * zoom),
+ vertAlignNames[vertAlign1],
+ (dropCapLine && wordIdx == 0) ? "line-height:75%;" : "",
+ (int)(r1 * 255), (int)(g1 * 255), (int)(b1 * 255),
+ invisible ? 0 : 1);
+ }
+
+ // add a space before the word, if needed
+ // -- this only happens with the first word in a reverse section
+ if (spanDir != primaryDir && wordIdx == firstWordIdx) {
+ if (spanDir >= 0) {
+ if (wordIdx > 0) {
+ sp = ((TextWord *)words->get(wordIdx - 1))->getSpaceAfter();
+ } else {
+ sp = gFalse;
+ }
+ } else {
+ sp = word1->getSpaceAfter();
+ }
+ if (sp) {
+ s->append(' ');
+ }
+ }
+
+ for (i = (spanDir >= 0) ? 0 : word1->getLength() - 1;
+ (spanDir >= 0) ? i < word1->getLength() : i >= 0;
+ i += spanDir) {
+ u = word1->getChar(i);
+ if (u >= privateUnicodeMapStart &&
+ u <= privateUnicodeMapEnd &&
+ privateUnicodeMap[u - privateUnicodeMapStart]) {
+ u = privateUnicodeMap[u - privateUnicodeMapStart];
+ }
+ appendUTF8(u, s);
+ }
+
+ // add a space after the word, if needed
+ // -- there is never a space after the last word in a reverse
+ // section (this will be handled as a space after the last word
+ // in the previous primary-direction section)
+ if (spanDir != primaryDir && wordIdx == lastWordIdx) {
+ sp = gFalse;
+ } else if (spanDir >= 0) {
+ sp = word1->getSpaceAfter();
+ } else {
+ if (wordIdx > 0) {
+ sp = ((TextWord *)words->get(wordIdx - 1))->getSpaceAfter();
+ } else {
+ sp = gFalse;
+ }
+ }
+ if (sp) {
+ s->append(' ');
+ }
+
+ word0 = word1;
+ vertAlign0 = vertAlign1;
+ r0 = r1;
+ g0 = g1;
+ b0 = b1;
+ }
+ s->append("</span>");
+}
+
+void HTMLGen::appendUTF8(Unicode u, GString *s) {
+ if (u <= 0x7f) {
+ if (u == '&') {
+ s->append("&amp;");
+ } else if (u == '<') {
+ s->append("&lt;");
+ } else if (u == '>') {
+ s->append("&gt;");
+ } else {
+ s->append((char)u);
+ }
+ } else if (u <= 0x7ff) {
+ s->append((char)(0xc0 + (u >> 6)));
+ s->append((char)(0x80 + (u & 0x3f)));
+ } else if (u <= 0xffff) {
+ s->append((char)0xe0 + (u >> 12));
+ s->append((char)0x80 + ((u >> 6) & 0x3f));
+ s->append((char)0x80 + (u & 0x3f));
+ } else if (u <= 0x1fffff) {
+ s->append((char)0xf0 + (u >> 18));
+ s->append((char)0x80 + ((u >> 12) & 0x3f));
+ s->append((char)0x80 + ((u >> 6) & 0x3f));
+ s->append((char)0x80 + (u & 0x3f));
+ } else if (u <= 0x3ffffff) {
+ s->append((char)0xf8 + (u >> 24));
+ s->append((char)0x80 + ((u >> 18) & 0x3f));
+ s->append((char)0x80 + ((u >> 12) & 0x3f));
+ s->append((char)0x80 + ((u >> 6) & 0x3f));
+ s->append((char)0x80 + (u & 0x3f));
+ } else if (u <= 0x7fffffff) {
+ s->append((char)0xfc + (u >> 30));
+ s->append((char)0x80 + ((u >> 24) & 0x3f));
+ s->append((char)0x80 + ((u >> 18) & 0x3f));
+ s->append((char)0x80 + ((u >> 12) & 0x3f));
+ s->append((char)0x80 + ((u >> 6) & 0x3f));
+ s->append((char)0x80 + (u & 0x3f));
+ }
+}
+
GString *HTMLGen::getFontDefn(TextFontInfo *font, double *scale) {
GString *fontName;
char *fontName2;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
index 7271c67bc32..e870d8ef842 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/HTMLGen.h
@@ -35,10 +35,17 @@ public:
void setBackgroundResolution(double backgroundResolutionA)
{ backgroundResolution = backgroundResolutionA; }
+ double getZoom() { return zoom; }
+ void setZoom(double zoomA) { zoom = zoomA; }
+
GBool getDrawInvisibleText() { return drawInvisibleText; }
void setDrawInvisibleText(GBool drawInvisibleTextA)
{ drawInvisibleText = drawInvisibleTextA; }
+ GBool getAllTextInvisible() { return allTextInvisible; }
+ void setAllTextInvisible(GBool allTextInvisibleA)
+ { allTextInvisible = allTextInvisibleA; }
+
void startDoc(PDFDoc *docA);
int convertPage(int pg, const char *pngURL,
int (*writeHTML)(void *stream, const char *data, int size),
@@ -48,15 +55,26 @@ public:
private:
+ int findDirSpan(GList *words, int firstWordIdx, int primaryDir,
+ int *spanDir);
+ void appendSpans(GList *words, int firstWordIdx, int lastWordIdx,
+ int primaryDir, int spanDir,
+ double base, GBool dropCapLine, GString *s);
+ void appendUTF8(Unicode u, GString *s);
GString *getFontDefn(TextFontInfo *font, double *scale);
double backgroundResolution;
+ double zoom;
GBool drawInvisibleText;
+ GBool allTextInvisible;
PDFDoc *doc;
TextOutputDev *textOut;
SplashOutputDev *splashOut;
+ GList *fonts;
+ double *fontScales;
+
GBool ok;
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc
index 3f6b1a1d49f..2e9b1390db9 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.cc
@@ -16,7 +16,9 @@
#include <stdlib.h>
#include <stddef.h>
#include <ctype.h>
+#include <math.h>
#include "gmem.h"
+#include "gmempp.h"
#include "config.h"
#include "Error.h"
#include "GfxState.h"
@@ -24,11 +26,15 @@
#include "Stream.h"
#include "ImageOutputDev.h"
-ImageOutputDev::ImageOutputDev(char *fileRootA, GBool dumpJPEGA) {
+ImageOutputDev::ImageOutputDev(char *fileRootA, GBool dumpJPEGA,
+ GBool dumpRawA, GBool listA) {
fileRoot = copyString(fileRootA);
- fileName = (char *)gmalloc((int)strlen(fileRoot) + 20);
+ fileName = (char *)gmalloc((int)strlen(fileRoot) + 30);
dumpJPEG = dumpJPEGA;
+ dumpRaw = dumpRawA;
+ list = listA;
imgNum = 0;
+ curPageNum = 0;
ok = gTrue;
}
@@ -37,9 +43,14 @@ ImageOutputDev::~ImageOutputDev() {
gfree(fileRoot);
}
+void ImageOutputDev::startPage(int pageNum, GfxState *state) {
+ curPageNum = pageNum;
+}
+
void ImageOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
Object *strRef,
- int paintType, Dict *resDict,
+ int paintType, int tilingType,
+ Dict *resDict,
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
double xStep, double yStep) {
@@ -53,8 +64,32 @@ void ImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
char buf[4096];
int size, n, i;
+ // dump raw file
+ if (dumpRaw && !inlineImg) {
+
+ // open the image file
+ sprintf(fileName, "%s-%04d.%s",
+ fileRoot, imgNum, getRawFileExtension(str));
+ ++imgNum;
+ if (!(f = fopen(fileName, "wb"))) {
+ error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
+ return;
+ }
+
+ // initialize stream
+ str = getRawStream(str);
+ str->reset();
+
+ // copy the stream
+ while ((n = str->getBlock(buf, sizeof(buf))) > 0) {
+ fwrite(buf, 1, n, f);
+ }
+
+ str->close();
+ fclose(f);
+
// dump JPEG file
- if (dumpJPEG && str->getKind() == strDCT && !inlineImg) {
+ } else if (dumpJPEG && str->getKind() == strDCT && !inlineImg) {
// open the image file
sprintf(fileName, "%s-%04d.jpg", fileRoot, imgNum);
@@ -107,6 +142,10 @@ void ImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
str->close();
fclose(f);
}
+
+ if (list) {
+ writeImageInfo(width, height, state, NULL);
+ }
}
void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
@@ -114,19 +153,51 @@ void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
GfxImageColorMap *colorMap,
int *maskColors, GBool inlineImg,
GBool interpolate) {
+ GfxColorSpaceMode csMode;
FILE *f;
ImageStream *imgStr;
Guchar *p;
GfxRGB rgb;
+ GfxGray gray;
int x, y;
char buf[4096];
- int size, n, i;
+ int size, n, i, j;
+
+ csMode = colorMap->getColorSpace()->getMode();
+ if (csMode == csIndexed) {
+ csMode = ((GfxIndexedColorSpace *)colorMap->getColorSpace())
+ ->getBase()->getMode();
+ }
+
+ // dump raw file
+ if (dumpRaw && !inlineImg) {
+
+ // open the image file
+ sprintf(fileName, "%s-%04d.%s",
+ fileRoot, imgNum, getRawFileExtension(str));
+ ++imgNum;
+ if (!(f = fopen(fileName, "wb"))) {
+ error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
+ return;
+ }
+
+ // initialize stream
+ str = getRawStream(str);
+ str->reset();
+
+ // copy the stream
+ while ((n = str->getBlock(buf, sizeof(buf))) > 0) {
+ fwrite(buf, 1, n, f);
+ }
+
+ str->close();
+ fclose(f);
// dump JPEG file
- if (dumpJPEG && str->getKind() == strDCT &&
- (colorMap->getNumPixelComps() == 1 ||
- colorMap->getNumPixelComps() == 3) &&
- !inlineImg) {
+ } else if (dumpJPEG && str->getKind() == strDCT &&
+ (colorMap->getNumPixelComps() == 1 ||
+ colorMap->getNumPixelComps() == 3) &&
+ !inlineImg) {
// open the image file
sprintf(fileName, "%s-%04d.jpg", fileRoot, imgNum);
@@ -170,6 +241,9 @@ void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
while (size > 0) {
i = size < (int)sizeof(buf) ? size : (int)sizeof(buf);
n = str->getBlock(buf, i);
+ for (j = 0; j < n; ++j) {
+ buf[j] ^= 0xff;
+ }
fwrite(buf, 1, n, f);
if (n < i) {
break;
@@ -180,6 +254,48 @@ void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
str->close();
fclose(f);
+ // dump PGM file
+ } else if (colorMap->getNumPixelComps() == 1 &&
+ (csMode == csDeviceGray || csMode == csCalGray)) {
+
+ // open the image file and write the PGM header
+ sprintf(fileName, "%s-%04d.pgm", fileRoot, imgNum);
+ ++imgNum;
+ if (!(f = fopen(fileName, "wb"))) {
+ error(errIO, -1, "Couldn't open image file '{0:s}'", fileName);
+ return;
+ }
+ fprintf(f, "P5\n");
+ fprintf(f, "%d %d\n", width, height);
+ fprintf(f, "255\n");
+
+ // initialize stream
+ imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgStr->reset();
+
+ // for each line...
+ for (y = 0; y < height; ++y) {
+
+ // write the line
+ if ((p = imgStr->getLine())) {
+ for (x = 0; x < width; ++x) {
+ colorMap->getGray(p, &gray, state->getRenderingIntent());
+ fputc(colToByte(gray), f);
+ ++p;
+ }
+ } else {
+ for (x = 0; x < width; ++x) {
+ fputc(0, f);
+ }
+ }
+ }
+
+ imgStr->close();
+ delete imgStr;
+
+ fclose(f);
+
// dump PPM file
} else {
@@ -205,7 +321,7 @@ void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
// write the line
if ((p = imgStr->getLine())) {
for (x = 0; x < width; ++x) {
- colorMap->getRGB(p, &rgb);
+ colorMap->getRGB(p, &rgb, state->getRenderingIntent());
fputc(colToByte(rgb.r), f);
fputc(colToByte(rgb.g), f);
fputc(colToByte(rgb.b), f);
@@ -225,6 +341,10 @@ void ImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
fclose(f);
}
+
+ if (list) {
+ writeImageInfo(width, height, state, colorMap);
+ }
}
void ImageOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
@@ -246,9 +366,75 @@ void ImageOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
Stream *maskStr,
int maskWidth, int maskHeight,
GfxImageColorMap *maskColorMap,
- GBool interpolate) {
+ double *matte, GBool interpolate) {
drawImage(state, ref, str, width, height, colorMap,
NULL, gFalse, interpolate);
drawImage(state, ref, maskStr, maskWidth, maskHeight, maskColorMap,
NULL, gFalse, interpolate);
}
+
+Stream *ImageOutputDev::getRawStream(Stream *str) {
+ switch (str->getKind()) {
+ case strLZW:
+ case strRunLength:
+ case strCCITTFax:
+ case strDCT:
+ case strFlate:
+ case strJBIG2:
+ case strJPX:
+ return ((FilterStream *)str)->getNextStream();
+ default:
+ return str;
+ }
+}
+
+const char *ImageOutputDev::getRawFileExtension(Stream *str) {
+ switch (str->getKind()) {
+ case strLZW: return "lzw";
+ case strRunLength: return "rle";
+ case strCCITTFax: return "fax";
+ case strDCT: return "jpg";
+ case strFlate: return "flate";
+ case strJBIG2: return "jb2";
+ case strJPX: return "jpx";
+ default: return "unknown";
+ }
+}
+
+void ImageOutputDev::writeImageInfo(int width, int height, GfxState *state,
+ GfxImageColorMap *colorMap) {
+ const char *mode;
+ double hdpi, vdpi, x0, y0, x1, y1;
+ int bpc;
+
+ // this works for 0/90/180/270-degree rotations, along with
+ // horizontal/vertical flips
+ state->transformDelta(1, 0, &x0, &y0);
+ state->transformDelta(0, 1, &x1, &y1);
+ x0 = fabs(x0);
+ y0 = fabs(y0);
+ x1 = fabs(x1);
+ y1 = fabs(y1);
+ if (x0 > y0) {
+ hdpi = (72 * width) / x0;
+ vdpi = (72 * height) / y1;
+ } else {
+ hdpi = (72 * height) / x1;
+ vdpi = (72 * width) / y0;
+ }
+
+ if (colorMap) {
+ mode = GfxColorSpace::getColorSpaceModeName(
+ colorMap->getColorSpace()->getMode());
+ bpc = colorMap->getBits();
+ } else {
+ mode = NULL;
+ bpc = 1;
+ }
+
+ printf("%s: page=%d width=%d height=%d hdpi=%.2f vdpi=%.2f %s%s bpc=%d\n",
+ fileName, curPageNum, width, height, hdpi, vdpi,
+ mode ? "colorspace=" : "mask",
+ mode ? mode : "",
+ bpc);
+}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h
index 29846865773..3cdae45da66 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/ImageOutputDev.h
@@ -19,6 +19,7 @@
#include "gtypes.h"
#include "OutputDev.h"
+class GfxImageColorMap;
class GfxState;
//------------------------------------------------------------------------
@@ -30,9 +31,12 @@ public:
// Create an OutputDev which will write images to files named
// <fileRoot>-NNN.<type>. Normally, all images are written as PBM
- // (.pbm) or PPM (.ppm) files. If <dumpJPEG> is set, JPEG images are
- // written as JPEG (.jpg) files.
- ImageOutputDev(char *fileRootA, GBool dumpJPEGA);
+ // (.pbm) or PPM (.ppm) files. If <dumpJPEG> is set, JPEG images
+ // are written as JPEG (.jpg) files. If <dumpRaw> is set, all
+ // images are written in PDF-native formats. If <list> is set, a
+ // one-line summary will be written to stdout for each image.
+ ImageOutputDev(char *fileRootA, GBool dumpJPEGA, GBool dumpRawA,
+ GBool listA);
// Destructor.
virtual ~ImageOutputDev();
@@ -61,9 +65,12 @@ public:
// Does this device use drawChar() or drawString()?
virtual GBool useDrawChar() { return gFalse; }
+ //----- initialization and control
+ virtual void startPage(int pageNum, GfxState *state);
+
//----- path painting
virtual void tilingPatternFill(GfxState *state, Gfx *gfx, Object *strRef,
- int paintType, Dict *resDict,
+ int paintType, int tilingType, Dict *resDict,
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
double xStep, double yStep);
@@ -86,14 +93,22 @@ public:
Stream *maskStr,
int maskWidth, int maskHeight,
GfxImageColorMap *maskColorMap,
- GBool interpolate);
+ double *matte, GBool interpolate);
private:
+ Stream *getRawStream(Stream *str);
+ const char *getRawFileExtension(Stream *str);
+ void writeImageInfo(int width, int height, GfxState *state,
+ GfxImageColorMap *colorMap);
+
char *fileRoot; // root of output file names
char *fileName; // buffer for output file names
GBool dumpJPEG; // set to dump native JPEG files
+ GBool dumpRaw; // set to dump raw PDF-native image files
+ GBool list; // set to write image info to stdout
int imgNum; // current image number
+ int curPageNum; // current page number
GBool ok; // set up ok?
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc
index 92db3265ede..5bbad63d9e1 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JArithmeticDecoder.cc
@@ -12,6 +12,7 @@
#pragma implementation
#endif
+#include "gmempp.h"
#include "Object.h"
#include "Stream.h"
#include "JArithmeticDecoder.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
index 8588931c9fe..5e8bca71335 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.cc
@@ -14,6 +14,7 @@
#include <stdlib.h>
#include <limits.h>
+#include "gmempp.h"
#include "GList.h"
#include "Error.h"
#include "JArithmeticDecoder.h"
@@ -1195,6 +1196,10 @@ JBIG2Stream::~JBIG2Stream() {
delete str;
}
+Stream *JBIG2Stream::copy() {
+ return new JBIG2Stream(str->copy(), &globalsStream);
+}
+
void JBIG2Stream::reset() {
// read the globals stream
globalSegments = new GList();
@@ -1288,8 +1293,10 @@ void JBIG2Stream::readSegments() {
Guint *refSegs;
int c1, c2, c3;
Guint i;
+ GBool done;
- while (readULong(&segNum)) {
+ done = gFalse;
+ while (!done && readULong(&segNum)) {
// segment header flags
if (!readUByte(&segFlags)) {
@@ -1424,6 +1431,10 @@ void JBIG2Stream::readSegments() {
case 50:
readEndOfStripeSeg(segLength);
break;
+ case 51:
+ // end of file segment
+ done = gTrue;
+ break;
case 52:
readProfilesSeg(segLength);
break;
@@ -1557,7 +1568,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
if ((seg = findSegment(refSegs[i]))) {
if (seg->getType() == jbig2SegSymbolDict) {
j = ((JBIG2SymbolDict *)seg)->getSize();
- if (numInputSyms > UINT_MAX - j) {
+ if (j > INT_MAX || numInputSyms > INT_MAX - j) {
error(errSyntaxError, getPos(),
"Too many input symbols in JBIG2 symbol dictionary");
delete codeTables;
@@ -1569,7 +1580,7 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
}
}
}
- if (numInputSyms > UINT_MAX - numNewSyms) {
+ if (numNewSyms > INT_MAX || numInputSyms > INT_MAX - numNewSyms) {
error(errSyntaxError, getPos(),
"Too many input symbols in JBIG2 symbol dictionary");
delete codeTables;
@@ -1695,7 +1706,8 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
} else {
arithDecoder->decodeInt(&dh, iadhStats);
}
- if (dh < 0 && (Guint)-dh >= symHeight) {
+ if ((dh <= 0 && (Guint)-dh >= symHeight) ||
+ (dh > 0 && (Guint)dh > UINT_MAX - symHeight)) {
error(errSyntaxError, getPos(),
"Bad delta-height value in JBIG2 symbol dictionary");
goto syntaxError;
@@ -1718,7 +1730,8 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
break;
}
}
- if (dw < 0 && (Guint)-dw >= symWidth) {
+ if ((dw <= 0 && (Guint)-dw >= symWidth) ||
+ (dw > 0 && (Guint)dw > UINT_MAX - symWidth)) {
error(errSyntaxError, getPos(),
"Bad delta-height value in JBIG2 symbol dictionary");
goto syntaxError;
@@ -1800,6 +1813,11 @@ GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
// read the collective bitmap
if (huff && !refAgg) {
+ if (totalWidth == 0) {
+ error(errSyntaxError, getPos(),
+ "Invalid height class width in JBIG2 symbol dictionary");
+ goto syntaxError;
+ }
huffDecoder->decodeInt(&bmSize, huffBMSizeTable);
huffDecoder->reset();
if (bmSize == 0) {
@@ -1928,6 +1946,10 @@ void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
!readUByte(&segInfoFlags)) {
goto eofError;
}
+ if (w == 0 || h == 0) {
+ error(errSyntaxError, getPos(), "Bad size in JBIG2 text region segment");
+ return;
+ }
extCombOp = segInfoFlags & 7;
// rest of the text region header
@@ -2258,17 +2280,25 @@ JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
// decode delta-T
if (huff) {
- huffDecoder->decodeInt(&dt, huffDTTable);
+ if (!huffDecoder->decodeInt(&dt, huffDTTable)) {
+ break;
+ }
} else {
- arithDecoder->decodeInt(&dt, iadtStats);
+ if (!arithDecoder->decodeInt(&dt, iadtStats)) {
+ break;
+ }
}
t += dt * strips;
// first S value
if (huff) {
- huffDecoder->decodeInt(&ds, huffFSTable);
+ if (!huffDecoder->decodeInt(&ds, huffFSTable)) {
+ break;
+ }
} else {
- arithDecoder->decodeInt(&ds, iafsStats);
+ if (!arithDecoder->decodeInt(&ds, iafsStats)) {
+ break;
+ }
}
sFirst += ds;
s = sFirst;
@@ -2421,6 +2451,11 @@ void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
!readULong(&grayMax)) {
goto eofError;
}
+ if (patternW == 0 || patternH == 0) {
+ error(errSyntaxError, getPos(),
+ "Bad size in JBIG2 pattern dictionary segment");
+ return;
+ }
templ = (flags >> 1) & 3;
mmr = flags & 1;
@@ -2504,7 +2539,7 @@ void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
"Bad bitmap size in JBIG2 halftone segment");
return;
}
- if (gridH == 0 || gridW >= INT_MAX / gridH) {
+ if (gridW == 0 || gridH == 0 || gridW >= INT_MAX / gridH) {
error(errSyntaxError, getPos(), "Bad grid size in JBIG2 halftone segment");
return;
}
@@ -2642,6 +2677,11 @@ void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
!readUByte(&segInfoFlags)) {
goto eofError;
}
+ if (w == 0 || h == 0) {
+ error(errSyntaxError, getPos(),
+ "Bad bitmap size in JBIG2 generic region segment");
+ return;
+ }
extCombOp = segInfoFlags & 7;
// rest of the generic region segment header
@@ -2939,10 +2979,13 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
// convert the run lengths to a bitmap line
i = 0;
while (1) {
+ if (codingLine[i] >= w) {
+ break;
+ }
for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
bitmap->setPixel(x, y);
}
- if (codingLine[i+1] >= w || codingLine[i+2] >= w) {
+ if (codingLine[i+1] >= w) {
break;
}
i += 2;
@@ -3026,7 +3069,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
atx[2] >= -8 && atx[2] <= 8 &&
atx[3] >= -8 && atx[3] <= 8) {
// set up the adaptive context
- if (y + aty[0] >= 0) {
+ if (aty[0] <= 0 && y + aty[0] >= 0) {
atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
atBuf0 = *atP0++ << 8;
} else {
@@ -3034,7 +3077,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
atBuf0 = 0;
}
atShift0 = 15 - atx[0];
- if (y + aty[1] >= 0) {
+ if (aty[1] <= 0 && y + aty[1] >= 0) {
atP1 = bitmap->getDataPtr() + (y + aty[1]) * bitmap->getLineSize();
atBuf1 = *atP1++ << 8;
} else {
@@ -3042,7 +3085,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
atBuf1 = 0;
}
atShift1 = 15 - atx[1];
- if (y + aty[2] >= 0) {
+ if (aty[2] <= 0 && y + aty[2] >= 0) {
atP2 = bitmap->getDataPtr() + (y + aty[2]) * bitmap->getLineSize();
atBuf2 = *atP2++ << 8;
} else {
@@ -3050,7 +3093,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
atBuf2 = 0;
}
atShift2 = 15 - atx[2];
- if (y + aty[3] >= 0) {
+ if (aty[3] <= 0 && y + aty[3] >= 0) {
atP3 = bitmap->getDataPtr() + (y + aty[3]) * bitmap->getLineSize();
atBuf3 = *atP3++ << 8;
} else {
@@ -3192,7 +3235,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
if (atx[0] >= -8 && atx[0] <= 8) {
// set up the adaptive context
- if (y + aty[0] >= 0) {
+ if (aty[0] <= 0 && y + aty[0] >= 0) {
atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
atBuf0 = *atP0++ << 8;
} else {
@@ -3307,7 +3350,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
if (atx[0] >= -8 && atx[0] <= 8) {
// set up the adaptive context
- if (y + aty[0] >= 0) {
+ if (aty[0] <= 0 && y + aty[0] >= 0) {
atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
atBuf0 = *atP0++ << 8;
} else {
@@ -3415,7 +3458,7 @@ JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
if (atx[0] >= -8 && atx[0] <= 8) {
// set up the adaptive context
- if (y + aty[0] >= 0) {
+ if (aty[0] <= 0 && y + aty[0] >= 0) {
atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
atBuf0 = *atP0++ << 8;
} else {
@@ -3520,6 +3563,11 @@ void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
!readUByte(&segInfoFlags)) {
goto eofError;
}
+ if (w == 0 || h == 0) {
+ error(errSyntaxError, getPos(),
+ "Bad size in JBIG2 generic refinement region segment");
+ return;
+ }
extCombOp = segInfoFlags & 7;
// rest of the generic refinement region segment header
@@ -3780,6 +3828,10 @@ void JBIG2Stream::readPageInfoSeg(Guint length) {
!readUByte(&flags) || !readUWord(&striping)) {
goto eofError;
}
+ if (pageW == 0 || pageH == 0 || pageW > INT_MAX / pageW) {
+ error(errSyntaxError, getPos(), "Bad page size in JBIG2 stream");
+ return;
+ }
pageDefPixel = (flags >> 2) & 1;
defCombOp = (flags >> 3) & 3;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
index 660f5827f31..17181d72038 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JBIG2Stream.h
@@ -35,6 +35,7 @@ public:
JBIG2Stream(Stream *strA, Object *globalsStreamA);
virtual ~JBIG2Stream();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strJBIG2; }
virtual void reset();
virtual void close();
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
index 7e2bc6b4c6d..90a52c455b8 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.cc
@@ -14,6 +14,7 @@
#include <limits.h>
#include "gmem.h"
+#include "gmempp.h"
#include "Error.h"
#include "JArithmeticDecoder.h"
#include "JPXStream.h"
@@ -264,6 +265,10 @@ JPXStream::~JPXStream() {
delete bufStr;
}
+Stream *JPXStream::copy() {
+ return new JPXStream(str->copy());
+}
+
void JPXStream::reset() {
bufStr->reset();
if (readBoxes() == jpxDecodeFatalError) {
@@ -405,7 +410,7 @@ void JPXStream::fillReadBuf() {
GBool eol;
do {
- if (curY >= img.ySizeR) {
+ if (curY >= (img.ySize >> reduction)) {
return;
}
tileIdx = ((curY - img.yTileOffsetR) / img.yTileSizeR) * img.nXTiles
@@ -434,7 +439,7 @@ void JPXStream::fillReadBuf() {
if (++curComp == (Guint)(havePalette ? palette.nComps : img.nComps)) {
#endif
curComp = 0;
- if (++curX == img.xSizeR) {
+ if (++curX == (img.xSize >> reduction)) {
curX = img.xOffsetR;
++curY;
eol = gTrue;
@@ -582,11 +587,13 @@ void JPXStream::getImageParams2(int *bitsPerComponent,
JPXDecodeResult JPXStream::readBoxes() {
JPXDecodeResult result;
+ GBool haveCodestream;
Guint boxType, boxLen, dataLen;
Guint bpc1, compression, unknownColorspace, ipr;
Guint i, j;
haveImgHdr = gFalse;
+ haveCodestream = gFalse;
// check for a naked JPEG 2000 codestream (without the JP2/JPX
// wrapper) -- this appears to be a violation of the PDF spec, but
@@ -746,12 +753,13 @@ JPXDecodeResult JPXStream::readBoxes() {
if ((result = readCodestream(dataLen)) != jpxDecodeOk) {
return result;
}
+ haveCodestream = gTrue;
break;
default:
cover(16);
if (bufStr->discardChars(dataLen) != dataLen) {
error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
- return jpxDecodeFatalError;
+ return haveCodestream ? jpxDecodeNonFatalError : jpxDecodeFatalError;
}
break;
}
@@ -937,14 +945,14 @@ JPXDecodeResult JPXStream::readCodestream(Guint len) {
error(errSyntaxError, getPos(), "Error in JPX SIZ marker segment");
return jpxDecodeFatalError;
}
- img.xSizeR = img.xSize >> reduction;
- img.ySizeR = img.ySize >> reduction;
- img.xOffsetR = img.xOffset >> reduction;
- img.yOffsetR = img.yOffset >> reduction;
- img.xTileSizeR = img.xTileSize >> reduction;
- img.yTileSizeR = img.yTileSize >> reduction;
- img.xTileOffsetR = img.xTileOffset >> reduction;
- img.yTileOffsetR = img.yTileOffset >> reduction;
+ img.xSizeR = jpxCeilDivPow2(img.xSize, reduction);
+ 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)
@@ -1916,10 +1924,8 @@ GBool JPXStream::readTilePart() {
tileComp->y1 = jpxCeilDiv(tile->y1, tileComp->vSep);
tileComp->cbW = 1 << tileComp->codeBlockW;
tileComp->cbH = 1 << tileComp->codeBlockH;
- tileComp->w = (tileComp->x1 - tileComp->x0 + (1 << reduction) - 1)
- >> reduction;
- tileComp->h = (tileComp->y1 - tileComp->y0 + (1 << reduction) - 1)
- >> reduction;
+ tileComp->w = jpxCeilDivPow2(tileComp->x1 - tileComp->x0, reduction);
+ tileComp->h = jpxCeilDivPow2(tileComp->y1 - tileComp->y0, reduction);
tileComp->data = (int *)gmallocn(tileComp->w * tileComp->h, sizeof(int));
if (tileComp->x1 - tileComp->x0 > tileComp->y1 - tileComp->y0) {
n = tileComp->x1 - tileComp->x0;
@@ -1940,6 +1946,8 @@ GBool JPXStream::readTilePart() {
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];
} else {
resLevel->bx0[0] = jpxCeilDivPow2(tileComp->x0 - (1 << (k-1)), k);
resLevel->by0[0] = resLevel->y0;
@@ -1953,6 +1961,12 @@ 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->by0[0] == resLevel->by1[0]) &&
+ (resLevel->bx0[1] == resLevel->bx1[1] ||
+ resLevel->by0[1] == resLevel->by1[1]) &&
+ (resLevel->bx0[2] == resLevel->bx1[2] ||
+ resLevel->by0[2] == resLevel->by1[2]);
}
resLevel->precincts = (JPXPrecinct *)gmallocn(1, sizeof(JPXPrecinct));
for (pre = 0; pre < 1; ++pre) {
@@ -2114,6 +2128,10 @@ GBool JPXStream::readTilePartData(Guint tileIdx,
resLevel = &tileComp->resLevels[tile->res];
precinct = &resLevel->precincts[tile->precinct];
+ if (resLevel->empty) {
+ goto nextPacket;
+ }
+
//----- packet header
// setup
@@ -2343,6 +2361,7 @@ GBool JPXStream::readTilePartData(Guint tileIdx,
//----- next packet
+ nextPacket:
switch (tile->progOrder) {
case 0: // layer, resolution level, component, precinct
cover(58);
@@ -2873,11 +2892,31 @@ void JPXStream::inverseTransformLevel(JPXTileComp *tileComp,
Guint nx1, nx2, ny1, ny2, offset;
Guint x, y, sb, cbX, cbY;
- //----- fixed-point adjustment and dequantization
-
qStyle = tileComp->quantStyle & 0x1f;
guard = (tileComp->quantStyle >> 5) & 7;
precinct = &resLevel->precincts[0];
+
+ //----- compute subband bounds
+
+ // 0 nx1 nx2
+ // | | |
+ // v v v
+ // +----+----+
+ // | LL | HL | <- 0
+ // +----+----+
+ // | LH | HH | <- ny1
+ // +----+----+
+ // <- ny2
+ nx1 = precinct->subbands[1].x1 - precinct->subbands[1].x0;
+ nx2 = nx1 + precinct->subbands[0].x1 - precinct->subbands[0].x0;
+ ny1 = precinct->subbands[0].y1 - precinct->subbands[0].y0;
+ ny2 = ny1 + precinct->subbands[1].y1 - precinct->subbands[1].y0;
+ if (nx2 == 0 || ny2 == 0) {
+ return;
+ }
+
+ //----- fixed-point adjustment and dequantization
+
for (sb = 0; sb < 3; ++sb) {
// i-quant parameters
@@ -2946,21 +2985,6 @@ void JPXStream::inverseTransformLevel(JPXTileComp *tileComp,
//----- inverse transform
- // compute the subband bounds:
- // 0 nx1 nx2
- // | | |
- // v v v
- // +----+----+
- // | LL | HL | <- 0
- // +----+----+
- // | LH | HH | <- ny1
- // +----+----+
- // <- ny2
- nx1 = precinct->subbands[1].x1 - precinct->subbands[1].x0;
- nx2 = nx1 + precinct->subbands[0].x1 - precinct->subbands[0].x0;
- ny1 = precinct->subbands[0].y1 - precinct->subbands[0].y0;
- ny2 = ny1 + precinct->subbands[1].y1 - precinct->subbands[1].y0;
-
// horizontal (row) transforms
if (r == tileComp->nDecompLevels) {
offset = 3 + (tileComp->x0 & 1);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
index d00a55e34e3..f1a66f5310d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/JPXStream.h
@@ -170,6 +170,7 @@ struct JPXResLevel {
Guint x0, y0, x1, y1; // bounds of the tile-comp (for this res level)
Guint bx0[3], by0[3], // subband bounds
bx1[3], by1[3];
+ GBool empty; // true if all subbands are zero width or height
//---- children
JPXPrecinct *precincts; // the precincts
@@ -280,6 +281,7 @@ public:
JPXStream(Stream *strA);
virtual ~JPXStream();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strJPX; }
virtual void reset();
virtual void close();
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc
index 058975691b1..d46303c6579 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc
@@ -16,6 +16,7 @@
#include <stddef.h>
#include <string.h>
#include <ctype.h>
+#include "gmempp.h"
#include "Lexer.h"
#include "Error.h"
@@ -111,7 +112,7 @@ int Lexer::lookChar() {
Object *Lexer::getObj(Object *obj) {
char *p;
int c, c2;
- GBool comment, neg, done;
+ GBool comment, neg, doubleMinus, done;
int numParen;
int xi;
double xf, scale;
@@ -141,10 +142,31 @@ Object *Lexer::getObj(Object *obj) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '-': case '.':
+ // Adobe's number lexer has some "interesting" behavior:
+ // "--123" is interpreted as 0
+ // "--123.4" is interpreted as -123.4 [I've seen this in the wild]
+ // "50-100" is interpreted as 50 [I've seen this in the wild]
+ // "50--100" is interpreted as 50
+ // "50-100.0" is an error -- but older versions of Acrobat may
+ // have interpreted it as 50100.0 (?)
+ // "50--100.0" is an error -- but older versions of Acrobat may
+ // have interpreted it as 50100.0 (?)
+ // "50.0-100" is interpreted as 50.0 (or maybe 50.0100?)
+ // "50.0--100" is interpreted as 50.0 (or maybe 50.0100?)
+ // "-50-100" is interpreted as -50
+ // "-" is interpreted as 0
+ // "-." is interpreted as 0.0
neg = gFalse;
+ doubleMinus = gFalse;
xf = xi = 0;
if (c == '-') {
neg = gTrue;
+ if (lookChar() == '-') {
+ doubleMinus = gTrue;
+ do {
+ getChar();
+ } while (lookChar() == '-');
+ }
} else if (c == '.') {
goto doReal;
} else {
@@ -163,9 +185,15 @@ Object *Lexer::getObj(Object *obj) {
break;
}
}
+ while ((c = lookChar()) == '-' || isdigit(c)) {
+ getChar();
+ }
if (neg) {
xi = -xi;
}
+ if (doubleMinus) {
+ xi = 0;
+ }
obj->initInt(xi);
break;
doReal:
@@ -173,8 +201,6 @@ Object *Lexer::getObj(Object *obj) {
while (1) {
c = lookChar();
if (c == '-') {
- // ignore minus signs in the middle of numbers to match
- // Adobe's behavior
error(errSyntaxWarning, getPos(), "Badly formatted number");
getChar();
continue;
@@ -186,6 +212,9 @@ Object *Lexer::getObj(Object *obj) {
xf = xf + scale * (c - '0');
scale *= 0.1;
}
+ while ((c = lookChar()) == '-' || isdigit(c)) {
+ getChar();
+ }
if (neg) {
xf = -xf;
}
@@ -321,20 +350,22 @@ Object *Lexer::getObj(Object *obj) {
} else if (c2 >= 'a' && c2 <= 'f') {
c = c2 - 'a' + 10;
} else {
+ error(errSyntaxError, getPos(), "Invalid hex escape in name");
goto notEscChar;
}
getChar();
- c <<= 4;
- c2 = getChar();
+ c2 = lookChar();
if (c2 >= '0' && c2 <= '9') {
- c += c2 - '0';
+ c = (c << 4) + (c2 - '0');
} else if (c2 >= 'A' && c2 <= 'F') {
- c += c2 - 'A' + 10;
+ c = (c << 4) + (c2 - 'A' + 10);
} else if (c2 >= 'a' && c2 <= 'f') {
- c += c2 - 'a' + 10;
+ c = (c << 4) + (c2 - 'a' + 10);
} else {
- error(errSyntaxError, getPos(), "Illegal digit in hex char in name");
+ error(errSyntaxError, getPos(), "Invalid hex escape in name");
+ goto notEscChar;
}
+ getChar();
}
notEscChar:
// the PDF spec claims that names are limited to 127 chars, but
@@ -496,6 +527,10 @@ void Lexer::skipToNextLine() {
}
}
+void Lexer::skipToEOF() {
+ while (getChar() != EOF) ;
+}
+
GBool Lexer::isSpace(int c) {
return c >= 0 && c <= 0xff && specialChars[c] == 1;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.h
index 3f466898575..d481c2c5a2b 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.h
@@ -46,9 +46,15 @@ public:
// Skip to the beginning of the next line in the input stream.
void skipToNextLine();
+ // Skip to the end of the input stream.
+ void skipToEOF();
+
// Skip over one character.
void skipChar() { getChar(); }
+ // Get stream index (for arrays of streams).
+ int getStreamIndex() { return strPtr; }
+
// Get stream.
Stream *getStream()
{ return curStr.isNone() ? (Stream *)NULL : curStr.getStream(); }
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc
index 86a3c417e45..900f79ddf85 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Link.cc
@@ -15,6 +15,7 @@
#include <stddef.h>
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "Error.h"
#include "Object.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Makefile.dep b/Build/source/libs/xpdf/xpdf-src/xpdf/Makefile.dep
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Makefile.dep
+++ /dev/null
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Makefile.in b/Build/source/libs/xpdf/xpdf-src/xpdf/Makefile.in
deleted file mode 100644
index de3e6766e60..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Makefile.in
+++ /dev/null
@@ -1,687 +0,0 @@
-#========================================================================
-#
-# Xpdf Makefile
-#
-# Copyright 1996-2003 Glyph & Cog, LLC
-#
-#========================================================================
-
-SHELL = /bin/sh
-
-prefix = @prefix@
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-GOOSRCDIR = $(srcdir)/../goo
-GOOLIBDIR = ../goo
-FOFISRCDIR = $(srcdir)/../fofi
-FOFILIBDIR = ../fofi
-SPLASHSRCDIR = $(srcdir)/../splash
-SPLASHLIBDIR = ../splash
-
-CXXFLAGS = @CXXFLAGS@ @DEFS@ -I.. -I$(srcdir)/.. -I$(GOOSRCDIR) -I$(FOFISRCDIR) -I$(SPLASHSRCDIR) -I$(srcdir) @freetype2_CFLAGS@ @Sgm_CFLAGS@ @Xm_CFLAGS@ @Xt_CFLAGS@ @Xp_CFLAGS@ @Xext_CFLAGS@ @Xpm_CFLAGS@ @libpng_CFLAGS@ @libpaper_CFLAGS@ @X_CFLAGS@ @EXTRA_CFLAGS@
-
-LDFLAGS = @LDFLAGS@
-
-FTLIBS = @freetype2_LIBS@ -lz
-
-XLIBS = @Sgm_LIBS@ @Xm_LIBS@ @Xt_LIBS@ @Xp_LIBS@ @Xext_LIBS@ @Xpm_LIBS@ @X_PRE_LIBS@ @X_LIBS@ -lX11 @X_EXTRA_LIBS@
-
-PNGLIBS = @libpng_LIBS@
-
-SPLASHLIBS = -L$(SPLASHLIBDIR) -lsplash
-
-OTHERLIBS = @LIBS@ @libpaper_LIBS@ @EXTRA_LIBS@ \
- -L$(FOFILIBDIR) -lfofi \
- -L$(GOOLIBDIR) -lGoo
-
-CXX = @CXX@
-
-LIBPREFIX = @LIBPREFIX@
-EXE = @EXE@
-
-#------------------------------------------------------------------------
-
-.SUFFIXES: .cc
-
-.cc.o:
- $(CXX) $(CXXFLAGS) -c $<
-
-#------------------------------------------------------------------------
-
-CXX_SRC = \
- $(srcdir)/AcroForm.cc \
- $(srcdir)/Annot.cc \
- $(srcdir)/Array.cc \
- $(srcdir)/BuiltinFont.cc \
- $(srcdir)/BuiltinFontTables.cc \
- $(srcdir)/CMap.cc \
- $(srcdir)/Catalog.cc \
- $(srcdir)/CharCodeToUnicode.cc \
- $(srcdir)/CoreOutputDev.cc \
- $(srcdir)/Decrypt.cc \
- $(srcdir)/Dict.cc \
- $(srcdir)/Error.cc \
- $(srcdir)/FontEncodingTables.cc \
- $(srcdir)/Form.cc \
- $(srcdir)/Function.cc \
- $(srcdir)/Gfx.cc \
- $(srcdir)/GfxFont.cc \
- $(srcdir)/GfxState.cc \
- $(srcdir)/GlobalParams.cc \
- $(srcdir)/HTMLGen.cc \
- $(srcdir)/ImageOutputDev.cc \
- $(srcdir)/JArithmeticDecoder.cc \
- $(srcdir)/JBIG2Stream.cc \
- $(srcdir)/JPXStream.cc \
- $(srcdir)/Lexer.cc \
- $(srcdir)/Link.cc \
- $(srcdir)/NameToCharCode.cc \
- $(srcdir)/Object.cc \
- $(srcdir)/OptionalContent.cc \
- $(srcdir)/Outline.cc \
- $(srcdir)/OutputDev.cc \
- $(srcdir)/PDFCore.cc \
- $(srcdir)/PDFDoc.cc \
- $(srcdir)/PDFDocEncoding.cc \
- $(srcdir)/PSOutputDev.cc \
- $(srcdir)/PSTokenizer.cc \
- $(srcdir)/Page.cc \
- $(srcdir)/Parser.cc \
- $(srcdir)/PreScanOutputDev.cc \
- $(srcdir)/SecurityHandler.cc \
- $(srcdir)/SplashOutputDev.cc \
- $(srcdir)/Stream.cc \
- $(srcdir)/TextOutputDev.cc \
- $(srcdir)/TextString.cc \
- $(srcdir)/UnicodeMap.cc \
- $(srcdir)/UnicodeTypeTable.cc \
- $(srcdir)/XFAForm.cc \
- $(srcdir)/XPDFApp.cc \
- $(srcdir)/XPDFCore.cc \
- $(srcdir)/XPDFTree.cc \
- $(srcdir)/XPDFViewer.cc \
- $(srcdir)/XpdfPluginAPI.cc \
- $(srcdir)/XRef.cc \
- $(srcdir)/Zoox.cc \
- $(srcdir)/pdftops.cc \
- $(srcdir)/pdftotext.cc \
- $(srcdir)/pdftohtml.cc \
- $(srcdir)/pdfinfo.cc \
- $(srcdir)/pdffonts.cc \
- $(srcdir)/pdfdetach.cc \
- $(srcdir)/pdftoppm.cc \
- $(srcdir)/pdftopng.cc \
- $(srcdir)/pdfimages.cc \
- $(srcdir)/xpdf.cc
-
-#------------------------------------------------------------------------
-
-all: xpdf$(EXE) pdftops$(EXE) pdftotext$(EXE) pdftohtml$(EXE) \
- pdfinfo$(EXE) pdffonts$(EXE) pdfdetach$(EXE) pdftoppm$(EXE) \
- pdftopng$(EXE) pdfimages$(EXE)
-
-all-no-x: pdftops$(EXE) pdftotext$(EXE) pdftohtml$(EXE) pdfinfo$(EXE) \
- pdffonts$(EXE) pdfdetach$(EXE) pdfimages$(EXE)
-
-#------------------------------------------------------------------------
-
-XPDF_OBJS = \
- AcroForm.o \
- Annot.o \
- Array.o \
- BuiltinFont.o \
- BuiltinFontTables.o \
- Catalog.o \
- CharCodeToUnicode.o \
- CMap.o \
- CoreOutputDev.o \
- Decrypt.o \
- Dict.o \
- Error.o \
- FontEncodingTables.o \
- Form.o \
- Function.o \
- Gfx.o \
- GfxFont.o \
- GfxState.o \
- GlobalParams.o \
- JArithmeticDecoder.o \
- JBIG2Stream.o \
- JPXStream.o \
- Lexer.o \
- Link.o \
- NameToCharCode.o \
- Object.o \
- OptionalContent.o \
- Outline.o \
- OutputDev.o \
- Page.o \
- Parser.o \
- PDFCore.o \
- PDFDoc.o \
- PDFDocEncoding.o \
- PreScanOutputDev.o \
- PSOutputDev.o \
- PSTokenizer.o \
- SecurityHandler.o \
- SplashOutputDev.o \
- Stream.o \
- TextOutputDev.o \
- TextString.o \
- UnicodeMap.o \
- UnicodeTypeTable.o \
- XFAForm.o \
- XPDFApp.o \
- XPDFCore.o \
- XPDFTree.o \
- XPDFViewer.o \
- XpdfPluginAPI.o \
- XRef.o \
- Zoox.o \
- xpdf.o
-XPDF_LIBS = -L$(GOOLIBDIR) -lGoo $(SPLASHLIBS) $(FTLIBS) \
- $(XLIBS) $(OTHERLIBS) -lm
-
-xpdf$(EXE): $(XPDF_OBJS) $(GOOLIBDIR)/$(LIBPREFIX)Goo.a
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o xpdf$(EXE) $(XPDF_OBJS) $(XPDF_LIBS)
-
-#------------------------------------------------------------------------
-
-PDFTOPS_OBJS = \
- AcroForm.o \
- Annot.o \
- Array.o \
- BuiltinFont.o \
- BuiltinFontTables.o \
- Catalog.o \
- CharCodeToUnicode.o \
- CMap.o \
- Decrypt.o \
- Dict.o \
- Error.o \
- FontEncodingTables.o \
- Form.o \
- Function.o \
- Gfx.o \
- GfxFont.o \
- GfxState.o \
- GlobalParams.o \
- JArithmeticDecoder.o \
- JBIG2Stream.o \
- JPXStream.o \
- Lexer.o \
- Link.o \
- NameToCharCode.o \
- OptionalContent.o \
- Outline.o \
- Object.o \
- OutputDev.o \
- Page.o \
- Parser.o \
- PDFDoc.o \
- PDFDocEncoding.o \
- PreScanOutputDev.o \
- PSOutputDev.o \
- PSTokenizer.o \
- SecurityHandler.o \
- SplashOutputDev.o \
- Stream.o \
- TextString.o \
- UnicodeMap.o \
- XFAForm.o \
- XpdfPluginAPI.o \
- XRef.o \
- Zoox.o \
- pdftops.o
-PDFTOPS_LIBS = -L$(GOOLIBDIR) -lGoo $(SPLASHLIBS) $(FTLIBS) \
- $(OTHERLIBS) -lm
-
-pdftops$(EXE): $(PDFTOPS_OBJS) $(GOOLIBDIR)/$(LIBPREFIX)Goo.a
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o pdftops$(EXE) $(PDFTOPS_OBJS) \
- $(PDFTOPS_LIBS)
-
-#------------------------------------------------------------------------
-
-PDFTOTEXT_OBJS = \
- AcroForm.o \
- Annot.o \
- Array.o \
- BuiltinFont.o \
- BuiltinFontTables.o \
- Catalog.o \
- CharCodeToUnicode.o \
- CMap.o \
- Decrypt.o \
- Dict.o \
- Error.o \
- FontEncodingTables.o \
- Form.o \
- Function.o \
- Gfx.o \
- GfxFont.o \
- GfxState.o \
- GlobalParams.o \
- JArithmeticDecoder.o \
- JBIG2Stream.o \
- JPXStream.o \
- Lexer.o \
- Link.o \
- NameToCharCode.o \
- Object.o \
- OptionalContent.o \
- Outline.o \
- OutputDev.o \
- Page.o \
- Parser.o \
- PDFDoc.o \
- PDFDocEncoding.o \
- PSTokenizer.o \
- SecurityHandler.o \
- Stream.o \
- TextOutputDev.o \
- TextString.o \
- UnicodeMap.o \
- UnicodeTypeTable.o \
- XFAForm.o \
- XpdfPluginAPI.o \
- XRef.o \
- Zoox.o \
- pdftotext.o
-PDFTOTEXT_LIBS = -L$(GOOLIBDIR) -lGoo $(OTHERLIBS) -lm
-
-pdftotext$(EXE): $(PDFTOTEXT_OBJS) $(GOOLIBDIR)/$(LIBPREFIX)Goo.a
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o pdftotext$(EXE) $(PDFTOTEXT_OBJS) \
- $(PDFTOTEXT_LIBS)
-
-#------------------------------------------------------------------------
-
-PDFTOHTML_OBJS = \
- AcroForm.o \
- Annot.o \
- Array.o \
- BuiltinFont.o \
- BuiltinFontTables.o \
- Catalog.o \
- CharCodeToUnicode.o \
- CMap.o \
- Decrypt.o \
- Dict.o \
- Error.o \
- FontEncodingTables.o \
- Form.o \
- Function.o \
- Gfx.o \
- GfxFont.o \
- GfxState.o \
- GlobalParams.o \
- HTMLGen.o \
- JArithmeticDecoder.o \
- JBIG2Stream.o \
- JPXStream.o \
- Lexer.o \
- Link.o \
- NameToCharCode.o \
- Object.o \
- OptionalContent.o \
- Outline.o \
- OutputDev.o \
- Page.o \
- Parser.o \
- PDFDoc.o \
- PDFDocEncoding.o \
- PSTokenizer.o \
- SecurityHandler.o \
- SplashOutputDev.o \
- Stream.o \
- TextOutputDev.o \
- TextString.o \
- UnicodeMap.o \
- UnicodeTypeTable.o \
- XFAForm.o \
- XpdfPluginAPI.o \
- XRef.o \
- Zoox.o \
- pdftohtml.o
-PDFTOHTML_LIBS = -L$(GOOLIBDIR) -lGoo $(SPLASHLIBS) $(FTLIBS) \
- $(OTHERLIBS) $(PNGLIBS) -lm
-
-pdftohtml$(EXE): $(PDFTOHTML_OBJS) $(GOOLIBDIR)/$(LIBPREFIX)Goo.a
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o pdftohtml$(EXE) $(PDFTOHTML_OBJS) \
- $(PDFTOHTML_LIBS)
-
-#------------------------------------------------------------------------
-
-PDFINFO_OBJS = \
- AcroForm.o \
- Annot.o \
- Array.o \
- BuiltinFont.o \
- BuiltinFontTables.o \
- Catalog.o \
- CharCodeToUnicode.o \
- CMap.o \
- Decrypt.o \
- Dict.o \
- Error.o \
- FontEncodingTables.o \
- Form.o \
- Function.o \
- Gfx.o \
- GfxFont.o \
- GfxState.o \
- GlobalParams.o \
- JArithmeticDecoder.o \
- JBIG2Stream.o \
- JPXStream.o \
- Lexer.o \
- Link.o \
- NameToCharCode.o \
- Object.o \
- OptionalContent.o \
- Outline.o \
- OutputDev.o \
- Page.o \
- Parser.o \
- PDFDoc.o \
- PDFDocEncoding.o \
- PSTokenizer.o \
- SecurityHandler.o \
- Stream.o \
- TextString.o \
- UnicodeMap.o \
- XFAForm.o \
- XpdfPluginAPI.o \
- XRef.o \
- Zoox.o \
- pdfinfo.o
-PDFINFO_LIBS = -L$(GOOLIBDIR) -lGoo $(OTHERLIBS) -lm
-
-pdfinfo$(EXE): $(PDFINFO_OBJS) $(GOOLIBDIR)/$(LIBPREFIX)Goo.a
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o pdfinfo$(EXE) $(PDFINFO_OBJS) \
- $(PDFINFO_LIBS)
-
-#------------------------------------------------------------------------
-
-PDFFONTS_OBJS = \
- AcroForm.o \
- Annot.o \
- Array.o \
- BuiltinFont.o \
- BuiltinFontTables.o \
- Catalog.o \
- CharCodeToUnicode.o \
- CMap.o \
- Decrypt.o \
- Dict.o \
- Error.o \
- FontEncodingTables.o \
- Form.o \
- Function.o \
- Gfx.o \
- GfxFont.o \
- GfxState.o \
- GlobalParams.o \
- JArithmeticDecoder.o \
- JBIG2Stream.o \
- JPXStream.o \
- Lexer.o \
- Link.o \
- NameToCharCode.o \
- Object.o \
- OptionalContent.o \
- Outline.o \
- OutputDev.o \
- Page.o \
- Parser.o \
- PDFDoc.o \
- PDFDocEncoding.o \
- PSTokenizer.o \
- SecurityHandler.o \
- Stream.o \
- TextString.o \
- UnicodeMap.o \
- XFAForm.o \
- XpdfPluginAPI.o \
- XRef.o \
- Zoox.o \
- pdffonts.o
-PDFFONTS_LIBS = -L$(GOOLIBDIR) -lGoo $(OTHERLIBS) -lm
-
-pdffonts$(EXE): $(PDFFONTS_OBJS) $(GOOLIBDIR)/$(LIBPREFIX)Goo.a
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o pdffonts$(EXE) $(PDFFONTS_OBJS) \
- $(PDFFONTS_LIBS)
-
-#------------------------------------------------------------------------
-
-PDFDETACH_OBJS = \
- AcroForm.o \
- Annot.o \
- Array.o \
- BuiltinFont.o \
- BuiltinFontTables.o \
- Catalog.o \
- CharCodeToUnicode.o \
- CMap.o \
- Decrypt.o \
- Dict.o \
- Error.o \
- FontEncodingTables.o \
- Form.o \
- Function.o \
- Gfx.o \
- GfxFont.o \
- GfxState.o \
- GlobalParams.o \
- JArithmeticDecoder.o \
- JBIG2Stream.o \
- JPXStream.o \
- Lexer.o \
- Link.o \
- NameToCharCode.o \
- Object.o \
- OptionalContent.o \
- Outline.o \
- OutputDev.o \
- Page.o \
- Parser.o \
- PDFDoc.o \
- PDFDocEncoding.o \
- PSTokenizer.o \
- SecurityHandler.o \
- Stream.o \
- TextString.o \
- UnicodeMap.o \
- XFAForm.o \
- XpdfPluginAPI.o \
- XRef.o \
- Zoox.o \
- pdfdetach.o
-PDFDETACH_LIBS = -L$(GOOLIBDIR) -lGoo $(OTHERLIBS) -lm
-
-pdfdetach$(EXE): $(PDFDETACH_OBJS) $(GOOLIBDIR)/$(LIBPREFIX)Goo.a
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o pdfdetach$(EXE) $(PDFDETACH_OBJS) \
- $(PDFDETACH_LIBS)
-
-#------------------------------------------------------------------------
-
-PDFTOPPM_OBJS = \
- AcroForm.o \
- Annot.o \
- Array.o \
- BuiltinFont.o \
- BuiltinFontTables.o \
- Catalog.o \
- CharCodeToUnicode.o \
- CMap.o \
- Decrypt.o \
- Dict.o \
- Error.o \
- FontEncodingTables.o \
- Form.o \
- Function.o \
- Gfx.o \
- GfxFont.o \
- GfxState.o \
- GlobalParams.o \
- JArithmeticDecoder.o \
- JBIG2Stream.o \
- JPXStream.o \
- Lexer.o \
- Link.o \
- NameToCharCode.o \
- Object.o \
- OptionalContent.o \
- Outline.o \
- OutputDev.o \
- Page.o \
- Parser.o \
- PDFDoc.o \
- PDFDocEncoding.o \
- PSTokenizer.o \
- SecurityHandler.o \
- SplashOutputDev.o \
- Stream.o \
- TextOutputDev.o \
- TextString.o \
- UnicodeMap.o \
- UnicodeTypeTable.o \
- XFAForm.o \
- XpdfPluginAPI.o \
- XRef.o \
- Zoox.o \
- pdftoppm.o
-PDFTOPPM_LIBS = -L$(GOOLIBDIR) -lGoo $(SPLASHLIBS) $(FTLIBS) \
- $(OTHERLIBS) -lm
-
-pdftoppm$(EXE): $(PDFTOPPM_OBJS) $(GOOLIBDIR)/$(LIBPREFIX)Goo.a
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o pdftoppm$(EXE) $(PDFTOPPM_OBJS) \
- $(PDFTOPPM_LIBS)
-
-#------------------------------------------------------------------------
-
-PDFTOPNG_OBJS = \
- AcroForm.o \
- Annot.o \
- Array.o \
- BuiltinFont.o \
- BuiltinFontTables.o \
- Catalog.o \
- CharCodeToUnicode.o \
- CMap.o \
- Decrypt.o \
- Dict.o \
- Error.o \
- FontEncodingTables.o \
- Form.o \
- Function.o \
- Gfx.o \
- GfxFont.o \
- GfxState.o \
- GlobalParams.o \
- JArithmeticDecoder.o \
- JBIG2Stream.o \
- JPXStream.o \
- Lexer.o \
- Link.o \
- NameToCharCode.o \
- Object.o \
- OptionalContent.o \
- Outline.o \
- OutputDev.o \
- Page.o \
- Parser.o \
- PDFDoc.o \
- PDFDocEncoding.o \
- PSTokenizer.o \
- SecurityHandler.o \
- SplashOutputDev.o \
- Stream.o \
- TextOutputDev.o \
- TextString.o \
- UnicodeMap.o \
- UnicodeTypeTable.o \
- XFAForm.o \
- XpdfPluginAPI.o \
- XRef.o \
- Zoox.o \
- pdftopng.o
-PDFTOPNG_LIBS = -L$(GOOLIBDIR) -lGoo $(SPLASHLIBS) $(FTLIBS) \
- $(OTHERLIBS) $(PNGLIBS) -lm
-
-pdftopng$(EXE): $(PDFTOPNG_OBJS) $(GOOLIBDIR)/$(LIBPREFIX)Goo.a
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o pdftopng$(EXE) $(PDFTOPNG_OBJS) \
- $(PDFTOPNG_LIBS)
-
-#------------------------------------------------------------------------
-
-PDFIMAGES_OBJS = \
- AcroForm.o \
- Annot.o \
- Array.o \
- BuiltinFont.o \
- BuiltinFontTables.o \
- Catalog.o \
- CharCodeToUnicode.o \
- CMap.o \
- Decrypt.o \
- Dict.o \
- Error.o \
- FontEncodingTables.o \
- Form.o \
- Function.o \
- Gfx.o \
- GfxFont.o \
- GfxState.o \
- GlobalParams.o \
- ImageOutputDev.o \
- JArithmeticDecoder.o \
- JBIG2Stream.o \
- JPXStream.o \
- Lexer.o \
- Link.o \
- NameToCharCode.o \
- Object.o \
- OptionalContent.o \
- Outline.o \
- OutputDev.o \
- Page.o \
- Parser.o \
- PDFDoc.o \
- PDFDocEncoding.o \
- PSTokenizer.o \
- SecurityHandler.o \
- Stream.o \
- TextString.o \
- UnicodeMap.o \
- XFAForm.o \
- XpdfPluginAPI.o \
- XRef.o \
- Zoox.o \
- pdfimages.o
-PDFIMAGES_LIBS = -L$(GOOLIBDIR) -lGoo $(OTHERLIBS) -lm
-
-pdfimages$(EXE): $(PDFIMAGES_OBJS) $(GOOLIBDIR)/$(LIBPREFIX)Goo.a
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o pdfimages$(EXE) $(PDFIMAGES_OBJS) \
- $(PDFIMAGES_LIBS)
-
-#------------------------------------------------------------------------
-
-clean:
- rm -f $(XPDF_OBJS) xpdf$(EXE)
- rm -f $(PDFTOPS_OBJS) pdftops$(EXE)
- rm -f $(PDFTOTEXT_OBJS) pdftotext$(EXE)
- rm -f $(PDFTOHTML_OBJS) pdftohtml$(EXE)
- rm -f $(PDFINFO_OBJS) pdfinfo$(EXE)
- rm -f $(PDFFONTS_OBJS) pdffonts$(EXE)
- rm -f $(PDFDETACH_OBJS) pdfdetach$(EXE)
- rm -f $(PDFTOPPM_OBJS) pdftoppm$(EXE)
- rm -f $(PDFTOPNG_OBJS) pdftopng$(EXE)
- rm -f $(PDFIMAGES_OBJS) pdfimages$(EXE)
-
-#------------------------------------------------------------------------
-
-depend:
- $(CXX) $(CXXFLAGS) -MM $(CXX_SRC) >Makefile.dep
-
--include Makefile.dep
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc
index c05fdf58787..f846d8e940d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/NameToCharCode.cc
@@ -14,6 +14,7 @@
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "NameToCharCode.h"
//------------------------------------------------------------------------
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc
index 3536bcfeed9..45d8cf8060c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Object.cc
@@ -13,6 +13,7 @@
#endif
#include <stddef.h>
+#include "gmempp.h"
#include "Object.h"
#include "Array.h"
#include "Dict.h"
@@ -42,7 +43,11 @@ const char *objTypeNames[numObjTypes] = {
};
#ifdef DEBUG_MEM
+#if MULTITHREADED
+GAtomicCounter Object::numAlloc[numObjTypes] =
+#else
int Object::numAlloc[numObjTypes] =
+#endif
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
#endif
@@ -87,7 +92,7 @@ Object *Object::copy(Object *obj) {
dict->incRef();
break;
case objStream:
- stream->incRef();
+ obj->stream = stream->copy();
break;
case objCmd:
obj->cmd = copyString(cmd);
@@ -96,8 +101,12 @@ Object *Object::copy(Object *obj) {
break;
}
#ifdef DEBUG_MEM
+#if MULTITHREADED
+ gAtomicIncrement(&numAlloc[type]);
+#else
++numAlloc[type];
#endif
+#endif
return obj;
}
@@ -125,9 +134,7 @@ void Object::free() {
}
break;
case objStream:
- if (!stream->decRef()) {
- delete stream;
- }
+ delete stream;
break;
case objCmd:
gfree(cmd);
@@ -136,8 +143,12 @@ void Object::free() {
break;
}
#ifdef DEBUG_MEM
+#if MULTITHREADED
+ gAtomicDecrement(&numAlloc[type]);
+#else
--numAlloc[type];
#endif
+#endif
type = objNone;
}
@@ -224,7 +235,7 @@ void Object::memCheck(FILE *f) {
fprintf(f, "Allocated objects:\n");
for (i = 0; i < numObjTypes; ++i) {
if (numAlloc[i] > 0)
- fprintf(f, " %-20s: %6d\n", objTypeNames[i], numAlloc[i]);
+ fprintf(f, " %-20s: %6ld\n", objTypeNames[i], numAlloc[i]);
}
}
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Object.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Object.h
index 64c75f737c7..68d59a05f84 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Object.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Object.h
@@ -21,6 +21,9 @@
#include "gmem.h"
#include "gfile.h"
#include "GString.h"
+#if MULTITHREADED
+#include "GMutex.h"
+#endif
class XRef;
class Array;
@@ -69,7 +72,11 @@ enum ObjType {
//------------------------------------------------------------------------
#ifdef DEBUG_MEM
-#define initObj(t) ++numAlloc[type = t]
+# if MULTITHREADED
+# define initObj(t) gAtomicIncrement(&numAlloc[type = t])
+# else
+# define initObj(t) ++numAlloc[type = t]
+# endif
#else
#define initObj(t) type = t
#endif
@@ -210,9 +217,14 @@ private:
};
#ifdef DEBUG_MEM
+#if MULTITHREADED
+ static GAtomicCounter // number of each type of object
+ numAlloc[numObjTypes]; // currently allocated
+#else
static int // number of each type of object
numAlloc[numObjTypes]; // currently allocated
#endif
+#endif
};
//------------------------------------------------------------------------
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc
index bebb674ce23..a790989a72c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.cc
@@ -12,6 +12,7 @@
#pragma implementation
#endif
+#include "gmempp.h"
#include "GString.h"
#include "GList.h"
#include "Error.h"
@@ -69,7 +70,7 @@ OptionalContent::OptionalContent(PDFDoc *doc) {
//----- read the default viewing OCCD
if (ocProps->dictLookup("D", &defView)->isDict()) {
- //----- initial state
+ //----- initial state from OCCD
if (defView.dictLookup("OFF", &obj1)->isArray()) {
for (i = 0; i < obj1.arrayGetLength(); ++i) {
if (obj1.arrayGetNF(i, &obj2)->isRef()) {
@@ -85,6 +86,34 @@ OptionalContent::OptionalContent(PDFDoc *doc) {
}
}
obj1.free();
+ // the default OCCD is required to have a BaseState of ON, so
+ // the ON array is redundant -- but some (broken) PDF files
+ // include OCGs in both the OFF and ON arrays
+ if (defView.dictLookup("ON", &obj1)->isArray()) {
+ for (i = 0; i < obj1.arrayGetLength(); ++i) {
+ if (obj1.arrayGetNF(i, &obj2)->isRef()) {
+ ref1 = obj2.getRef();
+ if ((ocg = findOCG(&ref1))) {
+ ocg->setState(gTrue);
+ } else {
+ error(errSyntaxError, -1,
+ "Invalid OCG reference in ON array in default viewing OCCD");
+ }
+ }
+ obj2.free();
+ }
+ }
+ obj1.free();
+
+ //----- initial state from OCG usage dict
+ for (i = 0; i < ocgs->getLength(); ++i) {
+ ocg = (OptionalContentGroup *)ocgs->get(i);
+ //~ should this look at PrintState when printing, or is it
+ //~ better to always print the ViewState?
+ if (ocg->getViewState() == ocUsageOff) {
+ ocg->setState(gFalse);
+ }
+ }
//----- display order
if (defView.dictLookup("Order", &obj1)->isArray()) {
@@ -418,6 +447,7 @@ OCDisplayNode *OCDisplayNode::parse(Object *obj, OptionalContent *oc,
OCDisplayNode::OCDisplayNode() {
name = new TextString();
ocg = NULL;
+ parent = NULL;
children = NULL;
}
@@ -438,21 +468,31 @@ void OCDisplayNode::addChild(OCDisplayNode *child) {
children = new GList();
}
children->append(child);
+ child->parent = this;
}
void OCDisplayNode::addChildren(GList *childrenA) {
+ int i;
+
if (!children) {
children = new GList();
}
children->append(childrenA);
+ for (i = 0; i < childrenA->getLength(); ++i) {
+ ((OCDisplayNode *)childrenA->get(i))->parent = this;
+ }
delete childrenA;
}
GList *OCDisplayNode::takeChildren() {
GList *childrenA;
+ int i;
childrenA = children;
children = NULL;
+ for (i = 0; i < childrenA->getLength(); ++i) {
+ ((OCDisplayNode *)childrenA->get(i))->parent = NULL;
+ }
return childrenA;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h b/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h
index e2ea2446bbc..4aa970e7356 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/OptionalContent.h
@@ -115,6 +115,7 @@ public:
OptionalContentGroup *getOCG() { return ocg; }
int getNumChildren();
OCDisplayNode *getChild(int idx);
+ OCDisplayNode *getParent() { return parent; }
private:
@@ -126,6 +127,7 @@ private:
TextString *name; // display name
OptionalContentGroup *ocg; // NULL for display labels
+ OCDisplayNode *parent; // parent node; NULL at root
GList *children; // NULL if there are no children
// [OCDisplayNode]
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc
index e87f61e0db9..9593956f8d0 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.cc
@@ -13,6 +13,7 @@
#endif
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "GList.h"
#include "Error.h"
@@ -83,6 +84,8 @@ OutlineItem::OutlineItem(Object *itemRefA, Dict *dict,
}
}
obj1.free();
+
+ pageNum = -1;
}
OutlineItem::~OutlineItem() {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h
index a9c2089e6c3..e9bce83cdad 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Outline.h
@@ -61,9 +61,12 @@ public:
GBool isOpen() { return startsOpen; }
GBool hasKids() { return firstRef.isRef(); }
GList *getKids() { return kids; }
+ OutlineItem *getParent() { return parent; }
private:
+ friend class PDFDoc;
+
XRef *xref;
TextString *title; // may be NULL
LinkAction *action;
@@ -72,6 +75,8 @@ private:
Object lastRef;
Object nextRef;
GBool startsOpen;
+ int pageNum; // page number (used by
+ // PDFDoc::getOutlineTargetPage)
GList *kids; // NULL unless this item is open [OutlineItem]
OutlineItem *parent;
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc
index 2d17547210e..adec372117d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.cc
@@ -13,6 +13,7 @@
#endif
#include <stddef.h>
+#include "gmempp.h"
#include "Object.h"
#include "Stream.h"
#include "GfxState.h"
@@ -125,7 +126,7 @@ void OutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
Stream *maskStr,
int maskWidth, int maskHeight,
GfxImageColorMap *maskColorMap,
- GBool interpolate) {
+ double *matte, GBool interpolate) {
drawImage(state, ref, str, width, height, colorMap, NULL, gFalse,
interpolate);
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h
index 759e356df18..bec419308a3 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/OutputDev.h
@@ -105,9 +105,6 @@ public:
// End a page.
virtual void endPage() {}
- // Dump page contents to display.
- virtual void dump() {}
-
//----- coordinate conversion
// Convert between device and user coordinates.
@@ -143,6 +140,7 @@ public:
virtual void updateFillOverprint(GfxState *state) {}
virtual void updateStrokeOverprint(GfxState *state) {}
virtual void updateOverprintMode(GfxState *state) {}
+ virtual void updateRenderingIntent(GfxState *state) {}
virtual void updateTransfer(GfxState *state) {}
//----- update text state
@@ -163,7 +161,7 @@ public:
virtual void fill(GfxState *state) {}
virtual void eoFill(GfxState *state) {}
virtual void tilingPatternFill(GfxState *state, Gfx *gfx, Object *strRef,
- int paintType, Dict *resDict,
+ int paintType, int tilingType, Dict *resDict,
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
double xStep, double yStep) {}
@@ -221,7 +219,7 @@ public:
Stream *maskStr,
int maskWidth, int maskHeight,
GfxImageColorMap *maskColorMap,
- GBool interpolate);
+ double *matte, GBool interpolate);
#if OPI_SUPPORT
//----- OPI functions
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
index 34b64835c67..de411537a66 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc
@@ -2,7 +2,7 @@
//
// PDFCore.cc
//
-// Copyright 2004-2013 Glyph & Cog, LLC
+// Copyright 2004-2014 Glyph & Cog, LLC
//
//========================================================================
@@ -13,6 +13,7 @@
#endif
#include <math.h>
+#include "gmempp.h"
#include "GString.h"
#include "GList.h"
#include "GlobalParams.h"
@@ -24,106 +25,83 @@
#include "ErrorCodes.h"
#include "PDFDoc.h"
#include "Link.h"
-#include "TextOutputDev.h"
-#include "CoreOutputDev.h"
+#include "Annot.h"
+#include "Form.h"
+#include "OptionalContent.h"
+#include "TileMap.h"
+#include "TileCache.h"
+#include "TileCompositor.h"
#include "PDFCore.h"
//------------------------------------------------------------------------
-// PDFCorePage
-//------------------------------------------------------------------------
-
-PDFCorePage::PDFCorePage(int pageA, int wA, int hA, int tileWA, int tileHA) {
- page = pageA;
- tiles = new GList();
- w = wA;
- h = hA;
- tileW = tileWA;
- tileH = tileHA;
- links = NULL;
- text = NULL;
-}
-
-PDFCorePage::~PDFCorePage() {
- deleteGList(tiles, PDFCoreTile);
- if (links) {
- delete links;
- }
- if (text) {
- delete text;
- }
-}
-
-//------------------------------------------------------------------------
-// PDFCoreTile
+// PDFCore
//------------------------------------------------------------------------
-PDFCoreTile::PDFCoreTile(int xDestA, int yDestA) {
- xMin = 0;
- yMin = 0;
- xMax = 0;
- yMax = 0;
- xDest = xDestA;
- yDest = yDestA;
- bitmap = NULL;
-}
+PDFCore::PDFCore(SplashColorMode colorMode, int bitmapRowPad,
+ GBool reverseVideo, SplashColorPtr paperColor) {
+ GString *initialZoom;
+ int z, i;
-PDFCoreTile::~PDFCoreTile() {
- if (bitmap) {
- delete bitmap;
- }
-}
+ doc = NULL;
+ linksPage = 0;
+ links = NULL;
-//------------------------------------------------------------------------
-// PDFCore
-//------------------------------------------------------------------------
+ annotsPage = 0;
+ annots = NULL;
-PDFCore::PDFCore(SplashColorMode colorModeA, int bitmapRowPadA,
- GBool reverseVideoA, SplashColorPtr paperColorA,
- GBool incrementalUpdate) {
- int i;
+ textPage = 0;
+ textDPI = 0;
+ textRotate = 0;
+ textOutCtrl.mode = textOutPhysLayout;
+ text = NULL;
- doc = NULL;
- continuousMode = globalParams->getContinuousView();
- drawAreaWidth = drawAreaHeight = 0;
- maxPageW = totalDocH = 0;
- pageY = NULL;
- topPage = 0;
- midPage = 0;
- scrollX = scrollY = 0;
- zoom = defZoom;
- dpi = 0;
- rotate = 0;
+ state = new DisplayState(globalParams->getMaxTileWidth(),
+ globalParams->getMaxTileHeight(),
+ globalParams->getTileCacheSize(),
+ globalParams->getWorkerThreads(),
+ colorMode, bitmapRowPad);
+ tileMap = new TileMap(state);
+ tileCache = new TileCache(state);
+ tileCompositor = new TileCompositor(state, tileMap, tileCache);
+ bitmapFinished = gTrue;
+
+ state->setReverseVideo(reverseVideo);
+ state->setPaperColor(paperColor);
+ initialZoom = globalParams->getInitialZoom();
+ if (!initialZoom->cmp("page")) {
+ state->setZoom(zoomPage);
+ } else if (!initialZoom->cmp("width")) {
+ state->setZoom(zoomWidth);
+ } else {
+ z = atoi(initialZoom->getCString());
+ if (z <= 0) {
+ z = zoomWidth;
+ }
+ state->setZoom(z);
+ }
+ delete initialZoom;
+ selectMode = selectModeBlock;
selectPage = 0;
- selectULX = selectLRX = 0;
- selectULY = selectLRY = 0;
- dragging = gFalse;
- lastDragLeft = lastDragTop = gTrue;
- selectXorColor[0] = selectXorColor[1] = selectXorColor[2] =
- reverseVideoA ? 0xff : 0x00;
- splashColorXor(selectXorColor, paperColorA);
+ selectStartX = selectStartY = 0;
historyCur = pdfHistorySize - 1;
historyBLen = historyFLen = 0;
for (i = 0; i < pdfHistorySize; ++i) {
history[i].fileName = NULL;
+ history[i].page = 0;
}
-
-
- pages = new GList();
- curTile = NULL;
-
- splashColorCopy(paperColor, paperColorA);
- out = new CoreOutputDev(colorModeA, bitmapRowPadA,
- reverseVideoA, paperColorA, incrementalUpdate,
- &redrawCbk, this);
- out->startDoc(NULL);
}
PDFCore::~PDFCore() {
int i;
+ delete tileCompositor;
+ delete tileCache;
+ delete tileMap;
+ delete state;
+ clearPage();
if (doc) {
delete doc;
}
@@ -136,9 +114,6 @@ PDFCore::~PDFCore() {
#endif
}
}
- gfree(pageY);
- deleteGList(pages, PDFCorePage);
- delete out;
}
int PDFCore::loadFile(GString *fileName, GString *ownerPassword,
@@ -181,10 +156,24 @@ void PDFCore::loadDoc(PDFDoc *docA) {
setBusyCursor(gFalse);
}
+int PDFCore::reload() {
+ int err;
+
+ if (!doc->getFileName()) {
+ return errOpenFile;
+ }
+ setBusyCursor(gTrue);
+ err = loadFile2(new PDFDoc(doc->getFileName()->copy(), NULL, NULL, this));
+ setBusyCursor(gFalse);
+ startUpdate();
+ finishUpdate(gTrue, gFalse);
+ return err;
+}
+
int PDFCore::loadFile2(PDFDoc *newDoc) {
int err;
- double w, h, t;
- int i;
+
+ clearSelection();
// open the PDF file
if (!newDoc->isOk()) {
@@ -193,37 +182,18 @@ int PDFCore::loadFile2(PDFDoc *newDoc) {
return err;
}
+ preLoad();
+
// replace old document
+ // NB: do not delete doc until after DisplayState::setDoc() returns
+ state->setDoc(newDoc);
if (doc) {
delete doc;
}
doc = newDoc;
- if (out) {
- out->startDoc(doc->getXRef());
- }
-
- // nothing displayed yet
- topPage = -99;
- midPage = -99;
- while (pages->getLength() > 0) {
- delete (PDFCorePage *)pages->del(0);
- }
+ clearPage();
- // compute the max unscaled page size
- maxUnscaledPageW = maxUnscaledPageH = 0;
- for (i = 1; i <= doc->getNumPages(); ++i) {
- w = doc->getPageCropWidth(i);
- h = doc->getPageCropHeight(i);
- if (doc->getPageRotate(i) == 90 || doc->getPageRotate(i) == 270) {
- t = w; w = h; h = t;
- }
- if (w > maxUnscaledPageW) {
- maxUnscaledPageW = w;
- }
- if (h > maxUnscaledPageH) {
- maxUnscaledPageH = h;
- }
- }
+ postLoad();
return errNone;
}
@@ -234,20 +204,15 @@ void PDFCore::clear() {
}
// no document
+ // NB: do not delete doc until after DisplayState::setDoc() returns
+ state->setDoc(NULL);
delete doc;
doc = NULL;
- out->clear();
-
- // no page displayed
- topPage = -99;
- midPage = -99;
- while (pages->getLength() > 0) {
- delete (PDFCorePage *)pages->del(0);
- }
+ clearPage();
// redraw
- scrollX = scrollY = 0;
- redrawWindow(0, 0, drawAreaWidth, drawAreaHeight, gTrue);
+ state->setScrollPosition(1, 0, 0);
+ invalidateWholeWindow();
updateScrollbars();
}
@@ -259,721 +224,298 @@ PDFDoc *PDFCore::takeDoc(GBool redraw) {
}
// no document
+ // NB: do not delete doc until after DisplayState::setDoc() returns
+ state->setDoc(NULL);
docA = doc;
doc = NULL;
- out->clear();
-
- // no page displayed
- topPage = -99;
- midPage = -99;
- while (pages->getLength() > 0) {
- delete (PDFCorePage *)pages->del(0);
- }
+ clearPage();
// redraw
- scrollX = scrollY = 0;
+ state->setScrollPosition(1, 0, 0);
if (redraw) {
- redrawWindow(0, 0, drawAreaWidth, drawAreaHeight, gTrue);
+ invalidateWholeWindow();
updateScrollbars();
}
return docA;
}
-void PDFCore::displayPage(int topPageA, double zoomA, int rotateA,
- GBool scrollToTop, GBool addToHist) {
- int scrollXA, scrollYA;
+void PDFCore::displayPage(int page, GBool scrollToTop,
+ GBool scrollToBottom, GBool addToHist) {
+ int scrollX, scrollY;
- scrollXA = scrollX;
- if (continuousMode) {
- scrollYA = -1;
- } else if (scrollToTop) {
- scrollYA = 0;
+ if (page <= 0 || page > doc->getNumPages()) {
+ return;
+ }
+ if (scrollToTop ||
+ state->getDisplayMode() == displayContinuous ||
+ state->getDisplayMode() == displaySideBySideContinuous) {
+ scrollY = tileMap->getPageTopY(page);
+ } else if (scrollToBottom) {
+ scrollY = tileMap->getPageBottomY(page);
} else {
- scrollYA = scrollY;
+ scrollY = state->getScrollY();
}
- if (zoomA != zoom) {
- scrollXA = 0;
- scrollYA = continuousMode ? -1 : 0;
+ if (state->getDisplayMode() == displayHorizontalContinuous) {
+ scrollX = tileMap->getPageLeftX(page);
+ } else {
+ scrollX = state->getScrollX();
}
-
- dragging = gFalse;
- lastDragLeft = lastDragTop = gTrue;
-
- update(topPageA, scrollXA, scrollYA, zoomA, rotateA, gTrue, addToHist,
- gTrue);
+ startUpdate();
+ state->setScrollPosition(page, scrollX, scrollY);
+ finishUpdate(addToHist, gTrue);
}
-void PDFCore::displayDest(LinkDest *dest, double zoomA, int rotateA,
- GBool addToHist) {
+void PDFCore::displayDest(LinkDest *dest) {
Ref pageRef;
- int topPageA;
- int dx, dy, scrollXA, scrollYA;
+ int page;
+ int dx, dy, scrollX, scrollY;
if (dest->isPageRef()) {
pageRef = dest->getPageRef();
- topPageA = doc->findPage(pageRef.num, pageRef.gen);
+ page = doc->findPage(pageRef.num, pageRef.gen);
} else {
- topPageA = dest->getPageNum();
+ page = dest->getPageNum();
}
- if (topPageA <= 0 || topPageA > doc->getNumPages()) {
- topPageA = 1;
+ if (page <= 0 || page > doc->getNumPages()) {
+ page = 1;
}
- scrollXA = scrollX;
- scrollYA = continuousMode ? -1 : scrollY;
+
switch (dest->getKind()) {
case destXYZ:
- cvtUserToDev(topPageA, dest->getLeft(), dest->getTop(), &dx, &dy);
- scrollXA = dest->getChangeLeft() ? dx : scrollX;
- if (continuousMode) {
- if (topPage <= 0) {
- scrollYA = -1;
- } else if (dest->getChangeTop()) {
- scrollYA = pageY[topPageA - 1] + dy;
- } else {
- scrollYA = pageY[topPageA - 1] + (scrollY - pageY[topPage - 1]);
- }
- } else {
- if (dest->getChangeTop()) {
- scrollYA = dy;
- } else if (topPage > 0) {
- scrollYA = scrollY;
- } else {
- scrollYA = 0;
- }
+ cvtUserToDev(page, dest->getLeft(), dest->getTop(), &dx, &dy);
+ scrollX = tileMap->getPageLeftX(page);
+ if (dest->getChangeLeft()) {
+ scrollX += dx;
}
- //~ this doesn't currently handle the zoom parameter
- update(topPageA, scrollXA, scrollYA, zoom, rotate, gFalse,
- addToHist && topPageA != topPage, gTrue);
+ scrollY = tileMap->getPageTopY(page);
+ if (dest->getChangeTop()) {
+ scrollY += dy;
+ }
+ startUpdate();
+ state->setScrollPosition(page, scrollX, scrollY);
+ finishUpdate(gTrue, gTrue);
break;
case destFit:
case destFitB:
- scrollXA = 0;
- scrollYA = continuousMode ? -1 : 0;
- update(topPageA, scrollXA, scrollYA, zoomPage, rotate, gFalse,
- addToHist && topPageA != topPage, gTrue);
+ state->setZoom(zoomPage);
+ scrollX = tileMap->getPageLeftX(page);
+ scrollY = tileMap->getPageTopY(page);
+ startUpdate();
+ state->setScrollPosition(page, scrollX, scrollY);
+ finishUpdate(gTrue, gTrue);
break;
case destFitH:
case destFitBH:
- //~ do fit: need a function similar to zoomToRect which will
- //~ accept an absolute top coordinate (rather than centering)
- scrollXA = 0;
- cvtUserToDev(topPageA, 0, dest->getTop(), &dx, &dy);
- if (continuousMode) {
- if (topPage <= 0) {
- scrollYA = -1;
- } else if (dest->getChangeTop()) {
- scrollYA = pageY[topPageA - 1] + dy;
- } else {
- scrollYA = pageY[topPageA - 1] + (scrollY - pageY[topPage - 1]);
- }
- } else {
- if (dest->getChangeTop()) {
- scrollYA = dy;
- } else if (topPage > 0) {
- scrollYA = scrollY;
- } else {
- scrollYA = 0;
- }
- }
- update(topPageA, scrollXA, scrollYA, zoom, rotate, gFalse,
- addToHist && topPageA != topPage, gTrue);
+ state->setZoom(zoomWidth);
+ scrollX = tileMap->getPageLeftX(page);
+ scrollY = tileMap->getPageTopY(page);
+ if (dest->getChangeTop()) {
+ cvtUserToDev(page, 0, dest->getTop(), &dx, &dy);
+ scrollY += dy;
+ }
+ startUpdate();
+ state->setScrollPosition(page, scrollX, scrollY);
+ finishUpdate(gTrue, gTrue);
break;
case destFitV:
case destFitBV:
- //~ do fit: need a function similar to zoomToRect which will
- //~ accept an absolute left coordinate (rather than centering)
- if (dest->getChangeLeft()) {
- cvtUserToDev(topPageA, dest->getLeft(), 0, &dx, &dy);
- scrollXA = dx;
- } else {
- scrollXA = scrollX;
- }
- scrollYA = continuousMode ? -1 : 0;
- update(topPageA, scrollXA, scrollYA, zoom, rotate, gFalse,
- addToHist && topPageA != topPage, gTrue);
+ state->setZoom(zoomHeight);
+ scrollX = tileMap->getPageLeftX(page);
+ scrollY = tileMap->getPageTopY(page);
+ if (dest->getChangeTop()) {
+ cvtUserToDev(page, dest->getLeft(), 0, &dx, &dy);
+ scrollX += dx;
+ }
+ startUpdate();
+ state->setScrollPosition(page, scrollX, scrollY);
+ finishUpdate(gTrue, gTrue);
break;
case destFitR:
- zoomToRect(topPageA, dest->getLeft(), dest->getTop(),
+ zoomToRect(page, dest->getLeft(), dest->getTop(),
dest->getRight(), dest->getBottom());
break;
}
}
-void PDFCore::update(int topPageA, int scrollXA, int scrollYA,
- double zoomA, int rotateA, GBool force,
- GBool addToHist, GBool adjustScrollX) {
- double hDPI, vDPI, dpiA, uw, uh, ut;
- int w, h, t, x0, x1, y0, y1, x, y;
- int rot;
- int pg0, pg1;
- PDFCoreTile *tile;
- PDFCorePage *page;
- PDFHistory *hist;
- GBool needUpdate;
- int i, j;
+void PDFCore::startUpdate() {
+}
+
+void PDFCore::finishUpdate(GBool addToHist, GBool checkForChangedFile) {
+ int scrollPage, scrollX, scrollY, maxScrollX, maxScrollY;
- // check for document and valid page number
if (!doc) {
- // save the new settings
- zoom = zoomA;
- rotate = rotateA;
- return;
- }
- if (topPageA <= 0 || topPageA > doc->getNumPages()) {
+ invalidateWholeWindow();
+ updateScrollbars();
return;
}
- needUpdate = gFalse;
-
// check for changes to the PDF file
- if ((force || (!continuousMode && topPage != topPageA)) &&
+ if (checkForChangedFile &&
doc->getFileName() &&
checkForNewFile()) {
- if (loadFile(doc->getFileName()) == errNone) {
- if (topPageA > doc->getNumPages()) {
- topPageA = doc->getNumPages();
- }
- needUpdate = gTrue;
- }
+ loadFile(doc->getFileName());
}
- // compute the DPI
- if (continuousMode) {
- uw = maxUnscaledPageW;
- uh = maxUnscaledPageH;
- rot = rotateA;
- } else {
- uw = doc->getPageCropWidth(topPageA);
- uh = doc->getPageCropHeight(topPageA);
- rot = rotateA + doc->getPageRotate(topPageA);
- if (rot >= 360) {
- rot -= 360;
- } else if (rot < 0) {
- rot += 360;
- }
- }
- if (rot == 90 || rot == 270) {
- ut = uw; uw = uh; uh = ut;
- }
- if (zoomA == zoomPage) {
- hDPI = (drawAreaWidth / uw) * 72;
- if (continuousMode) {
- vDPI = ((drawAreaHeight - continuousModePageSpacing) / uh) * 72;
- } else {
- vDPI = (drawAreaHeight / uh) * 72;
- }
- dpiA = (hDPI < vDPI) ? hDPI : vDPI;
- } else if (zoomA == zoomWidth) {
- dpiA = (drawAreaWidth / uw) * 72;
- } else {
- dpiA = 0.01 * zoomA * 72;
- }
- // this can happen if the window hasn't been sized yet
- if (dpiA <= 0) {
- dpiA = 1;
- }
-
- // if the display properties have changed, create a new PDFCorePage
- // object
- if (force || pages->getLength() == 0 ||
- (!continuousMode && topPageA != topPage) ||
- fabs(zoomA - zoom) > 1e-8 || fabs(dpiA - dpi) > 1e-8 ||
- rotateA != rotate) {
- needUpdate = gTrue;
- setSelection(0, 0, 0, 0, 0);
- while (pages->getLength() > 0) {
- delete (PDFCorePage *)pages->del(0);
- }
- zoom = zoomA;
- rotate = rotateA;
- dpi = dpiA;
- if (continuousMode) {
- maxPageW = totalDocH = 0;
- pageY = (int *)greallocn(pageY, doc->getNumPages(), sizeof(int));
- for (i = 1; i <= doc->getNumPages(); ++i) {
- pageY[i-1] = totalDocH;
- w = (int)((doc->getPageCropWidth(i) * dpi) / 72 + 0.5);
- h = (int)((doc->getPageCropHeight(i) * dpi) / 72 + 0.5);
- rot = rotate + doc->getPageRotate(i);
- if (rot >= 360) {
- rot -= 360;
- } else if (rot < 0) {
- rot += 360;
- }
- if (rot == 90 || rot == 270) {
- t = w; w = h; h = t;
- }
- if (w > maxPageW) {
- maxPageW = w;
- }
- totalDocH += h;
- if (i < doc->getNumPages()) {
- totalDocH += continuousModePageSpacing;
- }
- }
- } else {
- rot = rotate + doc->getPageRotate(topPageA);
- if (rot >= 360) {
- rot -= 360;
- } else if (rot < 0) {
- rot += 360;
- }
- addPage(topPageA, rot);
- }
- } else {
- // erase the selection
- if (selectULX != selectLRX && selectULY != selectLRY) {
- xorRectangle(selectPage, selectULX, selectULY, selectLRX, selectLRY,
- new SplashSolidColor(selectXorColor));
- }
- }
- if (continuousMode) {
- page = NULL; // make gcc happy
- } else {
- page = (PDFCorePage *)pages->get(0);
+ // zero-page documents are a special case
+ // (check for this *after* checking for changes to the file)
+ if (!doc->getNumPages()) {
+ invalidateWholeWindow();
+ updateScrollbars();
+ return;
}
- topPage = topPageA;
- midPage = topPage;
- // adjust the scroll position
- scrollX = scrollXA;
- if (continuousMode && scrollYA < 0) {
- scrollY = pageY[topPage - 1];
- } else {
- scrollY = scrollYA;
- }
- if (continuousMode && adjustScrollX) {
- rot = rotate + doc->getPageRotate(topPage);
- if (rot >= 360) {
- rot -= 360;
- } else if (rot < 0) {
- rot += 360;
- }
- if (rot == 90 || rot == 270) {
- w = (int)((doc->getPageCropHeight(topPage) * dpi) / 72 + 0.5);
- } else {
- w = (int)((doc->getPageCropWidth(topPage) * dpi) / 72 + 0.5);
- }
- if (scrollX < (maxPageW - w) / 2) {
- scrollX = (maxPageW - w) / 2;
- }
+ // check the scroll position
+ scrollPage = state->getScrollPage();
+ if (state->getDisplayMode() == displaySideBySideSingle &&
+ !(scrollPage & 1)) {
+ --scrollPage;
}
- w = continuousMode ? maxPageW : page->w;
- if (scrollX > w - drawAreaWidth) {
- scrollX = w - drawAreaWidth;
+ if (state->displayModeIsContinuous()) {
+ scrollPage = 0;
+ } else if (scrollPage <= 0 || scrollPage > doc->getNumPages()) {
+ scrollPage = 1;
+ }
+ scrollX = state->getScrollX();
+ scrollY = state->getScrollY();
+ // we need to set scrollPage before calling getScrollLimits()
+ state->setScrollPosition(scrollPage, scrollX, scrollY);
+ tileMap->getScrollLimits(&maxScrollX, &maxScrollY);
+ maxScrollX -= state->getWinW();
+ maxScrollY -= state->getWinH();
+ if (scrollX > maxScrollX) {
+ scrollX = maxScrollX;
}
if (scrollX < 0) {
scrollX = 0;
}
- h = continuousMode ? totalDocH : page->h;
- if (scrollY > h - drawAreaHeight) {
- scrollY = h - drawAreaHeight;
+ if (scrollY > maxScrollY) {
+ scrollY = maxScrollY;
}
if (scrollY < 0) {
scrollY = 0;
}
-
- // find topPage, and the first and last pages to be rasterized
- if (continuousMode) {
- //~ should use a binary search
- for (i = 2; i <= doc->getNumPages(); ++i) {
- if (pageY[i-1] > scrollY - drawAreaHeight / 2) {
- break;
- }
- }
- pg0 = i - 1;
- for (i = pg0 + 1; i <= doc->getNumPages(); ++i) {
- if (pageY[i-1] > scrollY) {
- break;
- }
- }
- topPage = i - 1;
- for (i = topPage + 1; i <= doc->getNumPages(); ++i) {
- if (pageY[i-1] > scrollY + drawAreaHeight / 2) {
- break;
- }
- }
- midPage = i - 1;
- for (i = midPage + 1; i <= doc->getNumPages(); ++i) {
- if (pageY[i-1] > scrollY + drawAreaHeight + drawAreaHeight / 2) {
- break;
- }
- }
- pg1 = i - 1;
-
- // delete pages that are no longer needed and insert new pages
- // objects that are needed
- while (pages->getLength() > 0 &&
- ((PDFCorePage *)pages->get(0))->page < pg0) {
- delete (PDFCorePage *)pages->del(0);
- }
- i = pages->getLength() - 1;
- while (i > 0 && ((PDFCorePage *)pages->get(i))->page > pg1) {
- delete (PDFCorePage *)pages->del(i--);
- }
- j = pages->getLength() > 0 ? ((PDFCorePage *)pages->get(0))->page - 1
- : pg1;
- for (i = pg0; i <= j; ++i) {
- rot = rotate + doc->getPageRotate(i);
- if (rot >= 360) {
- rot -= 360;
- } else if (rot < 0) {
- rot += 360;
- }
- addPage(i, rot);
- }
- j = ((PDFCorePage *)pages->get(pages->getLength() - 1))->page;
- for (i = j + 1; i <= pg1; ++i) {
- rot = rotate + doc->getPageRotate(i);
- if (rot >= 360) {
- rot -= 360;
- } else if (rot < 0) {
- rot += 360;
- }
- addPage(i, rot);
- }
-
- } else {
- pg0 = pg1 = topPage;
- }
-
- // delete tiles that are no longer needed
- for (i = 0; i < pages->getLength(); ++i) {
- page = (PDFCorePage *)pages->get(i);
- j = 0;
- while (j < page->tiles->getLength()) {
- tile = (PDFCoreTile *)page->tiles->get(j);
- if (continuousMode) {
- y0 = pageY[page->page - 1] + tile->yMin;
- y1 = pageY[page->page - 1] + tile->yMax;
- } else {
- y0 = tile->yMin;
- y1 = tile->yMax;
- }
- if (tile->xMax < scrollX - drawAreaWidth / 2 ||
- tile->xMin > scrollX + drawAreaWidth + drawAreaWidth / 2 ||
- y1 < scrollY - drawAreaHeight / 2 ||
- y0 > scrollY + drawAreaHeight + drawAreaHeight / 2) {
- delete (PDFCoreTile *)page->tiles->del(j);
- } else {
- ++j;
- }
- }
- }
-
- // update page positions
- for (i = 0; i < pages->getLength(); ++i) {
- page = (PDFCorePage *)pages->get(i);
- page->xDest = -scrollX;
- if (continuousMode) {
- page->yDest = pageY[page->page - 1] - scrollY;
- } else {
- page->yDest = -scrollY;
- }
- if (continuousMode) {
- if (page->w < maxPageW) {
- page->xDest += (maxPageW - page->w) / 2;
- }
- if (maxPageW < drawAreaWidth) {
- page->xDest += (drawAreaWidth - maxPageW) / 2;
- }
- } else if (page->w < drawAreaWidth) {
- page->xDest += (drawAreaWidth - page->w) / 2;
- }
- if (continuousMode && totalDocH < drawAreaHeight) {
- page->yDest += (drawAreaHeight - totalDocH) / 2;
- } else if (!continuousMode && page->h < drawAreaHeight) {
- page->yDest += (drawAreaHeight - page->h) / 2;
- }
- }
-
- // rasterize any new tiles
- for (i = 0; i < pages->getLength(); ++i) {
- page = (PDFCorePage *)pages->get(i);
- x0 = page->xDest;
- x1 = x0 + page->w - 1;
- if (x0 < -drawAreaWidth / 2) {
- x0 = -drawAreaWidth / 2;
- }
- if (x1 > drawAreaWidth + drawAreaWidth / 2) {
- x1 = drawAreaWidth + drawAreaWidth / 2;
- }
- x0 = ((x0 - page->xDest) / page->tileW) * page->tileW;
- x1 = ((x1 - page->xDest) / page->tileW) * page->tileW;
- y0 = page->yDest;
- y1 = y0 + page->h - 1;
- if (y0 < -drawAreaHeight / 2) {
- y0 = -drawAreaHeight / 2;
- }
- if (y1 > drawAreaHeight + drawAreaHeight / 2) {
- y1 = drawAreaHeight + drawAreaHeight / 2;
- }
- y0 = ((y0 - page->yDest) / page->tileH) * page->tileH;
- y1 = ((y1 - page->yDest) / page->tileH) * page->tileH;
- for (y = y0; y <= y1; y += page->tileH) {
- for (x = x0; x <= x1; x += page->tileW) {
- needTile(page, x, y);
- }
- }
+ if (scrollPage != state->getScrollPage() ||
+ scrollX != state->getScrollX() ||
+ scrollY != state->getScrollY()) {
+ state->setScrollPosition(scrollPage, scrollX, scrollY);
}
- // update tile positions
- for (i = 0; i < pages->getLength(); ++i) {
- page = (PDFCorePage *)pages->get(i);
- for (j = 0; j < page->tiles->getLength(); ++j) {
- tile = (PDFCoreTile *)page->tiles->get(j);
- tile->xDest = tile->xMin - scrollX;
- if (continuousMode) {
- tile->yDest = tile->yMin + pageY[page->page - 1] - scrollY;
- } else {
- tile->yDest = tile->yMin - scrollY;
- }
- if (continuousMode) {
- if (page->w < maxPageW) {
- tile->xDest += (maxPageW - page->w) / 2;
- }
- if (maxPageW < drawAreaWidth) {
- tile->xDest += (drawAreaWidth - maxPageW) / 2;
- }
- } else if (page->w < drawAreaWidth) {
- tile->xDest += (drawAreaWidth - page->w) / 2;
- }
- if (continuousMode && totalDocH < drawAreaHeight) {
- tile->yDest += (drawAreaHeight - totalDocH) / 2;
- } else if (!continuousMode && page->h < drawAreaHeight) {
- tile->yDest += (drawAreaHeight - page->h) / 2;
- }
- }
- }
-
- // redraw the selection
- if (selectULX != selectLRX && selectULY != selectLRY) {
- xorRectangle(selectPage, selectULX, selectULY, selectLRX, selectLRY,
- new SplashSolidColor(selectXorColor));
- }
-
- // redraw the window
- redrawWindow(0, 0, drawAreaWidth, drawAreaHeight, needUpdate);
+ // redraw
+ invalidateWholeWindow();
updateScrollbars();
// add to history
if (addToHist) {
- if (++historyCur == pdfHistorySize) {
- historyCur = 0;
- }
- hist = &history[historyCur];
- if (hist->fileName) {
-#ifdef _WIN32
- delete[] hist->fileName;
-#else
- delete hist->fileName;
-#endif
- }
-#ifdef _WIN32
- if (doc->getFileNameU()) {
- hist->fileName = (wchar_t *)gmallocn(MAX_PATH + 1, sizeof(wchar_t));
- if (GetFullPathNameW(doc->getFileNameU(), MAX_PATH + 1,
- hist->fileName, NULL) == 0) {
- delete[] hist->fileName;
- hist->fileName = NULL;
- }
- } else {
- hist->fileName = NULL;
- }
-#else
- if (doc->getFileName()) {
- hist->fileName = doc->getFileName()->copy();
- } else {
- hist->fileName = NULL;
- }
-#endif
- hist->page = topPage;
- if (historyBLen < pdfHistorySize) {
- ++historyBLen;
- }
- historyFLen = 0;
+ addToHistory();
}
}
-void PDFCore::addPage(int pg, int rot) {
- PDFCorePage *page;
- int w, h, t, tileW, tileH, i;
+void PDFCore::addToHistory() {
+ PDFHistory h;
+ PDFHistory *cur;
- w = (int)((doc->getPageCropWidth(pg) * dpi) / 72 + 0.5);
- h = (int)((doc->getPageCropHeight(pg) * dpi) / 72 + 0.5);
- if (rot == 90 || rot == 270) {
- t = w; w = h; h = t;
- }
- tileW = 2 * drawAreaWidth;
- if (tileW < 1500) {
- tileW = 1500;
- }
- if (tileW > w) {
- // tileW can't be zero -- we end up with div-by-zero problems
- tileW = w ? w : 1;
- }
- tileH = 2 * drawAreaHeight;
- if (tileH < 1500) {
- tileH = 1500;
- }
- if (tileH > h) {
- // tileH can't be zero -- we end up with div-by-zero problems
- tileH = h ? h : 1;
- }
- page = new PDFCorePage(pg, w, h, tileW, tileH);
- for (i = 0;
- i < pages->getLength() && pg > ((PDFCorePage *)pages->get(i))->page;
- ++i) ;
- pages->insert(i, page);
-}
-
-void PDFCore::needTile(PDFCorePage *page, int x, int y) {
- PDFCoreTile *tile;
- TextOutputControl textOutCtrl;
- TextOutputDev *textOut;
- int xDest, yDest, sliceW, sliceH;
- int i;
-
- for (i = 0; i < page->tiles->getLength(); ++i) {
- tile = (PDFCoreTile *)page->tiles->get(i);
- if (x == tile->xMin && y == tile->yMin) {
- return;
+ cur = &history[historyCur];
+ h.page = tileMap->getMidPage();
+#ifdef _WIN32
+ if (doc->getFileNameU()) {
+ h.fileName = (wchar_t *)gmallocn(MAX_PATH + 1, sizeof(wchar_t));
+ if (GetFullPathNameW(doc->getFileNameU(), MAX_PATH + 1,
+ h.fileName, NULL) == 0) {
+ h.fileName = NULL;
}
+ } else {
+ h.fileName = NULL;
}
-
- setBusyCursor(gTrue);
-
- sliceW = page->tileW;
- if (x + sliceW > page->w) {
- sliceW = page->w - x;
- }
- sliceH = page->tileH;
- if (y + sliceH > page->h) {
- sliceH = page->h - y;
- }
-
- xDest = x - scrollX;
- if (continuousMode) {
- yDest = y + pageY[page->page - 1] - scrollY;
+#else
+ if (doc->getFileName()) {
+ h.fileName = doc->getFileName()->copy();
} else {
- yDest = y - scrollY;
+ h.fileName = NULL;
}
- if (continuousMode) {
- if (page->w < maxPageW) {
- xDest += (maxPageW - page->w) / 2;
- }
- if (maxPageW < drawAreaWidth) {
- xDest += (drawAreaWidth - maxPageW) / 2;
- }
- } else if (page->w < drawAreaWidth) {
- xDest += (drawAreaWidth - page->w) / 2;
- }
- if (continuousMode && totalDocH < drawAreaHeight) {
- yDest += (drawAreaHeight - totalDocH) / 2;
- } else if (!continuousMode && page->h < drawAreaHeight) {
- yDest += (drawAreaHeight - page->h) / 2;
- }
- curTile = tile = newTile(xDest, yDest);
- curPage = page;
- tile->xMin = x;
- tile->yMin = y;
- tile->xMax = x + sliceW;
- tile->yMax = y + sliceH;
- tile->edges = 0;
- if (tile->xMin == 0) {
- tile->edges |= pdfCoreTileLeftEdge;
- }
- if (tile->xMax == page->w) {
- tile->edges |= pdfCoreTileRightEdge;
- }
- if (continuousMode) {
- if (tile->yMin == 0) {
- tile->edges |= pdfCoreTileTopSpace;
- if (page->page == 1) {
- tile->edges |= pdfCoreTileTopEdge;
- }
- }
- if (tile->yMax == page->h) {
- tile->edges |= pdfCoreTileBottomSpace;
- if (page->page == doc->getNumPages()) {
- tile->edges |= pdfCoreTileBottomEdge;
- }
+#endif
+ if (historyBLen > 0 && h.page == cur->page) {
+ if (!h.fileName && !cur->fileName) {
+ return;
}
- } else {
- if (tile->yMin == 0) {
- tile->edges |= pdfCoreTileTopEdge;
+#ifdef _WIN32
+ if (h.fileName && cur->fileName && !wcscmp(h.fileName, cur->fileName)) {
+ gfree(h.fileName);
+ return;
}
- if (tile->yMax == page->h) {
- tile->edges |= pdfCoreTileBottomEdge;
+#else
+ if (h.fileName && cur->fileName && !h.fileName->cmp(cur->fileName)) {
+ delete h.fileName;
+ return;
}
+#endif
}
- doc->displayPageSlice(out, page->page, dpi, dpi, rotate,
- gFalse, gTrue, gFalse, x, y, sliceW, sliceH);
- tile->bitmap = out->takeBitmap();
- memcpy(tile->ctm, out->getDefCTM(), 6 * sizeof(double));
- memcpy(tile->ictm, out->getDefICTM(), 6 * sizeof(double));
- if (!page->links) {
- page->links = doc->getLinks(page->page);
- }
- if (!page->text) {
- textOutCtrl.mode = textOutPhysLayout;
- if ((textOut = new TextOutputDev(NULL, &textOutCtrl, gFalse))) {
- doc->displayPage(textOut, page->page, dpi, dpi, rotate,
- gFalse, gTrue, gFalse);
- page->text = textOut->takeText();
- delete textOut;
- }
+ if (++historyCur == pdfHistorySize) {
+ historyCur = 0;
}
- page->tiles->append(tile);
- curTile = NULL;
- curPage = NULL;
-
- setBusyCursor(gFalse);
+ if (history[historyCur].fileName) {
+#ifdef _WIN32
+ gfree(history[historyCur].fileName);
+#else
+ delete history[historyCur].fileName;
+#endif
+ }
+ history[historyCur] = h;
+ if (historyBLen < pdfHistorySize) {
+ ++historyBLen;
+ }
+ historyFLen = 0;
}
GBool PDFCore::gotoNextPage(int inc, GBool top) {
- int pg, scrollYA;
+ GBool sideBySide;
+ int pg;
- if (!doc || doc->getNumPages() == 0 || topPage >= doc->getNumPages()) {
+ if (!doc || !doc->getNumPages()) {
return gFalse;
}
- if ((pg = topPage + inc) > doc->getNumPages()) {
- pg = doc->getNumPages();
+ pg = tileMap->getFirstPage();
+ sideBySide = state->displayModeIsSideBySide();
+ if (pg + (sideBySide ? 2 : 1) > doc->getNumPages()) {
+ return gFalse;
}
- if (continuousMode) {
- scrollYA = -1;
- } else if (top) {
- scrollYA = 0;
- } else {
- scrollYA = scrollY;
+ if (sideBySide && inc < 2) {
+ inc = 2;
+ }
+ if ((pg += inc) > doc->getNumPages()) {
+ pg = doc->getNumPages();
}
- update(pg, scrollX, scrollYA, zoom, rotate, gFalse, gTrue, gTrue);
+ displayPage(pg, top, gFalse);
return gTrue;
}
GBool PDFCore::gotoPrevPage(int dec, GBool top, GBool bottom) {
- int pg, scrollYA;
+ int pg;
- if (!doc || doc->getNumPages() == 0 || topPage <= 1) {
+ if (!doc || !doc->getNumPages()) {
return gFalse;
}
- if ((pg = topPage - dec) < 1) {
- pg = 1;
+ pg = tileMap->getFirstPage();
+ if (state->getDisplayMode() == displayContinuous &&
+ state->getScrollY() > tileMap->getPageTopY(pg)) {
+ ++pg;
+ } else if (state->getDisplayMode() == displaySideBySideContinuous &&
+ state->getScrollY() > tileMap->getPageTopY(pg)) {
+ pg += 2;
+ } else if (state->getDisplayMode() == displayHorizontalContinuous &&
+ state->getScrollX() > tileMap->getPageLeftX(pg)) {
+ ++pg;
+ }
+ if (pg <= 1) {
+ return gFalse;
}
- if (continuousMode) {
- scrollYA = -1;
- } else if (top) {
- scrollYA = 0;
- } else if (bottom) {
- scrollYA = ((PDFCorePage *)pages->get(0))->h - drawAreaHeight;
- if (scrollYA < 0) {
- scrollYA = 0;
- }
- } else {
- scrollYA = scrollY;
+ if (state->displayModeIsSideBySide() && dec < 2) {
+ dec = 2;
+ }
+ if ((pg -= dec) < 1) {
+ pg = 1;
}
- update(pg, scrollX, scrollYA, zoom, rotate, gFalse, gTrue, gTrue);
+ displayPage(pg, top, bottom);
return gTrue;
}
@@ -986,7 +528,7 @@ GBool PDFCore::gotoNamedDestination(GString *dest) {
if (!(d = doc->findDest(dest))) {
return gFalse;
}
- displayDest(d, zoom, rotate, gTrue);
+ displayDest(d);
delete d;
return gTrue;
}
@@ -1010,7 +552,7 @@ GBool PDFCore::goForward() {
!doc->getFileNameU() ||
wcscmp(history[historyCur].fileName, doc->getFileNameU()) != 0) {
if (loadFile(history[historyCur].fileName,
- wcslen(history[historyCur].fileName)) != errNone) {
+ (int)wcslen(history[historyCur].fileName)) != errNone) {
return gFalse;
}
}
@@ -1024,8 +566,7 @@ GBool PDFCore::goForward() {
}
#endif
pg = history[historyCur].page;
- update(pg, scrollX, continuousMode ? -1 : scrollY,
- zoom, rotate, gFalse, gFalse, gTrue);
+ displayPage(pg, gFalse, gFalse, gFalse);
return gTrue;
}
@@ -1048,7 +589,7 @@ GBool PDFCore::goBackward() {
!doc->getFileNameU() ||
wcscmp(history[historyCur].fileName, doc->getFileNameU()) != 0) {
if (loadFile(history[historyCur].fileName,
- wcslen(history[historyCur].fileName)) != errNone) {
+ (int)wcslen(history[historyCur].fileName)) != errNone) {
return gFalse;
}
}
@@ -1062,654 +603,737 @@ GBool PDFCore::goBackward() {
}
#endif
pg = history[historyCur].page;
- update(pg, scrollX, continuousMode ? -1 : scrollY,
- zoom, rotate, gFalse, gFalse, gTrue);
+ displayPage(pg, gFalse, gFalse, gFalse);
return gTrue;
}
void PDFCore::scrollLeft(int nCols) {
- scrollTo(scrollX - nCols, scrollY);
+ scrollTo(state->getScrollX() - nCols, state->getScrollY());
}
void PDFCore::scrollRight(int nCols) {
- scrollTo(scrollX + nCols, scrollY);
+ scrollTo(state->getScrollX() + nCols, state->getScrollY());
}
void PDFCore::scrollUp(int nLines) {
- scrollTo(scrollX, scrollY - nLines);
+ scrollTo(state->getScrollX(), state->getScrollY() - nLines);
}
void PDFCore::scrollUpPrevPage(int nLines) {
- if (!continuousMode && scrollY == 0) {
+ if (!state->displayModeIsContinuous() &&
+ state->getScrollY() == 0) {
gotoPrevPage(1, gFalse, gTrue);
} else {
- scrollTo(scrollX, scrollY - nLines);
+ scrollUp(nLines);
}
}
void PDFCore::scrollDown(int nLines) {
- scrollTo(scrollX, scrollY + nLines);
+ scrollTo(state->getScrollX(), state->getScrollY() + nLines);
}
void PDFCore::scrollDownNextPage(int nLines) {
- if (!continuousMode &&
- scrollY >= ((PDFCorePage *)pages->get(0))->h - drawAreaHeight) {
- gotoNextPage(1, gTrue);
+ int horizMax, vertMax;
+
+ if (!state->displayModeIsContinuous()) {
+ tileMap->getScrollLimits(&horizMax, &vertMax);
+ if (state->getScrollY() >= vertMax - state->getWinH()) {
+ gotoNextPage(1, gTrue);
+ } else {
+ scrollDown(nLines);
+ }
} else {
- scrollTo(scrollX, scrollY + nLines);
+ scrollDown(nLines);
}
}
void PDFCore::scrollPageUp() {
- if (!continuousMode && scrollY == 0) {
- gotoPrevPage(1, gFalse, gTrue);
- } else {
- scrollTo(scrollX, scrollY - drawAreaHeight);
- }
+ scrollUpPrevPage(state->getWinH());
}
void PDFCore::scrollPageDown() {
- if (!continuousMode &&
- pages->getLength() > 0 &&
- scrollY >= ((PDFCorePage *)pages->get(0))->h - drawAreaHeight) {
- gotoNextPage(1, gTrue);
- } else {
- scrollTo(scrollX, scrollY + drawAreaHeight);
- }
+ scrollDownNextPage(state->getWinH());
}
void PDFCore::scrollTo(int x, int y) {
- update(topPage, x, y < 0 ? 0 : y, zoom, rotate, gFalse, gFalse, gFalse);
+ startUpdate();
+ state->setScrollPosition(state->getScrollPage(), x, y);
+ finishUpdate(gTrue, gTrue);
}
void PDFCore::scrollToLeftEdge() {
- update(topPage, 0, scrollY, zoom, rotate, gFalse, gFalse, gFalse);
+ scrollTo(0, state->getScrollY());
}
void PDFCore::scrollToRightEdge() {
- PDFCorePage *page;
+ int horizMax, vertMax;
- page = (PDFCorePage *)pages->get(0);
- update(topPage, page->w - drawAreaWidth, scrollY,
- zoom, rotate, gFalse, gFalse, gFalse);
+ tileMap->getScrollLimits(&horizMax, &vertMax);
+ scrollTo(horizMax - state->getWinW(), state->getScrollY());
}
void PDFCore::scrollToTopEdge() {
- int y;
-
- y = continuousMode ? pageY[topPage - 1] : 0;
- update(topPage, scrollX, y, zoom, rotate, gFalse, gFalse, gFalse);
+ scrollTo(state->getScrollX(), tileMap->getPageTopY(tileMap->getFirstPage()));
}
void PDFCore::scrollToBottomEdge() {
- PDFCorePage *page;
- int y, i;
+ int horizMax, vertMax;
- for (i = pages->getLength() - 1; i > 0; --i) {
- page = (PDFCorePage *)pages->get(i);
- if (page->yDest < drawAreaHeight) {
- break;
- }
- }
- page = (PDFCorePage *)pages->get(i);
- if (continuousMode) {
- y = pageY[page->page - 1] + page->h - drawAreaHeight;
- } else {
- y = page->h - drawAreaHeight;
- }
- update(topPage, scrollX, y, zoom, rotate, gFalse, gFalse, gFalse);
+ tileMap->getScrollLimits(&horizMax, &vertMax);
+ scrollTo(state->getScrollX(), vertMax - state->getWinH());
}
void PDFCore::scrollToTopLeft() {
- int y;
-
- y = continuousMode ? pageY[topPage - 1] : 0;
- update(topPage, 0, y, zoom, rotate, gFalse, gFalse, gFalse);
+ scrollTo(0, tileMap->getPageTopY(tileMap->getFirstPage()));
}
void PDFCore::scrollToBottomRight() {
- PDFCorePage *page;
- int x, y, i;
+ int horizMax, vertMax;
- for (i = pages->getLength() - 1; i > 0; --i) {
- page = (PDFCorePage *)pages->get(i);
- if (page->yDest < drawAreaHeight) {
- break;
- }
+ tileMap->getScrollLimits(&horizMax, &vertMax);
+ scrollTo(horizMax - state->getWinW(), vertMax - state->getWinH());
+}
+
+void PDFCore::setZoom(double zoom) {
+ int page;
+
+ if (state->getZoom() == zoom) {
+ return;
}
- page = (PDFCorePage *)pages->get(i);
- x = page->w - drawAreaWidth;
- if (continuousMode) {
- y = pageY[page->page - 1] + page->h - drawAreaHeight;
- } else {
- y = page->h - drawAreaHeight;
+ if (!doc || !doc->getNumPages()) {
+ state->setZoom(zoom);
+ return;
}
- update(topPage, x, y, zoom, rotate, gFalse, gFalse, gFalse);
+ startUpdate();
+ page = tileMap->getFirstPage();
+ state->setZoom(zoom);
+ state->setScrollPosition(page, tileMap->getPageLeftX(page),
+ tileMap->getPageTopY(page));
+ finishUpdate(gTrue, gTrue);
}
-void PDFCore::zoomToRect(int pg, double ulx, double uly,
+void PDFCore::zoomToRect(int page, double ulx, double uly,
double lrx, double lry) {
- int x0, y0, x1, y1, u, sx, sy;
- double rx, ry, newZoom, t;
- PDFCorePage *p;
+ int x0, y0, x1, y1, sx, sy, t;
+ double dpi, rx, ry, zoom;
+
+ startUpdate();
- cvtUserToDev(pg, ulx, uly, &x0, &y0);
- cvtUserToDev(pg, lrx, lry, &x1, &y1);
+ // set the new zoom level
+ cvtUserToDev(page, ulx, uly, &x0, &y0);
+ cvtUserToDev(page, lrx, lry, &x1, &y1);
if (x0 > x1) {
- u = x0; x0 = x1; x1 = u;
+ t = x0; x0 = x1; x1 = t;
}
if (y0 > y1) {
- u = y0; y0 = y1; y1 = u;
+ t = y0; y0 = y1; y1 = t;
}
- rx = (double)drawAreaWidth / (double)(x1 - x0);
- ry = (double)drawAreaHeight / (double)(y1 - y0);
+ rx = (double)state->getWinW() / (double)(x1 - x0);
+ ry = (double)state->getWinH() / (double)(y1 - y0);
+ dpi = tileMap->getDPI(page);
if (rx < ry) {
- newZoom = rx * (dpi / (0.01 * 72));
- sx = (int)(rx * x0);
- t = (drawAreaHeight * (x1 - x0)) / drawAreaWidth;
- sy = (int)(rx * (y0 + y1 - t) / 2);
- if (continuousMode) {
- if ((p = findPage(pg)) && p->w < maxPageW) {
- sx += (int)(0.5 * rx * (maxPageW - p->w));
- }
- u = (pg - 1) * continuousModePageSpacing;
- sy += (int)(rx * (pageY[pg - 1] - u)) + u;
- }
+ zoom = rx * (dpi / (0.01 * 72));
} else {
- newZoom = ry * (dpi / (0.01 * 72));
- t = (drawAreaWidth * (y1 - y0)) / drawAreaHeight;
- sx = (int)(ry * (x0 + x1 - t) / 2);
- sy = (int)(ry * y0);
- if (continuousMode) {
- if ((p = findPage(pg)) && p->w < maxPageW) {
- sx += (int)(0.5 * rx * (maxPageW - p->w));
- }
- u = (pg - 1) * continuousModePageSpacing;
- sy += (int)(ry * (pageY[pg - 1] - u)) + u;
- }
+ zoom = ry * (dpi / (0.01 * 72));
}
- update(pg, sx, sy, newZoom, rotate, gFalse, gFalse, gFalse);
-}
-
-void PDFCore::zoomCentered(double zoomA) {
- int sx, sy, rot, hAdjust, vAdjust, i;
- double dpi1, dpi2, pageW, pageH;
- PDFCorePage *page;
-
- if (zoomA == zoomPage) {
- if (continuousMode) {
- pageW = (rotate == 90 || rotate == 270) ? maxUnscaledPageH
- : maxUnscaledPageW;
- pageH = (rotate == 90 || rotate == 270) ? maxUnscaledPageW
- : maxUnscaledPageH;
- dpi1 = 72.0 * (double)drawAreaWidth / pageW;
- dpi2 = 72.0 * (double)(drawAreaHeight - continuousModePageSpacing) /
- pageH;
- if (dpi2 < dpi1) {
- dpi1 = dpi2;
- }
- } else {
- // in single-page mode, sx=sy=0 -- so dpi1 is irrelevant
- dpi1 = dpi;
- }
- sx = 0;
+ state->setZoom(zoom);
- } else if (zoomA == zoomWidth) {
- if (continuousMode) {
- pageW = (rotate == 90 || rotate == 270) ? maxUnscaledPageH
- : maxUnscaledPageW;
- } else {
- rot = rotate + doc->getPageRotate(topPage);
- if (rot >= 360) {
- rot -= 360;
- } else if (rot < 0) {
- rot += 360;
- }
- pageW = (rot == 90 || rot == 270) ? doc->getPageCropHeight(topPage)
- : doc->getPageCropWidth(topPage);
- }
- dpi1 = 72.0 * (double)drawAreaWidth / pageW;
- sx = 0;
+ // scroll to the requested page
+ state->setScrollPosition(page, tileMap->getPageLeftX(page),
+ tileMap->getPageTopY(page));
- } else if (zoomA <= 0) {
- return;
+ // scroll the requested rectangle to the center of the window
+ cvtUserToWindow(page, 0.5 * (ulx + lrx), 0.5 * (uly + lry), &x0, &y0);
+ sx = state->getScrollX() + x0 - state->getWinW() / 2;
+ sy = state->getScrollY() + y0 - state->getWinH() / 2;
+ state->setScrollPosition(page, sx, sy);
- } else {
- dpi1 = 72.0 * zoomA / 100.0;
- if ((page = (PDFCorePage *)pages->get(0)) && page->xDest > 0) {
- hAdjust = page->xDest;
- } else {
- hAdjust = 0;
- }
- sx = (int)((scrollX - hAdjust + drawAreaWidth / 2) * (dpi1 / dpi)) -
- drawAreaWidth / 2;
- if (sx < 0) {
- sx = 0;
- }
- }
+ finishUpdate(gTrue, gFalse);
+}
- if (continuousMode) {
- // we can't just multiply scrollY by dpi1/dpi -- the rounding
- // errors add up (because the pageY values are integers) -- so
- // we compute the pageY values at the new zoom level instead
- sy = 0;
- for (i = 1; i < topPage; ++i) {
- rot = rotate + doc->getPageRotate(i);
- if (rot >= 360) {
- rot -= 360;
- } else if (rot < 0) {
- rot += 360;
- }
- if (rot == 90 || rot == 270) {
- sy += (int)((doc->getPageCropWidth(i) * dpi1) / 72 + 0.5);
- } else {
- sy += (int)((doc->getPageCropHeight(i) * dpi1) / 72 + 0.5);
- }
- }
- vAdjust = (topPage - 1) * continuousModePageSpacing;
- sy = sy + (int)((scrollY - pageY[topPage - 1] + drawAreaHeight / 2)
- * (dpi1 / dpi))
- + vAdjust - drawAreaHeight / 2;
- } else {
- sy = (int)((scrollY + drawAreaHeight / 2) * (dpi1 / dpi))
- - drawAreaHeight / 2;
+void PDFCore::zoomCentered(double zoom) {
+ int page, wx, wy, sx, sy;
+ double cx, cy;
+
+ if (state->getZoom() == zoom) {
+ return;
}
- update(topPage, sx, sy, zoomA, rotate, gFalse, gFalse, gFalse);
+ startUpdate();
+
+ // get the center of the window, in user coords
+ cvtWindowToUser(state->getWinW() / 2, state->getWinH() / 2,
+ &page, &cx, &cy);
+
+ // set the new zoom level
+ state->setZoom(zoom);
+
+ // scroll to re-center
+ cvtUserToWindow(page, cx, cy, &wx, &wy);
+ sx = state->getScrollX() + wx - state->getWinW() / 2;
+ sy = state->getScrollY() + wy - state->getWinH() / 2;
+ state->setScrollPosition(page, sx, sy);
+
+ finishUpdate(gTrue, gFalse);
}
// Zoom so that the current page(s) fill the window width. Maintain
// the vertical center.
void PDFCore::zoomToCurrentWidth() {
- double w, maxW, dpi1;
- int sx, sy, vAdjust, rot, i;
-
- // compute the maximum page width of visible pages
- rot = rotate + doc->getPageRotate(topPage);
- if (rot >= 360) {
- rot -= 360;
- } else if (rot < 0) {
- rot += 360;
- }
- if (rot == 90 || rot == 270) {
- maxW = doc->getPageCropHeight(topPage);
- } else {
- maxW = doc->getPageCropWidth(topPage);
- }
- if (continuousMode) {
- for (i = topPage + 1;
- i < doc->getNumPages() && pageY[i-1] < scrollY + drawAreaHeight;
- ++i) {
- rot = rotate + doc->getPageRotate(i);
- if (rot >= 360) {
- rot -= 360;
- } else if (rot < 0) {
- rot += 360;
+ int page0, page1, page, gap;
+ double w, w1, zoom;
+
+ startUpdate();
+
+ // get first and last pages
+ page0 = tileMap->getFirstPage();
+ page1 = tileMap->getLastPage();
+
+ // compute the desired width (in points)
+ gap = 0;
+ switch (state->getDisplayMode()) {
+ case displaySingle:
+ default:
+ w = tileMap->getPageBoxWidth(page0);
+ break;
+ case displayContinuous:
+ w = 0;
+ for (page = page0; page <= page1; ++page) {
+ w1 = tileMap->getPageBoxWidth(page);
+ if (w1 > w) {
+ w = w1;
}
- if (rot == 90 || rot == 270) {
- w = doc->getPageCropHeight(i);
- } else {
- w = doc->getPageCropWidth(i);
+ }
+ break;
+ case displaySideBySideSingle:
+ w = tileMap->getPageBoxWidth(page0);
+ if (page1 != page0) {
+ w += tileMap->getPageBoxWidth(page1);
+ gap = tileMap->getSideBySidePageSpacing();
+ }
+ break;
+ case displaySideBySideContinuous:
+ w = 0;
+ for (page = page0; w <= page1; w += 2) {
+ w1 = tileMap->getPageBoxWidth(page);
+ if (page + 1 <= doc->getNumPages()) {
+ w1 += tileMap->getPageBoxWidth(page + 1);
+ }
+ if (w1 > w) {
+ w = w1;
}
- if (w > maxW) {
- maxW = w;
+ }
+ gap = tileMap->getSideBySidePageSpacing();
+ break;
+ case displayHorizontalContinuous:
+ w = 0;
+ gap = 0;
+ for (page = page0; page <= page1; ++page) {
+ w += tileMap->getPageBoxWidth(page);
+ if (page != page0) {
+ gap += tileMap->getHorizContinuousPageSpacing();
}
}
+ break;
}
- // compute the resolution
- dpi1 = (drawAreaWidth / maxW) * 72;
+ // set the new zoom level
+ zoom = 100.0 * (state->getWinW() - gap) / w;
+ state->setZoom(zoom);
- // compute the horizontal scroll position
- if (continuousMode) {
- sx = ((int)(maxPageW * dpi1 / dpi) - drawAreaWidth) / 2;
- } else {
- sx = 0;
- }
-
- // compute the vertical scroll position
- if (continuousMode) {
- // we can't just multiply scrollY by dpi1/dpi -- the rounding
- // errors add up (because the pageY values are integers) -- so
- // we compute the pageY values at the new zoom level instead
- sy = 0;
- for (i = 1; i < topPage; ++i) {
- rot = rotate + doc->getPageRotate(i);
- if (rot >= 360) {
- rot -= 360;
- } else if (rot < 0) {
- rot += 360;
- }
- if (rot == 90 || rot == 270) {
- sy += (int)((doc->getPageCropWidth(i) * dpi1) / 72 + 0.5);
- } else {
- sy += (int)((doc->getPageCropHeight(i) * dpi1) / 72 + 0.5);
- }
- }
- vAdjust = (topPage - 1) * continuousModePageSpacing;
- sy = sy + (int)((scrollY - pageY[topPage - 1] + drawAreaHeight / 2)
- * (dpi1 / dpi))
- + vAdjust - drawAreaHeight / 2;
- } else {
- sy = (int)((scrollY + drawAreaHeight / 2) * (dpi1 / dpi))
- - drawAreaHeight / 2;
+ // scroll so that the first page is at the left edge of the window
+ state->setScrollPosition(page0, tileMap->getPageLeftX(page0),
+ tileMap->getPageTopY(page0));
+
+ finishUpdate(gTrue, gFalse);
+}
+
+void PDFCore::setRotate(int rotate) {
+ int page;
+
+ if (state->getRotate() == rotate) {
+ return;
}
+ if (!doc || !doc->getNumPages()) {
+ state->setRotate(rotate);
+ return;
+ }
+ startUpdate();
+ page = tileMap->getFirstPage();
+ state->setRotate(rotate);
+ state->setScrollPosition(page, tileMap->getPageLeftX(page),
+ tileMap->getPageTopY(page));
+ finishUpdate(gTrue, gTrue);
+}
+
+void PDFCore::setDisplayMode(DisplayMode mode) {
+ int page;
- update(topPage, sx, sy, (dpi1 * 100) / 72, rotate, gFalse, gFalse, gFalse);
+ if (state->getDisplayMode() == mode) {
+ return;
+ }
+ if (!doc || !doc->getNumPages()) {
+ state->setDisplayMode(mode);
+ return;
+ }
+ startUpdate();
+ page = tileMap->getFirstPage();
+ state->setDisplayMode(mode);
+ state->setScrollPosition(page, tileMap->getPageLeftX(page),
+ tileMap->getPageTopY(page));
+ finishUpdate(gTrue, gTrue);
}
-void PDFCore::setContinuousMode(GBool cm) {
- if (continuousMode != cm) {
- continuousMode = cm;
- update(topPage, scrollX, -1, zoom, rotate, gTrue, gFalse, gTrue);
+void PDFCore::setOCGState(OptionalContentGroup *ocg, GBool ocgState) {
+ if (ocgState != ocg->getState()) {
+ ocg->setState(ocgState);
+ state->optionalContentChanged();
+ invalidateWholeWindow();
+ }
+}
+
+void PDFCore::setSelectMode(SelectMode mode) {
+ if (mode != selectMode) {
+ selectMode = mode;
+ clearSelection();
}
}
void PDFCore::setSelectionColor(SplashColor color) {
- splashColorCopy(selectXorColor, color);
- splashColorXor(selectXorColor, paperColor);
+ int wx0, wy0, wx1, wy1;
+
+ state->setSelectColor(color);
+ if (state->hasSelection()) {
+ getSelectionBBox(&wx0, &wy0, &wx1, &wy1);
+ checkInvalidate(wx0, wy0, wx1 - wx0, wy1 - wy0);
+ }
}
-void PDFCore::setSelection(int newSelectPage,
- int newSelectULX, int newSelectULY,
- int newSelectLRX, int newSelectLRY) {
- int x0, y0, x1, y1, py;
- GBool haveSel, newHaveSel;
- GBool needRedraw, needScroll;
- GBool moveLeft, moveRight, moveTop, moveBottom;
- PDFCorePage *page;
+void PDFCore::setSelection(int page, int x0, int y0, int x1, int y1) {
+ SelectRect *rect;
+ GBool moveLeft, moveTop, moveRight, moveBottom, needScroll;
+ double selectX0, selectY0, selectX1, selectY1;
+ int oldWx0, oldWy0, oldWx1, oldWy1, ix0, iy0, ix1, iy1;
+ int wx0, wy0, wx1, wy1, sx, sy, t;
- haveSel = selectULX != selectLRX && selectULY != selectLRY;
- newHaveSel = newSelectULX != newSelectLRX && newSelectULY != newSelectLRY;
+ // if selection rectangle is empty, clear the selection
+ if (x0 == x1 || y0 == y1) {
+ clearSelection();
+ return;
+ }
- // erase old selection on off-screen bitmap
- needRedraw = gFalse;
- if (haveSel) {
- xorRectangle(selectPage, selectULX, selectULY, selectLRX, selectLRY,
- new SplashSolidColor(selectXorColor));
- needRedraw = gTrue;
+ // x0 = left, x1 = right
+ // y0 = top, y1 = bottom
+ if (x0 > x1) {
+ t = x0; x0 = x1; x1 = t;
+ }
+ if (y0 > y1) {
+ t = y0; y0 = y1; y1 = t;
}
- // draw new selection on off-screen bitmap
- if (newHaveSel) {
- xorRectangle(newSelectPage, newSelectULX, newSelectULY,
- newSelectLRX, newSelectLRY,
- new SplashSolidColor(selectXorColor));
- needRedraw = gTrue;
+ // convert new selection coords to user space and window space
+ tileMap->cvtDevToUser(page, x0, y0, &selectX0, &selectY0);
+ tileMap->cvtDevToUser(page, x1, y1, &selectX1, &selectY1);
+ cvtUserToWindow(page, selectX0, selectY0, &wx0, &wy0);
+ cvtUserToWindow(page, selectX1, selectY1, &wx1, &wy1);
+ if (wx0 > wx1) {
+ t = wx0; wx0 = wx1; wx1 = t;
+ }
+ if (wy0 > wy1) {
+ t = wy0; wy0 = wy1; wy1 = t;
}
+ // convert current selection coords to window space;
// check which edges moved
- if (!haveSel || newSelectPage != selectPage) {
- moveLeft = moveTop = moveRight = moveBottom = gTrue;
+ if (state->hasSelection()) {
+ rect = state->getSelectRect(0);
+ tileMap->cvtUserToWindow(rect->page, rect->x0, rect->y0, &oldWx0, &oldWy0);
+ tileMap->cvtUserToWindow(rect->page, rect->x1, rect->y1, &oldWx1, &oldWy1);
+ if (oldWx0 > oldWx1) {
+ t = oldWx0; oldWx0 = oldWx1; oldWx1 = t;
+ }
+ if (oldWy0 > oldWy1) {
+ t = oldWy0; oldWy0 = oldWy1; oldWy1 = t;
+ }
+ moveLeft = wx0 != oldWx0;
+ moveTop = wy0 != oldWy0;
+ moveRight = wx1 != oldWx1;
+ moveBottom = wy1 != oldWy1;
} else {
- moveLeft = newSelectULX != selectULX;
- moveTop = newSelectULY != selectULY;
- moveRight = newSelectLRX != selectLRX;
- moveBottom = newSelectLRY != selectLRY;
- }
-
- // redraw currently visible part of bitmap
- if (needRedraw) {
- if (!haveSel) {
- page = findPage(newSelectPage);
- x0 = newSelectULX;
- y0 = newSelectULY;
- x1 = newSelectLRX;
- y1 = newSelectLRY;
- redrawWindow(page->xDest + x0, page->yDest + y0,
- x1 - x0 + 1, y1 - y0 + 1, gFalse);
- } else if (!newHaveSel) {
- if ((page = findPage(selectPage))) {
- x0 = selectULX;
- y0 = selectULY;
- x1 = selectLRX;
- y1 = selectLRY;
- redrawWindow(page->xDest + x0, page->yDest + y0,
- x1 - x0 + 1, y1 - y0 + 1, gFalse);
- }
- } else {
- page = findPage(newSelectPage);
- if (moveLeft) {
- x0 = newSelectULX < selectULX ? newSelectULX : selectULX;
- y0 = newSelectULY < selectULY ? newSelectULY : selectULY;
- x1 = newSelectULX > selectULX ? newSelectULX : selectULX;
- y1 = newSelectLRY > selectLRY ? newSelectLRY : selectLRY;
- redrawWindow(page->xDest + x0, page->yDest + y0,
- x1 - x0 + 1, y1 - y0 + 1, gFalse);
- }
- if (moveRight) {
- x0 = newSelectLRX < selectLRX ? newSelectLRX : selectLRX;
- y0 = newSelectULY < selectULY ? newSelectULY : selectULY;
- x1 = newSelectLRX > selectLRX ? newSelectLRX : selectLRX;
- y1 = newSelectLRY > selectLRY ? newSelectLRY : selectLRY;
- redrawWindow(page->xDest + x0, page->yDest + y0,
- x1 - x0 + 1, y1 - y0 + 1, gFalse);
- }
- if (moveTop) {
- x0 = newSelectULX < selectULX ? newSelectULX : selectULX;
- y0 = newSelectULY < selectULY ? newSelectULY : selectULY;
- x1 = newSelectLRX > selectLRX ? newSelectLRX : selectLRX;
- y1 = newSelectULY > selectULY ? newSelectULY : selectULY;
- redrawWindow(page->xDest + x0, page->yDest + y0,
- x1 - x0 + 1, y1 - y0 + 1, gFalse);
- }
- if (moveBottom) {
- x0 = newSelectULX < selectULX ? newSelectULX : selectULX;
- y0 = newSelectLRY < selectLRY ? newSelectLRY : selectLRY;
- x1 = newSelectLRX > selectLRX ? newSelectLRX : selectLRX;
- y1 = newSelectLRY > selectLRY ? newSelectLRY : selectLRY;
- redrawWindow(page->xDest + x0, page->yDest + y0,
- x1 - x0 + 1, y1 - y0 + 1, gFalse);
- }
- }
+ oldWx0 = wx0;
+ oldWy0 = wy0;
+ oldWx1 = wx1;
+ oldWy1 = wy1;
+ moveLeft = moveTop = moveRight = moveBottom = gTrue;
}
- // switch to new selection coords
- selectPage = newSelectPage;
- selectULX = newSelectULX;
- selectULY = newSelectULY;
- selectLRX = newSelectLRX;
- selectLRY = newSelectLRY;
+ // set the new selection
+ state->setSelection(page, selectX0, selectY0, selectX1, selectY1);
// scroll if necessary
- if (newHaveSel) {
- page = findPage(selectPage);
- needScroll = gFalse;
- x0 = scrollX;
- y0 = scrollY;
- if (moveLeft && page->xDest + selectULX < 0) {
- x0 += page->xDest + selectULX;
- needScroll = gTrue;
- } else if (moveRight && page->xDest + selectLRX >= drawAreaWidth) {
- x0 += page->xDest + selectLRX - drawAreaWidth;
- needScroll = gTrue;
- } else if (moveLeft && page->xDest + selectULX >= drawAreaWidth) {
- x0 += page->xDest + selectULX - drawAreaWidth;
- needScroll = gTrue;
- } else if (moveRight && page->xDest + selectLRX < 0) {
- x0 += page->xDest + selectLRX;
- needScroll = gTrue;
- }
- py = continuousMode ? pageY[selectPage - 1] : 0;
- if (moveTop && py + selectULY < y0) {
- y0 = py + selectULY;
- needScroll = gTrue;
- } else if (moveBottom && py + selectLRY >= y0 + drawAreaHeight) {
- y0 = py + selectLRY - drawAreaHeight;
- needScroll = gTrue;
- } else if (moveTop && py + selectULY >= y0 + drawAreaHeight) {
- y0 = py + selectULY - drawAreaHeight;
- needScroll = gTrue;
- } else if (moveBottom && py + selectLRY < y0) {
- y0 = py + selectLRY;
- needScroll = gTrue;
- }
- if (needScroll) {
- scrollTo(x0, y0);
- }
+ needScroll = gFalse;
+ sx = state->getScrollX();
+ sy = state->getScrollY();
+ if (moveLeft && wx0 < 0) {
+ sx += wx0;
+ needScroll = gTrue;
+ } else if (moveRight && wx1 >= state->getWinW()) {
+ sx += wx1 - state->getWinW();
+ needScroll = gTrue;
+ } else if (moveLeft && wx0 >= state->getWinW()) {
+ sx += wx0 - state->getWinW();
+ needScroll = gTrue;
+ } else if (moveRight && wx1 < 0) {
+ sx += wx1;
+ needScroll = gTrue;
+ }
+ if (moveTop && wy0 < 0) {
+ sy += wy0;
+ needScroll = gTrue;
+ } else if (moveBottom && wy1 >= state->getWinH()) {
+ sy += wy1 - state->getWinH();
+ needScroll = gTrue;
+ } else if (moveTop && wy0 >= state->getWinH()) {
+ sy += wy0 - state->getWinH();
+ needScroll = gTrue;
+ } else if (moveBottom && wy1 < 0) {
+ sy += wy1;
+ needScroll = gTrue;
+ }
+ if (needScroll) {
+ scrollTo(sx, sy);
+ } else {
+ ix0 = (wx0 < oldWx0) ? wx0 : oldWx0;
+ iy0 = (wy0 < oldWy0) ? wy0 : oldWy0;
+ ix1 = (wx1 > oldWx1) ? wx1 : oldWx1;
+ iy1 = (wy1 > oldWy1) ? wy1 : oldWy1;
+ checkInvalidate(ix0, iy0, ix1 - ix0, iy1 - iy0);
}
}
-void PDFCore::moveSelection(int pg, int x, int y) {
- int newSelectULX, newSelectULY, newSelectLRX, newSelectLRY;
+void PDFCore::setLinearSelection(int page, TextPosition *pos0,
+ TextPosition *pos1) {
+ TextPosition begin, end;
+ GList *rects;
+ GBool moveLeft, moveTop, moveRight, moveBottom, needScroll;
+ double x0, y0, x1, y1, x2, y2, x3, y3;
+ double ux0, uy0, ux1, uy1;
+ int oldWx0, oldWy0, oldWx1, oldWy1, ix0, iy0, ix1, iy1;
+ int wx0, wy0, wx1, wy1;
+ int sx, sy, colIdx;
- // don't allow selections to span multiple pages
- if (pg != selectPage) {
+
+ // if selection rectangle is empty, clear the selection
+ if (*pos0 == *pos1) {
+ clearSelection();
return;
}
- // move appropriate edges of selection
- if (lastDragLeft) {
- if (x < selectLRX) {
- newSelectULX = x;
- newSelectLRX = selectLRX;
- } else {
- newSelectULX = selectLRX;
- newSelectLRX = x;
- lastDragLeft = gFalse;
- }
+ // swap into correct order
+ if (*pos0 < *pos1) {
+ begin = *pos0;
+ end = *pos1;
} else {
- if (x > selectULX) {
- newSelectULX = selectULX;
- newSelectLRX = x;
- } else {
- newSelectULX = x;
- newSelectLRX = selectULX;
- lastDragLeft = gTrue;
- }
+ begin = *pos1;
+ end = *pos0;
+ }
+
+ // build the list of rectangles
+ //~ this doesn't handle RtL, vertical, or rotated text
+ loadText(selectPage);
+ rects = new GList();
+ if (begin.colIdx == end.colIdx &&
+ begin.parIdx == end.parIdx &&
+ begin.lineIdx == end.lineIdx) {
+ // same line
+ text->convertPosToPointUpper(&begin, &x0, &y0);
+ text->convertPosToPointLower(&end, &x1, &y1);
+ cvtDevToUser(selectPage, (int)(x0 + 0.5), (int)(y0 + 0.5), &ux0, &uy0);
+ cvtDevToUser(selectPage, (int)(x1 + 0.5), (int)(y1 + 0.5), &ux1, &uy1);
+ rects->append(new SelectRect(selectPage, ux0, uy0, ux1, uy1));
+ } else if (begin.colIdx == end.colIdx) {
+ // same column
+ text->convertPosToPointUpper(&begin, &x0, &y0);
+ text->convertPosToPointRightEdge(&begin, &x1, &y1);
+ text->convertPosToPointLeftEdge(&end, &x2, &y2);
+ text->convertPosToPointLower(&end, &x3, &y3);
+ cvtDevToUser(selectPage, (int)(x0 + 0.5), (int)(y0 + 0.5), &ux0, &uy0);
+ cvtDevToUser(selectPage, (int)(x1 + 0.5), (int)(y1 + 0.5), &ux1, &uy1);
+ rects->append(new SelectRect(selectPage, ux0, uy0, ux1, uy1));
+ cvtDevToUser(selectPage, (int)(x2 + 0.5), (int)(y1 + 0.5), &ux0, &uy0);
+ cvtDevToUser(selectPage, (int)(x1 + 0.5), (int)(y2 + 0.5), &ux1, &uy1);
+ rects->append(new SelectRect(selectPage, ux0, uy0, ux1, uy1));
+ cvtDevToUser(selectPage, (int)(x2 + 0.5), (int)(y2 + 0.5), &ux0, &uy0);
+ cvtDevToUser(selectPage, (int)(x3 + 0.5), (int)(y3 + 0.5), &ux1, &uy1);
+ rects->append(new SelectRect(selectPage, ux0, uy0, ux1, uy1));
+ } else {
+ // different columns
+ text->convertPosToPointUpper(&begin, &x0, &y0);
+ text->convertPosToPointRightEdge(&begin, &x1, &y1);
+ text->getColumnLowerLeft(begin.colIdx, &x2, &y2);
+ cvtDevToUser(selectPage, (int)(x0 + 0.5), (int)(y0 + 0.5), &ux0, &uy0);
+ cvtDevToUser(selectPage, (int)(x1 + 0.5), (int)(y1 + 0.5), &ux1, &uy1);
+ rects->append(new SelectRect(selectPage, ux0, uy0, ux1, uy1));
+ cvtDevToUser(selectPage, (int)(x2 + 0.5), (int)(y1 + 0.5), &ux0, &uy0);
+ cvtDevToUser(selectPage, (int)(x1 + 0.5), (int)(y2 + 0.5), &ux1, &uy1);
+ rects->append(new SelectRect(selectPage, ux0, uy0, ux1, uy1));
+ for (colIdx = begin.colIdx + 1; colIdx < end.colIdx; ++colIdx) {
+ text->getColumnLowerLeft(colIdx, &x0, &y0);
+ text->getColumnUpperRight(colIdx, &x1, &y1);
+ cvtDevToUser(selectPage, (int)(x0 + 0.5), (int)(y1 + 0.5), &ux0, &uy0);
+ cvtDevToUser(selectPage, (int)(x1 + 0.5), (int)(y0 + 0.5), &ux1, &uy1);
+ rects->append(new SelectRect(selectPage, ux0, uy0, ux1, uy1));
+ }
+ text->getColumnUpperRight(end.colIdx, &x0, &y0);
+ text->convertPosToPointLeftEdge(&end, &x1, &y1);
+ text->convertPosToPointLower(&end, &x2, &y2);
+ cvtDevToUser(selectPage, (int)(x1 + 0.5), (int)(y0 + 0.5), &ux0, &uy0);
+ cvtDevToUser(selectPage, (int)(x0 + 0.5), (int)(y1 + 0.5), &ux1, &uy1);
+ rects->append(new SelectRect(selectPage, ux0, uy0, ux1, uy1));
+ cvtDevToUser(selectPage, (int)(x1 + 0.5), (int)(y1 + 0.5), &ux0, &uy0);
+ cvtDevToUser(selectPage, (int)(x2 + 0.5), (int)(y2 + 0.5), &ux1, &uy1);
+ rects->append(new SelectRect(selectPage, ux0, uy0, ux1, uy1));
+ }
+
+ // get window coord bboxes for old selection and new selection;
+ // check which edges moved
+ if (state->hasSelection()) {
+ getSelectionBBox(&oldWx0, &oldWy0, &oldWx1, &oldWy1);
+ getSelectRectListBBox(rects, &wx0, &wy0, &wx1, &wy1);
+ moveLeft = wx0 != oldWx0;
+ moveTop = wy0 != oldWy0;
+ moveRight = wx1 != oldWx1;
+ moveBottom = wy1 != oldWy1;
+ } else {
+ getSelectRectListBBox(rects, &wx0, &wy0, &wx1, &wy1);
+ oldWx0 = wx0;
+ oldWy0 = wy0;
+ oldWx1 = wx1;
+ oldWy1 = wy1;
+ moveLeft = moveTop = moveRight = moveBottom = gTrue;
}
- if (lastDragTop) {
- if (y < selectLRY) {
- newSelectULY = y;
- newSelectLRY = selectLRY;
- } else {
- newSelectULY = selectLRY;
- newSelectLRY = y;
- lastDragTop = gFalse;
- }
+
+ // set the new selection
+ state->setSelection(rects);
+
+ // scroll if necessary
+ needScroll = gFalse;
+ sx = state->getScrollX();
+ sy = state->getScrollY();
+ if (moveLeft && wx0 < 0) {
+ sx += wx0;
+ needScroll = gTrue;
+ } else if (moveRight && wx1 >= state->getWinW()) {
+ sx += wx1 - state->getWinW();
+ needScroll = gTrue;
+ } else if (moveLeft && wx0 >= state->getWinW()) {
+ sx += wx0 - state->getWinW();
+ needScroll = gTrue;
+ } else if (moveRight && wx1 < 0) {
+ sx += wx1;
+ needScroll = gTrue;
+ }
+ if (moveTop && wy0 < 0) {
+ sy += wy0;
+ needScroll = gTrue;
+ } else if (moveBottom && wy1 >= state->getWinH()) {
+ sy += wy1 - state->getWinH();
+ needScroll = gTrue;
+ } else if (moveTop && wy0 >= state->getWinH()) {
+ sy += wy0 - state->getWinH();
+ needScroll = gTrue;
+ } else if (moveBottom && wy1 < 0) {
+ sy += wy1;
+ needScroll = gTrue;
+ }
+ if (needScroll) {
+ scrollTo(sx, sy);
} else {
- if (y > selectULY) {
- newSelectULY = selectULY;
- newSelectLRY = y;
+ ix0 = (wx0 < oldWx0) ? wx0 : oldWx0;
+ iy0 = (wy0 < oldWy0) ? wy0 : oldWy0;
+ ix1 = (wx1 > oldWx1) ? wx1 : oldWx1;
+ iy1 = (wy1 > oldWy1) ? wy1 : oldWy1;
+ checkInvalidate(ix0, iy0, ix1 - ix0, iy1 - iy0);
+ }
+}
+
+void PDFCore::clearSelection() {
+ int wx0, wy0, wx1, wy1;
+
+ if (state->hasSelection()) {
+ getSelectionBBox(&wx0, &wy0, &wx1, &wy1);
+ state->clearSelection();
+ checkInvalidate(wx0, wy0, wx1 - wx0, wy1 - wy0);
+ }
+}
+
+void PDFCore::startSelectionDrag(int pg, int x, int y) {
+ clearSelection();
+ if (selectMode == selectModeBlock) {
+ selectPage = pg;
+ selectStartX = x;
+ selectStartY = y;
+ } else { // selectModeLinear
+ loadText(pg);
+ if (text->findPointInside(x, y, &selectStartPos)) {
+ selectPage = pg;
} else {
- newSelectULY = y;
- newSelectLRY = selectULY;
- lastDragTop = gTrue;
+ selectPage = 0;
}
}
-
- // redraw the selection
- setSelection(selectPage, newSelectULX, newSelectULY,
- newSelectLRX, newSelectLRY);
}
-void PDFCore::xorRectangle(int pg, int x0, int y0, int x1, int y1,
- SplashPattern *pattern, PDFCoreTile *oneTile) {
- Splash *splash;
- SplashPath *path;
- PDFCorePage *page;
- PDFCoreTile *tile;
- SplashCoord xx0, yy0, xx1, yy1;
- int xi, yi, wi, hi;
- int i;
+void PDFCore::moveSelectionDrag(int pg, int x, int y) {
+ TextPosition pos;
- if ((page = findPage(pg))) {
- for (i = 0; i < page->tiles->getLength(); ++i) {
- tile = (PDFCoreTile *)page->tiles->get(i);
- if (!oneTile || tile == oneTile) {
- splash = new Splash(tile->bitmap, gFalse);
- splash->setFillPattern(pattern->copy());
- xx0 = (SplashCoord)(x0 - tile->xMin);
- yy0 = (SplashCoord)(y0 - tile->yMin);
- xx1 = (SplashCoord)(x1 - tile->xMin);
- yy1 = (SplashCoord)(y1 - tile->yMin);
- path = new SplashPath();
- path->moveTo(xx0, yy0);
- path->lineTo(xx1, yy0);
- path->lineTo(xx1, yy1);
- path->lineTo(xx0, yy1);
- path->close();
- splash->xorFill(path, gTrue);
- delete path;
- delete splash;
- xi = x0 - tile->xMin;
- wi = x1 - x0;
- if (xi < 0) {
- wi += xi;
- xi = 0;
- }
- if (xi + wi > tile->bitmap->getWidth()) {
- wi = tile->bitmap->getWidth() - xi;
- }
- yi = y0 - tile->yMin;
- hi = y1 - y0;
- if (yi < 0) {
- hi += yi;
- yi = 0;
- }
- if (yi + hi > tile->bitmap->getHeight()) {
- hi = tile->bitmap->getHeight() - yi;
- }
- updateTileData(tile, xi, yi, wi, hi, gTrue);
- }
+ // don't allow selections to span multiple pages
+ // -- this also handles the case where a linear selection was started
+ // outside any text column, in which case selectPage = 0
+ if (pg != selectPage) {
+ return;
+ }
+
+ if (selectMode == selectModeBlock) {
+ setSelection(pg, selectStartX, selectStartY, x, y);
+ } else { // selectModeLinear
+ loadText(pg);
+ if (text->findPointNear(x, y, &pos)) {
+ setLinearSelection(pg, &selectStartPos, &pos);
}
}
- delete pattern;
+}
+
+void PDFCore::finishSelectionDrag() {
+ selectPage = 0;
+ selectStartX = selectStartY = 0;
}
GBool PDFCore::getSelection(int *pg, double *ulx, double *uly,
double *lrx, double *lry) {
- if (selectULX == selectLRX || selectULY == selectLRY) {
+ SelectRect *rect;
+ double xMin, yMin, xMax, yMax;
+ int page, i;
+
+ if (!state->hasSelection()) {
return gFalse;
}
- *pg = selectPage;
- cvtDevToUser(selectPage, selectULX, selectULY, ulx, uly);
- cvtDevToUser(selectPage, selectLRX, selectLRY, lrx, lry);
+ page = state->getSelectRect(0)->page;
+ xMin = yMin = xMax = yMax = 0;
+ for (i = 0; i < state->getNumSelectRects(); ++i) {
+ rect = state->getSelectRect(i);
+ if (rect->page != page) {
+ continue;
+ }
+ if (i == 0) {
+ xMin = xMax = rect->x0;
+ yMin = yMax = rect->y0;
+ } else {
+ if (rect->x0 < xMin) {
+ xMin = rect->x0;
+ } else if (rect->x0 > xMax) {
+ xMax = rect->x0;
+ }
+ if (rect->y0 < yMin) {
+ yMin = rect->y0;
+ } else if (rect->y0 > yMax) {
+ yMax = rect->y0;
+ }
+ }
+ if (rect->x1 < xMin) {
+ xMin = rect->x1;
+ } else if (rect->x1 > xMax) {
+ xMax = rect->x1;
+ }
+ if (rect->y1 < yMin) {
+ yMin = rect->y1;
+ } else if (rect->y1 > yMax) {
+ yMax = rect->y1;
+ }
+ }
+ *pg = page;
+ *ulx = xMin;
+ *uly = yMax;
+ *lrx = xMax;
+ *lry = yMin;
return gTrue;
}
+GBool PDFCore::hasSelection() {
+ return state->hasSelection();
+}
+
+void PDFCore::setTextExtractionMode(TextOutputMode mode) {
+ if (textOutCtrl.mode != mode) {
+ textOutCtrl.mode = mode;
+ if (text) {
+ delete text;
+ text = NULL;
+ }
+ textPage = 0;
+ textDPI = 0;
+ textRotate = 0;
+ }
+}
+
+GBool PDFCore::getDiscardDiagonalText() {
+ return textOutCtrl.discardDiagonalText;
+}
+
+void PDFCore::setDiscardDiagonalText(GBool discard) {
+ if (textOutCtrl.discardDiagonalText != discard) {
+ textOutCtrl.discardDiagonalText = discard;
+ if (text) {
+ delete text;
+ text = NULL;
+ }
+ textPage = 0;
+ textDPI = 0;
+ textRotate = 0;
+ }
+}
+
GString *PDFCore::extractText(int pg, double xMin, double yMin,
double xMax, double yMax) {
- PDFCorePage *page;
- TextOutputControl textOutCtrl;
- TextOutputDev *textOut;
int x0, y0, x1, y1, t;
- GString *s;
- if (!doc->okToCopy()) {
+ loadText(pg);
+ cvtUserToDev(pg, xMin, yMin, &x0, &y0);
+ cvtUserToDev(pg, xMax, yMax, &x1, &y1);
+ if (x0 > x1) {
+ t = x0; x0 = x1; x1 = t;
+ }
+ if (y0 > y1) {
+ t = y0; y0 = y1; y1 = t;
+ }
+ return text->getText(x0, y0, x1, y1);
+}
+
+GString *PDFCore::getSelectedText() {
+ SelectRect *rect;
+ GString *ret, *s;
+ int x0, y0, x1, y1, t, i;
+
+ if (!state->hasSelection()) {
return NULL;
}
- if ((page = findPage(pg))) {
- cvtUserToDev(pg, xMin, yMin, &x0, &y0);
- cvtUserToDev(pg, xMax, yMax, &x1, &y1);
+ ret = new GString();
+ for (i = 0; i < state->getNumSelectRects(); ++i) {
+ rect = state->getSelectRect(i);
+ loadText(rect->page);
+ cvtUserToDev(rect->page, rect->x0, rect->y0, &x0, &y0);
+ cvtUserToDev(rect->page, rect->x1, rect->y1, &x1, &y1);
if (x0 > x1) {
t = x0; x0 = x1; x1 = t;
}
if (y0 > y1) {
t = y0; y0 = y1; y1 = t;
}
- s = page->text->getText(x0, y0, x1, y1);
- } else {
- textOutCtrl.mode = textOutPhysLayout;
- textOut = new TextOutputDev(NULL, &textOutCtrl, gFalse);
- if (textOut->isOk()) {
- doc->displayPage(textOut, pg, dpi, dpi, rotate, gFalse, gTrue, gFalse);
- textOut->cvtUserToDev(xMin, yMin, &x0, &y0);
- textOut->cvtUserToDev(xMax, yMax, &x1, &y1);
- if (x0 > x1) {
- t = x0; x0 = x1; x1 = t;
- }
- if (y0 > y1) {
- t = y0; y0 = y1; y1 = t;
- }
- s = textOut->getText(x0, y0, x1, y1);
- } else {
- s = new GString();
- }
- delete textOut;
+ s = text->getText(x0, y0, x1, y1, state->getNumSelectRects() > 1);
+ ret->append(s);
+ delete s;
}
- return s;
+ return ret;
}
GBool PDFCore::find(char *s, GBool caseSensitive, GBool next, GBool backward,
@@ -1734,11 +1358,10 @@ GBool PDFCore::find(char *s, GBool caseSensitive, GBool next, GBool backward,
GBool PDFCore::findU(Unicode *u, int len, GBool caseSensitive,
GBool next, GBool backward, GBool wholeWord,
GBool onePageOnly) {
- TextOutputControl textOutCtrl;
TextOutputDev *textOut;
+ SelectRect *rect;
double xMin, yMin, xMax, yMax;
- PDFCorePage *page;
- int pg;
+ int topPage, pg, x, y, x2, y2;
GBool startAtTop, startAtLast, stopAtLast;
// check for zero-length string
@@ -1751,36 +1374,46 @@ GBool PDFCore::findU(Unicode *u, int len, GBool caseSensitive,
// search current page starting at previous result, current
// selection, or top/bottom of page
startAtTop = startAtLast = gFalse;
+ rect = NULL;
xMin = yMin = xMax = yMax = 0;
+ topPage = tileMap->getFirstPage();
pg = topPage;
if (next) {
- startAtLast = gTrue;
- } else if (selectULX != selectLRX && selectULY != selectLRY) {
- pg = selectPage;
+ if (textPage >= 1 && textPage <= doc->getNumPages()) {
+ startAtLast = gTrue;
+ pg = textPage;
+ }
+ } else if (state->hasSelection()) {
+ rect = state->getSelectRect(0);
+ pg = rect->page;
+ cvtUserToDev(pg, rect->x0, rect->y0, &x, &y);
+ cvtUserToDev(pg, rect->x1, rect->y1, &x2, &y2);
+ if (x2 < x) {
+ x = x2;
+ }
+ if (y2 < y) {
+ y = y2;
+ }
if (backward) {
- xMin = selectULX - 1;
- yMin = selectULY - 1;
+ xMin = x - 1;
+ yMin = y - 1;
} else {
- xMin = selectULX + 1;
- yMin = selectULY + 1;
+ xMin = x + 1;
+ yMin = y + 1;
}
} else {
startAtTop = gTrue;
}
- if (!(page = findPage(pg))) {
- displayPage(pg, zoom, rotate, gTrue, gFalse);
- page = findPage(pg);
- }
- if (page->text->findText(u, len, startAtTop, gTrue, startAtLast, gFalse,
- caseSensitive, backward, wholeWord,
- &xMin, &yMin, &xMax, &yMax)) {
+ loadText(pg);
+ if (text->findText(u, len, startAtTop, gTrue, startAtLast, gFalse,
+ caseSensitive, backward, wholeWord,
+ &xMin, &yMin, &xMax, &yMax)) {
goto found;
}
if (!onePageOnly) {
// search following/previous pages
- textOutCtrl.mode = textOutPhysLayout;
textOut = new TextOutputDev(NULL, &textOutCtrl, gFalse);
if (!textOut->isOk()) {
delete textOut;
@@ -1822,12 +1455,13 @@ GBool PDFCore::findU(Unicode *u, int len, GBool caseSensitive,
stopAtLast = gTrue;
} else {
stopAtLast = gFalse;
- xMax = selectLRX;
- yMax = selectLRY;
+ cvtUserToDev(pg, rect->x1, rect->y1, &x, &y);
+ xMax = x;
+ yMax = y;
}
- if (page->text->findText(u, len, gTrue, gFalse, gFalse, stopAtLast,
- caseSensitive, backward, wholeWord,
- &xMin, &yMin, &xMax, &yMax)) {
+ if (text->findText(u, len, gTrue, gFalse, gFalse, stopAtLast,
+ caseSensitive, backward, wholeWord,
+ &xMin, &yMin, &xMax, &yMax)) {
goto found;
}
}
@@ -1839,12 +1473,11 @@ GBool PDFCore::findU(Unicode *u, int len, GBool caseSensitive,
// found on a different page
foundPage:
- update(pg, scrollX, continuousMode ? -1 : 0, zoom, rotate, gFalse, gTrue,
- gTrue);
- page = findPage(pg);
- if (!page->text->findText(u, len, gTrue, gTrue, gFalse, gFalse,
- caseSensitive, backward, wholeWord,
- &xMin, &yMin, &xMax, &yMax)) {
+ displayPage(pg, gTrue, gFalse);
+ loadText(pg);
+ if (!text->findText(u, len, gTrue, gTrue, gFalse, gFalse,
+ caseSensitive, backward, wholeWord,
+ &xMin, &yMin, &xMax, &yMax)) {
// this can happen if coalescing is bad
goto notFound;
}
@@ -1861,304 +1494,380 @@ GBool PDFCore::findU(Unicode *u, int len, GBool caseSensitive,
GBool PDFCore::cvtWindowToUser(int xw, int yw,
int *pg, double *xu, double *yu) {
- PDFCorePage *page;
- PDFCoreTile *tile;
- int i;
+ return tileMap->cvtWindowToUser(xw, yw, pg, xu, yu);
+}
- for (i = 0; i < pages->getLength(); ++i) {
- page = (PDFCorePage *)pages->get(i);
- if (xw >= page->xDest && xw < page->xDest + page->w &&
- yw >= page->yDest && yw < page->yDest + page->h) {
- if (page->tiles->getLength() == 0) {
- break;
- }
- tile = (PDFCoreTile *)page->tiles->get(0);
- *pg = page->page;
- xw -= tile->xDest;
- yw -= tile->yDest;
- *xu = tile->ictm[0] * xw + tile->ictm[2] * yw + tile->ictm[4];
- *yu = tile->ictm[1] * xw + tile->ictm[3] * yw + tile->ictm[5];
- return gTrue;
- }
+GBool PDFCore::cvtWindowToDev(int xw, int yw, int *pg, int *xd, int *yd) {
+ return tileMap->cvtWindowToDev(xw, yw, pg, xd, yd);
+}
+
+GBool PDFCore::cvtUserToWindow(int pg, double xu, double yu, int *xw, int *yw) {
+ return tileMap->cvtUserToWindow(pg, xu, yu, xw, yw);
+}
+
+void PDFCore::cvtUserToDev(int pg, double xu, double yu, int *xd, int *yd) {
+ tileMap->cvtUserToDev(pg, xu, yu, xd, yd);
+}
+
+GBool PDFCore::cvtDevToWindow(int pg, int xd, int yd, int *xw, int *yw) {
+ return tileMap->cvtDevToWindow(pg, xd, yd, xw, yw);
+}
+
+void PDFCore::cvtDevToUser(int pg, int xd, int yd, double *xu, double *yu) {
+ tileMap->cvtDevToUser(pg, xd, yd, xu, yu);
+}
+
+void PDFCore::getWindowPageRange(int x, int y, int w, int h,
+ int *firstPage, int *lastPage) {
+ tileMap->getWindowPageRange(x, y, w, h, firstPage, lastPage);
+}
+
+int PDFCore::getPageNum() {
+ if (!doc || !doc->getNumPages()) {
+ return 0;
}
- *pg = 0;
- *xu = *yu = 0;
- return gFalse;
+ return tileMap->getFirstPage();
}
-GBool PDFCore::cvtWindowToDev(int xw, int yw, int *pg, int *xd, int *yd) {
- PDFCorePage *page;
+int PDFCore::getMidPageNum() {
+ if (!doc || !doc->getNumPages()) {
+ return 0;
+ }
+ return tileMap->getMidPage();
+}
+
+double PDFCore::getZoom() {
+ return state->getZoom();
+}
+
+double PDFCore::getZoomDPI(int page) {
+ if (!doc) {
+ return 0;
+ }
+ return tileMap->getDPI(page);
+}
+
+int PDFCore::getRotate() {
+ return state->getRotate();
+}
+
+DisplayMode PDFCore::getDisplayMode() {
+ return state->getDisplayMode();
+}
+
+int PDFCore::getScrollX() {
+ return state->getScrollX();
+}
+
+int PDFCore::getScrollY() {
+ return state->getScrollY();
+}
+
+int PDFCore::getWindowWidth() {
+ return state->getWinW();
+}
+
+int PDFCore::getWindowHeight() {
+ return state->getWinH();
+}
+
+void PDFCore::setPaperColor(SplashColorPtr paperColor) {
+ state->setPaperColor(paperColor);
+ invalidateWholeWindow();
+}
+
+void PDFCore::setMatteColor(SplashColorPtr matteColor) {
+ state->setMatteColor(matteColor);
+ invalidateWholeWindow();
+}
+
+void PDFCore::setReverseVideo(GBool reverseVideo) {
+ SplashColorPtr oldPaperColor;
+ SplashColor newPaperColor;
int i;
- for (i = 0; i < pages->getLength(); ++i) {
- page = (PDFCorePage *)pages->get(i);
- if (xw >= page->xDest && xw < page->xDest + page->w &&
- yw >= page->yDest && yw < page->yDest + page->h) {
- *pg = page->page;
- *xd = xw - page->xDest;
- *yd = yw - page->yDest;
- return gTrue;
+ if (reverseVideo != state->getReverseVideo()) {
+ state->setReverseVideo(reverseVideo);
+ oldPaperColor = state->getPaperColor();
+ for (i = 0; i < splashColorModeNComps[state->getColorMode()]; ++i) {
+ newPaperColor[i] = oldPaperColor[i] ^ 0xff;
}
+ state->setPaperColor(newPaperColor);
+ invalidateWholeWindow();
}
- *pg = 0;
- *xd = *yd = 0;
- return gFalse;
}
-void PDFCore::cvtUserToWindow(int pg, double xu, double yu, int *xw, int *yw) {
- PDFCorePage *page;
- PDFCoreTile *tile;
- if ((page = findPage(pg)) &&
- page->tiles->getLength() > 0) {
- tile = (PDFCoreTile *)page->tiles->get(0);
- } else if (curTile && curPage->page == pg) {
- tile = curTile;
- } else {
- tile = NULL;
- }
- if (tile) {
- *xw = tile->xDest + (int)(tile->ctm[0] * xu + tile->ctm[2] * yu +
- tile->ctm[4] + 0.5);
- *yw = tile->yDest + (int)(tile->ctm[1] * xu + tile->ctm[3] * yu +
- tile->ctm[5] + 0.5);
- } else {
- // this should never happen
- *xw = *yw = 0;
- }
+
+LinkAction *PDFCore::findLink(int pg, double x, double y) {
+ loadLinks(pg);
+ return links->find(x, y);
}
-void PDFCore::cvtUserToDev(int pg, double xu, double yu, int *xd, int *yd) {
- PDFCorePage *page;
- PDFCoreTile *tile;
- double ctm[6];
-
- if ((page = findPage(pg)) &&
- page->tiles->getLength() > 0) {
- tile = (PDFCoreTile *)page->tiles->get(0);
- } else if (curTile && curPage->page == pg) {
- tile = curTile;
- } else {
- tile = NULL;
+Annot *PDFCore::findAnnot(int pg, double x, double y) {
+ loadAnnots(pg);
+ return annots->find(x, y);
+}
+
+int PDFCore::findAnnotIdx(int pg, double x, double y) {
+ loadAnnots(pg);
+ return annots->findIdx(x, y);
+}
+
+Annot *PDFCore::getAnnot(int idx) {
+ if (!annots) {
+ return NULL;
}
- if (tile) {
- *xd = (int)(tile->xMin + tile->ctm[0] * xu +
- tile->ctm[2] * yu + tile->ctm[4] + 0.5);
- *yd = (int)(tile->yMin + tile->ctm[1] * xu +
- tile->ctm[3] * yu + tile->ctm[5] + 0.5);
- } else {
- doc->getCatalog()->getPage(pg)->getDefaultCTM(ctm, dpi, dpi, rotate,
- gFalse, out->upsideDown());
- *xd = (int)(ctm[0] * xu + ctm[2] * yu + ctm[4] + 0.5);
- *yd = (int)(ctm[1] * xu + ctm[3] * yu + ctm[5] + 0.5);
+ if (idx < 0 || idx >= annots->getNumAnnots()) {
+ return NULL;
}
+ return annots->getAnnot(idx);
}
-void PDFCore::cvtDevToWindow(int pg, int xd, int yd, int *xw, int *yw) {
- PDFCorePage *page;
+FormField *PDFCore::findFormField(int pg, double x, double y) {
+ if (!doc->getCatalog()->getForm()) {
+ return NULL;
+ }
+ return doc->getCatalog()->getForm()->findField(pg, x, y);
+}
- if ((page = findPage(pg))) {
- *xw = page->xDest + xd;
- *yw = page->yDest + yd;
- } else {
- // this should never happen
- *xw = *yw = 0;
+int PDFCore::findFormFieldIdx(int pg, double x, double y) {
+ if (!doc->getCatalog()->getForm()) {
+ return -1;
}
+ return doc->getCatalog()->getForm()->findFieldIdx(pg, x, y);
}
-void PDFCore::cvtDevToUser(int pg, int xd, int yd, double *xu, double *yu) {
- PDFCorePage *page;
- PDFCoreTile *tile;
-
- if ((page = findPage(pg)) &&
- page->tiles->getLength() > 0) {
- tile = (PDFCoreTile *)page->tiles->get(0);
- } else if (curTile && curPage->page == pg) {
- tile = curTile;
- } else {
- tile = NULL;
+FormField *PDFCore::getFormField(int idx) {
+ if (!doc->getCatalog()->getForm()) {
+ return NULL;
}
- if (tile) {
- xd -= tile->xMin;
- yd -= tile->yMin;
- *xu = tile->ictm[0] * xd + tile->ictm[2] * yd + tile->ictm[4];
- *yu = tile->ictm[1] * xd + tile->ictm[3] * yd + tile->ictm[5];
- } else {
- // this should never happen
- *xu = *yu = 0;
+ if (idx < 0 || idx >= doc->getCatalog()->getForm()->getNumFields()) {
+ return NULL;
}
+ return doc->getCatalog()->getForm()->getField(idx);
}
-void PDFCore::setReverseVideo(GBool reverseVideoA) {
- out->setReverseVideo(reverseVideoA);
- update(topPage, scrollX, scrollY, zoom, rotate, gTrue, gFalse, gFalse);
+void PDFCore::forceRedraw() {
+ startUpdate();
+ state->forceRedraw();
+ finishUpdate(gFalse, gFalse);
}
-LinkAction *PDFCore::findLink(int pg, double x, double y) {
- PDFCorePage *page;
+void PDFCore::setTileDoneCbk(void (*cbk)(void *data), void *data) {
+ tileCache->setTileDoneCbk(cbk, data);
+}
- if ((page = findPage(pg))) {
- return page->links ? page->links->find(x, y) : (LinkAction *)NULL;
+void PDFCore::setWindowSize(int winWidth, int winHeight) {
+ GBool doScroll;
+ int page, wx0, wy0, wx, wy, sx, sy;
+ double ux, uy;
+
+ startUpdate();
+
+ wx0 = wy0 = 0; // make gcc happy
+ doScroll = gFalse;
+ if (state->getZoom() < 0 && state->displayModeIsContinuous()) {
+ // save the user coordinates of the appropriate edge of the window
+ if (state->getDisplayMode() == displayHorizontalContinuous) {
+ wx0 = 0;
+ wy0 = state->getWinH() / 2;
+ } else {
+ wx0 = state->getWinW() / 2;
+ wy0 = 0;
+ }
+ if (!(doScroll = cvtWindowToUser(wx0, wy0, &page, &ux, &uy))) {
+ // tweak the save position if it happens to fall in a gutter
+ if (state->getDisplayMode() == displayContinuous) {
+ wy0 += tileMap->getContinuousPageSpacing();
+ } else if (state->getDisplayMode() == displaySideBySideContinuous) {
+ wx0 += tileMap->getSideBySidePageSpacing();
+ wy0 += tileMap->getContinuousPageSpacing();
+ } else { // state->getDisplayMode() == displayHorizontalContinuous
+ wx0 += tileMap->getHorizContinuousPageSpacing();
+ }
+ doScroll = cvtWindowToUser(wx0, wy0, &page, &ux, &uy);
+ }
}
- return NULL;
-}
-PDFCorePage *PDFCore::findPage(int pg) {
- PDFCorePage *page;
- int i;
+ state->setWindowSize(winWidth, winHeight);
- for (i = 0; i < pages->getLength(); ++i) {
- page = (PDFCorePage *)pages->get(i);
- if (page->page == pg) {
- return page;
+ if (doScroll) {
+ // restore the saved scroll position
+ cvtUserToWindow(page, ux, uy, &wx, &wy);
+ sx = state->getScrollX();
+ sy = state->getScrollY();
+ if (state->getDisplayMode() == displayHorizontalContinuous) {
+ sx += wx - wx0;
+ } else {
+ sy += wy - wy0;
}
+ state->setScrollPosition(page, sx, sy);
}
- return NULL;
+
+ finishUpdate(gTrue, gFalse);
}
-void PDFCore::redrawCbk(void *data, int x0, int y0, int x1, int y1,
- GBool composited) {
- PDFCore *core = (PDFCore *)data;
+SplashBitmap *PDFCore::getWindowBitmap(GBool wholeWindow) {
+ GBool dummy;
+
+ return tileCompositor->getBitmap(wholeWindow ? &bitmapFinished : &dummy);
+}
- core->curTile->bitmap = core->out->getBitmap();
+void PDFCore::tick() {
+ if (!bitmapFinished) {
+ invalidateWholeWindow();
+ }
+}
- // the default CTM is set by the Gfx constructor; tile->ctm is
- // needed by the coordinate conversion functions (which may be
- // called during redraw)
- memcpy(core->curTile->ctm, core->out->getDefCTM(), 6 * sizeof(double));
- memcpy(core->curTile->ictm, core->out->getDefICTM(), 6 * sizeof(double));
+// Clear cached info (links, text) that's tied to a PDFDoc.
+void PDFCore::clearPage() {
+ if (links) {
+ delete links;
+ }
+ links = NULL;
+ linksPage = 0;
- // the bitmap created by Gfx and SplashOutputDev can be a slightly
- // different size due to rounding errors
- if (x1 >= core->curTile->xMax - core->curTile->xMin) {
- x1 = core->curTile->xMax - core->curTile->xMin - 1;
+ if (annots) {
+ delete annots;
}
- if (y1 >= core->curTile->yMax - core->curTile->yMin) {
- y1 = core->curTile->yMax - core->curTile->yMin - 1;
+ annots = NULL;
+ annotsPage = 0;
+
+ if (text) {
+ delete text;
}
+ text = NULL;
+ textPage = 0;
+ textDPI = 0;
+ textRotate = 0;
+}
- core->clippedRedrawRect(core->curTile, x0, y0,
- core->curTile->xDest + x0, core->curTile->yDest + y0,
- x1 - x0 + 1, y1 - y0 + 1,
- 0, 0, core->drawAreaWidth, core->drawAreaHeight,
- gTrue, composited);
+// Load the links for <pg>.
+void PDFCore::loadLinks(int pg) {
+ if (links && linksPage == pg) {
+ return;
+ }
+ if (links) {
+ delete links;
+ }
+ links = doc->getLinks(pg);
+ linksPage = pg;
}
-void PDFCore::redrawWindow(int x, int y, int width, int height,
- GBool needUpdate) {
- PDFCorePage *page;
- PDFCoreTile *tile;
- int xDest, yDest, w, i, j;
+// Load the annotations for <pg>.
+void PDFCore::loadAnnots(int pg) {
+ Object annotsObj;
- if (pages->getLength() == 0) {
- redrawRect(NULL, 0, 0, x, y, width, height, gTrue);
+ if (annots && annotsPage == pg) {
return;
}
+ if (annots) {
+ delete annots;
+ }
+ doc->getCatalog()->getPage(pg)->getAnnots(&annotsObj);
+ annots = new Annots(doc, &annotsObj);
+ annotsObj.free();
+ annotsPage = pg;
+}
- for (i = 0; i < pages->getLength(); ++i) {
- page = (PDFCorePage *)pages->get(i);
- for (j = 0; j < page->tiles->getLength(); ++j) {
- tile = (PDFCoreTile *)page->tiles->get(j);
- if (tile->edges & pdfCoreTileTopEdge) {
- if (tile->edges & pdfCoreTileLeftEdge) {
- xDest = 0;
- } else {
- xDest = tile->xDest;
- }
- if (tile->edges & pdfCoreTileRightEdge) {
- w = drawAreaWidth - xDest;
- } else {
- w = tile->xDest + (tile->xMax - tile->xMin) - xDest;
- }
- clippedRedrawRect(NULL, 0, 0,
- xDest, 0, w, tile->yDest,
- x, y, width, height, gFalse);
- }
- if (tile->edges & pdfCoreTileBottomEdge) {
- if (tile->edges & pdfCoreTileLeftEdge) {
- xDest = 0;
- } else {
- xDest = tile->xDest;
- }
- if (tile->edges & pdfCoreTileRightEdge) {
- w = drawAreaWidth - xDest;
- } else {
- w = tile->xDest + (tile->xMax - tile->xMin) - xDest;
- }
- yDest = tile->yDest + (tile->yMax - tile->yMin);
- clippedRedrawRect(NULL, 0, 0,
- xDest, yDest, w, drawAreaHeight - yDest,
- x, y, width, height, gFalse);
- } else if ((tile->edges & pdfCoreTileBottomSpace) &&
- i+1 < pages->getLength()) {
- if (tile->edges & pdfCoreTileLeftEdge) {
- xDest = 0;
- } else {
- xDest = tile->xDest;
- }
- if (tile->edges & pdfCoreTileRightEdge) {
- w = drawAreaWidth - xDest;
- } else {
- w = tile->xDest + (tile->xMax - tile->xMin) - xDest;
- }
- yDest = tile->yDest + (tile->yMax - tile->yMin);
- clippedRedrawRect(NULL, 0, 0,
- xDest, yDest,
- w, ((PDFCorePage *)pages->get(i+1))->yDest - yDest,
- x, y, width, height, gFalse);
- }
- if (tile->edges & pdfCoreTileLeftEdge) {
- clippedRedrawRect(NULL, 0, 0,
- 0, tile->yDest,
- tile->xDest, tile->yMax - tile->yMin,
- x, y, width, height, gFalse);
- }
- if (tile->edges & pdfCoreTileRightEdge) {
- xDest = tile->xDest + (tile->xMax - tile->xMin);
- clippedRedrawRect(NULL, 0, 0,
- xDest, tile->yDest,
- drawAreaWidth - xDest, tile->yMax - tile->yMin,
- x, y, width, height, gFalse);
- }
- clippedRedrawRect(tile, 0, 0, tile->xDest, tile->yDest,
- tile->bitmap->getWidth(), tile->bitmap->getHeight(),
- x, y, width, height, needUpdate);
- }
+// Extract text from <pg>.
+void PDFCore::loadText(int pg) {
+ TextOutputDev *textOut;
+ double dpi;
+ int rotate;
+
+ dpi = tileMap->getDPI(pg);
+ rotate = state->getRotate();
+ if (text && textPage == pg && textDPI == dpi && textRotate == rotate) {
+ return;
}
+ if (text) {
+ delete text;
+ }
+ textOut = new TextOutputDev(NULL, &textOutCtrl, gFalse);
+ if (!textOut->isOk()) {
+ text = new TextPage(&textOutCtrl);
+ } else {
+ doc->displayPage(textOut, pg, dpi, dpi, rotate, gFalse, gTrue, gFalse);
+ text = textOut->takeText();
+ }
+ delete textOut;
+ textPage = pg;
+ textDPI = dpi;
+ textRotate = rotate;
}
-PDFCoreTile *PDFCore::newTile(int xDestA, int yDestA) {
- return new PDFCoreTile(xDestA, yDestA);
+void PDFCore::getSelectionBBox(int *wxMin, int *wyMin, int *wxMax, int *wyMax) {
+ *wxMin = *wyMin = *wxMax = *wyMax = 0;
+ if (!state->hasSelection()) {
+ return;
+ }
+ getSelectRectListBBox(state->getSelectRects(), wxMin, wyMin, wxMax, wyMax);
}
-void PDFCore::updateTileData(PDFCoreTile *tileA, int xSrc, int ySrc,
- int width, int height, GBool composited) {
+void PDFCore::getSelectRectListBBox(GList *rects, int *wxMin, int *wyMin,
+ int *wxMax, int *wyMax) {
+ SelectRect *rect;
+ int x, y, i;
+
+ *wxMin = *wyMin = *wxMax = *wyMax = 0;
+ for (i = 0; i < rects->getLength(); ++i) {
+ rect = (SelectRect *)rects->get(i);
+ tileMap->cvtUserToWindow(rect->page, rect->x0, rect->y0, &x, &y);
+ if (i == 0) {
+ *wxMin = *wxMax = x;
+ *wyMin = *wyMax = y;
+ } else {
+ if (x < *wxMin) {
+ *wxMin = x;
+ } else if (x > *wxMax) {
+ *wxMax = x;
+ }
+ if (y < *wyMin) {
+ *wyMin = y;
+ } else if (y > *wyMax) {
+ *wyMax = y;
+ }
+ }
+ tileMap->cvtUserToWindow(rect->page, rect->x1, rect->y1, &x, &y);
+ if (x < *wxMin) {
+ *wxMin = x;
+ } else if (x > *wxMax) {
+ *wxMax = x;
+ }
+ if (y < *wyMin) {
+ *wyMin = y;
+ } else if (y > *wyMax) {
+ *wyMax = y;
+ }
+ }
}
-void PDFCore::clippedRedrawRect(PDFCoreTile *tile, int xSrc, int ySrc,
- int xDest, int yDest, int width, int height,
- int xClip, int yClip, int wClip, int hClip,
- GBool needUpdate, GBool composited) {
- if (tile && needUpdate) {
- updateTileData(tile, xSrc, ySrc, width, height, composited);
+void PDFCore::checkInvalidate(int x, int y, int w, int h) {
+ if (x < 0) {
+ w += x;
+ x = 0;
}
- if (xDest < xClip) {
- xSrc += xClip - xDest;
- width -= xClip - xDest;
- xDest = xClip;
+ if (x + w > state->getWinW()) {
+ w = state->getWinW() - x;
}
- if (xDest + width > xClip + wClip) {
- width = xClip + wClip - xDest;
+ if (w <= 0) {
+ return;
}
- if (yDest < yClip) {
- ySrc += yClip - yDest;
- height -= yClip - yDest;
- yDest = yClip;
+ if (y < 0) {
+ h += y;
+ y = 0;
}
- if (yDest + height > yClip + hClip) {
- height = yClip + hClip - yDest;
+ if (y + h > state->getWinH()) {
+ h = state->getWinH() - y;
}
- if (width > 0 && height > 0) {
- redrawRect(tile, xSrc, ySrc, xDest, yDest, width, height, composited);
+ if (h <= 0) {
+ return;
}
+ invalidate(x, y, w, h);
+}
+
+void PDFCore::invalidateWholeWindow() {
+ invalidate(0, 0, state->getWinW(), state->getWinH());
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h
index 1be1010024b..bb327318a4b 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h
@@ -2,7 +2,7 @@
//
// PDFCore.h
//
-// Copyright 2004 Glyph & Cog, LLC
+// Copyright 2004-2014 Glyph & Cog, LLC
//
//========================================================================
@@ -18,6 +18,8 @@
#include <stdlib.h>
#include "SplashTypes.h"
#include "CharTypes.h"
+#include "DisplayState.h"
+#include "TextOutputDev.h"
class GString;
class GList;
@@ -28,74 +30,18 @@ class PDFDoc;
class Links;
class LinkDest;
class LinkAction;
+class Annot;
+class Annots;
+class FormField;
class TextPage;
class HighlightFile;
-class CoreOutputDev;
+class OptionalContentGroup;
+class TileMap;
+class TileCache;
+class TileCompositor;
class PDFCore;
//------------------------------------------------------------------------
-// zoom factor
-//------------------------------------------------------------------------
-
-#define zoomPage -1
-#define zoomWidth -2
-#define defZoom 125
-
-//------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------
-
-// Number of pixels of matte color between pages in continuous mode.
-#define continuousModePageSpacing 3
-
-//------------------------------------------------------------------------
-// PDFCorePage
-//------------------------------------------------------------------------
-
-class PDFCorePage {
-public:
-
- PDFCorePage(int pageA, int wA, int hA, int tileWA, int tileHA);
- ~PDFCorePage();
-
- int page;
- GList *tiles; // cached tiles [PDFCoreTile]
- int xDest, yDest; // position of upper-left corner
- // in the drawing area
- int w, h; // size of whole page bitmap
- int tileW, tileH; // size of tiles
- Links *links; // hyperlinks for this page
- TextPage *text; // extracted text
-};
-
-//------------------------------------------------------------------------
-// PDFCoreTile
-//------------------------------------------------------------------------
-
-class PDFCoreTile {
-public:
-
- PDFCoreTile(int xDestA, int yDestA);
- virtual ~PDFCoreTile();
-
- int xMin, yMin, xMax, yMax;
- int xDest, yDest;
- Guint edges;
- SplashBitmap *bitmap;
- double ctm[6]; // coordinate transform matrix:
- // default user space -> device space
- double ictm[6]; // inverse CTM
-};
-
-#define pdfCoreTileTopEdge 0x01
-#define pdfCoreTileBottomEdge 0x02
-#define pdfCoreTileLeftEdge 0x04
-#define pdfCoreTileRightEdge 0x08
-#define pdfCoreTileTopSpace 0x10
-#define pdfCoreTileBottomSpace 0x20
-
-//------------------------------------------------------------------------
// PDFHistory
//------------------------------------------------------------------------
@@ -110,6 +56,14 @@ struct PDFHistory {
#define pdfHistorySize 50
+//------------------------------------------------------------------------
+// SelectMode
+//------------------------------------------------------------------------
+
+enum SelectMode {
+ selectModeBlock,
+ selectModeLinear
+};
//------------------------------------------------------------------------
// PDFCore
@@ -118,9 +72,8 @@ struct PDFHistory {
class PDFCore {
public:
- PDFCore(SplashColorMode colorModeA, int bitmapRowPadA,
- GBool reverseVideoA, SplashColorPtr paperColorA,
- GBool incrementalUpdate);
+ PDFCore(SplashColorMode colorMode, int bitmapRowPad,
+ GBool reverseVideo, SplashColorPtr paperColor);
virtual ~PDFCore();
//----- loadFile / displayPage / displayDest
@@ -144,6 +97,10 @@ public:
// Load an already-created PDFDoc object.
virtual void loadDoc(PDFDoc *docA);
+ // Reload the current file. This only works if the PDF was loaded
+ // via a file. Returns pdfOk or error code.
+ virtual int reload();
+
// Clear out the current document, if any.
virtual void clear();
@@ -152,20 +109,22 @@ public:
virtual PDFDoc *takeDoc(GBool redraw);
// Display (or redisplay) the specified page. If <scrollToTop> is
- // set, the window is vertically scrolled to the top; otherwise, no
- // scrolling is done. If <addToHist> is set, this page change is
- // added to the history list.
- virtual void displayPage(int topPageA, double zoomA, int rotateA,
- GBool scrollToTop, GBool addToHist);
+ // set, the window is vertically scrolled to the top; if
+ // <scrollToBottom> is set, the window is vertically scrolled to the
+ // bottom; otherwise, no scrolling is done. If <addToHist> is set,
+ // this page change is added to the history list.
+ virtual void displayPage(int page, GBool scrollToTop,
+ GBool scrollToBottom, GBool addToHist = gTrue);
// Display a link destination.
- virtual void displayDest(LinkDest *dest, double zoomA, int rotateA,
- GBool addToHist);
+ virtual void displayDest(LinkDest *dest);
+
+ // Called before any update is started.
+ virtual void startUpdate();
- // Update the display, given the specified parameters.
- virtual void update(int topPageA, int scrollXA, int scrollYA,
- double zoomA, int rotateA, GBool force,
- GBool addToHist, GBool adjustScrollX);
+ // Called after any update is complete. Subclasses can check for
+ // changes in the display parameters here.
+ virtual void finishUpdate(GBool addToHist, GBool checkForChangedFile);
//----- page/position changes
@@ -189,28 +148,45 @@ public:
virtual void scrollToBottomEdge();
virtual void scrollToTopLeft();
virtual void scrollToBottomRight();
- virtual void zoomToRect(int pg, double ulx, double uly,
+ virtual void setZoom(double zoom);
+ virtual void zoomToRect(int page, double ulx, double uly,
double lrx, double lry);
- virtual void zoomCentered(double zoomA);
+ virtual void zoomCentered(double zoom);
virtual void zoomToCurrentWidth();
- virtual void setContinuousMode(GBool cm);
+ virtual void setRotate(int rotate);
+ virtual void setDisplayMode(DisplayMode mode);
+ virtual void setOCGState(OptionalContentGroup *ocg, GBool ocgState);
//----- selection
+ // Selection mode.
+ SelectMode getSelectMode() { return selectMode; }
+ void setSelectMode(SelectMode mode);
+
// Selection color.
void setSelectionColor(SplashColor color);
- // Current selected region.
- void setSelection(int newSelectPage,
- int newSelectULX, int newSelectULY,
- int newSelectLRX, int newSelectLRY);
- void moveSelection(int pg, int x, int y);
+ // Modify the selection. These functions use device coordinates.
+ void setSelection(int page, int x0, int y0, int x1, int y1);
+ void setLinearSelection(int page, TextPosition *pos0, TextPosition *pos1);
+ void clearSelection();
+ void startSelectionDrag(int pg, int x, int y);
+ void moveSelectionDrag(int pg, int x, int y);
+ void finishSelectionDrag();
+
+ // Retrieve the current selection. This function uses user
+ // coordinates. Returns false if there is no selection.
GBool getSelection(int *pg, double *ulx, double *uly,
double *lrx, double *lry);
+ GBool hasSelection();
// Text extraction.
+ void setTextExtractionMode(TextOutputMode mode);
+ GBool getDiscardDiagonalText();
+ void setDiscardDiagonalText(GBool discard);
GString *extractText(int pg, double xMin, double yMin,
double xMax, double yMax);
+ GString *getSelectedText();
//----- find
@@ -223,16 +199,18 @@ public:
//----- coordinate conversion
- // user space: per-pace, as defined by PDF file; unit = point
+ // user space: per-page, as defined by PDF file; unit = point
// device space: (0,0) is upper-left corner of a page; unit = pixel
// window space: (0,0) is upper-left corner of drawing area; unit = pixel
GBool cvtWindowToUser(int xw, int yw, int *pg, double *xu, double *yu);
GBool cvtWindowToDev(int xw, int yw, int *pg, int *xd, int *yd);
- void cvtUserToWindow(int pg, double xy, double yu, int *xw, int *yw);
+ GBool cvtUserToWindow(int pg, double xy, double yu, int *xw, int *yw);
void cvtUserToDev(int pg, double xu, double yu, int *xd, int *yd);
- void cvtDevToWindow(int pg, int xd, int yd, int *xw, int *yw);
+ GBool cvtDevToWindow(int pg, int xd, int yd, int *xw, int *yw);
void cvtDevToUser(int pg, int xd, int yd, double *xu, double *yu);
+ void getWindowPageRange(int x, int y, int w, int h,
+ int *firstPage, int *lastPage);
//----- password dialog
@@ -241,78 +219,112 @@ public:
//----- misc access
PDFDoc *getDoc() { return doc; }
- int getPageNum() { return topPage; }
- double getZoom() { return zoom; }
- double getZoomDPI() { return dpi; }
- int getRotate() { return rotate; }
- GBool getContinuousMode() { return continuousMode; }
- virtual void setReverseVideo(GBool reverseVideoA);
+ int getPageNum();
+ int getMidPageNum();
+ double getZoom();
+ double getZoomDPI(int page);
+ int getRotate();
+ DisplayMode getDisplayMode();
+ virtual void setPaperColor(SplashColorPtr paperColor);
+ virtual void setMatteColor(SplashColorPtr matteColor);
+ virtual void setReverseVideo(GBool reverseVideo);
GBool canGoBack() { return historyBLen > 1; }
GBool canGoForward() { return historyFLen > 0; }
- int getScrollX() { return scrollX; }
- int getScrollY() { return scrollY; }
- int getDrawAreaWidth() { return drawAreaWidth; }
- int getDrawAreaHeight() { return drawAreaHeight; }
+ int getScrollX();
+ int getScrollY();
+ int getWindowWidth();
+ int getWindowHeight();
virtual void setBusyCursor(GBool busy) = 0;
LinkAction *findLink(int pg, double x, double y);
+ Annot *findAnnot(int pg, double x, double y);
+ int findAnnotIdx(int pg, double x, double y);
+ Annot *getAnnot(int idx);
+ FormField *findFormField(int pg, double x, double y);
+ int findFormFieldIdx(int pg, double x, double y);
+ FormField *getFormField(int idx);
+ void forceRedraw();
+ void setTileDoneCbk(void (*cbk)(void *data), void *data);
protected:
- int loadFile2(PDFDoc *newDoc);
- void addPage(int pg, int rot);
- void needTile(PDFCorePage *page, int x, int y);
- void xorRectangle(int pg, int x0, int y0, int x1, int y1,
- SplashPattern *pattern, PDFCoreTile *oneTile = NULL);
- int loadHighlightFile(HighlightFile *hf, SplashColorPtr color,
- SplashColorPtr selectColor, GBool selectable);
- PDFCorePage *findPage(int pg);
- static void redrawCbk(void *data, int x0, int y0, int x1, int y1,
- GBool composited);
- void redrawWindow(int x, int y, int width, int height,
- GBool needUpdate);
- virtual PDFCoreTile *newTile(int xDestA, int yDestA);
- virtual void updateTileData(PDFCoreTile *tileA, int xSrc, int ySrc,
- int width, int height, GBool composited);
- virtual void redrawRect(PDFCoreTile *tileA, int xSrc, int ySrc,
- int xDest, int yDest, int width, int height,
- GBool composited) = 0;
- void clippedRedrawRect(PDFCoreTile *tile, int xSrc, int ySrc,
- int xDest, int yDest, int width, int height,
- int xClip, int yClip, int wClip, int hClip,
- GBool needUpdate, GBool composited = gTrue);
+ //--- calls from PDFCore subclass
+
+ // Set the window size (when the window is resized).
+ void setWindowSize(int winWidthA, int winHeightA);
+
+ // Get the current window bitmap. If <wholeWindow> is true, the
+ // full window is being redrawn -- this is used to end incremental
+ // updates when the rasterization is done.
+ SplashBitmap *getWindowBitmap(GBool wholeWindow);
+
+ // Returns true if the last call to getWindowBitmap() returned a
+ // finished bitmap; or false if the bitmap was still being
+ // rasterized.
+ GBool isBitmapFinished() { return bitmapFinished; }
+
+ // This should be called periodically (typically every ~0.1 seconds)
+ // to do incremental updates. If an update is required, it will
+ // trigger a call to invalidate().
+ virtual void tick();
+
+ //--- callbacks to PDFCore subclass
+
+ // Invalidate the specified rectangle (in window coordinates).
+ virtual void invalidate(int x, int y, int w, int h) = 0;
+
+ // Update the scrollbars.
virtual void updateScrollbars() = 0;
+
+ // This returns true if the PDF file has changed on disk (if it can
+ // be checked).
virtual GBool checkForNewFile() { return gFalse; }
- PDFDoc *doc; // current PDF file
- GBool continuousMode; // false for single-page mode, true for
- // continuous mode
- int drawAreaWidth, // size of the PDF display area
- drawAreaHeight;
- double maxUnscaledPageW, // maximum unscaled page size
- maxUnscaledPageH;
- int maxPageW; // maximum page width (only used in
- // continuous mode)
- int totalDocH; // total document height (only used in
- // continuous mode)
- int *pageY; // top coordinates for each page (only used
- // in continuous mode)
- int topPage; // page at top of window
- int midPage; // page at middle of window
- int scrollX, scrollY; // offset from top left corner of topPage
- // to top left corner of window
- double zoom; // current zoom level, in percent of 72 dpi
- double dpi; // current zoom level, in DPI
- int rotate; // current page rotation
-
- int selectPage; // page number of current selection
- int selectULX, // coordinates of current selection,
- selectULY, // in device space -- (ULX==LRX || ULY==LRY)
- selectLRX, // means there is no selection
- selectLRY;
- GBool dragging; // set while selection is being dragged
- GBool lastDragLeft; // last dragged selection edge was left/right
- GBool lastDragTop; // last dragged selection edge was top/bottom
- SplashColor selectXorColor; // selection xor color
+ // This is called just before a PDF file is loaded.
+ virtual void preLoad() {}
+
+ // This is called just after a PDF file is loaded.
+ virtual void postLoad() {}
+
+ //--- internal
+
+ int loadFile2(PDFDoc *newDoc);
+ void addToHistory();
+ void clearPage();
+ void loadLinks(int pg);
+ void loadAnnots(int pg);
+ void loadText(int pg);
+ void getSelectionBBox(int *wxMin, int *wyMin, int *wxMax, int *wyMax);
+ void getSelectRectListBBox(GList *rects, int *wxMin, int *wyMin,
+ int *wxMax, int *wyMax);
+ void checkInvalidate(int x, int y, int w, int h);
+ void invalidateWholeWindow();
+
+ PDFDoc *doc;
+
+ int linksPage; // cached links for one page
+ Links *links;
+
+ int annotsPage; // cached annotations for one page
+ Annots *annots;
+
+ int textPage; // cached extracted text for one page
+ double textDPI;
+ int textRotate;
+ TextOutputControl textOutCtrl;
+ TextPage *text;
+
+ DisplayState *state;
+ TileMap *tileMap;
+ TileCache *tileCache;
+ TileCompositor *tileCompositor;
+ GBool bitmapFinished;
+
+ SelectMode selectMode;
+ int selectPage; // page of current selection
+ int selectStartX, // for block mode: start point of current
+ selectStartY; // selection, in device coords
+ TextPosition selectStartPos; // for linear mode: start position of
+ // current selection
PDFHistory // page history queue
history[pdfHistorySize];
@@ -321,16 +333,6 @@ protected:
// current entry
int historyFLen; // number of valid entries forward from
// current entry
-
-
- GList *pages; // cached pages [PDFCorePage]
- PDFCoreTile *curTile; // tile currently being rasterized
- PDFCorePage *curPage; // page to which curTile belongs
-
- SplashColor paperColor;
- CoreOutputDev *out;
-
- friend class PDFCoreTile;
};
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
index 51262897f72..8c4033b0312 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc
@@ -19,6 +19,7 @@
#ifdef _WIN32
# include <windows.h>
#endif
+#include "gmempp.h"
#include "GString.h"
#include "config.h"
#include "GlobalParams.h"
@@ -204,6 +205,7 @@ PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword,
}
GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
+
str->reset();
// check header
@@ -421,6 +423,47 @@ void PDFDoc::processLinks(OutputDev *out, int page) {
catalog->getPage(page)->processLinks(out);
}
+#ifndef DISABLE_OUTLINE
+int PDFDoc::getOutlineTargetPage(OutlineItem *outlineItem) {
+ LinkAction *action;
+ LinkActionKind kind;
+ LinkDest *dest;
+ GString *namedDest;
+ Ref pageRef;
+ int pg;
+
+ if (outlineItem->pageNum >= 0) {
+ return outlineItem->pageNum;
+ }
+ if (!(action = outlineItem->getAction())) {
+ outlineItem->pageNum = 0;
+ return 0;
+ }
+ kind = action->getKind();
+ if (kind != actionGoTo) {
+ outlineItem->pageNum = 0;
+ return 0;
+ }
+ if ((dest = ((LinkGoTo *)action)->getDest())) {
+ dest = dest->copy();
+ } else if ((namedDest = ((LinkGoTo *)action)->getNamedDest())) {
+ dest = findDest(namedDest);
+ }
+ pg = 0;
+ if (dest) {
+ if (dest->isPageRef()) {
+ pageRef = dest->getPageRef();
+ pg = findPage(pageRef.num, pageRef.gen);
+ } else {
+ pg = dest->getPageNum();
+ }
+ delete dest;
+ }
+ outlineItem->pageNum = pg;
+ return pg;
+}
+#endif
+
GBool PDFDoc::isLinearized() {
Parser *parser;
Object obj1, obj2, obj3, obj4, obj5;
@@ -470,7 +513,7 @@ GBool PDFDoc::saveAs(GString *name) {
return gTrue;
}
-GBool PDFDoc::saveEmbeddedFile(int idx, char *path) {
+GBool PDFDoc::saveEmbeddedFile(int idx, const char *path) {
FILE *f;
GBool ret;
@@ -483,7 +526,7 @@ GBool PDFDoc::saveEmbeddedFile(int idx, char *path) {
}
#ifdef _WIN32
-GBool PDFDoc::saveEmbeddedFile(int idx, wchar_t *path, int pathLen) {
+GBool PDFDoc::saveEmbeddedFile(int idx, const wchar_t *path, int pathLen) {
FILE *f;
OSVERSIONINFO version;
wchar_t path2w[_MAX_PATH + 1];
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h
index 509c1d5ac84..0d67c0dc4c8 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.h
@@ -27,6 +27,7 @@ class Links;
class LinkAction;
class LinkDest;
class Outline;
+class OutlineItem;
class OptionalContent;
class PDFCore;
@@ -131,6 +132,10 @@ public:
#ifndef DISABLE_OUTLINE
// Return the outline object.
Outline *getOutline() { return outline; }
+
+ // Return the target page number for an outline item. Returns 0 if
+ // the item doesn't target a page in this PDF file.
+ int getOutlineTargetPage(OutlineItem *outlineItem);
#endif
// Return the OptionalContent object.
@@ -171,9 +176,9 @@ public:
{ return catalog->getEmbeddedFileName(idx); }
int getEmbeddedFileNameLength(int idx)
{ return catalog->getEmbeddedFileNameLength(idx); }
- GBool saveEmbeddedFile(int idx, char *path);
+ GBool saveEmbeddedFile(int idx, const char *path);
#ifdef _WIN32
- GBool saveEmbeddedFile(int idx, wchar_t *path, int pathLen);
+ GBool saveEmbeddedFile(int idx, const wchar_t *path, int pathLen);
#endif
char *getEmbeddedFileMem(int idx, int *size);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDocEncoding.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDocEncoding.cc
index d173cefd717..c4eef7c24b8 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 "gmempp.h"
#include "PDFDocEncoding.h"
Unicode pdfDocEncoding[256] = {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
index 9521f6ce0e5..050311a3b1d 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc
@@ -17,6 +17,7 @@
#include <stdarg.h>
#include <signal.h>
#include <math.h>
+#include "gmempp.h"
#include "GString.h"
#include "GList.h"
#include "GHash.h"
@@ -48,11 +49,6 @@
#endif
#include "PSOutputDev.h"
-#ifdef MACOS
-// needed for setting type/creator of MacOS files
-#include "ICSupport.h"
-#endif
-
// the MSVC math.h doesn't define this
#ifndef M_PI
#define M_PI 3.14159265358979323846
@@ -65,22 +61,22 @@
// The '~' escapes mark prolog code that is emitted only in certain
// levels:
//
-// ~[123][sn]
-// ^ ^----- s=psLevel*Sep, n=psLevel*
-// +----- 1=psLevel1*, 2=psLevel2*, 3=psLevel3*
+// ~[123][ngs]
+// ^ ^----- n=psLevel_, g=psLevel_Gray, s=psLevel_Sep
+// +----- 1=psLevel1__, 2=psLevel2__, 3=psLevel3__
static const char *prolog[] = {
"/xpdf 75 dict def xpdf begin",
"% PDF special state",
"/pdfDictSize 15 def",
- "~1sn",
+ "~1ns",
"/pdfStates 64 array def",
" 0 1 63 {",
" pdfStates exch pdfDictSize dict",
" dup /pdfStateIdx 3 index put",
" put",
" } for",
- "~123sn",
+ "~123ngs",
"/pdfSetup {",
" /pdfDuplex exch def",
" /setpagedevice where {",
@@ -107,17 +103,17 @@ static const char *prolog[] = {
" pop pop",
" } ifelse",
"} def",
- "~1sn",
+ "~1ns",
"/pdfOpNames [",
" /pdfFill /pdfStroke /pdfLastFill /pdfLastStroke",
" /pdfTextMat /pdfFontSize /pdfCharSpacing /pdfTextRender",
" /pdfTextRise /pdfWordSpacing /pdfHorizScaling /pdfTextClipPath",
"] def",
- "~123sn",
+ "~123ngs",
"/pdfStartPage {",
- "~1sn",
+ "~1ns",
" pdfStates 0 get begin",
- "~23sn",
+ "~23ngs",
" pdfDictSize dict begin",
"~23n",
" /pdfFillCS [] def",
@@ -130,12 +126,15 @@ static const char *prolog[] = {
"~1s",
" /pdfFill [0 0 0 1] def",
" /pdfStroke [0 0 0 1] def",
- "~23sn",
+ "~23g",
+ " /pdfFill 0 def",
+ " /pdfStroke 0 def",
+ "~23ns",
" /pdfFill [0] def",
" /pdfStroke [0] def",
" /pdfFillOP false def",
" /pdfStrokeOP false def",
- "~123sn",
+ "~123ngs",
" /pdfLastFill false def",
" /pdfLastStroke false def",
" /pdfTextMat [1 0 0 1 0 0] def",
@@ -190,7 +189,7 @@ static const char *prolog[] = {
" grestore",
" } def",
"} ifelse",
- "~123sn",
+ "~123ngs",
"% PDF color state",
"~1n",
"/g { dup /pdfFill exch def setgray",
@@ -231,12 +230,16 @@ static const char *prolog[] = {
" setcolorspace } def",
"/CS { /pdfStrokeXform exch def dup /pdfStrokeCS exch def",
" setcolorspace } def",
- "/sc { pdfLastFill not { pdfFillCS setcolorspace } if",
+ "/sc { pdfLastFill not {",
+ " pdfFillCS setcolorspace pdfFillOP setoverprint",
+ " } if",
" dup /pdfFill exch def aload pop pdfFillXform setcolor",
- " /pdfLastFill true def /pdfLastStroke false def } def",
- "/SC { pdfLastStroke not { pdfStrokeCS setcolorspace } if",
+ " /pdfLastFill true def /pdfLastStroke false def } def",
+ "/SC { pdfLastStroke not {",
+ " pdfStrokeCS setcolorspace pdfStrokeOP setoverprint",
+ " } if",
" dup /pdfStroke exch def aload pop pdfStrokeXform setcolor",
- " /pdfLastStroke true def /pdfLastFill false def } def",
+ " /pdfLastStroke true def /pdfLastFill false def } def",
"/op { /pdfFillOP exch def",
" pdfLastFill { pdfFillOP setoverprint } if } def",
"/OP { /pdfStrokeOP exch def",
@@ -257,16 +260,37 @@ static const char *prolog[] = {
" /pdfLastStroke true def /pdfLastFill false def",
" } if",
"} def",
+ "~23g",
+ "/g { dup /pdfFill exch def setgray",
+ " /pdfLastFill true def /pdfLastStroke false def } def",
+ "/G { dup /pdfStroke exch def setgray",
+ " /pdfLastStroke true def /pdfLastFill false def } def",
+ "/fCol {",
+ " pdfLastFill not {",
+ " pdfFill setgray",
+ " /pdfLastFill true def /pdfLastStroke false def",
+ " } if",
+ "} def",
+ "/sCol {",
+ " pdfLastStroke not {",
+ " pdfStroke setgray",
+ " /pdfLastStroke true def /pdfLastFill false def",
+ " } if",
+ "} def",
"~23s",
"/k { 4 copy 4 array astore /pdfFill exch def setcmykcolor",
+ " pdfFillOP setoverprint",
" /pdfLastFill true def /pdfLastStroke false def } def",
"/K { 4 copy 4 array astore /pdfStroke exch def setcmykcolor",
+ " pdfStrokeOP setoverprint",
" /pdfLastStroke true def /pdfLastFill false def } def",
"/ck { 6 copy 6 array astore /pdfFill exch def",
" findcmykcustomcolor exch setcustomcolor",
+ " pdfFillOP setoverprint",
" /pdfLastFill true def /pdfLastStroke false def } def",
"/CK { 6 copy 6 array astore /pdfStroke exch def",
" findcmykcustomcolor exch setcustomcolor",
+ " pdfStrokeOP setoverprint",
" /pdfLastStroke true def /pdfLastFill false def } def",
"/op { /pdfFillOP exch def",
" pdfLastFill { pdfFillOP setoverprint } if } def",
@@ -294,7 +318,11 @@ static const char *prolog[] = {
" /pdfLastStroke true def /pdfLastFill false def",
" } if",
"} def",
- "~123sn",
+ "~3ns",
+ "/opm {",
+ " /setoverprintmode where { pop setoverprintmode } { pop } ifelse",
+ "} def",
+ "~123ngs",
"% build a font",
"/pdfMakeFont {",
" 4 3 roll findfont",
@@ -315,7 +343,7 @@ static const char *prolog[] = {
" end",
" definefont pop",
"} def",
- "~3sn",
+ "~3ngs",
"/pdfMakeFont16L3 {",
" 1 index /CIDFont resourcestatus {",
" pop pop 1 index /CIDFont findresource /CIDFontType known",
@@ -329,9 +357,9 @@ static const char *prolog[] = {
" pdfMakeFont16",
" } ifelse",
"} def",
- "~123sn",
+ "~123ngs",
"% graphics state operators",
- "~1sn",
+ "~1ns",
"/q {",
" gsave",
" pdfOpNames length 1 sub -1 0 { pdfOpNames exch get load } for",
@@ -339,20 +367,12 @@ static const char *prolog[] = {
" pdfOpNames { exch def } forall",
"} def",
"/Q { end grestore } def",
- "~23sn",
+ "~23ngs",
"/q { gsave pdfDictSize dict begin } def",
"/Q {",
" end grestore",
- " /pdfLastFill where {",
- " pop",
- " pdfLastFill {",
- " pdfFillOP setoverprint",
- " } {",
- " pdfStrokeOP setoverprint",
- " } ifelse",
- " } if",
"} def",
- "~123sn",
+ "~123ngs",
"/cm { concat } def",
"/d { setdash } def",
"/i { setflat } def",
@@ -478,6 +498,16 @@ static const char *prolog[] = {
" } ifelse",
" 0 pdfTextRise neg pdfTextMat dtransform rmoveto",
"} def",
+ "/Tj3 {",
+ " pdfTextRender 3 and 3 ne {"
+ " fCol", // because stringwidth has to draw Type 3 chars
+ " 0 pdfTextRise pdfTextMat dtransform rmoveto",
+ " xyshow2",
+ " 0 pdfTextRise neg pdfTextMat dtransform rmoveto",
+ " } {",
+ " pop pop",
+ " } ifelse",
+ "} def",
"/TJm { 0.001 mul pdfFontSize mul pdfHorizScaling mul neg 0",
" pdfTextMat dtransform rmoveto } def",
"/TJmV { 0.001 mul pdfFontSize mul neg 0 exch",
@@ -519,7 +549,7 @@ static const char *prolog[] = {
" { pdfImStr } imagemask",
" pop pop",
"} def",
- "~23sn",
+ "~23ngs",
"% Level 2/3 image operators",
"/pdfImBuf 100 string def",
"/pdfImStr {",
@@ -535,7 +565,7 @@ static const char *prolog[] = {
" (%-EOD-) eq { exit } if } loop",
"} def",
"/pdfIm { image skipEOD } def",
- "~3sn",
+ "~3ngs",
"/pdfMask {",
" /ReusableStreamDecode filter",
" skipEOD",
@@ -571,7 +601,7 @@ static const char *prolog[] = {
" 6 5 roll customcolorimage",
" skipEOD",
"} def",
- "~23sn",
+ "~23ngs",
"/pdfImM { fCol imagemask skipEOD } def",
"/pr {",
" 4 2 roll exch 5 index div exch 4 index div moveto",
@@ -582,7 +612,7 @@ static const char *prolog[] = {
"} def",
"/pdfImClip { gsave clip } def",
"/pdfImClipEnd { grestore } def",
- "~23sn",
+ "~23ns",
"% shading operators",
"/colordelta {",
" false 0 1 3 index length 1 sub {",
@@ -623,7 +653,7 @@ static const char *prolog[] = {
" funcCol sc",
"~23s",
" funcCol aload pop k",
- "~23sn",
+ "~23ns",
" dup 4 index exch mat transform m",
" 3 index 3 index mat transform l",
" 1 index 3 index mat transform l",
@@ -662,7 +692,7 @@ static const char *prolog[] = {
" axialCol sc",
"~23s",
" axialCol aload pop k",
- "~23sn",
+ "~23ns",
" exch dup dx mul x0 add exch dy mul y0 add",
" 3 2 roll dup dx mul x0 add exch dy mul y0 add",
" dx abs dy abs ge {",
@@ -711,7 +741,7 @@ static const char *prolog[] = {
" radialCol sc",
"~23s",
" radialCol aload pop k",
- "~23sn",
+ "~23ns",
" encl {",
" exch dup dx mul x0 add exch dup dy mul y0 add exch dr mul r0 add",
" 0 360 arc h",
@@ -730,7 +760,7 @@ static const char *prolog[] = {
" } ifelse",
" } ifelse",
"} def",
- "~123sn",
+ "~123ngs",
"end",
NULL
};
@@ -868,6 +898,7 @@ PSFontFileInfo::PSFontFileInfo(GString *psNameA, GfxFontType typeA,
extFileName = NULL;
encoding = NULL;
codeToGID = NULL;
+ codeToGIDLen = 0;
}
PSFontFileInfo::~PSFontFileInfo() {
@@ -946,13 +977,15 @@ public:
DeviceNRecoder(Stream *strA, int widthA, int heightA,
GfxImageColorMap *colorMapA);
virtual ~DeviceNRecoder();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strWeird; }
virtual void reset();
+ virtual void close();
virtual int getChar()
{ return (bufIdx >= bufSize && !fillBuf()) ? EOF : buf[bufIdx++]; }
virtual int lookChar()
{ return (bufIdx >= bufSize && !fillBuf()) ? EOF : buf[bufIdx]; }
- virtual GString *getPSFilter(int psLevel, char *indent) { return NULL; }
+ virtual GString *getPSFilter(int psLevel, const char *indent) { return NULL; }
virtual GBool isBinary(GBool last = gTrue) { return gTrue; }
virtual GBool isEncoder() { return gTrue; }
@@ -986,20 +1019,28 @@ DeviceNRecoder::DeviceNRecoder(Stream *strA, int widthA, int heightA,
}
DeviceNRecoder::~DeviceNRecoder() {
- if (imgStr) {
- delete imgStr;
- }
if (str->isEncoder()) {
delete str;
}
}
+Stream *DeviceNRecoder::copy() {
+ error(errInternal, -1, "Called copy() on DeviceNRecoder");
+ return NULL;
+}
+
void DeviceNRecoder::reset() {
imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
colorMap->getBits());
imgStr->reset();
}
+void DeviceNRecoder::close() {
+ delete imgStr;
+ imgStr = NULL;
+ str->close();
+}
+
GBool DeviceNRecoder::fillBuf() {
Guchar pixBuf[gfxColorMaxComps];
GfxColor color;
@@ -1026,6 +1067,202 @@ GBool DeviceNRecoder::fillBuf() {
}
//------------------------------------------------------------------------
+// GrayRecoder
+//------------------------------------------------------------------------
+
+class GrayRecoder: public FilterStream {
+public:
+
+ GrayRecoder(Stream *strA, int widthA, int heightA,
+ GfxImageColorMap *colorMapA);
+ virtual ~GrayRecoder();
+ virtual Stream *copy();
+ virtual StreamKind getKind() { return strWeird; }
+ virtual void reset();
+ virtual void close();
+ virtual int getChar()
+ { 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 GBool isBinary(GBool last = gTrue) { return gTrue; }
+ virtual GBool isEncoder() { return gTrue; }
+
+private:
+
+ GBool fillBuf();
+
+ int width, height;
+ GfxImageColorMap *colorMap;
+ ImageStream *imgStr;
+ Guchar *buf;
+ int bufIdx;
+};
+
+GrayRecoder::GrayRecoder(Stream *strA, int widthA, int heightA,
+ GfxImageColorMap *colorMapA):
+ FilterStream(strA) {
+ width = widthA;
+ height = heightA;
+ colorMap = colorMapA;
+ imgStr = NULL;
+ buf = (Guchar *)gmalloc(width);
+ bufIdx = width;
+}
+
+GrayRecoder::~GrayRecoder() {
+ gfree(buf);
+ if (str->isEncoder()) {
+ delete str;
+ }
+}
+
+Stream *GrayRecoder::copy() {
+ error(errInternal, -1, "Called copy() on GrayRecoder");
+ return NULL;
+}
+
+void GrayRecoder::reset() {
+ imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgStr->reset();
+}
+
+void GrayRecoder::close() {
+ delete imgStr;
+ imgStr = NULL;
+ str->close();
+}
+
+GBool GrayRecoder::fillBuf() {
+ Guchar *line;
+
+ if (!(line = imgStr->getLine())) {
+ bufIdx = width;
+ return gFalse;
+ }
+ //~ this should probably use the rendering intent from the image
+ //~ dict, or from the content stream
+ colorMap->getGrayByteLine(line, buf, width,
+ gfxRenderingIntentRelativeColorimetric);
+ bufIdx = 0;
+ return gTrue;
+}
+
+//------------------------------------------------------------------------
+// ColorKeyToMaskEncoder
+//------------------------------------------------------------------------
+
+class ColorKeyToMaskEncoder: public FilterStream {
+public:
+
+ ColorKeyToMaskEncoder(Stream *strA, int widthA, int heightA,
+ GfxImageColorMap *colorMapA, int *maskColorsA);
+ virtual ~ColorKeyToMaskEncoder();
+ virtual Stream *copy();
+ virtual StreamKind getKind() { return strWeird; }
+ virtual void reset();
+ virtual void close();
+ virtual int getChar()
+ { 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 GBool isBinary(GBool last = gTrue) { return gTrue; }
+ virtual GBool isEncoder() { return gTrue; }
+
+private:
+
+ GBool fillBuf();
+
+ int width, height;
+ GfxImageColorMap *colorMap;
+ int numComps;
+ int *maskColors;
+ ImageStream *imgStr;
+ Guchar *buf;
+ int bufIdx;
+ int bufSize;
+};
+
+ColorKeyToMaskEncoder::ColorKeyToMaskEncoder(Stream *strA,
+ int widthA, int heightA,
+ GfxImageColorMap *colorMapA,
+ int *maskColorsA):
+ FilterStream(strA)
+{
+ width = widthA;
+ height = heightA;
+ colorMap = colorMapA;
+ numComps = colorMap->getNumPixelComps();
+ maskColors = maskColorsA;
+ imgStr = NULL;
+ bufSize = (width + 7) / 8;
+ buf = (Guchar *)gmalloc(bufSize);
+ bufIdx = width;
+}
+
+ColorKeyToMaskEncoder::~ColorKeyToMaskEncoder() {
+ gfree(buf);
+ if (str->isEncoder()) {
+ delete str;
+ }
+}
+
+Stream *ColorKeyToMaskEncoder::copy() {
+ error(errInternal, -1, "Called copy() on ColorKeyToMaskEncoder");
+ return NULL;
+}
+
+void ColorKeyToMaskEncoder::reset() {
+ imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgStr->reset();
+}
+
+void ColorKeyToMaskEncoder::close() {
+ delete imgStr;
+ imgStr = NULL;
+ str->close();
+}
+
+GBool ColorKeyToMaskEncoder::fillBuf() {
+ Guchar *line, *linePtr, *bufPtr;
+ Guchar byte;
+ int x, xx, i;
+
+ if (!(line = imgStr->getLine())) {
+ bufIdx = width;
+ return gFalse;
+ }
+ linePtr = line;
+ bufPtr = buf;
+ for (x = 0; x < width; x += 8) {
+ byte = 0;
+ for (xx = 0; xx < 8; ++xx) {
+ byte <<= 1;
+ if (x + xx < width) {
+ for (i = 0; i < numComps; ++i) {
+ if (linePtr[i] < maskColors[2 * i] ||
+ linePtr[i] > maskColors[2 * i + 1]) {
+ break;
+ }
+ }
+ if (i >= numComps) {
+ byte |= 1;
+ }
+ linePtr += numComps;
+ } else {
+ byte |= 1;
+ }
+ }
+ *bufPtr++ = byte;
+ }
+ bufIdx = 0;
+ return gTrue;
+}
+
+//------------------------------------------------------------------------
// PSOutputDev
//------------------------------------------------------------------------
@@ -1038,11 +1275,12 @@ static void outputToFile(void *stream, const char *data, int len) {
}
PSOutputDev::PSOutputDev(char *fileName, PDFDoc *docA,
- int firstPage, int lastPage, PSOutMode modeA,
+ int firstPageA, int lastPageA, PSOutMode modeA,
int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
GBool manualCtrlA,
PSOutCustomCodeCbk customCodeCbkA,
- void *customCodeCbkDataA) {
+ void *customCodeCbkDataA,
+ GBool honorUserUnitA) {
FILE *f;
PSFileType fileTypeA;
@@ -1053,11 +1291,13 @@ PSOutputDev::PSOutputDev(char *fileName, PDFDoc *docA,
customCodeCbk = customCodeCbkA;
customCodeCbkData = customCodeCbkDataA;
+ rasterizePage = NULL;
fontInfo = new GList();
fontFileInfo = new GHash();
imgIDs = NULL;
formIDs = NULL;
xobjStack = NULL;
+ saveStack = NULL;
paperSizes = NULL;
embFontList = NULL;
customColors = NULL;
@@ -1094,17 +1334,18 @@ PSOutputDev::PSOutputDev(char *fileName, PDFDoc *docA,
}
init(outputToFile, f, fileTypeA,
- docA, firstPage, lastPage, modeA,
- imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA);
+ docA, firstPageA, lastPageA, modeA,
+ imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA, honorUserUnitA);
}
PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA,
PDFDoc *docA,
- int firstPage, int lastPage, PSOutMode modeA,
+ int firstPageA, int lastPageA, PSOutMode modeA,
int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
GBool manualCtrlA,
PSOutCustomCodeCbk customCodeCbkA,
- void *customCodeCbkDataA) {
+ void *customCodeCbkDataA,
+ GBool honorUserUnitA) {
underlayCbk = NULL;
underlayCbkData = NULL;
overlayCbk = NULL;
@@ -1112,11 +1353,13 @@ PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA,
customCodeCbk = customCodeCbkA;
customCodeCbkData = customCodeCbkDataA;
+ rasterizePage = NULL;
fontInfo = new GList();
fontFileInfo = new GHash();
imgIDs = NULL;
formIDs = NULL;
xobjStack = NULL;
+ saveStack = NULL;
paperSizes = NULL;
embFontList = NULL;
customColors = NULL;
@@ -1124,21 +1367,22 @@ PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA,
t3String = NULL;
init(outputFuncA, outputStreamA, psGeneric,
- docA, firstPage, lastPage, modeA,
- imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA);
+ docA, firstPageA, lastPageA, modeA,
+ imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA, honorUserUnitA);
}
void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
PSFileType fileTypeA, PDFDoc *docA,
- int firstPage, int lastPage, PSOutMode modeA,
+ int firstPageA, int lastPageA, PSOutMode modeA,
int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
- GBool manualCtrlA) {
+ GBool manualCtrlA, GBool honorUserUnitA) {
Catalog *catalog;
Page *page;
PDFRectangle *box;
PSOutPaperSize *size;
PSFontFileInfo *ff;
GList *names;
+ double userUnit;
int pg, w, h, i;
// initialize
@@ -1149,8 +1393,15 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
doc = docA;
xref = doc->getXRef();
catalog = doc->getCatalog();
+ if ((firstPage = firstPageA) < 1) {
+ firstPage = 1;
+ }
+ if ((lastPage = lastPageA) > doc->getNumPages()) {
+ lastPage = doc->getNumPages();
+ }
level = globalParams->getPSLevel();
mode = modeA;
+ honorUserUnit = honorUserUnitA;
paperWidth = globalParams->getPSPaperWidth();
paperHeight = globalParams->getPSPaperHeight();
imgLLX = imgLLXA;
@@ -1164,16 +1415,19 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
paperMatch = gTrue;
paperSizes = new GList();
paperWidth = paperHeight = 1; // in case the document has zero pages
- for (pg = (firstPage >= 1) ? firstPage : 1;
- pg <= lastPage && pg <= catalog->getNumPages();
- ++pg) {
+ for (pg = firstPage; pg <= lastPage; ++pg) {
page = catalog->getPage(pg);
+ if (honorUserUnit) {
+ userUnit = page->getUserUnit();
+ } else {
+ userUnit = 1;
+ }
if (globalParams->getPSUseCropBoxAsPage()) {
- w = (int)ceil(page->getCropWidth());
- h = (int)ceil(page->getCropHeight());
+ w = (int)ceil(page->getCropWidth() * userUnit);
+ h = (int)ceil(page->getCropHeight() * userUnit);
} else {
- w = (int)ceil(page->getMediaWidth());
- h = (int)ceil(page->getMediaHeight());
+ w = (int)ceil(page->getMediaWidth() * userUnit);
+ h = (int)ceil(page->getMediaHeight() * userUnit);
}
for (i = 0; i < paperSizes->getLength(); ++i) {
size = (PSOutPaperSize *)paperSizes->get(i);
@@ -1236,7 +1490,8 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
formIDSize = 0;
xobjStack = new GList();
- numSaves = 0;
+ noStateChanges = gFalse;
+ saveStack = new GList();
numTilingPatterns = 0;
nextFunc = 0;
@@ -1245,14 +1500,13 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
if (!manualCtrl) {
// this check is needed in case the document has zero pages
- if (firstPage > 0 && firstPage <= catalog->getNumPages()) {
- writeHeader(firstPage, lastPage,
- catalog->getPage(firstPage)->getMediaBox(),
+ if (firstPage <= catalog->getNumPages()) {
+ writeHeader(catalog->getPage(firstPage)->getMediaBox(),
catalog->getPage(firstPage)->getCropBox(),
catalog->getPage(firstPage)->getRotate());
} else {
box = new PDFRectangle(0, 0, 1, 1);
- writeHeader(firstPage, lastPage, box, box, 0);
+ writeHeader(box, box, 0);
delete box;
}
if (mode != psModeForm) {
@@ -1263,7 +1517,7 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
writePS("%%EndProlog\n");
writePS("%%BeginSetup\n");
}
- writeDocSetup(catalog, firstPage, lastPage);
+ writeDocSetup(catalog);
if (mode != psModeForm) {
writePS("%%EndSetup\n");
}
@@ -1285,9 +1539,6 @@ PSOutputDev::~PSOutputDev() {
}
}
if (fileType == psFile) {
-#ifdef MACOS
- ICS_MapRefNumAndAssign((short)((FILE *)outputStream)->handle);
-#endif
fclose((FILE *)outputStream);
}
#ifdef HAVE_POPEN
@@ -1299,6 +1550,7 @@ PSOutputDev::~PSOutputDev() {
}
#endif
}
+ gfree(rasterizePage);
if (paperSizes) {
deleteGList(paperSizes, PSOutPaperSize);
}
@@ -1312,6 +1564,9 @@ PSOutputDev::~PSOutputDev() {
if (xobjStack) {
delete xobjStack;
}
+ if (saveStack) {
+ delete saveStack;
+ }
while (customColors) {
cc = customColors;
customColors = cc->next;
@@ -1329,8 +1584,7 @@ GBool PSOutputDev::checkIO() {
return gTrue;
}
-void PSOutputDev::writeHeader(int firstPage, int lastPage,
- PDFRectangle *mediaBox, PDFRectangle *cropBox,
+void PSOutputDev::writeHeader(PDFRectangle *mediaBox, PDFRectangle *cropBox,
int pageRotate) {
Object info, obj1;
PSOutPaperSize *size;
@@ -1363,8 +1617,7 @@ void PSOutputDev::writeHeader(int firstPage, int lastPage,
obj1.free();
info.free();
writePSFmt("%%LanguageLevel: {0:d}\n",
- (level == psLevel1 || level == psLevel1Sep) ? 1 :
- (level == psLevel2 || level == psLevel2Sep) ? 2 : 3);
+ level >= psLevel3 ? 3 : level >= psLevel2 ? 2 : 1);
if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) {
writePS("%%DocumentProcessColors: (atend)\n");
writePS("%%DocumentCustomColors: (atend)\n");
@@ -1430,31 +1683,34 @@ void PSOutputDev::writeHeader(int firstPage, int lastPage,
}
void PSOutputDev::writeXpdfProcset() {
- GBool lev1, lev2, lev3, sep, nonSep;
+ GBool lev1, lev2, lev3, nonSep, gray, sep;
const char **p;
const char *q;
double w;
writePSFmt("%%BeginResource: procset xpdf {0:s} 0\n", xpdfVersion);
writePSFmt("%%Copyright: {0:s}\n", xpdfCopyright);
- lev1 = lev2 = lev3 = sep = nonSep = gTrue;
+ lev1 = lev2 = lev3 = nonSep = gray = sep = gTrue;
for (p = prolog; *p; ++p) {
if ((*p)[0] == '~') {
- lev1 = lev2 = lev3 = sep = nonSep = gFalse;
+ lev1 = lev2 = lev3 = nonSep = gray = sep = gFalse;
for (q = *p + 1; *q; ++q) {
switch (*q) {
case '1': lev1 = gTrue; break;
case '2': lev2 = gTrue; break;
case '3': lev3 = gTrue; break;
- case 's': sep = gTrue; break;
+ case 'g': gray = gTrue; break;
case 'n': nonSep = gTrue; break;
+ case 's': sep = gTrue; break;
}
}
} else if ((level == psLevel1 && lev1 && nonSep) ||
(level == psLevel1Sep && lev1 && sep) ||
(level == psLevel2 && lev2 && nonSep) ||
+ (level == psLevel2Gray && lev2 && gray) ||
(level == psLevel2Sep && lev2 && sep) ||
(level == psLevel3 && lev3 && nonSep) ||
+ (level == psLevel3Gray && lev3 && gray) ||
(level == psLevel3Sep && lev3 && sep)) {
writePSFmt("{0:s}\n", *p);
}
@@ -1474,8 +1730,7 @@ void PSOutputDev::writeXpdfProcset() {
}
}
-void PSOutputDev::writeDocSetup(Catalog *catalog,
- int firstPage, int lastPage) {
+void PSOutputDev::writeDocSetup(Catalog *catalog) {
Page *page;
Dict *resDict;
Annots *annots;
@@ -1484,6 +1739,16 @@ void PSOutputDev::writeDocSetup(Catalog *catalog,
GString *s;
int pg, i, j;
+ // check to see which pages will be rasterized
+ if (firstPage <= lastPage) {
+ rasterizePage = (char *)gmalloc(lastPage - firstPage + 1);
+ for (pg = firstPage; pg <= lastPage; ++pg) {
+ rasterizePage[pg - firstPage] = (char)checkIfPageNeedsToBeRasterized(pg);
+ }
+ } else {
+ rasterizePage = NULL;
+ }
+
if (mode == psModeForm) {
// swap the form and xpdf dicts
writePS("xpdf end begin dup begin\n");
@@ -1491,6 +1756,9 @@ void PSOutputDev::writeDocSetup(Catalog *catalog,
writePS("xpdf begin\n");
}
for (pg = firstPage; pg <= lastPage; ++pg) {
+ if (rasterizePage[pg - firstPage]) {
+ continue;
+ }
page = catalog->getPage(pg);
if ((resDict = page->getResourceDict())) {
setupResources(resDict);
@@ -1599,6 +1867,31 @@ void PSOutputDev::writeTrailer() {
}
}
+GBool PSOutputDev::checkIfPageNeedsToBeRasterized(int pg) {
+ PreScanOutputDev *scan;
+ GBool rasterize;
+
+ if (globalParams->getPSAlwaysRasterize()) {
+ rasterize = gTrue;
+ } else {
+ scan = new PreScanOutputDev();
+ //~ this could depend on the printing flag, e.g., if an annotation
+ //~ uses transparency --> need to pass the printing flag into
+ //~ constructor, init, writeDocSetup
+ doc->getCatalog()->getPage(pg)->display(scan, 72, 72, 0,
+ gTrue, gTrue, gTrue);
+ rasterize = scan->usesTransparency() || scan->usesPatternImageMask();
+ delete scan;
+ if (rasterize && globalParams->getPSNeverRasterize()) {
+ error(errSyntaxWarning, -1,
+ "PDF page uses transparency and the psNeverRasterize option is "
+ "set - output may not be correct");
+ rasterize = gFalse;
+ }
+ }
+ return rasterize;
+}
+
void PSOutputDev::setupResources(Dict *resDict) {
Object xObjDict, xObjRef, xObj, patDict, patRef, pat;
Object gsDict, gsRef, gs, smask, smaskGroup, resObj;
@@ -1931,7 +2224,7 @@ void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {
// generate PostScript code to set up the font
if (font->isCIDFont()) {
- if (level == psLevel3 || level == psLevel3Sep) {
+ if (level >= psLevel3) {
writePSFmt("/F{0:d}_{1:d} /{2:t} {3:d} pdfMakeFont16L3\n",
font->getID()->num, font->getID()->gen, fi->ff->psName,
font->getWMode());
@@ -1970,26 +2263,34 @@ void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {
}
PSFontFileInfo *PSOutputDev::setupEmbeddedType1Font(GfxFont *font, Ref *id) {
- static char hexChar[17] = "0123456789abcdef";
- GString *psName;
+ GString *psName, *origFont, *cleanFont;
PSFontFileInfo *ff;
Object refObj, strObj, obj1, obj2;
Dict *dict;
- int length1, length2;
- int c;
- int start[6];
- GBool binMode;
- int n, i;
+ char buf[4096];
+ GBool rename;
+ int length1, length2, n;
// check if font is already embedded
if ((ff = (PSFontFileInfo *)
fontFileInfo->lookup(font->getEmbeddedFontName()))) {
- return ff;
+ if (ff->loc == psFontFileEmbedded &&
+ ff->embFontID.num == id->num &&
+ ff->embFontID.gen == id->gen) {
+ return ff;
+ }
+ rename = gTrue;
+ } else {
+ rename = gFalse;
}
// generate name
// (this assumes that the PS font name matches the PDF font name)
- psName = font->getEmbeddedFontName()->copy();
+ if (rename) {
+ psName = makePSFontName(font, id);
+ } else {
+ psName = font->getEmbeddedFontName()->copy();
+ }
// get the font stream and info
refObj.initRef(id->num, id->gen);
@@ -2018,144 +2319,39 @@ PSFontFileInfo *PSOutputDev::setupEmbeddedType1Font(GfxFont *font, Ref *id) {
obj1.free();
obj2.free();
+ // read the font file
+ origFont = new GString();
+ strObj.streamReset();
+ while ((n = strObj.streamGetBlock(buf, sizeof(buf))) > 0) {
+ origFont->append(buf, n);
+ }
+ strObj.streamClose();
+ strObj.free();
+
// beginning comment
writePSFmt("%%BeginResource: font {0:t}\n", psName);
embFontList->append("%%+ font ");
embFontList->append(psName->getCString());
embFontList->append("\n");
- // check for PFB format
- strObj.streamReset();
- start[0] = strObj.streamGetChar();
- start[1] = strObj.streamGetChar();
- if (start[0] == 0x80 && start[1] == 0x01) {
- error(errSyntaxWarning, -1, "Embedded Type 1 font is in PFB format");
- while (1) {
- for (i = 2; i < 6; ++i) {
- start[i] = strObj.streamGetChar();
- }
- if (start[2] == EOF || start[3] == EOF ||
- start[4] == EOF || start[5] == EOF) {
- break;
- }
- n = start[2] + (start[3] << 8) + (start[4] << 16) + (start[5] << 24);
- if (start[1] == 0x01) {
- for (i = 0; i < n; ++i) {
- if ((c = strObj.streamGetChar()) == EOF) {
- break;
- }
- writePSChar(c);
- }
- } else {
- for (i = 0; i < n; ++i) {
- if ((c = strObj.streamGetChar()) == EOF) {
- break;
- }
- writePSChar(hexChar[(c >> 4) & 0x0f]);
- writePSChar(hexChar[c & 0x0f]);
- if (i % 32 == 31) {
- writePSChar('\n');
- }
- }
- }
- start[0] = strObj.streamGetChar();
- start[1] = strObj.streamGetChar();
- if (start[0] == EOF || start[1] == EOF ||
- (start[0] == 0x80 && start[1] == 0x03)) {
- break;
- } else if (!(start[0] == 0x80 &&
- (start[1] == 0x01 || start[1] == 0x02))) {
- error(errSyntaxError, -1,
- "Invalid PFB header in embedded font stream");
- break;
- }
- }
- writePSChar('\n');
-
- // plain text (PFA) format
- } else {
-
- // copy ASCII portion of font
- writePSChar(start[0]);
- writePSChar(start[1]);
- for (i = 2; i < length1 && (c = strObj.streamGetChar()) != EOF; ++i) {
- writePSChar(c);
- }
-
- // figure out if encrypted portion is binary or ASCII
- binMode = gFalse;
- for (i = 0; i < 4; ++i) {
- start[i] = strObj.streamGetChar();
- if (start[i] == EOF) {
- error(errSyntaxError, -1,
- "Unexpected end of file in embedded font stream");
- goto err1;
- }
- if (!((start[i] >= '0' && start[i] <= '9') ||
- (start[i] >= 'A' && start[i] <= 'F') ||
- (start[i] >= 'a' && start[i] <= 'f')))
- binMode = gTrue;
- }
-
- // convert binary data to ASCII
- if (binMode) {
- for (i = 0; i < 4; ++i) {
- writePSChar(hexChar[(start[i] >> 4) & 0x0f]);
- writePSChar(hexChar[start[i] & 0x0f]);
- }
-#if 0 // this causes trouble for various PostScript printers
- // if Length2 is incorrect (too small), font data gets chopped, so
- // we take a few extra characters from the trailer just in case
- length2 += length3 >= 8 ? 8 : length3;
-#endif
- while (i < length2) {
- if ((c = strObj.streamGetChar()) == EOF) {
- break;
- }
- writePSChar(hexChar[(c >> 4) & 0x0f]);
- writePSChar(hexChar[c & 0x0f]);
- if (++i % 32 == 0) {
- writePSChar('\n');
- }
- }
- if (i % 32 > 0) {
- writePSChar('\n');
- }
-
- // already in ASCII format -- just copy it
- } else {
- for (i = 0; i < 4; ++i) {
- writePSChar(start[i]);
- }
- for (i = 4; i < length2; ++i) {
- if ((c = strObj.streamGetChar()) == EOF) {
- break;
- }
- writePSChar(c);
- }
- }
-
- // write padding and "cleartomark"
- for (i = 0; i < 8; ++i) {
- writePS("00000000000000000000000000000000"
- "00000000000000000000000000000000\n");
- }
- writePS("cleartomark\n");
+ // clean up the font file
+ cleanFont = fixType1Font(origFont, length1, length2);
+ if (rename) {
+ renameType1Font(cleanFont, psName);
}
+ writePSBlock(cleanFont->getCString(), cleanFont->getLength());
+ delete cleanFont;
+ delete origFont;
// ending comment
writePS("%%EndResource\n");
- strObj.streamClose();
- strObj.free();
-
ff = new PSFontFileInfo(psName, font->getType(), psFontFileEmbedded);
ff->embFontID = *id;
fontFileInfo->add(ff->psName, ff);
return ff;
err1:
- strObj.streamClose();
strObj.free();
delete psName;
return NULL;
@@ -2338,7 +2534,7 @@ PSFontFileInfo *PSOutputDev::setupEmbeddedOpenTypeT1CFont(GfxFont *font,
// convert it to a Type 1 font
if ((fontBuf = font->readEmbFontFile(xref, &fontLen))) {
- if ((ffTT = FoFiTrueType::make(fontBuf, fontLen, 0))) {
+ if ((ffTT = FoFiTrueType::make(fontBuf, fontLen, 0, gTrue))) {
if (ffTT->isOpenTypeCFF()) {
ffTT->convertToType1(psName->getCString(), NULL, gTrue,
outputFunc, outputStream);
@@ -2380,6 +2576,7 @@ PSFontFileInfo *PSOutputDev::setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id) {
fontFileInfo->startIter(&iter);
while (fontFileInfo->getNext(&iter, &psName, (void **)&ff)) {
if (ff->loc == psFontFileEmbedded &&
+ ff->type == font->getType() &&
ff->embFontID.num == id->num &&
ff->embFontID.gen == id->gen &&
ff->codeToGIDLen == 256 &&
@@ -2512,11 +2709,15 @@ PSFontFileInfo *PSOutputDev::setupEmbeddedCIDType0Font(GfxFont *font, Ref *id) {
if ((ffT1C = FoFiType1C::make(fontBuf, fontLen))) {
if (globalParams->getPSLevel() >= psLevel3) {
// Level 3: use a CID font
- ffT1C->convertToCIDType0(psName->getCString(), NULL, 0,
+ ffT1C->convertToCIDType0(psName->getCString(),
+ ((GfxCIDFont *)font)->getCIDToGID(),
+ ((GfxCIDFont *)font)->getCIDToGIDLen(),
outputFunc, outputStream);
} else {
// otherwise: use a non-CID composite font
- ffT1C->convertToType0(psName->getCString(), NULL, 0,
+ ffT1C->convertToType0(psName->getCString(),
+ ((GfxCIDFont *)font)->getCIDToGID(),
+ ((GfxCIDFont *)font)->getCIDToGIDLen(),
outputFunc, outputStream);
}
delete ffT1C;
@@ -2553,6 +2754,7 @@ PSFontFileInfo *PSOutputDev::setupEmbeddedCIDTrueTypeFont(
fontFileInfo->startIter(&iter);
while (fontFileInfo->getNext(&iter, &psName, (void **)&ff)) {
if (ff->loc == psFontFileEmbedded &&
+ ff->type == font->getType() &&
ff->embFontID.num == id->num &&
ff->embFontID.gen == id->gen &&
ff->codeToGIDLen == codeToGIDLen &&
@@ -2620,7 +2822,7 @@ PSFontFileInfo *PSOutputDev::setupExternalCIDTrueTypeFont(
int codeToGIDLen;
CharCodeToUnicode *ctu;
Unicode uBuf[8];
- int cmap, code;
+ int cmap, cmapPlatform, cmapEncoding, code;
GHashIter *iter;
// create a code-to-GID mapping, via Unicode
@@ -2636,9 +2838,10 @@ PSFontFileInfo *PSOutputDev::setupExternalCIDTrueTypeFont(
}
// look for a Unicode cmap
for (cmap = 0; cmap < ffTT->getNumCmaps(); ++cmap) {
- if ((ffTT->getCmapPlatform(cmap) == 3 &&
- ffTT->getCmapEncoding(cmap) == 1) ||
- ffTT->getCmapPlatform(cmap) == 0) {
+ cmapPlatform = ffTT->getCmapPlatform(cmap);
+ cmapEncoding = ffTT->getCmapEncoding(cmap);
+ if ((cmapPlatform == 3 && cmapEncoding == 1) ||
+ (cmapPlatform == 0 && cmapEncoding <= 4)) {
break;
}
}
@@ -2761,7 +2964,7 @@ PSFontFileInfo *PSOutputDev::setupEmbeddedOpenTypeCFFFont(GfxFont *font,
// convert it to a Type 0 font
if ((fontBuf = font->readEmbFontFile(xref, &fontLen))) {
- if ((ffTT = FoFiTrueType::make(fontBuf, fontLen, 0))) {
+ if ((ffTT = FoFiTrueType::make(fontBuf, fontLen, 0, gTrue))) {
if (ffTT->isOpenTypeCFF()) {
if (globalParams->getPSLevel() >= psLevel3) {
// Level 3: use a CID font
@@ -2932,6 +3135,428 @@ GString *PSOutputDev::makePSFontName(GfxFont *font, Ref *id) {
return psName;
}
+GString *PSOutputDev::fixType1Font(GString *font, int length1, int length2) {
+ Guchar *fontData;
+ GString *out, *binSection;
+ GBool pfb;
+ int fontSize, i;
+
+ fontData = (Guchar *)font->getCString();
+ fontSize = font->getLength();
+
+ // check for PFB
+ pfb = fontSize >= 6 && fontData[0] == 0x80 && fontData[1] == 0x01;
+ out = new GString();
+ binSection = new GString();
+ if (pfb) {
+ if (!splitType1PFB(fontData, fontSize, out, binSection)) {
+ delete out;
+ delete binSection;
+ return copyType1PFB(fontData, fontSize);
+ }
+ } else {
+ if (!splitType1PFA(fontData, fontSize, length1, length2,
+ out, binSection)) {
+ delete out;
+ delete binSection;
+ return copyType1PFA(fontData, fontSize);
+ }
+ }
+
+ out->append('\n');
+
+ binSection = asciiHexDecodeType1EexecSection(binSection);
+
+ if (!fixType1EexecSection(binSection, out)) {
+ delete out;
+ delete binSection;
+ return pfb ? copyType1PFB(fontData, fontSize)
+ : copyType1PFA(fontData, fontSize);
+ }
+ delete binSection;
+
+ for (i = 0; i < 8; ++i) {
+ out->append("0000000000000000000000000000000000000000000000000000000000000000\n");
+ }
+ out->append("cleartomark\n");
+
+ return out;
+}
+
+// Split a Type 1 font in PFA format into a text section and a binary
+// section.
+GBool PSOutputDev::splitType1PFA(Guchar *font, int fontSize,
+ int length1, int length2,
+ GString *textSection, GString *binSection) {
+ int textLength, binStart, binLength, lastSpace, i;
+
+ //--- extract the text section
+
+ // Length1 is correct, and the text section ends with whitespace
+ if (length1 <= fontSize &&
+ length1 >= 18 &&
+ !memcmp(font + length1 - 18, "currentfile eexec", 17)) {
+ textLength = length1 - 1;
+
+ // Length1 is correct, but the trailing whitespace is missing
+ } else if (length1 <= fontSize &&
+ length1 >= 17 &&
+ !memcmp(font + length1 - 17, "currentfile eexec", 17)) {
+ textLength = length1;
+
+ // Length1 is incorrect
+ } else {
+ for (textLength = 17; textLength <= fontSize; ++textLength) {
+ if (!memcmp(font + textLength - 17, "currentfile eexec", 17)) {
+ break;
+ }
+ }
+ if (textLength > fontSize) {
+ return gFalse;
+ }
+ }
+
+ textSection->append((char *)font, textLength);
+
+ //--- skip whitespace between the text section and the binary section
+
+ for (i = 0, binStart = textLength;
+ i < 8 && binStart < fontSize;
+ ++i, ++binStart) {
+ if (font[binStart] != ' ' && font[binStart] != '\t' &&
+ font[binStart] != '\n' && font[binStart] != '\r') {
+ break;
+ }
+ }
+ if (i == 8) {
+ return gFalse;
+ }
+
+ //--- extract binary section
+
+ // if we see "0000", assume Length2 is correct
+ // (if Length2 is too long, it will be corrected by fixType1EexecSection)
+ if (length2 > 0 && length2 < INT_MAX - 4 &&
+ binStart <= fontSize - length2 - 4 &&
+ !memcmp(font + binStart + length2, "0000", 4)) {
+ binLength = length2;
+
+ } else {
+
+ // look for "0000" near the end of the font (note that there can
+ // be intervening "\n", "\r\n", etc.), then search backward
+ if (fontSize - binStart < 512) {
+ return gFalse;
+ }
+ if (!memcmp(font + fontSize - 256, "0000", 4) ||
+ !memcmp(font + fontSize - 255, "0000", 4) ||
+ !memcmp(font + fontSize - 254, "0000", 4) ||
+ !memcmp(font + fontSize - 253, "0000", 4) ||
+ !memcmp(font + fontSize - 252, "0000", 4) ||
+ !memcmp(font + fontSize - 251, "0000", 4)) {
+ i = fontSize - 252;
+ lastSpace = -1;
+ while (i >= binStart) {
+ if (font[i] == ' ' || font[i] == '\t' ||
+ font[i] == '\n' || font[i] == '\r') {
+ lastSpace = i;
+ --i;
+ } else if (font[i] == '0') {
+ --i;
+ } else {
+ break;
+ }
+ }
+ if (lastSpace < 0) {
+ return gFalse;
+ }
+ // check for the case where the newline/space is missing between
+ // the binary section and the first set of 64 '0' chars
+ if (lastSpace - binStart > 64 &&
+ !memcmp(font + lastSpace - 64,
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ 64)) {
+ binLength = lastSpace - 64 - binStart;
+ } else {
+ binLength = lastSpace - binStart;
+ }
+
+ // couldn't find zeros after binary section -- assume they're
+ // missing and the binary section extends to the end of the file
+ } else {
+ binLength = fontSize - binStart;
+ }
+ }
+
+ binSection->append((char *)(font + binStart), binLength);
+
+ return gTrue;
+}
+
+// Split a Type 1 font in PFB format into a text section and a binary
+// section.
+GBool PSOutputDev::splitType1PFB(Guchar *font, int fontSize,
+ GString *textSection, GString *binSection) {
+ Guchar *p;
+ int state, remain, len, n;
+
+ // states:
+ // 0: text section
+ // 1: binary section
+ // 2: trailer section
+ // 3: eof
+
+ state = 0;
+ p = font;
+ remain = fontSize;
+ while (remain >= 2) {
+ if (p[0] != 0x80) {
+ return gFalse;
+ }
+ switch (state) {
+ case 0:
+ if (p[1] == 0x02) {
+ state = 1;
+ } else if (p[1] != 0x01) {
+ return gFalse;
+ }
+ break;
+ case 1:
+ if (p[1] == 0x01) {
+ state = 2;
+ } else if (p[1] != 0x02) {
+ return gFalse;
+ }
+ break;
+ case 2:
+ if (p[1] == 0x03) {
+ state = 3;
+ } else if (p[1] != 0x01) {
+ return gFalse;
+ }
+ break;
+ default: // shouldn't happen
+ return gFalse;
+ }
+ if (state == 3) {
+ break;
+ }
+
+ if (remain < 6) {
+ break;
+ }
+ len = p[2] + (p[3] << 8) + (p[4] << 16) + (p[5] << 24);
+ if (len < 0 || len > remain - 6) {
+ return gFalse;
+ }
+
+ switch (state) {
+ case 0:
+ textSection->append((char *)(p + 6), len);
+ break;
+ case 1:
+ binSection->append((char *)(p + 6), len);
+ break;
+ case 2:
+ // we don't use the trailer
+ break;
+ default: // shouldn't happen
+ return gFalse;
+ }
+
+ p += len + 6;
+ remain -= len + 6;
+ }
+
+ if (state != 3) {
+ return gFalse;
+ }
+
+ n = textSection->getLength();
+ if (n >= 18 && !memcmp(textSection->getCString() + n - 18,
+ "currentfile eexec", 17)) {
+ // remove the trailing whitespace
+ textSection->del(n - 1, 1);
+ } else if (n >= 17 && !memcmp(textSection->getCString() + n - 17,
+ "currentfile eexec", 17)) {
+ // missing whitespace at end -- leave as-is
+ } else {
+ return gFalse;
+ }
+
+ return gTrue;
+}
+
+// If <in> is ASCIIHex-encoded, decode it, delete <in>, and return the
+// binary version. Else return <in> unchanged.
+GString *PSOutputDev::asciiHexDecodeType1EexecSection(GString *in) {
+ GString *out;
+ char c;
+ Guchar byte;
+ int state, i;
+
+ out = new GString();
+ state = 0;
+ byte = 0;
+ for (i = 0; i < in->getLength(); ++i) {
+ c = in->getChar(i);
+ if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
+ continue;
+ }
+ if (c >= '0' && c <= '9') {
+ byte += c - '0';
+ } else if (c >= 'A' && c <= 'F') {
+ byte += c - 'A' + 10;
+ } else if (c >= 'a' && c <= 'f') {
+ byte += c - 'a' + 10;
+ } else {
+ delete out;
+ return in;
+ }
+ if (state == 0) {
+ byte <<= 4;
+ state = 1;
+ } else {
+ out->append((char)byte);
+ state = 0;
+ byte = 0;
+ }
+ }
+ delete in;
+ return out;
+}
+
+GBool PSOutputDev::fixType1EexecSection(GString *binSection, GString *out) {
+ static char hexChars[17] = "0123456789abcdef";
+ Guchar buf[16], buf2[16];
+ Guchar byte;
+ int r, i, j;
+
+ // eexec-decode the binary section, keeping the last 16 bytes
+ r = 55665;
+ for (i = 0; i < binSection->getLength(); ++i) {
+ byte = (Guchar)binSection->getChar(i);
+ buf[i & 15] = byte ^ (Guchar)(r >> 8);
+ r = ((r + byte) * 52845 + 22719) & 0xffff;
+ }
+ for (j = 0; j < 16; ++j) {
+ buf2[j] = buf[(i + j) & 15];
+ }
+
+ // look for 'closefile'
+ for (i = 0; i <= 16 - 9; ++i) {
+ if (!memcmp(buf2 + i, "closefile", 9)) {
+ break;
+ }
+ }
+ if (i > 16 - 9) {
+ return gFalse;
+ }
+ // three cases:
+ // - short: missing space after "closefile" (i == 16 - 9)
+ // - correct: exactly one space after "closefile" (i == 16 - 10)
+ // - long: extra chars after "closefile" (i < 16 - 10)
+ if (i == 16 - 9) {
+ binSection->append((char)((Guchar)'\n' ^ (Guchar)(r >> 8)));
+ } else if (i < 16 - 10) {
+ binSection->del(binSection->getLength() - (16 - 10 - i), 16 - 10 - i);
+ }
+
+ // ASCIIHex encode
+ for (i = 0; i < binSection->getLength(); i += 32) {
+ for (j = 0; j < 32 && i+j < binSection->getLength(); ++j) {
+ byte = (Guchar)binSection->getChar(i+j);
+ out->append(hexChars[(byte >> 4) & 0x0f]);
+ out->append(hexChars[byte & 0x0f]);
+ }
+ out->append('\n');
+ }
+
+ return gTrue;
+}
+
+// The Type 1 cleanup code failed -- assume it's a valid PFA-format
+// font and copy it to the output.
+GString *PSOutputDev::copyType1PFA(Guchar *font, int fontSize) {
+ GString *out;
+
+ error(errSyntaxWarning, -1, "Couldn't parse embedded Type 1 font");
+
+ out = new GString((char *)font, fontSize);
+ // append a newline to avoid problems where the original font
+ // doesn't end with one
+ out->append('\n');
+ return out;
+}
+
+// The Type 1 cleanup code failed -- assume it's a valid PFB-format
+// font, decode the PFB blocks, and copy them to the output.
+GString *PSOutputDev::copyType1PFB(Guchar *font, int fontSize) {
+ static char hexChars[17] = "0123456789abcdef";
+ GString *out;
+ Guchar *p;
+ int remain, len, i, j;
+
+ error(errSyntaxWarning, -1, "Couldn't parse embedded Type 1 (PFB) font");
+
+ out = new GString();
+ p = font;
+ remain = fontSize;
+ while (remain >= 6 &&
+ p[0] == 0x80 &&
+ (p[1] == 0x01 || p[1] == 0x02)) {
+ len = p[2] + (p[3] << 8) + (p[4] << 16) + (p[5] << 24);
+ if (len > remain - 6) {
+ break;
+ }
+ if (p[1] == 0x01) {
+ out->append((char *)(p + 6), len);
+ } else {
+ for (i = 0; i < len; i += 32) {
+ for (j = 0; j < 32 && i+j < len; ++j) {
+ out->append(hexChars[(p[6+i+j] >> 4) & 0x0f]);
+ out->append(hexChars[p[6+i+j] & 0x0f]);
+ }
+ out->append('\n');
+ }
+ }
+ p += len + 6;
+ remain -= len + 6;
+ }
+ // append a newline to avoid problems where the original font
+ // doesn't end with one
+ out->append('\n');
+ return out;
+}
+
+void PSOutputDev::renameType1Font(GString *font, GString *name) {
+ char *p1, *p2;
+ int i;
+
+ if (!(p1 = strstr(font->getCString(), "\n/FontName")) &&
+ !(p1 = strstr(font->getCString(), "\r/FontName"))) {
+ return;
+ }
+ p1 += 10;
+ while (*p1 == ' ' || *p1 == '\t' || *p1 == '\n' || *p1 == '\r') {
+ ++p1;
+ }
+ if (*p1 != '/') {
+ return;
+ }
+ ++p1;
+ p2 = p1;
+ while (*p2 && *p2 != ' ' && *p2 != '\t' && *p2 != '\n' && *p2 != '\r') {
+ ++p2;
+ }
+ if (!*p2) {
+ return;
+ }
+ i = (int)(p1 - font->getCString());
+ font->del(i, (int)(p2 - p1));
+ font->insert(i, name);
+}
+
void PSOutputDev::setupImages(Dict *resDict) {
Object xObjDict, xObj, xObjRef, subtypeObj, maskObj, maskRef;
Ref imgID;
@@ -2987,21 +3612,101 @@ void PSOutputDev::setupImages(Dict *resDict) {
xObjDict.free();
}
+//~ this doesn't currently handle color key masks in psLevel3Gray
+//~ (which need to be converted to explicit masks)
void PSOutputDev::setupImage(Ref id, Stream *str, GBool mask) {
- GBool useLZW, useRLE, useCompressed, useASCIIHex;
+ StreamColorSpaceMode csMode;
+ GfxColorSpace *colorSpace;
+ GfxImageColorMap *colorMap;
+ Object obj1;
+ GBool imageMask, useLZW, useRLE, useCompressed, useASCIIHex;
GString *s;
- int c;
- int size, line, col, i;
+ int c, width, height, bits, size, line, col, i;
+
+ // check for mask
+ str->getDict()->lookup("ImageMask", &obj1);
+ if (obj1.isBool()) {
+ imageMask = obj1.getBool();
+ } else {
+ imageMask = gFalse;
+ }
+ obj1.free();
+
+ // get image size
+ str->getDict()->lookup("Width", &obj1);
+ if (!obj1.isInt() || obj1.getInt() <= 0) {
+ error(errSyntaxError, -1, "Invalid Width in image");
+ obj1.free();
+ return;
+ }
+ width = obj1.getInt();
+ obj1.free();
+ str->getDict()->lookup("Height", &obj1);
+ if (!obj1.isInt() || obj1.getInt() <= 0) {
+ error(errSyntaxError, -1, "Invalid Height in image");
+ obj1.free();
+ return;
+ }
+ height = obj1.getInt();
+ obj1.free();
+
+ // build the color map
+ if (mask || imageMask) {
+ colorMap = NULL;
+ } else {
+ bits = 0;
+ csMode = streamCSNone;
+ str->getImageParams(&bits, &csMode);
+ if (bits == 0) {
+ str->getDict()->lookup("BitsPerComponent", &obj1);
+ if (!obj1.isInt()) {
+ error(errSyntaxError, -1, "Invalid BitsPerComponent in image");
+ obj1.free();
+ return;
+ }
+ bits = obj1.getInt();
+ obj1.free();
+ }
+ str->getDict()->lookup("ColorSpace", &obj1);
+ if (!obj1.isNull()) {
+ colorSpace = GfxColorSpace::parse(&obj1
+ );
+ } else if (csMode == streamCSDeviceGray) {
+ colorSpace = GfxColorSpace::create(csDeviceGray);
+ } else if (csMode == streamCSDeviceRGB) {
+ colorSpace = GfxColorSpace::create(csDeviceRGB);
+ } else if (csMode == streamCSDeviceCMYK) {
+ colorSpace = GfxColorSpace::create(csDeviceCMYK);
+ } else {
+ colorSpace = NULL;
+ }
+ obj1.free();
+ if (!colorSpace) {
+ error(errSyntaxError, -1, "Invalid ColorSpace in image");
+ return;
+ }
+ str->getDict()->lookup("Decode", &obj1);
+ colorMap = new GfxImageColorMap(bits, &obj1, colorSpace);
+ obj1.free();
+ }
// filters
- //~ this does not correctly handle the DeviceN color space
- //~ -- need to use DeviceNRecoder
if (level < psLevel2) {
useLZW = useRLE = gFalse;
useCompressed = gFalse;
useASCIIHex = gTrue;
} else {
- if (globalParams->getPSUncompressPreloadedImages()) {
+ if (colorMap && (colorMap->getColorSpace()->getMode() == csDeviceN ||
+ level == psLevel2Gray || level == psLevel3Gray)) {
+ if (globalParams->getPSLZW()) {
+ useLZW = gTrue;
+ useRLE = gFalse;
+ } else {
+ useRLE = gTrue;
+ useLZW = gFalse;
+ }
+ useCompressed = gFalse;
+ } else if (globalParams->getPSUncompressPreloadedImages()) {
useLZW = useRLE = gFalse;
useCompressed = gFalse;
} else {
@@ -3026,6 +3731,11 @@ void PSOutputDev::setupImage(Ref id, Stream *str, GBool mask) {
if (useCompressed) {
str = str->getUndecodedStream();
}
+ if (colorMap && (level == psLevel2Gray || level == psLevel3Gray)) {
+ str = new GrayRecoder(str, width, height, colorMap);
+ } else if (colorMap && colorMap->getColorSpace()->getMode() == csDeviceN) {
+ str = new DeviceNRecoder(str, width, height, colorMap);
+ }
if (useLZW) {
str = new LZWEncoder(str);
} else if (useRLE) {
@@ -3125,6 +3835,10 @@ void PSOutputDev::setupImage(Ref id, Stream *str, GBool mask) {
str->close();
delete str;
+
+ if (colorMap) {
+ delete colorMap;
+ }
}
void PSOutputDev::setupForms(Dict *resDict) {
@@ -3247,8 +3961,7 @@ GBool PSOutputDev::checkPageSlice(Page *page, double hDPI, double vDPI,
GBool printing,
GBool (*abortCheckCbk)(void *data),
void *abortCheckCbkData) {
- PreScanOutputDev *scan;
- GBool rasterize;
+ int pg;
#if HAVE_SPLASH
GBool mono;
GBool useLZW;
@@ -3263,34 +3976,36 @@ GBool PSOutputDev::checkPageSlice(Page *page, double hDPI, double vDPI,
Guchar *p;
Guchar col[4];
char buf[4096];
- double hDPI2, vDPI2;
+ double userUnit, hDPI2, vDPI2;
double m0, m1, m2, m3, m4, m5;
int nStripes, stripeH, stripeY;
int w, h, x, y, comp, i, n;
#endif
- if (globalParams->getPSAlwaysRasterize()) {
- rasterize = gTrue;
- } else {
- scan = new PreScanOutputDev();
- page->displaySlice(scan, 72, 72, rotateA, useMediaBox, crop,
- sliceX, sliceY, sliceW, sliceH,
- printing, abortCheckCbk, abortCheckCbkData);
- rasterize = scan->usesTransparency() || scan->usesPatternImageMask();
- delete scan;
- }
- if (!rasterize) {
+ pg = page->getNum();
+ if (!(pg >= firstPage && pg <= lastPage &&
+ rasterizePage[pg - firstPage])) {
return gTrue;
}
#if HAVE_SPLASH
// get the rasterization parameters
dpi = globalParams->getPSRasterResolution();
- mono = globalParams->getPSRasterMono();
+ mono = globalParams->getPSRasterMono() ||
+ level == psLevel1 ||
+ level == psLevel2Gray ||
+ level == psLevel3Gray;
useLZW = globalParams->getPSLZW();
+ // get the UserUnit
+ if (honorUserUnit) {
+ userUnit = page->getUserUnit();
+ } else {
+ userUnit = 1;
+ }
+
// start the PS page
- page->makeBox(dpi, dpi, rotateA, useMediaBox, gFalse,
+ page->makeBox(userUnit * dpi, userUnit * dpi, rotateA, useMediaBox, gFalse,
sliceX, sliceY, sliceW, sliceH, &box, &crop);
rotateA += page->getRotate();
if (rotateA >= 360) {
@@ -3303,7 +4018,7 @@ GBool PSOutputDev::checkPageSlice(Page *page, double hDPI, double vDPI,
delete state;
// set up the SplashOutputDev
- if (mono || level == psLevel1) {
+ if (mono) {
paperColor[0] = 0xff;
splashOut = new SplashOutputDev(splashModeMono8, 1, gFalse,
paperColor, gFalse,
@@ -3324,6 +4039,7 @@ GBool PSOutputDev::checkPageSlice(Page *page, double hDPI, double vDPI,
splashOut->startDoc(xref);
// break the page into stripes
+ // NB: startPage() has already multiplied xScale and yScale by UserUnit
hDPI2 = xScale * dpi;
vDPI2 = yScale * dpi;
if (sliceW < 0 || sliceH < 0) {
@@ -3419,8 +4135,10 @@ GBool PSOutputDev::checkPageSlice(Page *page, double hDPI, double vDPI,
}
break;
case psLevel2:
+ case psLevel2Gray:
case psLevel2Sep:
case psLevel3:
+ case psLevel3Gray:
case psLevel3Sep:
if (mono) {
writePS("/DeviceGray setcolorspace\n");
@@ -3495,22 +4213,29 @@ GBool PSOutputDev::checkPageSlice(Page *page, double hDPI, double vDPI,
void PSOutputDev::startPage(int pageNum, GfxState *state) {
Page *page;
+ double userUnit;
int x1, y1, x2, y2, width, height, t;
int imgWidth, imgHeight, imgWidth2, imgHeight2;
GBool landscape;
GString *s;
+ page = doc->getCatalog()->getPage(pageNum);
+ if (honorUserUnit) {
+ userUnit = page->getUserUnit();
+ } else {
+ userUnit = 1;
+ }
+
if (mode == psModePS) {
writePSFmt("%%Page: {0:d} {1:d}\n", pageNum, seqPage);
if (paperMatch) {
- page = doc->getCatalog()->getPage(pageNum);
imgLLX = imgLLY = 0;
if (globalParams->getPSUseCropBoxAsPage()) {
- imgURX = (int)ceil(page->getCropWidth());
- imgURY = (int)ceil(page->getCropHeight());
+ imgURX = (int)ceil(page->getCropWidth() * userUnit);
+ imgURY = (int)ceil(page->getCropHeight() * userUnit);
} else {
- imgURX = (int)ceil(page->getMediaWidth());
- imgURY = (int)ceil(page->getMediaHeight());
+ imgURX = (int)ceil(page->getMediaWidth() * userUnit);
+ imgURY = (int)ceil(page->getMediaHeight() * userUnit);
}
if (state->getRotate() == 90 || state->getRotate() == 270) {
t = imgURX;
@@ -3526,6 +4251,12 @@ void PSOutputDev::startPage(int pageNum, GfxState *state) {
writePS("xpdf begin\n");
}
+ // set up paper size for paper=match mode
+ // NB: this must be done *before* the saveState() for overlays.
+ if (mode == psModePS && paperMatch) {
+ writePSFmt("{0:d} {1:d} pdfSetupPaper\n", imgURX, imgURY);
+ }
+
// underlays
if (underlayCbk) {
(*underlayCbk)(this, underlayCbkData);
@@ -3576,9 +4307,6 @@ void PSOutputDev::startPage(int pageNum, GfxState *state) {
}
writePSFmt("%%PageOrientation: {0:s}\n",
landscape ? "Landscape" : "Portrait");
- if (paperMatch) {
- writePSFmt("{0:d} {1:d} pdfSetupPaper\n", imgURX, imgURY);
- }
writePS("pdfStartPage\n");
if (rotate == 0) {
imgWidth2 = imgWidth;
@@ -3602,12 +4330,14 @@ void PSOutputDev::startPage(int pageNum, GfxState *state) {
}
// shrink or expand
if (xScale0 > 0 && yScale0 > 0) {
- xScale = xScale0;
- yScale = yScale0;
+ xScale = xScale0 * userUnit;
+ yScale = yScale0 * userUnit;
} else if ((globalParams->getPSShrinkLarger() &&
- (width > imgWidth2 || height > imgHeight2)) ||
+ (width * userUnit > imgWidth2 ||
+ height * userUnit > imgHeight2)) ||
(globalParams->getPSExpandSmaller() &&
- (width < imgWidth2 && height < imgHeight2))) {
+ (width * userUnit < imgWidth2 &&
+ height * userUnit < imgHeight2))) {
xScale = (double)imgWidth2 / (double)width;
yScale = (double)imgHeight2 / (double)height;
if (yScale < xScale) {
@@ -3616,7 +4346,7 @@ void PSOutputDev::startPage(int pageNum, GfxState *state) {
yScale = xScale;
}
} else {
- xScale = yScale = 1;
+ xScale = yScale = userUnit;
}
// deal with odd bounding boxes or clipping
if (clipLLX0 < clipURX0 && clipLLY0 < clipURY0) {
@@ -3691,6 +4421,10 @@ void PSOutputDev::startPage(int pageNum, GfxState *state) {
break;
}
+ if (level == psLevel2Gray || level == psLevel3Gray) {
+ writePS("/DeviceGray setcolorspace\n");
+ }
+
if (customCodeCbk) {
if ((s = (*customCodeCbk)(this, psOutCustomPageSetup, pageNum,
customCodeCbkData))) {
@@ -3702,6 +4436,8 @@ void PSOutputDev::startPage(int pageNum, GfxState *state) {
if (mode == psModePS) {
writePS("%%EndPageSetup\n");
}
+
+ noStateChanges = gFalse;
}
void PSOutputDev::endPage() {
@@ -3726,24 +4462,47 @@ void PSOutputDev::endPage() {
}
void PSOutputDev::saveState(GfxState *state) {
- writePS("q\n");
- ++numSaves;
+ // The noStateChanges and saveStack fields are used to implement an
+ // optimization to reduce gsave/grestore nesting. The idea is to
+ // look for sequences like this:
+ // q q AAA Q BBB Q (where AAA and BBB are sequences of operations)
+ // and transform them to:
+ // q AAA Q q BBB Q
+ if (noStateChanges) {
+ // any non-NULL pointer will work here
+ saveStack->append(this);
+ } else {
+ saveStack->append((PSOutputDev *)NULL);
+ writePS("q\n");
+ noStateChanges = gTrue;
+ }
}
void PSOutputDev::restoreState(GfxState *state) {
- writePS("Q\n");
- --numSaves;
+ if (saveStack->getLength()) {
+ writePS("Q\n");
+ if (saveStack->del(saveStack->getLength() - 1)) {
+ writePS("q\n");
+ noStateChanges = gTrue;
+ } else {
+ noStateChanges = gFalse;
+ }
+ }
}
void PSOutputDev::updateCTM(GfxState *state, double m11, double m12,
double m21, double m22, double m31, double m32) {
- if (fabs(m11 * m22 - m12 * m21) < 0.00001) {
+ if (m11 == 1 && m12 == 0 && m21 == 0 && m22 == 1 && m31 == 0 && m32 == 0) {
+ return;
+ }
+ if (fabs(m11 * m22 - m12 * m21) < 1e-10) {
// avoid a singular (or close-to-singular) matrix
- writePSFmt("[0.00001 0 0 0.00001 {0:.6g} {1:.6g}] Tm\n", m31, m32);
+ writePSFmt("[0.00001 0 0 0.00001 {0:.6g} {1:.6g}] cm\n", m31, m32);
} else {
writePSFmt("[{0:.6g} {1:.6g} {2:.6g} {3:.6g} {4:.6g} {5:.6g}] cm\n",
m11, m12, m21, m22, m31, m32);
}
+ noStateChanges = gFalse;
}
void PSOutputDev::updateLineDash(GfxState *state) {
@@ -3759,26 +4518,32 @@ void PSOutputDev::updateLineDash(GfxState *state) {
(i == length-1) ? 0 : 1);
}
writePSFmt("] {0:.6g} d\n", start);
+ noStateChanges = gFalse;
}
void PSOutputDev::updateFlatness(GfxState *state) {
- writePSFmt("{0:d} i\n", state->getFlatness());
+ writePSFmt("{0:.4g} i\n", state->getFlatness());
+ noStateChanges = gFalse;
}
void PSOutputDev::updateLineJoin(GfxState *state) {
writePSFmt("{0:d} j\n", state->getLineJoin());
+ noStateChanges = gFalse;
}
void PSOutputDev::updateLineCap(GfxState *state) {
writePSFmt("{0:d} J\n", state->getLineCap());
+ noStateChanges = gFalse;
}
void PSOutputDev::updateMiterLimit(GfxState *state) {
writePSFmt("{0:.4g} M\n", state->getMiterLimit());
+ noStateChanges = gFalse;
}
void PSOutputDev::updateLineWidth(GfxState *state) {
writePSFmt("{0:.6g} w\n", state->getLineWidth());
+ noStateChanges = gFalse;
}
void PSOutputDev::updateFillColorSpace(GfxState *state) {
@@ -3789,10 +4554,14 @@ void PSOutputDev::updateFillColorSpace(GfxState *state) {
case psLevel2:
case psLevel3:
if (state->getFillColorSpace()->getMode() != csPattern) {
- dumpColorSpaceL2(state->getFillColorSpace(), gTrue, gFalse, gFalse);
+ dumpColorSpaceL2(state, state->getFillColorSpace(),
+ gTrue, gFalse, gFalse);
writePS(" cs\n");
+ noStateChanges = gFalse;
}
break;
+ case psLevel2Gray:
+ case psLevel3Gray:
case psLevel2Sep:
case psLevel3Sep:
break;
@@ -3807,10 +4576,14 @@ void PSOutputDev::updateStrokeColorSpace(GfxState *state) {
case psLevel2:
case psLevel3:
if (state->getStrokeColorSpace()->getMode() != csPattern) {
- dumpColorSpaceL2(state->getStrokeColorSpace(), gTrue, gFalse, gFalse);
+ dumpColorSpaceL2(state, state->getStrokeColorSpace(),
+ gTrue, gFalse, gFalse);
writePS(" CS\n");
+ noStateChanges = gFalse;
}
break;
+ case psLevel2Gray:
+ case psLevel3Gray:
case psLevel2Sep:
case psLevel3Sep:
break;
@@ -3828,6 +4601,8 @@ void PSOutputDev::updateFillColor(GfxState *state) {
switch (level) {
case psLevel1:
+ case psLevel2Gray:
+ case psLevel3Gray:
state->getFillGray(&gray);
writePSFmt("{0:.4g} g\n", colToDbl(gray));
break;
@@ -3859,13 +4634,13 @@ void PSOutputDev::updateFillColor(GfxState *state) {
if (state->getFillColorSpace()->getMode() == csSeparation) {
sepCS = (GfxSeparationColorSpace *)state->getFillColorSpace();
color.c[0] = gfxColorComp1;
- sepCS->getCMYK(&color, &cmyk);
+ sepCS->getCMYK(&color, &cmyk, state->getRenderingIntent());
writePSFmt("{0:.4g} {1:.4g} {2:.4g} {3:.4g} {4:.4g} ({5:t}) ck\n",
colToDbl(state->getFillColor()->c[0]),
colToDbl(cmyk.c), colToDbl(cmyk.m),
colToDbl(cmyk.y), colToDbl(cmyk.k),
sepCS->getName());
- addCustomColor(sepCS);
+ addCustomColor(state, sepCS);
} else {
state->getFillCMYK(&cmyk);
c = colToDbl(cmyk.c);
@@ -3878,6 +4653,7 @@ void PSOutputDev::updateFillColor(GfxState *state) {
break;
}
t3Cacheable = gFalse;
+ noStateChanges = gFalse;
}
void PSOutputDev::updateStrokeColor(GfxState *state) {
@@ -3891,6 +4667,8 @@ void PSOutputDev::updateStrokeColor(GfxState *state) {
switch (level) {
case psLevel1:
+ case psLevel2Gray:
+ case psLevel3Gray:
state->getStrokeGray(&gray);
writePSFmt("{0:.4g} G\n", colToDbl(gray));
break;
@@ -3922,13 +4700,13 @@ void PSOutputDev::updateStrokeColor(GfxState *state) {
if (state->getStrokeColorSpace()->getMode() == csSeparation) {
sepCS = (GfxSeparationColorSpace *)state->getStrokeColorSpace();
color.c[0] = gfxColorComp1;
- sepCS->getCMYK(&color, &cmyk);
+ sepCS->getCMYK(&color, &cmyk, state->getRenderingIntent());
writePSFmt("{0:.4g} {1:.4g} {2:.4g} {3:.4g} {4:.4g} ({5:t}) CK\n",
colToDbl(state->getStrokeColor()->c[0]),
colToDbl(cmyk.c), colToDbl(cmyk.m),
colToDbl(cmyk.y), colToDbl(cmyk.k),
sepCS->getName());
- addCustomColor(sepCS);
+ addCustomColor(state, sepCS);
} else {
state->getStrokeCMYK(&cmyk);
c = colToDbl(cmyk.c);
@@ -3941,6 +4719,7 @@ void PSOutputDev::updateStrokeColor(GfxState *state) {
break;
}
t3Cacheable = gFalse;
+ noStateChanges = gFalse;
}
void PSOutputDev::addProcessColor(double c, double m, double y, double k) {
@@ -3958,7 +4737,8 @@ void PSOutputDev::addProcessColor(double c, double m, double y, double k) {
}
}
-void PSOutputDev::addCustomColor(GfxSeparationColorSpace *sepCS) {
+void PSOutputDev::addCustomColor(GfxState *state,
+ GfxSeparationColorSpace *sepCS) {
PSOutCustomColor *cc;
GfxColor color;
GfxCMYK cmyk;
@@ -3969,7 +4749,7 @@ void PSOutputDev::addCustomColor(GfxSeparationColorSpace *sepCS) {
}
}
color.c[0] = gfxColorComp1;
- sepCS->getCMYK(&color, &cmyk);
+ sepCS->getCMYK(&color, &cmyk, state->getRenderingIntent());
cc = new PSOutCustomColor(colToDbl(cmyk.c), colToDbl(cmyk.m),
colToDbl(cmyk.y), colToDbl(cmyk.k),
sepCS->getName()->copy());
@@ -3977,15 +4757,56 @@ void PSOutputDev::addCustomColor(GfxSeparationColorSpace *sepCS) {
customColors = cc;
}
+void PSOutputDev::addCustomColors(GfxState *state,
+ GfxDeviceNColorSpace *devnCS) {
+ PSOutCustomColor *cc;
+ GfxColor color;
+ GfxCMYK cmyk;
+ int i;
+
+ for (i = 0; i < devnCS->getNComps(); ++i) {
+ color.c[i] = 0;
+ }
+ for (i = 0; i < devnCS->getNComps(); ++i) {
+ for (cc = customColors; cc; cc = cc->next) {
+ if (!cc->name->cmp(devnCS->getColorantName(i))) {
+ break;
+ }
+ }
+ if (cc) {
+ continue;
+ }
+ color.c[i] = gfxColorComp1;
+ devnCS->getCMYK(&color, &cmyk, state->getRenderingIntent());
+ color.c[i] = 0;
+ cc = new PSOutCustomColor(colToDbl(cmyk.c), colToDbl(cmyk.m),
+ colToDbl(cmyk.y), colToDbl(cmyk.k),
+ devnCS->getColorantName(i)->copy());
+ cc->next = customColors;
+ customColors = cc;
+ }
+}
+
void PSOutputDev::updateFillOverprint(GfxState *state) {
- if (level >= psLevel2) {
+ if (level == psLevel2 || level == psLevel2Sep ||
+ level == psLevel3 || level == psLevel3Sep) {
writePSFmt("{0:s} op\n", state->getFillOverprint() ? "true" : "false");
+ noStateChanges = gFalse;
}
}
void PSOutputDev::updateStrokeOverprint(GfxState *state) {
- if (level >= psLevel2) {
+ if (level == psLevel2 || level == psLevel2Sep ||
+ level == psLevel3 || level == psLevel3Sep) {
writePSFmt("{0:s} OP\n", state->getStrokeOverprint() ? "true" : "false");
+ noStateChanges = gFalse;
+ }
+}
+
+void PSOutputDev::updateOverprintMode(GfxState *state) {
+ if (level == psLevel3 || level == psLevel3Sep) {
+ writePSFmt("{0:s} opm\n", state->getOverprintMode() ? "true" : "false");
+ noStateChanges = gFalse;
}
}
@@ -3995,7 +4816,8 @@ void PSOutputDev::updateTransfer(GfxState *state) {
funcs = state->getTransfer();
if (funcs[0] && funcs[1] && funcs[2] && funcs[3]) {
- if (level >= psLevel2) {
+ if (level == psLevel2 || level == psLevel2Sep ||
+ level == psLevel3 || level == psLevel3Sep) {
for (i = 0; i < 4; ++i) {
cvtFunction(funcs[i]);
}
@@ -4010,6 +4832,7 @@ void PSOutputDev::updateTransfer(GfxState *state) {
} else {
writePS("{} settransfer\n");
}
+ noStateChanges = gFalse;
}
void PSOutputDev::updateFont(GfxState *state) {
@@ -4018,6 +4841,7 @@ void PSOutputDev::updateFont(GfxState *state) {
state->getFont()->getID()->num, state->getFont()->getID()->gen,
fabs(state->getFontSize()) < 0.0001 ? 0.0001
: state->getFontSize());
+ noStateChanges = gFalse;
}
}
@@ -4025,17 +4849,19 @@ void PSOutputDev::updateTextMat(GfxState *state) {
double *mat;
mat = state->getTextMat();
- if (fabs(mat[0] * mat[3] - mat[1] * mat[2]) < 0.00001) {
+ if (fabs(mat[0] * mat[3] - mat[1] * mat[2]) < 1e-10) {
// avoid a singular (or close-to-singular) matrix
writePSFmt("[0.00001 0 0 0.00001 {0:.6g} {1:.6g}] Tm\n", mat[4], mat[5]);
} else {
writePSFmt("[{0:.6g} {1:.6g} {2:.6g} {3:.6g} {4:.6g} {5:.6g}] Tm\n",
mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
}
+ noStateChanges = gFalse;
}
void PSOutputDev::updateCharSpace(GfxState *state) {
writePSFmt("{0:.6g} Tc\n", state->getCharSpace());
+ noStateChanges = gFalse;
}
void PSOutputDev::updateRender(GfxState *state) {
@@ -4047,14 +4873,17 @@ void PSOutputDev::updateRender(GfxState *state) {
if (rm != 0 && rm != 3) {
t3Cacheable = gFalse;
}
+ noStateChanges = gFalse;
}
void PSOutputDev::updateRise(GfxState *state) {
writePSFmt("{0:.6g} Ts\n", state->getRise());
+ noStateChanges = gFalse;
}
void PSOutputDev::updateWordSpace(GfxState *state) {
writePSFmt("{0:.6g} Tw\n", state->getWordSpace());
+ noStateChanges = gFalse;
}
void PSOutputDev::updateHorizScaling(GfxState *state) {
@@ -4065,10 +4894,12 @@ void PSOutputDev::updateHorizScaling(GfxState *state) {
h = 0.01;
}
writePSFmt("{0:.6g} Tz\n", h);
+ noStateChanges = gFalse;
}
void PSOutputDev::updateTextPos(GfxState *state) {
writePSFmt("{0:.6g} {1:.6g} Td\n", state->getLineX(), state->getLineY());
+ noStateChanges = gFalse;
}
void PSOutputDev::updateTextShift(GfxState *state, double shift) {
@@ -4077,14 +4908,17 @@ void PSOutputDev::updateTextShift(GfxState *state, double shift) {
} else {
writePSFmt("{0:.6g} TJm\n", shift);
}
+ noStateChanges = gFalse;
}
void PSOutputDev::saveTextPos(GfxState *state) {
writePS("currentpoint\n");
+ noStateChanges = gFalse;
}
void PSOutputDev::restoreTextPos(GfxState *state) {
writePS("m\n");
+ noStateChanges = gFalse;
}
void PSOutputDev::stroke(GfxState *state) {
@@ -4096,23 +4930,43 @@ void PSOutputDev::stroke(GfxState *state) {
} else {
writePS("S\n");
}
+ noStateChanges = gFalse;
}
void PSOutputDev::fill(GfxState *state) {
doPath(state->getPath());
writePS("f\n");
+ noStateChanges = gFalse;
}
void PSOutputDev::eoFill(GfxState *state) {
doPath(state->getPath());
writePS("f*\n");
+ noStateChanges = gFalse;
}
void PSOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx, Object *strRef,
- int paintType, Dict *resDict,
+ int paintType, int tilingType,
+ Dict *resDict,
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
double xStep, double yStep) {
+ if (level <= psLevel1Sep) {
+ tilingPatternFillL1(state, gfx, strRef, paintType, tilingType,
+ resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep);
+ } else {
+ tilingPatternFillL2(state, gfx, strRef, paintType, tilingType,
+ resDict, mat, bbox, x0, y0, x1, y1, xStep, yStep);
+ }
+}
+
+void PSOutputDev::tilingPatternFillL1(GfxState *state, Gfx *gfx,
+ Object *strRef,
+ int paintType, int tilingType,
+ Dict *resDict,
+ double *mat, double *bbox,
+ int x0, int y0, int x1, int y1,
+ double xStep, double yStep) {
PDFRectangle box;
Gfx *gfx2;
@@ -4174,6 +5028,65 @@ void PSOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx, Object *strRef,
writePSFmt("{0:d} 1 {1:d} {{ {2:.6g} exch {3:.6g} mul m {4:d} 1 {5:d} {{ pop (x) show }} for }} for\n",
y0, y1 - 1, x0 * xStep, yStep, x0, x1 - 1);
writePS("grestore\n");
+ noStateChanges = gFalse;
+}
+
+void PSOutputDev::tilingPatternFillL2(GfxState *state, Gfx *gfx,
+ Object *strRef,
+ int paintType, int tilingType,
+ Dict *resDict,
+ double *mat, double *bbox,
+ int x0, int y0, int x1, int y1,
+ double xStep, double yStep) {
+ PDFRectangle box;
+ Gfx *gfx2;
+
+ // switch to pattern space
+ writePSFmt("gsave [{0:.6g} {1:.6g} {2:.6g} {3:.6g} {4:.6g} {5:.6g}] concat\n",
+ mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
+
+ // define a pattern
+ writePSFmt("/xpdfTile{0:d}\n", numTilingPatterns);
+ writePS("<<\n");
+ writePS(" /PatternType 1\n");
+ writePSFmt(" /PaintType {0:d}\n", paintType);
+ writePSFmt(" /TilingType {0:d}\n", tilingType);
+ writePSFmt(" /BBox [{0:.6g} {1:.6g} {2:.6g} {3:.6g}]\n",
+ bbox[0], bbox[1], bbox[2], bbox[3]);
+ writePSFmt(" /XStep {0:.6g}\n", xStep);
+ writePSFmt(" /YStep {0:.6g}\n", yStep);
+ writePS(" /PaintProc {\n");
+ box.x1 = bbox[0];
+ box.y1 = bbox[1];
+ box.x2 = bbox[2];
+ box.y2 = bbox[3];
+ gfx2 = new Gfx(doc, this, resDict, &box, NULL);
+ gfx2->takeContentStreamStack(gfx);
+ t3FillColorOnly = paintType == 2;
+ inType3Char = gTrue;
+ ++numTilingPatterns;
+ gfx2->display(strRef);
+ --numTilingPatterns;
+ inType3Char = gFalse;
+ delete gfx2;
+ writePS(" }\n");
+ writePS(">> matrix makepattern def\n");
+
+ // set the pattern
+ if (paintType == 2) {
+ writePS("currentcolor ");
+ }
+ writePSFmt("xpdfTile{0:d} setpattern\n", numTilingPatterns);
+
+ // fill with the pattern
+ writePSFmt("{0:.6g} {1:.6g} {2:.6g} {3:.6g} rectfill\n",
+ x0 * xStep + bbox[0],
+ y0 * yStep + bbox[1],
+ (x1 - x0) * xStep + bbox[2],
+ (y1 - y0) * yStep + bbox[3]);
+
+ writePS("grestore\n");
+ noStateChanges = gFalse;
}
GBool PSOutputDev::functionShadedFill(GfxState *state,
@@ -4214,6 +5127,7 @@ GBool PSOutputDev::functionShadedFill(GfxState *state,
}
writePSFmt("{0:.6g} {1:.6g} {2:.6g} {3:.6g} 0 funcSH\n", x0, y0, x1, y1);
+ noStateChanges = gFalse;
return gTrue;
}
@@ -4308,6 +5222,7 @@ GBool PSOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading) {
}
writePSFmt("{0:.6g} {1:.6g} 0 axialSH\n", tMin, tMax);
+ noStateChanges = gFalse;
return gTrue;
}
@@ -4555,22 +5470,26 @@ GBool PSOutputDev::radialShadedFill(GfxState *state,
}
}
+ noStateChanges = gFalse;
return gTrue;
}
void PSOutputDev::clip(GfxState *state) {
doPath(state->getPath());
writePS("W\n");
+ noStateChanges = gFalse;
}
void PSOutputDev::eoClip(GfxState *state) {
doPath(state->getPath());
writePS("W*\n");
+ noStateChanges = gFalse;
}
void PSOutputDev::clipToStrokePath(GfxState *state) {
doPath(state->getPath());
writePS("Ws\n");
+ noStateChanges = gFalse;
}
void PSOutputDev::doPath(GfxPath *path) {
@@ -4784,7 +5703,11 @@ void PSOutputDev::drawString(GfxState *state, GString *s) {
}
writePSFmt("{0:.6g}", dxdy[i]);
}
- writePS("] Tj\n");
+ if (font->getType() == fontType3) {
+ writePS("] Tj3\n");
+ } else {
+ writePS("] Tj\n");
+ }
if (wMode) {
writePSFmt("{0:.6g} {1:.6g} rmoveto\n", tOriginX0, tOriginY0);
}
@@ -4792,15 +5715,18 @@ void PSOutputDev::drawString(GfxState *state, GString *s) {
gfree(dxdy);
delete s2;
- if (state->getRender() & 4) {
+ if ((state->getRender() & 4) && font->getType() != fontType3) {
haveTextClip = gTrue;
}
+
+ noStateChanges = gFalse;
}
void PSOutputDev::endTextObject(GfxState *state) {
if (haveTextClip) {
writePS("Tclip\n");
haveTextClip = gFalse;
+ noStateChanges = gFalse;
}
}
@@ -4813,19 +5739,22 @@ void PSOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
switch (level) {
case psLevel1:
case psLevel1Sep:
- doImageL1(ref, NULL, invert, inlineImg, str, width, height, len);
+ doImageL1(ref, state, NULL, invert, inlineImg, str, width, height, len);
break;
case psLevel2:
+ case psLevel2Gray:
case psLevel2Sep:
- doImageL2(ref, NULL, invert, inlineImg, str, width, height, len,
+ doImageL2(ref, state, NULL, invert, inlineImg, str, width, height, len,
NULL, NULL, 0, 0, gFalse);
break;
case psLevel3:
+ case psLevel3Gray:
case psLevel3Sep:
- doImageL3(ref, NULL, invert, inlineImg, str, width, height, len,
+ doImageL3(ref, state, NULL, invert, inlineImg, str, width, height, len,
NULL, NULL, 0, 0, gFalse);
break;
}
+ noStateChanges = gFalse;
}
void PSOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
@@ -4838,24 +5767,28 @@ void PSOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
colorMap->getBits() + 7) / 8);
switch (level) {
case psLevel1:
- doImageL1(ref, colorMap, gFalse, inlineImg, str, width, height, len);
+ doImageL1(ref, state, colorMap, gFalse, inlineImg, str,
+ width, height, len);
break;
case psLevel1Sep:
//~ handle indexed, separation, ... color spaces
- doImageL1Sep(colorMap, gFalse, inlineImg, str, width, height, len);
+ doImageL1Sep(state, colorMap, gFalse, inlineImg, str, width, height, len);
break;
case psLevel2:
+ case psLevel2Gray:
case psLevel2Sep:
- doImageL2(ref, colorMap, gFalse, inlineImg, str,
+ doImageL2(ref, state, colorMap, gFalse, inlineImg, str,
width, height, len, maskColors, NULL, 0, 0, gFalse);
break;
case psLevel3:
+ case psLevel3Gray:
case psLevel3Sep:
- doImageL3(ref, colorMap, gFalse, inlineImg, str,
+ doImageL3(ref, state, colorMap, gFalse, inlineImg, str,
width, height, len, maskColors, NULL, 0, 0, gFalse);
break;
}
t3Cacheable = gFalse;
+ noStateChanges = gFalse;
}
void PSOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
@@ -4870,27 +5803,31 @@ void PSOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
colorMap->getBits() + 7) / 8);
switch (level) {
case psLevel1:
- doImageL1(ref, colorMap, gFalse, gFalse, str, width, height, len);
+ doImageL1(ref, state, colorMap, gFalse, gFalse, str, width, height, len);
break;
case psLevel1Sep:
//~ handle indexed, separation, ... color spaces
- doImageL1Sep(colorMap, gFalse, gFalse, str, width, height, len);
+ doImageL1Sep(state, colorMap, gFalse, gFalse, str, width, height, len);
break;
case psLevel2:
+ case psLevel2Gray:
case psLevel2Sep:
- doImageL2(ref, colorMap, gFalse, gFalse, str, width, height, len,
+ doImageL2(ref, state, colorMap, gFalse, gFalse, str, width, height, len,
NULL, maskStr, maskWidth, maskHeight, maskInvert);
break;
case psLevel3:
+ case psLevel3Gray:
case psLevel3Sep:
- doImageL3(ref, colorMap, gFalse, gFalse, str, width, height, len,
+ doImageL3(ref, state, colorMap, gFalse, gFalse, str, width, height, len,
NULL, maskStr, maskWidth, maskHeight, maskInvert);
break;
}
t3Cacheable = gFalse;
+ noStateChanges = gFalse;
}
-void PSOutputDev::doImageL1(Object *ref, GfxImageColorMap *colorMap,
+void PSOutputDev::doImageL1(Object *ref, GfxState *state,
+ GfxImageColorMap *colorMap,
GBool invert, GBool inlineImg,
Stream *str, int width, int height, int len) {
ImageStream *imgStr;
@@ -4966,7 +5903,7 @@ void PSOutputDev::doImageL1(Object *ref, GfxImageColorMap *colorMap,
// write the line
for (x = 0; x < width; ++x) {
imgStr->getPixel(pixBuf);
- colorMap->getGray(pixBuf, &gray);
+ colorMap->getGray(pixBuf, &gray, state->getRenderingIntent());
writePSFmt("{0:02x}", colToByte(gray));
if (++i == 32) {
writePSChar('\n');
@@ -5001,7 +5938,7 @@ void PSOutputDev::doImageL1(Object *ref, GfxImageColorMap *colorMap,
}
}
-void PSOutputDev::doImageL1Sep(GfxImageColorMap *colorMap,
+void PSOutputDev::doImageL1Sep(GfxState *state, GfxImageColorMap *colorMap,
GBool invert, GBool inlineImg,
Stream *str, int width, int height, int len) {
ImageStream *imgStr;
@@ -5030,7 +5967,7 @@ void PSOutputDev::doImageL1Sep(GfxImageColorMap *colorMap,
// read the line
for (x = 0; x < width; ++x) {
imgStr->getPixel(pixBuf);
- colorMap->getCMYK(pixBuf, &cmyk);
+ colorMap->getCMYK(pixBuf, &cmyk, state->getRenderingIntent());
lineBuf[4*x+0] = colToByte(cmyk.c);
lineBuf[4*x+1] = colToByte(cmyk.m);
lineBuf[4*x+2] = colToByte(cmyk.y);
@@ -5060,17 +5997,13 @@ void PSOutputDev::doImageL1Sep(GfxImageColorMap *colorMap,
gfree(lineBuf);
}
-void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
+void PSOutputDev::doImageL2(Object *ref, GfxState *state,
+ GfxImageColorMap *colorMap,
GBool invert, GBool inlineImg,
Stream *str, int width, int height, int len,
int *maskColors, Stream *maskStr,
int maskWidth, int maskHeight, GBool maskInvert) {
Stream *str2;
- ImageStream *imgStr;
- Guchar *line;
- PSOutImgClipRect *rects0, *rects1, *rectsTmp, *rectsOut;
- int rects0Len, rects1Len, rectsSize, rectsOutLen, rectsOutSize;
- GBool emitRect, addRect, extendRect;
GString *s;
int n, numComps;
GBool useLZW, useRLE, useASCII, useASCIIHex, useCompressed;
@@ -5078,259 +6011,22 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
GfxColor color;
GfxCMYK cmyk;
char buf[4096];
- int c;
- int col, i, j, x0, x1, y, maskXor;
+ int c, col, i;
// color key masking
if (maskColors && colorMap && !inlineImg) {
// can't read the stream twice for inline images -- but masking
// isn't allowed with inline images anyway
- numComps = colorMap->getNumPixelComps();
- imgStr = new ImageStream(str, width, numComps, colorMap->getBits());
- imgStr->reset();
- rects0Len = rects1Len = rectsOutLen = 0;
- rectsSize = rectsOutSize = 64;
- rects0 = (PSOutImgClipRect *)gmallocn(rectsSize, sizeof(PSOutImgClipRect));
- rects1 = (PSOutImgClipRect *)gmallocn(rectsSize, sizeof(PSOutImgClipRect));
- rectsOut = (PSOutImgClipRect *)gmallocn(rectsOutSize,
- sizeof(PSOutImgClipRect));
- for (y = 0; y < height; ++y) {
- if (!(line = imgStr->getLine())) {
- break;
- }
- i = 0;
- rects1Len = 0;
- for (x0 = 0; x0 < width; ++x0) {
- for (j = 0; j < numComps; ++j) {
- if (line[x0*numComps+j] < maskColors[2*j] ||
- line[x0*numComps+j] > maskColors[2*j+1]) {
- break;
- }
- }
- if (j < numComps) {
- break;
- }
- }
- for (x1 = x0; x1 < width; ++x1) {
- for (j = 0; j < numComps; ++j) {
- if (line[x1*numComps+j] < maskColors[2*j] ||
- line[x1*numComps+j] > maskColors[2*j+1]) {
- break;
- }
- }
- if (j == numComps) {
- break;
- }
- }
- while (x0 < width || i < rects0Len) {
- emitRect = addRect = extendRect = gFalse;
- if (x0 >= width) {
- emitRect = gTrue;
- } else if (i >= rects0Len) {
- addRect = gTrue;
- } else if (rects0[i].x0 < x0) {
- emitRect = gTrue;
- } else if (x0 < rects0[i].x0) {
- addRect = gTrue;
- } else if (rects0[i].x1 == x1) {
- extendRect = gTrue;
- } else {
- emitRect = addRect = gTrue;
- }
- if (emitRect) {
- if (rectsOutLen == rectsOutSize) {
- rectsOutSize *= 2;
- rectsOut = (PSOutImgClipRect *)greallocn(rectsOut, rectsOutSize,
- sizeof(PSOutImgClipRect));
- }
- rectsOut[rectsOutLen].x0 = rects0[i].x0;
- rectsOut[rectsOutLen].x1 = rects0[i].x1;
- rectsOut[rectsOutLen].y0 = height - y - 1;
- rectsOut[rectsOutLen].y1 = height - rects0[i].y0 - 1;
- ++rectsOutLen;
- ++i;
- }
- if (addRect || extendRect) {
- if (rects1Len == rectsSize) {
- rectsSize *= 2;
- rects0 = (PSOutImgClipRect *)greallocn(rects0, rectsSize,
- sizeof(PSOutImgClipRect));
- rects1 = (PSOutImgClipRect *)greallocn(rects1, rectsSize,
- sizeof(PSOutImgClipRect));
- }
- rects1[rects1Len].x0 = x0;
- rects1[rects1Len].x1 = x1;
- if (addRect) {
- rects1[rects1Len].y0 = y;
- }
- if (extendRect) {
- rects1[rects1Len].y0 = rects0[i].y0;
- ++i;
- }
- ++rects1Len;
- for (x0 = x1; x0 < width; ++x0) {
- for (j = 0; j < numComps; ++j) {
- if (line[x0*numComps+j] < maskColors[2*j] ||
- line[x0*numComps+j] > maskColors[2*j+1]) {
- break;
- }
- }
- if (j < numComps) {
- break;
- }
- }
- for (x1 = x0; x1 < width; ++x1) {
- for (j = 0; j < numComps; ++j) {
- if (line[x1*numComps+j] < maskColors[2*j] ||
- line[x1*numComps+j] > maskColors[2*j+1]) {
- break;
- }
- }
- if (j == numComps) {
- break;
- }
- }
- }
- }
- rectsTmp = rects0;
- rects0 = rects1;
- rects1 = rectsTmp;
- i = rects0Len;
- rects0Len = rects1Len;
- rects1Len = i;
- }
- for (i = 0; i < rects0Len; ++i) {
- if (rectsOutLen == rectsOutSize) {
- rectsOutSize *= 2;
- rectsOut = (PSOutImgClipRect *)greallocn(rectsOut, rectsOutSize,
- sizeof(PSOutImgClipRect));
- }
- rectsOut[rectsOutLen].x0 = rects0[i].x0;
- rectsOut[rectsOutLen].x1 = rects0[i].x1;
- rectsOut[rectsOutLen].y0 = height - y - 1;
- rectsOut[rectsOutLen].y1 = height - rects0[i].y0 - 1;
- ++rectsOutLen;
- }
- writePSFmt("{0:d} {1:d}\n", maskWidth, maskHeight);
- for (i = 0; i < rectsOutLen; ++i) {
- writePSFmt("{0:d} {1:d} {2:d} {3:d} pr\n",
- rectsOut[i].x0, rectsOut[i].y0,
- rectsOut[i].x1 - rectsOut[i].x0,
- rectsOut[i].y1 - rectsOut[i].y0);
- }
- writePS("pop pop pdfImClip\n");
- gfree(rectsOut);
- gfree(rects0);
- gfree(rects1);
- delete imgStr;
- str->close();
+ convertColorKeyMaskToClipRects(colorMap, str, width, height, maskColors);
// explicit masking
} else if (maskStr) {
- imgStr = new ImageStream(maskStr, maskWidth, 1, 1);
- imgStr->reset();
- rects0Len = rects1Len = rectsOutLen = 0;
- rectsSize = rectsOutSize = 64;
- rects0 = (PSOutImgClipRect *)gmallocn(rectsSize, sizeof(PSOutImgClipRect));
- rects1 = (PSOutImgClipRect *)gmallocn(rectsSize, sizeof(PSOutImgClipRect));
- rectsOut = (PSOutImgClipRect *)gmallocn(rectsOutSize,
- sizeof(PSOutImgClipRect));
- maskXor = maskInvert ? 1 : 0;
- for (y = 0; y < maskHeight; ++y) {
- if (!(line = imgStr->getLine())) {
- break;
- }
- i = 0;
- rects1Len = 0;
- for (x0 = 0; x0 < maskWidth && (line[x0] ^ maskXor); ++x0) ;
- for (x1 = x0; x1 < maskWidth && !(line[x1] ^ maskXor); ++x1) ;
- while (x0 < maskWidth || i < rects0Len) {
- emitRect = addRect = extendRect = gFalse;
- if (x0 >= maskWidth) {
- emitRect = gTrue;
- } else if (i >= rects0Len) {
- addRect = gTrue;
- } else if (rects0[i].x0 < x0) {
- emitRect = gTrue;
- } else if (x0 < rects0[i].x0) {
- addRect = gTrue;
- } else if (rects0[i].x1 == x1) {
- extendRect = gTrue;
- } else {
- emitRect = addRect = gTrue;
- }
- if (emitRect) {
- if (rectsOutLen == rectsOutSize) {
- rectsOutSize *= 2;
- rectsOut = (PSOutImgClipRect *)greallocn(rectsOut, rectsOutSize,
- sizeof(PSOutImgClipRect));
- }
- rectsOut[rectsOutLen].x0 = rects0[i].x0;
- rectsOut[rectsOutLen].x1 = rects0[i].x1;
- rectsOut[rectsOutLen].y0 = maskHeight - y - 1;
- rectsOut[rectsOutLen].y1 = maskHeight - rects0[i].y0 - 1;
- ++rectsOutLen;
- ++i;
- }
- if (addRect || extendRect) {
- if (rects1Len == rectsSize) {
- rectsSize *= 2;
- rects0 = (PSOutImgClipRect *)greallocn(rects0, rectsSize,
- sizeof(PSOutImgClipRect));
- rects1 = (PSOutImgClipRect *)greallocn(rects1, rectsSize,
- sizeof(PSOutImgClipRect));
- }
- rects1[rects1Len].x0 = x0;
- rects1[rects1Len].x1 = x1;
- if (addRect) {
- rects1[rects1Len].y0 = y;
- }
- if (extendRect) {
- rects1[rects1Len].y0 = rects0[i].y0;
- ++i;
- }
- ++rects1Len;
- for (x0 = x1; x0 < maskWidth && (line[x0] ^ maskXor); ++x0) ;
- for (x1 = x0; x1 < maskWidth && !(line[x1] ^ maskXor); ++x1) ;
- }
- }
- rectsTmp = rects0;
- rects0 = rects1;
- rects1 = rectsTmp;
- i = rects0Len;
- rects0Len = rects1Len;
- rects1Len = i;
- }
- for (i = 0; i < rects0Len; ++i) {
- if (rectsOutLen == rectsOutSize) {
- rectsOutSize *= 2;
- rectsOut = (PSOutImgClipRect *)greallocn(rectsOut, rectsOutSize,
- sizeof(PSOutImgClipRect));
- }
- rectsOut[rectsOutLen].x0 = rects0[i].x0;
- rectsOut[rectsOutLen].x1 = rects0[i].x1;
- rectsOut[rectsOutLen].y0 = maskHeight - y - 1;
- rectsOut[rectsOutLen].y1 = maskHeight - rects0[i].y0 - 1;
- ++rectsOutLen;
- }
- writePSFmt("{0:d} {1:d}\n", maskWidth, maskHeight);
- for (i = 0; i < rectsOutLen; ++i) {
- writePSFmt("{0:d} {1:d} {2:d} {3:d} pr\n",
- rectsOut[i].x0, rectsOut[i].y0,
- rectsOut[i].x1 - rectsOut[i].x0,
- rectsOut[i].y1 - rectsOut[i].y0);
- }
- writePS("pop pop pdfImClip\n");
- gfree(rectsOut);
- gfree(rects0);
- gfree(rects1);
- delete imgStr;
- maskStr->close();
+ convertExplicitMaskToClipRects(maskStr, maskWidth, maskHeight, maskInvert);
}
// color space
- if (colorMap) {
- dumpColorSpaceL2(colorMap->getColorSpace(), gFalse, gTrue, gFalse);
+ if (colorMap && !(level == psLevel2Gray || level == psLevel3Gray)) {
+ dumpColorSpaceL2(state, colorMap->getColorSpace(), gFalse, gTrue, gFalse);
writePS(" setcolorspace\n");
}
@@ -5341,6 +6037,9 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
if (inlineImg) {
// create an array
str2 = new FixedLengthEncoder(str, len);
+ if (colorMap && (level == psLevel2Gray || level == psLevel3Gray)) {
+ str2 = new GrayRecoder(str2, width, height, colorMap);
+ }
if (globalParams->getPSLZW()) {
str2 = new LZWEncoder(str2);
} else {
@@ -5408,7 +6107,8 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
writePSFmt(" /Height {0:d}\n", height);
writePSFmt(" /ImageMatrix [{0:d} 0 0 {1:d} 0 {2:d}]\n",
width, -height, height);
- if (colorMap && colorMap->getColorSpace()->getMode() == csDeviceN) {
+ if (colorMap && (colorMap->getColorSpace()->getMode() == csDeviceN ||
+ level == psLevel2Gray || level == psLevel3Gray)) {
writePS(" /BitsPerComponent 8\n");
} else {
writePSFmt(" /BitsPerComponent {0:d}\n",
@@ -5424,6 +6124,8 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
n = (1 << colorMap->getBits()) - 1;
writePSFmt("{0:.4g} {1:.4g}", colorMap->getDecodeLow(0) * n,
colorMap->getDecodeHigh(0) * n);
+ } else if (level == psLevel2Gray || level == psLevel3Gray) {
+ writePS("0 1");
} else if (colorMap->getColorSpace()->getMode() == csDeviceN) {
numComps = ((GfxDeviceNColorSpace *)colorMap->getColorSpace())->
getAlt()->getNComps();
@@ -5465,7 +6167,8 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
} else {
s = str->getPSFilter(level < psLevel2 ? 1 : level < psLevel3 ? 2 : 3,
" ");
- if ((colorMap && colorMap->getColorSpace()->getMode() == csDeviceN) ||
+ if ((colorMap && (colorMap->getColorSpace()->getMode() == csDeviceN ||
+ level == psLevel2Gray || level == psLevel3Gray)) ||
inlineImg || !s) {
if (globalParams->getPSLZW()) {
useLZW = gTrue;
@@ -5516,8 +6219,12 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
str = str->getUndecodedStream();
}
+ // recode to grayscale
+ if (colorMap && (level == psLevel2Gray || level == psLevel3Gray)) {
+ str = new GrayRecoder(str, width, height, colorMap);
+
// recode DeviceN data
- if (colorMap && colorMap->getColorSpace()->getMode() == csDeviceN) {
+ } else if (colorMap && colorMap->getColorSpace()->getMode() == csDeviceN) {
str = new DeviceNRecoder(str, width, height, colorMap);
}
@@ -5565,7 +6272,7 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
colorMap->getColorSpace()->getMode() == csSeparation) {
color.c[0] = gfxColorComp1;
sepCS = (GfxSeparationColorSpace *)colorMap->getColorSpace();
- sepCS->getCMYK(&color, &cmyk);
+ sepCS->getCMYK(&color, &cmyk, state->getRenderingIntent());
writePSFmt("{0:.4g} {1:.4g} {2:.4g} {3:.4g} ({4:t}) pdfImSep\n",
colToDbl(cmyk.c), colToDbl(cmyk.m),
colToDbl(cmyk.y), colToDbl(cmyk.k),
@@ -5601,8 +6308,276 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
}
}
+// Convert color key masking to a clipping region consisting of a
+// sequence of clip rectangles.
+void PSOutputDev::convertColorKeyMaskToClipRects(GfxImageColorMap *colorMap,
+ Stream *str,
+ int width, int height,
+ int *maskColors) {
+ ImageStream *imgStr;
+ Guchar *line;
+ PSOutImgClipRect *rects0, *rects1, *rectsTmp, *rectsOut;
+ int rects0Len, rects1Len, rectsSize, rectsOutLen, rectsOutSize;
+ GBool emitRect, addRect, extendRect;
+ int numComps, i, j, x0, x1, y;
+
+ numComps = colorMap->getNumPixelComps();
+ imgStr = new ImageStream(str, width, numComps, colorMap->getBits());
+ imgStr->reset();
+ rects0Len = rects1Len = rectsOutLen = 0;
+ rectsSize = rectsOutSize = 64;
+ rects0 = (PSOutImgClipRect *)gmallocn(rectsSize, sizeof(PSOutImgClipRect));
+ rects1 = (PSOutImgClipRect *)gmallocn(rectsSize, sizeof(PSOutImgClipRect));
+ rectsOut = (PSOutImgClipRect *)gmallocn(rectsOutSize,
+ sizeof(PSOutImgClipRect));
+ for (y = 0; y < height; ++y) {
+ if (!(line = imgStr->getLine())) {
+ break;
+ }
+ i = 0;
+ rects1Len = 0;
+ for (x0 = 0; x0 < width; ++x0) {
+ for (j = 0; j < numComps; ++j) {
+ if (line[x0*numComps+j] < maskColors[2*j] ||
+ line[x0*numComps+j] > maskColors[2*j+1]) {
+ break;
+ }
+ }
+ if (j < numComps) {
+ break;
+ }
+ }
+ for (x1 = x0; x1 < width; ++x1) {
+ for (j = 0; j < numComps; ++j) {
+ if (line[x1*numComps+j] < maskColors[2*j] ||
+ line[x1*numComps+j] > maskColors[2*j+1]) {
+ break;
+ }
+ }
+ if (j == numComps) {
+ break;
+ }
+ }
+ while (x0 < width || i < rects0Len) {
+ emitRect = addRect = extendRect = gFalse;
+ if (x0 >= width) {
+ emitRect = gTrue;
+ } else if (i >= rects0Len) {
+ addRect = gTrue;
+ } else if (rects0[i].x0 < x0) {
+ emitRect = gTrue;
+ } else if (x0 < rects0[i].x0) {
+ addRect = gTrue;
+ } else if (rects0[i].x1 == x1) {
+ extendRect = gTrue;
+ } else {
+ emitRect = addRect = gTrue;
+ }
+ if (emitRect) {
+ if (rectsOutLen == rectsOutSize) {
+ rectsOutSize *= 2;
+ rectsOut = (PSOutImgClipRect *)greallocn(rectsOut, rectsOutSize,
+ sizeof(PSOutImgClipRect));
+ }
+ rectsOut[rectsOutLen].x0 = rects0[i].x0;
+ rectsOut[rectsOutLen].x1 = rects0[i].x1;
+ rectsOut[rectsOutLen].y0 = height - y - 1;
+ rectsOut[rectsOutLen].y1 = height - rects0[i].y0 - 1;
+ ++rectsOutLen;
+ ++i;
+ }
+ if (addRect || extendRect) {
+ if (rects1Len == rectsSize) {
+ rectsSize *= 2;
+ rects0 = (PSOutImgClipRect *)greallocn(rects0, rectsSize,
+ sizeof(PSOutImgClipRect));
+ rects1 = (PSOutImgClipRect *)greallocn(rects1, rectsSize,
+ sizeof(PSOutImgClipRect));
+ }
+ rects1[rects1Len].x0 = x0;
+ rects1[rects1Len].x1 = x1;
+ if (addRect) {
+ rects1[rects1Len].y0 = y;
+ }
+ if (extendRect) {
+ rects1[rects1Len].y0 = rects0[i].y0;
+ ++i;
+ }
+ ++rects1Len;
+ for (x0 = x1; x0 < width; ++x0) {
+ for (j = 0; j < numComps; ++j) {
+ if (line[x0*numComps+j] < maskColors[2*j] ||
+ line[x0*numComps+j] > maskColors[2*j+1]) {
+ break;
+ }
+ }
+ if (j < numComps) {
+ break;
+ }
+ }
+ for (x1 = x0; x1 < width; ++x1) {
+ for (j = 0; j < numComps; ++j) {
+ if (line[x1*numComps+j] < maskColors[2*j] ||
+ line[x1*numComps+j] > maskColors[2*j+1]) {
+ break;
+ }
+ }
+ if (j == numComps) {
+ break;
+ }
+ }
+ }
+ }
+ rectsTmp = rects0;
+ rects0 = rects1;
+ rects1 = rectsTmp;
+ i = rects0Len;
+ rects0Len = rects1Len;
+ rects1Len = i;
+ }
+ for (i = 0; i < rects0Len; ++i) {
+ if (rectsOutLen == rectsOutSize) {
+ rectsOutSize *= 2;
+ rectsOut = (PSOutImgClipRect *)greallocn(rectsOut, rectsOutSize,
+ sizeof(PSOutImgClipRect));
+ }
+ rectsOut[rectsOutLen].x0 = rects0[i].x0;
+ rectsOut[rectsOutLen].x1 = rects0[i].x1;
+ rectsOut[rectsOutLen].y0 = height - y - 1;
+ rectsOut[rectsOutLen].y1 = height - rects0[i].y0 - 1;
+ ++rectsOutLen;
+ }
+ writePSFmt("{0:d} {1:d}\n", width, height);
+ for (i = 0; i < rectsOutLen; ++i) {
+ writePSFmt("{0:d} {1:d} {2:d} {3:d} pr\n",
+ rectsOut[i].x0, rectsOut[i].y0,
+ rectsOut[i].x1 - rectsOut[i].x0,
+ rectsOut[i].y1 - rectsOut[i].y0);
+ }
+ writePS("pop pop pdfImClip\n");
+ gfree(rectsOut);
+ gfree(rects0);
+ gfree(rects1);
+ delete imgStr;
+ str->close();
+}
+
+// Convert an explicit mask image to a clipping region consisting of a
+// sequence of clip rectangles.
+void PSOutputDev::convertExplicitMaskToClipRects(Stream *maskStr,
+ int maskWidth, int maskHeight,
+ GBool maskInvert) {
+ ImageStream *imgStr;
+ Guchar *line;
+ PSOutImgClipRect *rects0, *rects1, *rectsTmp, *rectsOut;
+ int rects0Len, rects1Len, rectsSize, rectsOutLen, rectsOutSize;
+ GBool emitRect, addRect, extendRect;
+ int i, x0, x1, y, maskXor;
+
+ imgStr = new ImageStream(maskStr, maskWidth, 1, 1);
+ imgStr->reset();
+ rects0Len = rects1Len = rectsOutLen = 0;
+ rectsSize = rectsOutSize = 64;
+ rects0 = (PSOutImgClipRect *)gmallocn(rectsSize, sizeof(PSOutImgClipRect));
+ rects1 = (PSOutImgClipRect *)gmallocn(rectsSize, sizeof(PSOutImgClipRect));
+ rectsOut = (PSOutImgClipRect *)gmallocn(rectsOutSize,
+ sizeof(PSOutImgClipRect));
+ maskXor = maskInvert ? 1 : 0;
+ for (y = 0; y < maskHeight; ++y) {
+ if (!(line = imgStr->getLine())) {
+ break;
+ }
+ i = 0;
+ rects1Len = 0;
+ for (x0 = 0; x0 < maskWidth && (line[x0] ^ maskXor); ++x0) ;
+ for (x1 = x0; x1 < maskWidth && !(line[x1] ^ maskXor); ++x1) ;
+ while (x0 < maskWidth || i < rects0Len) {
+ emitRect = addRect = extendRect = gFalse;
+ if (x0 >= maskWidth) {
+ emitRect = gTrue;
+ } else if (i >= rects0Len) {
+ addRect = gTrue;
+ } else if (rects0[i].x0 < x0) {
+ emitRect = gTrue;
+ } else if (x0 < rects0[i].x0) {
+ addRect = gTrue;
+ } else if (rects0[i].x1 == x1) {
+ extendRect = gTrue;
+ } else {
+ emitRect = addRect = gTrue;
+ }
+ if (emitRect) {
+ if (rectsOutLen == rectsOutSize) {
+ rectsOutSize *= 2;
+ rectsOut = (PSOutImgClipRect *)greallocn(rectsOut, rectsOutSize,
+ sizeof(PSOutImgClipRect));
+ }
+ rectsOut[rectsOutLen].x0 = rects0[i].x0;
+ rectsOut[rectsOutLen].x1 = rects0[i].x1;
+ rectsOut[rectsOutLen].y0 = maskHeight - y - 1;
+ rectsOut[rectsOutLen].y1 = maskHeight - rects0[i].y0 - 1;
+ ++rectsOutLen;
+ ++i;
+ }
+ if (addRect || extendRect) {
+ if (rects1Len == rectsSize) {
+ rectsSize *= 2;
+ rects0 = (PSOutImgClipRect *)greallocn(rects0, rectsSize,
+ sizeof(PSOutImgClipRect));
+ rects1 = (PSOutImgClipRect *)greallocn(rects1, rectsSize,
+ sizeof(PSOutImgClipRect));
+ }
+ rects1[rects1Len].x0 = x0;
+ rects1[rects1Len].x1 = x1;
+ if (addRect) {
+ rects1[rects1Len].y0 = y;
+ }
+ if (extendRect) {
+ rects1[rects1Len].y0 = rects0[i].y0;
+ ++i;
+ }
+ ++rects1Len;
+ for (x0 = x1; x0 < maskWidth && (line[x0] ^ maskXor); ++x0) ;
+ for (x1 = x0; x1 < maskWidth && !(line[x1] ^ maskXor); ++x1) ;
+ }
+ }
+ rectsTmp = rects0;
+ rects0 = rects1;
+ rects1 = rectsTmp;
+ i = rects0Len;
+ rects0Len = rects1Len;
+ rects1Len = i;
+ }
+ for (i = 0; i < rects0Len; ++i) {
+ if (rectsOutLen == rectsOutSize) {
+ rectsOutSize *= 2;
+ rectsOut = (PSOutImgClipRect *)greallocn(rectsOut, rectsOutSize,
+ sizeof(PSOutImgClipRect));
+ }
+ rectsOut[rectsOutLen].x0 = rects0[i].x0;
+ rectsOut[rectsOutLen].x1 = rects0[i].x1;
+ rectsOut[rectsOutLen].y0 = maskHeight - y - 1;
+ rectsOut[rectsOutLen].y1 = maskHeight - rects0[i].y0 - 1;
+ ++rectsOutLen;
+ }
+ writePSFmt("{0:d} {1:d}\n", maskWidth, maskHeight);
+ for (i = 0; i < rectsOutLen; ++i) {
+ writePSFmt("{0:d} {1:d} {2:d} {3:d} pr\n",
+ rectsOut[i].x0, rectsOut[i].y0,
+ rectsOut[i].x1 - rectsOut[i].x0,
+ rectsOut[i].y1 - rectsOut[i].y0);
+ }
+ writePS("pop pop pdfImClip\n");
+ gfree(rectsOut);
+ gfree(rects0);
+ gfree(rects1);
+ delete imgStr;
+ maskStr->close();
+}
+
//~ this doesn't currently support OPI
-void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
+void PSOutputDev::doImageL3(Object *ref, GfxState *state,
+ GfxImageColorMap *colorMap,
GBool invert, GBool inlineImg,
Stream *str, int width, int height, int len,
int *maskColors, Stream *maskStr,
@@ -5627,11 +6602,26 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
maskFilters = NULL; // make gcc happy
// explicit masking
- if (maskStr) {
+ // -- this also converts color key masking in grayscale mode
+ if (maskStr || (maskColors && colorMap && level == psLevel3Gray)) {
// mask data source
- if ((mode == psModeForm || inType3Char || preload) &&
- globalParams->getPSUncompressPreloadedImages()) {
+ if (maskColors && colorMap && level == psLevel3Gray) {
+ s = NULL;
+ if (globalParams->getPSLZW()) {
+ maskUseLZW = gTrue;
+ maskUseRLE = gFalse;
+ } else {
+ maskUseRLE = gTrue;
+ maskUseLZW = gFalse;
+ }
+ maskUseASCII = gTrue;
+ maskUseCompressed = gFalse;
+ maskWidth = width;
+ maskHeight = height;
+ maskInvert = gFalse;
+ } else if ((mode == psModeForm || inType3Char || preload) &&
+ globalParams->getPSUncompressPreloadedImages()) {
s = NULL;
maskUseLZW = maskUseRLE = gFalse;
maskUseCompressed = gFalse;
@@ -5671,7 +6661,8 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
if (s) {
delete s;
}
- if (mode == psModeForm || inType3Char || preload) {
+ if ((mode == psModeForm || inType3Char || preload) &&
+ !(maskColors && colorMap && level == psLevel3Gray)) {
writePSFmt("MaskData_{0:d}_{1:d} pdfMaskInit\n",
ref->getRefNum(), ref->getRefGen());
} else {
@@ -5679,6 +6670,12 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
writePS(maskFilters->getCString());
writePS("pdfMask\n");
+ // add the ColorKeyToMask filter
+ if (maskColors && colorMap && level == psLevel3Gray) {
+ maskStr = new ColorKeyToMaskEncoder(str, width, height, colorMap,
+ maskColors);
+ }
+
// add LZWEncode/RunLengthEncode and ASCIIHex/85 encode filters
if (maskUseCompressed) {
maskStr = maskStr->getUndecodedStream();
@@ -5713,8 +6710,8 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
}
// color space
- if (colorMap) {
- dumpColorSpaceL2(colorMap->getColorSpace(), gFalse, gTrue, gFalse);
+ if (colorMap && level != psLevel3Gray) {
+ dumpColorSpaceL2(state, colorMap->getColorSpace(), gFalse, gTrue, gFalse);
writePS(" setcolorspace\n");
}
@@ -5723,6 +6720,9 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
if (inlineImg) {
// create an array
str2 = new FixedLengthEncoder(str, len);
+ if (colorMap && level == psLevel3Gray) {
+ str2 = new GrayRecoder(str2, width, height, colorMap);
+ }
if (globalParams->getPSLZW()) {
str2 = new LZWEncoder(str2);
} else {
@@ -5783,17 +6783,18 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
}
// explicit masking
- if (maskStr) {
+ if (maskStr || (maskColors && colorMap && level == psLevel3Gray)) {
writePS("<<\n /ImageType 3\n");
writePS(" /InterleaveType 3\n");
writePS(" /DataDict\n");
}
// image (data) dictionary
- writePSFmt("<<\n /ImageType {0:d}\n", (maskColors && colorMap) ? 4 : 1);
+ writePSFmt("<<\n /ImageType {0:d}\n",
+ (maskColors && colorMap && level != psLevel3Gray) ? 4 : 1);
// color key masking
- if (maskColors && colorMap) {
+ if (maskColors && colorMap && level != psLevel3Gray) {
writePS(" /MaskColor [\n");
numComps = colorMap->getNumPixelComps();
for (i = 0; i < 2 * numComps; i += 2) {
@@ -5807,7 +6808,7 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
writePSFmt(" /Height {0:d}\n", height);
writePSFmt(" /ImageMatrix [{0:d} 0 0 {1:d} 0 {2:d}]\n",
width, -height, height);
- if (colorMap && colorMap->getColorSpace()->getMode() == csDeviceN) {
+ if (colorMap && level == psLevel3Gray) {
writePS(" /BitsPerComponent 8\n");
} else {
writePSFmt(" /BitsPerComponent {0:d}\n",
@@ -5817,21 +6818,14 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
// decode
if (colorMap) {
writePS(" /Decode [");
- if ((level == psLevel2Sep || level == psLevel3Sep) &&
+ if (level == psLevel3Sep &&
colorMap->getColorSpace()->getMode() == csSeparation) {
// this matches up with the code in the pdfImSep operator
n = (1 << colorMap->getBits()) - 1;
writePSFmt("{0:.4g} {1:.4g}", colorMap->getDecodeLow(0) * n,
colorMap->getDecodeHigh(0) * n);
- } else if (colorMap->getColorSpace()->getMode() == csDeviceN) {
- numComps = ((GfxDeviceNColorSpace *)colorMap->getColorSpace())->
- getAlt()->getNComps();
- for (i = 0; i < numComps; ++i) {
- if (i > 0) {
- writePS(" ");
- }
- writePS("0 1");
- }
+ } else if (level == psLevel3Gray) {
+ writePS("0 1");
} else {
numComps = colorMap->getNumPixelComps();
for (i = 0; i < numComps; ++i) {
@@ -5862,10 +6856,8 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
useCompressed = gFalse;
useASCII = gFalse;
} else {
- s = str->getPSFilter(level < psLevel2 ? 1 : level < psLevel3 ? 2 : 3,
- " ");
- if ((colorMap && colorMap->getColorSpace()->getMode() == csDeviceN) ||
- inlineImg || !s) {
+ s = str->getPSFilter(3, " ");
+ if ((colorMap && level == psLevel3Gray) || inlineImg || !s) {
if (globalParams->getPSLZW()) {
useLZW = gTrue;
useRLE = gFalse;
@@ -5902,7 +6894,7 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
writePS(">>\n");
// explicit masking
- if (maskStr) {
+ if (maskStr || (maskColors && colorMap && level == psLevel3Gray)) {
writePS(" /MaskDict\n");
writePS("<<\n");
writePS(" /ImageType 1\n");
@@ -5915,7 +6907,8 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
maskInvert ? 1 : 0, maskInvert ? 0 : 1);
// mask data source
- if (mode == psModeForm || inType3Char || preload) {
+ if ((mode == psModeForm || inType3Char || preload) &&
+ !(maskColors && colorMap && level == psLevel3Gray)) {
writePS(" /DataSource {pdfMaskSrc}\n");
writePS(maskFilters->getCString());
} else {
@@ -5934,11 +6927,11 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
} else {
- if ((level == psLevel2Sep || level == psLevel3Sep) && colorMap &&
+ if (level == psLevel3Sep && colorMap &&
colorMap->getColorSpace()->getMode() == csSeparation) {
color.c[0] = gfxColorComp1;
sepCS = (GfxSeparationColorSpace *)colorMap->getColorSpace();
- sepCS->getCMYK(&color, &cmyk);
+ sepCS->getCMYK(&color, &cmyk, state->getRenderingIntent());
writePSFmt("{0:.4g} {1:.4g} {2:.4g} {3:.4g} ({4:t}) pdfImSep\n",
colToDbl(cmyk.c), colToDbl(cmyk.m),
colToDbl(cmyk.y), colToDbl(cmyk.k),
@@ -5963,9 +6956,9 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
str = str->getUndecodedStream();
}
- // recode DeviceN data
- if (colorMap && colorMap->getColorSpace()->getMode() == csDeviceN) {
- str = new DeviceNRecoder(str, width, height, colorMap);
+ // recode to grayscale
+ if (colorMap && level == psLevel3Gray) {
+ str = new GrayRecoder(str, width, height, colorMap);
}
// add LZWEncode/RunLengthEncode and ASCIIHex/85 encode filters
@@ -6000,266 +6993,453 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
}
// close the mask stream
- if (maskStr) {
+ if (maskStr || (maskColors && colorMap && level == psLevel3Gray)) {
if (!(mode == psModeForm || inType3Char || preload)) {
writePS("pdfMaskEnd\n");
}
}
}
-void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace,
+void PSOutputDev::dumpColorSpaceL2(GfxState *state, GfxColorSpace *colorSpace,
GBool genXform, GBool updateColors,
GBool map01) {
- GfxCalGrayColorSpace *calGrayCS;
- GfxCalRGBColorSpace *calRGBCS;
- GfxLabColorSpace *labCS;
- GfxIndexedColorSpace *indexedCS;
- GfxSeparationColorSpace *separationCS;
- GfxDeviceNColorSpace *deviceNCS;
- GfxColorSpace *baseCS;
- Guchar *lookup, *p;
- double x[gfxColorMaxComps], y[gfxColorMaxComps];
- double low[gfxColorMaxComps], range[gfxColorMaxComps];
- GfxColor color;
- GfxCMYK cmyk;
- Function *func;
- int n, numComps, numAltComps;
- int byte;
- int i, j, k;
-
switch (colorSpace->getMode()) {
-
case csDeviceGray:
- writePS("/DeviceGray");
- if (genXform) {
- writePS(" {}");
- }
- if (updateColors) {
- processColors |= psProcessBlack;
- }
+ dumpDeviceGrayColorSpace((GfxDeviceGrayColorSpace *)colorSpace,
+ genXform, updateColors, map01);
break;
-
case csCalGray:
- calGrayCS = (GfxCalGrayColorSpace *)colorSpace;
- writePS("[/CIEBasedA <<\n");
- writePSFmt(" /DecodeA {{{0:.4g} exp}} bind\n", calGrayCS->getGamma());
- writePSFmt(" /MatrixA [{0:.4g} {1:.4g} {2:.4g}]\n",
- calGrayCS->getWhiteX(), calGrayCS->getWhiteY(),
- calGrayCS->getWhiteZ());
- writePSFmt(" /WhitePoint [{0:.4g} {1:.4g} {2:.4g}]\n",
- calGrayCS->getWhiteX(), calGrayCS->getWhiteY(),
- calGrayCS->getWhiteZ());
- writePSFmt(" /BlackPoint [{0:.4g} {1:.4g} {2:.4g}]\n",
- calGrayCS->getBlackX(), calGrayCS->getBlackY(),
- calGrayCS->getBlackZ());
- writePS(">>]");
- if (genXform) {
- writePS(" {}");
- }
- if (updateColors) {
- processColors |= psProcessBlack;
- }
+ dumpCalGrayColorSpace((GfxCalGrayColorSpace *)colorSpace,
+ genXform, updateColors, map01);
break;
-
case csDeviceRGB:
- writePS("/DeviceRGB");
- if (genXform) {
- writePS(" {}");
- }
- if (updateColors) {
- processColors |= psProcessCMYK;
- }
+ dumpDeviceRGBColorSpace((GfxDeviceRGBColorSpace *)colorSpace,
+ genXform, updateColors, map01);
break;
-
case csCalRGB:
- calRGBCS = (GfxCalRGBColorSpace *)colorSpace;
- writePS("[/CIEBasedABC <<\n");
- writePSFmt(" /DecodeABC [{{{0:.4g} exp}} bind {{{1:.4g} exp}} bind {{{2:.4g} exp}} bind]\n",
- calRGBCS->getGammaR(), calRGBCS->getGammaG(),
- calRGBCS->getGammaB());
- writePSFmt(" /MatrixABC [{0:.4g} {1:.4g} {2:.4g} {3:.4g} {4:.4g} {5:.4g} {6:.4g} {7:.4g} {8:.4g}]\n",
- calRGBCS->getMatrix()[0], calRGBCS->getMatrix()[1],
- calRGBCS->getMatrix()[2], calRGBCS->getMatrix()[3],
- calRGBCS->getMatrix()[4], calRGBCS->getMatrix()[5],
- calRGBCS->getMatrix()[6], calRGBCS->getMatrix()[7],
- calRGBCS->getMatrix()[8]);
- writePSFmt(" /WhitePoint [{0:.4g} {1:.4g} {2:.4g}]\n",
- calRGBCS->getWhiteX(), calRGBCS->getWhiteY(),
- calRGBCS->getWhiteZ());
- writePSFmt(" /BlackPoint [{0:.4g} {1:.4g} {2:.4g}]\n",
- calRGBCS->getBlackX(), calRGBCS->getBlackY(),
- calRGBCS->getBlackZ());
- writePS(">>]");
- if (genXform) {
- writePS(" {}");
- }
- if (updateColors) {
- processColors |= psProcessCMYK;
- }
+ dumpCalRGBColorSpace((GfxCalRGBColorSpace *)colorSpace,
+ genXform, updateColors, map01);
break;
-
case csDeviceCMYK:
- writePS("/DeviceCMYK");
- if (genXform) {
- writePS(" {}");
- }
- if (updateColors) {
- processColors |= psProcessCMYK;
- }
+ dumpDeviceCMYKColorSpace((GfxDeviceCMYKColorSpace *)colorSpace,
+ genXform, updateColors, map01);
break;
-
case csLab:
- labCS = (GfxLabColorSpace *)colorSpace;
- writePS("[/CIEBasedABC <<\n");
- if (map01) {
- writePS(" /RangeABC [0 1 0 1 0 1]\n");
- writePSFmt(" /DecodeABC [{{100 mul 16 add 116 div}} bind {{{0:.4g} mul {1:.4g} add}} bind {{{2:.4g} mul {3:.4g} add}} bind]\n",
- (labCS->getAMax() - labCS->getAMin()) / 500.0,
- labCS->getAMin() / 500.0,
- (labCS->getBMax() - labCS->getBMin()) / 200.0,
- labCS->getBMin() / 200.0);
+ dumpLabColorSpace((GfxLabColorSpace *)colorSpace,
+ genXform, updateColors, map01);
+ break;
+ case csICCBased:
+ dumpICCBasedColorSpace(state, (GfxICCBasedColorSpace *)colorSpace,
+ genXform, updateColors, map01);
+ break;
+ case csIndexed:
+ dumpIndexedColorSpace(state, (GfxIndexedColorSpace *)colorSpace,
+ genXform, updateColors, map01);
+ break;
+ case csSeparation:
+ dumpSeparationColorSpace(state, (GfxSeparationColorSpace *)colorSpace,
+ genXform, updateColors, map01);
+ break;
+ case csDeviceN:
+ if (level >= psLevel3) {
+ dumpDeviceNColorSpaceL3(state, (GfxDeviceNColorSpace *)colorSpace,
+ genXform, updateColors, map01);
} else {
- writePSFmt(" /RangeABC [0 100 {0:.4g} {1:.4g} {2:.4g} {3:.4g}]\n",
- labCS->getAMin(), labCS->getAMax(),
- labCS->getBMin(), labCS->getBMax());
- writePS(" /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind]\n");
- }
- writePS(" /MatrixABC [1 1 1 1 0 0 0 0 -1]\n");
- writePS(" /DecodeLMN\n");
- writePS(" [{dup 6 29 div ge {dup dup mul mul}\n");
- writePSFmt(" {{4 29 div sub 108 841 div mul }} ifelse {0:.4g} mul}} bind\n",
- labCS->getWhiteX());
- writePS(" {dup 6 29 div ge {dup dup mul mul}\n");
- writePSFmt(" {{4 29 div sub 108 841 div mul }} ifelse {0:.4g} mul}} bind\n",
- labCS->getWhiteY());
- writePS(" {dup 6 29 div ge {dup dup mul mul}\n");
- writePSFmt(" {{4 29 div sub 108 841 div mul }} ifelse {0:.4g} mul}} bind]\n",
- labCS->getWhiteZ());
- writePSFmt(" /WhitePoint [{0:.4g} {1:.4g} {2:.4g}]\n",
- labCS->getWhiteX(), labCS->getWhiteY(), labCS->getWhiteZ());
- writePSFmt(" /BlackPoint [{0:.4g} {1:.4g} {2:.4g}]\n",
- labCS->getBlackX(), labCS->getBlackY(), labCS->getBlackZ());
- writePS(">>]");
- if (genXform) {
- writePS(" {}");
- }
- if (updateColors) {
- processColors |= psProcessCMYK;
+ dumpDeviceNColorSpaceL2(state, (GfxDeviceNColorSpace *)colorSpace,
+ genXform, updateColors, map01);
}
break;
-
- case csICCBased:
- // there is no transform function to the alternate color space, so
- // we can use it directly
- dumpColorSpaceL2(((GfxICCBasedColorSpace *)colorSpace)->getAlt(),
- genXform, updateColors, gFalse);
+ case csPattern:
+ //~ unimplemented
break;
+ }
+}
- case csIndexed:
- indexedCS = (GfxIndexedColorSpace *)colorSpace;
- baseCS = indexedCS->getBase();
- writePS("[/Indexed ");
- dumpColorSpaceL2(baseCS, gFalse, gFalse, gTrue);
- n = indexedCS->getIndexHigh();
- numComps = baseCS->getNComps();
- lookup = indexedCS->getLookup();
- writePSFmt(" {0:d} <\n", n);
- if (baseCS->getMode() == csDeviceN) {
- func = ((GfxDeviceNColorSpace *)baseCS)->getTintTransformFunc();
- baseCS->getDefaultRanges(low, range, indexedCS->getIndexHigh());
- if (((GfxDeviceNColorSpace *)baseCS)->getAlt()->getMode() == csLab) {
- labCS = (GfxLabColorSpace *)((GfxDeviceNColorSpace *)baseCS)->getAlt();
- } else {
- labCS = NULL;
- }
- numAltComps = ((GfxDeviceNColorSpace *)baseCS)->getAlt()->getNComps();
- p = lookup;
- for (i = 0; i <= n; i += 8) {
- writePS(" ");
- for (j = i; j < i+8 && j <= n; ++j) {
- for (k = 0; k < numComps; ++k) {
- x[k] = low[k] + (*p++ / 255.0) * range[k];
- }
- func->transform(x, y);
- if (labCS) {
- y[0] /= 100.0;
- y[1] = (y[1] - labCS->getAMin()) /
- (labCS->getAMax() - labCS->getAMin());
- y[2] = (y[2] - labCS->getBMin()) /
- (labCS->getBMax() - labCS->getBMin());
- }
- for (k = 0; k < numAltComps; ++k) {
- byte = (int)(y[k] * 255 + 0.5);
- if (byte < 0) {
- byte = 0;
- } else if (byte > 255) {
- byte = 255;
- }
- writePSFmt("{0:02x}", byte);
- }
- if (updateColors) {
- color.c[0] = dblToCol(j);
- indexedCS->getCMYK(&color, &cmyk);
- addProcessColor(colToDbl(cmyk.c), colToDbl(cmyk.m),
- colToDbl(cmyk.y), colToDbl(cmyk.k));
- }
- }
- writePS("\n");
- }
+void PSOutputDev::dumpDeviceGrayColorSpace(GfxDeviceGrayColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01) {
+ writePS("/DeviceGray");
+ if (genXform) {
+ writePS(" {}");
+ }
+ if (updateColors) {
+ processColors |= psProcessBlack;
+ }
+}
+
+void PSOutputDev::dumpCalGrayColorSpace(GfxCalGrayColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01) {
+ writePS("[/CIEBasedA <<\n");
+ writePSFmt(" /DecodeA {{{0:.4g} exp}} bind\n", cs->getGamma());
+ writePSFmt(" /MatrixA [{0:.4g} {1:.4g} {2:.4g}]\n",
+ cs->getWhiteX(), cs->getWhiteY(), cs->getWhiteZ());
+ writePSFmt(" /WhitePoint [{0:.4g} {1:.4g} {2:.4g}]\n",
+ cs->getWhiteX(), cs->getWhiteY(), cs->getWhiteZ());
+ writePSFmt(" /BlackPoint [{0:.4g} {1:.4g} {2:.4g}]\n",
+ cs->getBlackX(), cs->getBlackY(), cs->getBlackZ());
+ writePS(">>]");
+ if (genXform) {
+ writePS(" {}");
+ }
+ if (updateColors) {
+ processColors |= psProcessBlack;
+ }
+}
+
+void PSOutputDev::dumpDeviceRGBColorSpace(GfxDeviceRGBColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01) {
+ writePS("/DeviceRGB");
+ if (genXform) {
+ writePS(" {}");
+ }
+ if (updateColors) {
+ processColors |= psProcessCMYK;
+ }
+}
+
+void PSOutputDev::dumpCalRGBColorSpace(GfxCalRGBColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01) {
+ writePS("[/CIEBasedABC <<\n");
+ writePSFmt(" /DecodeABC [{{{0:.4g} exp}} bind {{{1:.4g} exp}} bind {{{2:.4g} exp}} bind]\n",
+ cs->getGammaR(), cs->getGammaG(), cs->getGammaB());
+ writePSFmt(" /MatrixABC [{0:.4g} {1:.4g} {2:.4g} {3:.4g} {4:.4g} {5:.4g} {6:.4g} {7:.4g} {8:.4g}]\n",
+ cs->getMatrix()[0], cs->getMatrix()[1], cs->getMatrix()[2],
+ cs->getMatrix()[3], cs->getMatrix()[4], cs->getMatrix()[5],
+ cs->getMatrix()[6], cs->getMatrix()[7], cs->getMatrix()[8]);
+ writePSFmt(" /WhitePoint [{0:.4g} {1:.4g} {2:.4g}]\n",
+ cs->getWhiteX(), cs->getWhiteY(), cs->getWhiteZ());
+ writePSFmt(" /BlackPoint [{0:.4g} {1:.4g} {2:.4g}]\n",
+ cs->getBlackX(), cs->getBlackY(), cs->getBlackZ());
+ writePS(">>]");
+ if (genXform) {
+ writePS(" {}");
+ }
+ if (updateColors) {
+ processColors |= psProcessCMYK;
+ }
+}
+
+void PSOutputDev::dumpDeviceCMYKColorSpace(GfxDeviceCMYKColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01) {
+ writePS("/DeviceCMYK");
+ if (genXform) {
+ writePS(" {}");
+ }
+ if (updateColors) {
+ processColors |= psProcessCMYK;
+ }
+}
+
+void PSOutputDev::dumpLabColorSpace(GfxLabColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01) {
+ writePS("[/CIEBasedABC <<\n");
+ if (map01) {
+ writePS(" /RangeABC [0 1 0 1 0 1]\n");
+ writePSFmt(" /DecodeABC [{{100 mul 16 add 116 div}} bind {{{0:.4g} mul {1:.4g} add}} bind {{{2:.4g} mul {3:.4g} add}} bind]\n",
+ (cs->getAMax() - cs->getAMin()) / 500.0,
+ cs->getAMin() / 500.0,
+ (cs->getBMax() - cs->getBMin()) / 200.0,
+ cs->getBMin() / 200.0);
+ } else {
+ writePSFmt(" /RangeABC [0 100 {0:.4g} {1:.4g} {2:.4g} {3:.4g}]\n",
+ cs->getAMin(), cs->getAMax(),
+ cs->getBMin(), cs->getBMax());
+ writePS(" /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind]\n");
+ }
+ writePS(" /MatrixABC [1 1 1 1 0 0 0 0 -1]\n");
+ writePS(" /DecodeLMN\n");
+ writePS(" [{dup 6 29 div ge {dup dup mul mul}\n");
+ writePSFmt(" {{4 29 div sub 108 841 div mul }} ifelse {0:.4g} mul}} bind\n",
+ cs->getWhiteX());
+ writePS(" {dup 6 29 div ge {dup dup mul mul}\n");
+ writePSFmt(" {{4 29 div sub 108 841 div mul }} ifelse {0:.4g} mul}} bind\n",
+ cs->getWhiteY());
+ writePS(" {dup 6 29 div ge {dup dup mul mul}\n");
+ writePSFmt(" {{4 29 div sub 108 841 div mul }} ifelse {0:.4g} mul}} bind]\n",
+ cs->getWhiteZ());
+ writePSFmt(" /WhitePoint [{0:.4g} {1:.4g} {2:.4g}]\n",
+ cs->getWhiteX(), cs->getWhiteY(), cs->getWhiteZ());
+ writePSFmt(" /BlackPoint [{0:.4g} {1:.4g} {2:.4g}]\n",
+ cs->getBlackX(), cs->getBlackY(), cs->getBlackZ());
+ writePS(">>]");
+ if (genXform) {
+ writePS(" {}");
+ }
+ if (updateColors) {
+ processColors |= psProcessCMYK;
+ }
+}
+
+void PSOutputDev::dumpICCBasedColorSpace(GfxState *state,
+ GfxICCBasedColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01) {
+ // there is no transform function to the alternate color space, so
+ // we can use it directly
+ dumpColorSpaceL2(state, cs->getAlt(), genXform, updateColors, gFalse);
+}
+
+
+void PSOutputDev::dumpIndexedColorSpace(GfxState *state,
+ GfxIndexedColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01) {
+ GfxColorSpace *baseCS;
+ GfxLabColorSpace *labCS;
+ Guchar *lookup, *p;
+ double x[gfxColorMaxComps], y[gfxColorMaxComps];
+ double low[gfxColorMaxComps], range[gfxColorMaxComps];
+ GfxColor color;
+ GfxCMYK cmyk;
+ Function *func;
+ int n, numComps, numAltComps;
+ int byte;
+ int i, j, k;
+
+ baseCS = cs->getBase();
+ writePS("[/Indexed ");
+ dumpColorSpaceL2(state, baseCS, gFalse, updateColors, gTrue);
+ n = cs->getIndexHigh();
+ numComps = baseCS->getNComps();
+ lookup = cs->getLookup();
+ writePSFmt(" {0:d} <\n", n);
+ if (baseCS->getMode() == csDeviceN && level < psLevel3) {
+ func = ((GfxDeviceNColorSpace *)baseCS)->getTintTransformFunc();
+ baseCS->getDefaultRanges(low, range, cs->getIndexHigh());
+ if (((GfxDeviceNColorSpace *)baseCS)->getAlt()->getMode() == csLab) {
+ labCS = (GfxLabColorSpace *)((GfxDeviceNColorSpace *)baseCS)->getAlt();
} else {
- for (i = 0; i <= n; i += 8) {
- writePS(" ");
- for (j = i; j < i+8 && j <= n; ++j) {
- for (k = 0; k < numComps; ++k) {
- writePSFmt("{0:02x}", lookup[j * numComps + k]);
- }
- if (updateColors) {
- color.c[0] = dblToCol(j);
- indexedCS->getCMYK(&color, &cmyk);
- addProcessColor(colToDbl(cmyk.c), colToDbl(cmyk.m),
- colToDbl(cmyk.y), colToDbl(cmyk.k));
+ labCS = NULL;
+ }
+ numAltComps = ((GfxDeviceNColorSpace *)baseCS)->getAlt()->getNComps();
+ p = lookup;
+ for (i = 0; i <= n; i += 8) {
+ writePS(" ");
+ for (j = i; j < i+8 && j <= n; ++j) {
+ for (k = 0; k < numComps; ++k) {
+ x[k] = low[k] + (*p++ / 255.0) * range[k];
+ }
+ func->transform(x, y);
+ if (labCS) {
+ y[0] /= 100.0;
+ y[1] = (y[1] - labCS->getAMin()) /
+ (labCS->getAMax() - labCS->getAMin());
+ y[2] = (y[2] - labCS->getBMin()) /
+ (labCS->getBMax() - labCS->getBMin());
+ }
+ for (k = 0; k < numAltComps; ++k) {
+ byte = (int)(y[k] * 255 + 0.5);
+ if (byte < 0) {
+ byte = 0;
+ } else if (byte > 255) {
+ byte = 255;
}
+ writePSFmt("{0:02x}", byte);
+ }
+ if (updateColors) {
+ color.c[0] = dblToCol(j);
+ cs->getCMYK(&color, &cmyk, state->getRenderingIntent());
+ addProcessColor(colToDbl(cmyk.c), colToDbl(cmyk.m),
+ colToDbl(cmyk.y), colToDbl(cmyk.k));
}
- writePS("\n");
}
+ writePS("\n");
}
- writePS(">]");
- if (genXform) {
- writePS(" {}");
+ } else {
+ for (i = 0; i <= n; i += 8) {
+ writePS(" ");
+ for (j = i; j < i+8 && j <= n; ++j) {
+ for (k = 0; k < numComps; ++k) {
+ writePSFmt("{0:02x}", lookup[j * numComps + k]);
+ }
+ if (updateColors) {
+ color.c[0] = dblToCol(j);
+ cs->getCMYK(&color, &cmyk, state->getRenderingIntent());
+ addProcessColor(colToDbl(cmyk.c), colToDbl(cmyk.m),
+ colToDbl(cmyk.y), colToDbl(cmyk.k));
+ }
+ }
+ writePS("\n");
}
- break;
+ }
+ writePS(">]");
+ if (genXform) {
+ writePS(" {}");
+ }
+}
- case csSeparation:
- separationCS = (GfxSeparationColorSpace *)colorSpace;
- writePS("[/Separation ");
- writePSString(separationCS->getName());
+void PSOutputDev::dumpSeparationColorSpace(GfxState *state,
+ GfxSeparationColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01) {
+ writePS("[/Separation ");
+ writePSString(cs->getName());
+ writePS(" ");
+ dumpColorSpaceL2(state, cs->getAlt(), gFalse, gFalse, gFalse);
+ writePS("\n");
+ cvtFunction(cs->getFunc());
+ writePS("]");
+ if (genXform) {
+ writePS(" {}");
+ }
+ if (updateColors) {
+ addCustomColor(state, cs);
+ }
+}
+
+void PSOutputDev::dumpDeviceNColorSpaceL2(GfxState *state,
+ GfxDeviceNColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01) {
+ dumpColorSpaceL2(state, cs->getAlt(), gFalse, updateColors, map01);
+ if (genXform) {
writePS(" ");
- dumpColorSpaceL2(separationCS->getAlt(), gFalse, gFalse, gFalse);
+ cvtFunction(cs->getTintTransformFunc());
+ }
+}
+
+void PSOutputDev::dumpDeviceNColorSpaceL3(GfxState *state,
+ GfxDeviceNColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01) {
+ GString *tint;
+ int i;
+
+ writePS("[/DeviceN [\n");
+ for (i = 0; i < cs->getNComps(); ++i) {
+ writePSString(cs->getColorantName(i));
writePS("\n");
- cvtFunction(separationCS->getFunc());
- writePS("]");
- if (genXform) {
- writePS(" {}");
- }
- if (updateColors) {
- addCustomColor(separationCS);
- }
- break;
+ }
+ writePS("]\n");
+ if ((tint = createDeviceNTintFunc(cs))) {
+ writePS("/DeviceCMYK\n");
+ writePS(tint->getCString());
+ delete tint;
+ } else {
+ dumpColorSpaceL2(state, cs->getAlt(), gFalse, gFalse, gFalse);
+ writePS("\n");
+ cvtFunction(cs->getTintTransformFunc());
+ }
+ writePS("]");
+ if (genXform) {
+ writePS(" {}");
+ }
+ if (updateColors) {
+ addCustomColors(state, cs);
+ }
+}
- case csDeviceN:
- // DeviceN color spaces are a Level 3 PostScript feature.
- deviceNCS = (GfxDeviceNColorSpace *)colorSpace;
- dumpColorSpaceL2(deviceNCS->getAlt(), gFalse, updateColors, map01);
- if (genXform) {
- writePS(" ");
- cvtFunction(deviceNCS->getTintTransformFunc());
+// If the DeviceN color space has a Colorants dictionary, and all of
+// the colorants are one of: "None", "Cyan", "Magenta", "Yellow",
+// "Black", or have an entry in the Colorants dict that maps to
+// DeviceCMYK, then build a new tint function; else use the existing
+// tint function.
+GString *PSOutputDev::createDeviceNTintFunc(GfxDeviceNColorSpace *cs) {
+ Object *attrs;
+ Object colorants, sepCSObj, funcObj, obj1;
+ GString *name;
+ Function *func;
+ double sepIn;
+ double cmyk[gfxColorMaxComps][4];
+ GString *tint;
+ GBool first;
+ int i, j;
+
+ attrs = cs->getAttrs();
+ if (!attrs->isDict()) {
+ return NULL;
+ }
+ if (!attrs->dictLookup("Colorants", &colorants)->isDict()) {
+ colorants.free();
+ return NULL;
+ }
+ for (i = 0; i < cs->getNComps(); ++i) {
+ name = cs->getColorantName(i);
+ if (!name->cmp("None")) {
+ cmyk[i][0] = cmyk[i][1] = cmyk[i][2] = cmyk[i][3] = 0;
+ } else if (!name->cmp("Cyan")) {
+ cmyk[i][1] = cmyk[i][2] = cmyk[i][3] = 0;
+ cmyk[i][0] = 1;
+ } else if (!name->cmp("Magenta")) {
+ cmyk[i][0] = cmyk[i][2] = cmyk[i][3] = 0;
+ cmyk[i][1] = 1;
+ } else if (!name->cmp("Yellow")) {
+ cmyk[i][0] = cmyk[i][1] = cmyk[i][3] = 0;
+ cmyk[i][2] = 1;
+ } else if (!name->cmp("Black")) {
+ cmyk[i][0] = cmyk[i][1] = cmyk[i][2] = 0;
+ cmyk[i][3] = 1;
+ } else {
+ colorants.dictLookup(name->getCString(), &sepCSObj);
+ if (!sepCSObj.isArray() || sepCSObj.arrayGetLength() != 4) {
+ sepCSObj.free();
+ colorants.free();
+ return NULL;
+ }
+ if (!sepCSObj.arrayGet(0, &obj1)->isName("Separation")) {
+ obj1.free();
+ sepCSObj.free();
+ colorants.free();
+ return NULL;
+ }
+ obj1.free();
+ if (!sepCSObj.arrayGet(2, &obj1)->isName("DeviceCMYK")) {
+ obj1.free();
+ sepCSObj.free();
+ colorants.free();
+ return NULL;
+ }
+ obj1.free();
+ sepCSObj.arrayGet(3, &funcObj);
+ if (!(func = Function::parse(&funcObj))) {
+ 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;
+ sepCSObj.free();
}
- break;
+ }
+ colorants.free();
- case csPattern:
- //~ unimplemented
- break;
+ tint = new GString();
+ tint->append("{\n");
+ for (j = 0; j < 4; ++j) { // C, M, Y, K
+ first = gTrue;
+ for (i = 0; i < cs->getNComps(); ++i) {
+ if (cmyk[i][j] != 0) {
+ tint->appendf("{0:d} index {1:.4f} mul{2:s}\n",
+ j + cs->getNComps() - 1 - i, cmyk[i][j],
+ first ? "" : " add");
+ first = gFalse;
+ }
+ }
+ if (first) {
+ tint->append("0\n");
+ }
+ }
+ tint->appendf("{0:d} 4 roll\n", cs->getNComps() + 4);
+ for (i = 0; i < cs->getNComps(); ++i) {
+ tint->append("pop\n");
}
+ tint->append("}\n");
+
+ return tint;
}
#if OPI_SUPPORT
@@ -6695,6 +7875,7 @@ void PSOutputDev::type3D0(GfxState *state, double wx, double wy) {
writePSFmt("{0:.6g} {1:.6g} setcharwidth\n", wx, wy);
writePS("q\n");
t3NeedsRestore = gTrue;
+ noStateChanges = gFalse;
}
void PSOutputDev::type3D1(GfxState *state, double wx, double wy,
@@ -6714,10 +7895,12 @@ void PSOutputDev::type3D1(GfxState *state, double wx, double wy,
t3FillColorOnly = gTrue;
t3Cacheable = gTrue;
t3NeedsRestore = gTrue;
+ noStateChanges = gFalse;
}
void PSOutputDev::drawForm(Ref id) {
writePSFmt("f_{0:d}_{1:d}\n", id.num, id.gen);
+ noStateChanges = gFalse;
}
void PSOutputDev::psXObject(Stream *psStream, Stream *level1Stream) {
@@ -6735,6 +7918,7 @@ void PSOutputDev::psXObject(Stream *psStream, Stream *level1Stream) {
writePSBlock(buf, n);
}
str->close();
+ noStateChanges = gFalse;
}
//~ can nextFunc be reset to 0 -- maybe at the start of each page?
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h
index 7118830aceb..8e3a74878af 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.h
@@ -28,7 +28,16 @@ class Function;
class GfxPath;
class GfxFont;
class GfxColorSpace;
+class GfxDeviceGrayColorSpace;
+class GfxCalGrayColorSpace;
+class GfxDeviceRGBColorSpace;
+class GfxCalRGBColorSpace;
+class GfxDeviceCMYKColorSpace;
+class GfxLabColorSpace;
+class GfxICCBasedColorSpace;
+class GfxIndexedColorSpace;
class GfxSeparationColorSpace;
+class GfxDeviceNColorSpace;
class PDFRectangle;
class PSOutCustomColor;
class PSOutputDev;
@@ -67,22 +76,24 @@ public:
// Open a PostScript output file, and write the prolog.
PSOutputDev(char *fileName, PDFDoc *docA,
- int firstPage, int lastPage, PSOutMode modeA,
+ int firstPageA, int lastPageA, PSOutMode modeA,
int imgLLXA = 0, int imgLLYA = 0,
int imgURXA = 0, int imgURYA = 0,
GBool manualCtrlA = gFalse,
PSOutCustomCodeCbk customCodeCbkA = NULL,
- void *customCodeCbkDataA = NULL);
+ void *customCodeCbkDataA = NULL,
+ GBool honorUserUnitA = gFalse);
// Open a PSOutputDev that will write to a generic stream.
PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA,
PDFDoc *docA,
- int firstPage, int lastPage, PSOutMode modeA,
+ int firstPageA, int lastPageA, PSOutMode modeA,
int imgLLXA = 0, int imgLLYA = 0,
int imgURXA = 0, int imgURYA = 0,
GBool manualCtrlA = gFalse,
PSOutCustomCodeCbk customCodeCbkA = NULL,
- void *customCodeCbkDataA = NULL);
+ void *customCodeCbkDataA = NULL,
+ GBool honorUserUnitA = gFalse);
// Destructor -- writes the trailer and closes the file.
virtual ~PSOutputDev();
@@ -111,7 +122,8 @@ public:
// radialShadedFill()? If this returns false, these shaded fills
// will be reduced to a series of other drawing operations.
virtual GBool useShadedFills()
- { return level >= psLevel2; }
+ { return level == psLevel2 || level == psLevel2Sep ||
+ level == psLevel3 || level == psLevel3Sep; }
// Does this device use drawForm()? If this returns false,
// form-type XObjects will be interpreted (i.e., unrolled).
@@ -124,15 +136,14 @@ public:
//----- header/trailer (used only if manualCtrl is true)
// Write the document-level header.
- void writeHeader(int firstPage, int lastPage,
- PDFRectangle *mediaBox, PDFRectangle *cropBox,
+ void writeHeader(PDFRectangle *mediaBox, PDFRectangle *cropBox,
int pageRotate);
// Write the Xpdf procset.
void writeXpdfProcset();
// Write the document-level setup.
- void writeDocSetup(Catalog *catalog, int firstPage, int lastPage);
+ void writeDocSetup(Catalog *catalog);
// Write the trailer for the current page.
void writePageTrailer();
@@ -178,6 +189,7 @@ public:
virtual void updateStrokeColor(GfxState *state);
virtual void updateFillOverprint(GfxState *state);
virtual void updateStrokeOverprint(GfxState *state);
+ virtual void updateOverprintMode(GfxState *state);
virtual void updateTransfer(GfxState *state);
//----- update text state
@@ -198,7 +210,7 @@ public:
virtual void fill(GfxState *state);
virtual void eoFill(GfxState *state);
virtual void tilingPatternFill(GfxState *state, Gfx *gfx, Object *strRef,
- int paintType, Dict *resDict,
+ int paintType, int tilingType, Dict *resDict,
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
double xStep, double yStep);
@@ -273,9 +285,10 @@ private:
void init(PSOutputFunc outputFuncA, void *outputStreamA,
PSFileType fileTypeA, PDFDoc *docA,
- int firstPage, int lastPage, PSOutMode modeA,
+ int firstPageA, int lastPageA, PSOutMode modeA,
int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
- GBool manualCtrlA);
+ GBool manualCtrlA, GBool honorUserUnitA);
+ GBool checkIfPageNeedsToBeRasterized(int pg);
void setupResources(Dict *resDict);
void setupFonts(Dict *resDict);
void setupFont(GfxFont *font, Dict *parentResDict);
@@ -296,32 +309,100 @@ private:
PSFontFileInfo *setupEmbeddedOpenTypeCFFFont(GfxFont *font, Ref *id);
PSFontFileInfo *setupType3Font(GfxFont *font, Dict *parentResDict);
GString *makePSFontName(GfxFont *font, Ref *id);
+ GString *fixType1Font(GString *font, int length1, int length2);
+ GBool splitType1PFA(Guchar *font, int fontSize,
+ int length1, int length2,
+ GString *textSection, GString *binSection);
+ GBool splitType1PFB(Guchar *font, int fontSize,
+ GString *textSection, GString *binSection);
+ GString *asciiHexDecodeType1EexecSection(GString *in);
+ GBool fixType1EexecSection(GString *binSection, GString *out);
+ GString *copyType1PFA(Guchar *font, int fontSize);
+ GString *copyType1PFB(Guchar *font, int fontSize);
+ void renameType1Font(GString *font, GString *name);
void setupImages(Dict *resDict);
- void setupImage(Ref id, Stream *str, GBool mask);
+ void setupImage(Ref id, Stream *stream, GBool mask);
void setupForms(Dict *resDict);
void setupForm(Object *strRef, Object *strObj);
void addProcessColor(double c, double m, double y, double k);
- void addCustomColor(GfxSeparationColorSpace *sepCS);
+ void addCustomColor(GfxState *state, GfxSeparationColorSpace *sepCS);
+ void addCustomColors(GfxState *state, GfxDeviceNColorSpace *devnCS);
+ void tilingPatternFillL1(GfxState *state, Gfx *gfx, Object *strRef,
+ int paintType, int tilingType, Dict *resDict,
+ double *mat, double *bbox,
+ int x0, int y0, int x1, int y1,
+ double xStep, double yStep);
+ void tilingPatternFillL2(GfxState *state, Gfx *gfx, Object *strRef,
+ int paintType, int tilingType, Dict *resDict,
+ double *mat, double *bbox,
+ int x0, int y0, int x1, int y1,
+ double xStep, double yStep);
void doPath(GfxPath *path);
- void doImageL1(Object *ref, GfxImageColorMap *colorMap,
+ void doImageL1(Object *ref, GfxState *state,
+ GfxImageColorMap *colorMap,
GBool invert, GBool inlineImg,
Stream *str, int width, int height, int len);
- void doImageL1Sep(GfxImageColorMap *colorMap,
+ void doImageL1Sep(GfxState *state, GfxImageColorMap *colorMap,
GBool invert, GBool inlineImg,
Stream *str, int width, int height, int len);
- void doImageL2(Object *ref, GfxImageColorMap *colorMap,
+ void doImageL2(Object *ref, GfxState *state,
+ GfxImageColorMap *colorMap,
GBool invert, GBool inlineImg,
Stream *str, int width, int height, int len,
int *maskColors, Stream *maskStr,
int maskWidth, int maskHeight, GBool maskInvert);
- void doImageL3(Object *ref, GfxImageColorMap *colorMap,
+ void convertColorKeyMaskToClipRects(GfxImageColorMap *colorMap,
+ Stream *str,
+ int width, int height,
+ int *maskColors);
+ void convertExplicitMaskToClipRects(Stream *maskStr,
+ int maskWidth, int maskHeight,
+ GBool maskInvert);
+ void doImageL3(Object *ref, GfxState *state,
+ GfxImageColorMap *colorMap,
GBool invert, GBool inlineImg,
Stream *str, int width, int height, int len,
int *maskColors, Stream *maskStr,
int maskWidth, int maskHeight, GBool maskInvert);
- void dumpColorSpaceL2(GfxColorSpace *colorSpace,
+ void dumpColorSpaceL2(GfxState *state, GfxColorSpace *colorSpace,
GBool genXform, GBool updateColors,
GBool map01);
+ void dumpDeviceGrayColorSpace(GfxDeviceGrayColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01);
+ void dumpCalGrayColorSpace(GfxCalGrayColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01);
+ void dumpDeviceRGBColorSpace(GfxDeviceRGBColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01);
+ void dumpCalRGBColorSpace(GfxCalRGBColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01);
+ void dumpDeviceCMYKColorSpace(GfxDeviceCMYKColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01);
+ void dumpLabColorSpace(GfxLabColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01);
+ void dumpICCBasedColorSpace(GfxState *state, GfxICCBasedColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01);
+ void dumpIndexedColorSpace(GfxState *state,
+ GfxIndexedColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01);
+ void dumpSeparationColorSpace(GfxState *state,
+ GfxSeparationColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01);
+ void dumpDeviceNColorSpaceL2(GfxState *state, GfxDeviceNColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01);
+ void dumpDeviceNColorSpaceL3(GfxState *state, GfxDeviceNColorSpace *cs,
+ GBool genXform, GBool updateColors,
+ GBool map01);
+ GString *createDeviceNTintFunc(GfxDeviceNColorSpace *cs);
#if OPI_SUPPORT
void opiBegin20(GfxState *state, Dict *dict);
void opiBegin13(GfxState *state, Dict *dict);
@@ -333,7 +414,7 @@ private:
GString *filterPSName(GString *name);
void writePSTextLine(GString *s);
- PSLevel level; // PostScript level (1, 2, separation)
+ PSLevel level; // PostScript level
PSOutMode mode; // PostScript mode (PS, EPS, form)
int paperWidth; // width of paper, in pts
int paperHeight; // height of paper, in pts
@@ -356,10 +437,16 @@ private:
PSOutCustomCodeLocation loc, int n,
void *data);
void *customCodeCbkData;
+ GBool honorUserUnit;
PDFDoc *doc;
XRef *xref; // the xref table for this PDF file
+ int firstPage; // first output page
+ int lastPage; // last output page
+ char *rasterizePage; // boolean for each page - true if page
+ // needs to be rasterized
+
GList *fontInfo; // info for each font [PSFontInfo]
GHash *fontFileInfo; // info for each font file [PSFontFileInfo]
Ref *imgIDs; // list of image IDs for in-memory images
@@ -370,7 +457,10 @@ private:
int formIDSize; // size of formIDs array
GList *xobjStack; // stack of XObject dicts currently being
// processed
- int numSaves; // current number of gsaves
+ GBool noStateChanges; // true if there have been no state changes
+ // since the last save
+ GList *saveStack; // "no state changes" flag for each
+ // pending save
int numTilingPatterns; // current number of nested tiling patterns
int nextFunc; // next unique number to use for a function
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc
index 0ad37618563..dd49630b463 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PSTokenizer.cc
@@ -14,6 +14,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include "gmempp.h"
#include "PSTokenizer.h"
//------------------------------------------------------------------------
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc
index 2eadb24d9f9..b2820d3a2bf 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Page.cc
@@ -13,6 +13,7 @@
#endif
#include <stddef.h>
+#include "gmempp.h"
#include "GlobalParams.h"
#include "Object.h"
#include "Array.h"
@@ -266,12 +267,22 @@ Page::Page(PDFDoc *docA, int numA, Dict *pageDict, PageAttrs *attrsA) {
goto err1;
}
+ // thumbnail
+ pageDict->lookupNF("Thumb", &thumbnail);
+ if (!thumbnail.isRef()) {
+ if (!thumbnail.isNull()) {
+ thumbnail.free();
+ thumbnail.initNull();
+ }
+ }
+
return;
err2:
annots.initNull();
err1:
contents.initNull();
+ thumbnail.initNull();
ok = gFalse;
}
@@ -282,6 +293,7 @@ Page::Page(PDFDoc *docA, int numA) {
attrs = new PageAttrs();
annots.initNull();
contents.initNull();
+ thumbnail.initNull();
ok = gTrue;
}
@@ -289,6 +301,7 @@ Page::~Page() {
delete attrs;
annots.free();
contents.free();
+ thumbnail.free();
}
Links *Page::getLinks() {
@@ -358,13 +371,7 @@ void Page::displaySlice(OutputDev *out, double hDPI, double vDPI,
if (!obj.isNull()) {
gfx->saveState();
gfx->display(&contents);
- while (gfx->getState()->hasSaves()) {
- gfx->restoreState();
- }
- } else {
- // empty pages need to call dump to do any setup required by the
- // OutputDev
- out->dump();
+ gfx->endOfPage();
}
obj.free();
@@ -378,17 +385,22 @@ void Page::displaySlice(OutputDev *out, double hDPI, double vDPI,
printf("***** Annotations\n");
}
for (i = 0; i < annotList->getNumAnnots(); ++i) {
+ if (abortCheckCbk && (*abortCheckCbk)(abortCheckCbkData)) {
+ break;
+ }
annotList->getAnnot(i)->draw(gfx, printing);
}
- out->dump();
}
delete annotList;
}
// draw form fields
- if ((form = doc->getCatalog()->getForm())) {
- form->draw(num, gfx, printing);
- out->dump();
+ if (globalParams->getDrawFormFields()) {
+ if ((form = doc->getCatalog()->getForm())) {
+ if (!(abortCheckCbk && (*abortCheckCbk)(abortCheckCbkData))) {
+ form->draw(num, gfx, printing);
+ }
+ }
}
delete gfx;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h
index 0e7729efc47..ee30a1a8b47 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Page.h
@@ -162,6 +162,9 @@ public:
// Get contents.
Object *getContents(Object *obj) { return contents.fetch(xref, obj); }
+ // Get the page's thumbnail image.
+ Object *getThumbnail(Object *obj) { return thumbnail.fetch(xref, obj); }
+
// Display a page.
void display(OutputDev *out, double hDPI, double vDPI,
int rotate, GBool useMediaBox, GBool crop,
@@ -196,6 +199,7 @@ private:
PageAttrs *attrs; // page attributes
Object annots; // annotations array
Object contents; // page contents
+ Object thumbnail; // reference to thumbnail image
GBool ok; // true if page is valid
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc
index dd37470b139..87e3fc5e24b 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.cc
@@ -13,6 +13,8 @@
#endif
#include <stddef.h>
+#include <string.h>
+#include "gmempp.h"
#include "Object.h"
#include "Array.h"
#include "Dict.h"
@@ -152,8 +154,11 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey,
int objNum, int objGen, int recursion) {
Object obj;
BaseStream *baseStr;
- Stream *str;
+ Stream *str, *str2;
GFileOffset pos, endPos, length;
+ char endstreamBuf[8];
+ GBool foundEndstream;
+ int c, i;
// get stream start position
lexer->skipToNextLine();
@@ -184,25 +189,51 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey,
if (!lexer->getStream()) {
return NULL;
}
- baseStr = lexer->getStream()->getBaseStream();
+ // copy the base stream (Lexer will free stream objects when it gets
+ // to end of stream -- which can happen in the shift() calls below)
+ baseStr = (BaseStream *)lexer->getStream()->getBaseStream()->copy();
+
+ // make new base stream
+ str = baseStr->makeSubStream(pos, gTrue, length, dict);
// skip over stream data
lexer->setPos(pos + length);
- // refill token buffers and check for 'endstream'
- shift(); // kill '>>'
- shift(); // kill 'stream'
- if (buf1.isCmd("endstream")) {
- shift();
- } else {
+ // check for 'endstream'
+ // NB: we never reuse the Parser object to parse objects after a
+ // stream, and we could (if the PDF file is damaged) be in the
+ // middle of binary data at this point, so we check the stream data
+ // directly for 'endstream', rather than calling shift() to parse
+ // objects
+ foundEndstream = gFalse;
+ if ((str2 = lexer->getStream())) {
+ // skip up to 100 whitespace chars
+ for (i = 0; i < 100; ++i) {
+ c = str2->getChar();
+ if (!Lexer::isSpace(c)) {
+ break;
+ }
+ }
+ if (c == 'e') {
+ if (str2->getBlock(endstreamBuf, 8) == 8 ||
+ !memcmp(endstreamBuf, "ndstream", 8)) {
+ foundEndstream = gTrue;
+ }
+ }
+ }
+ if (!foundEndstream) {
error(errSyntaxError, getPos(), "Missing 'endstream'");
// kludge for broken PDF files: just add 5k to the length, and
- // hope its enough
+ // hope it's enough
+ // (dict is now owned by str, so we need to copy it before deleting str)
+ dict->copy(&obj);
+ delete str;
length += 5000;
+ str = baseStr->makeSubStream(pos, gTrue, length, &obj);
}
- // make base stream
- str = baseStr->makeSubStream(pos, gTrue, length, dict);
+ // free the copied base stream
+ delete baseStr;
// handle decryption
if (fileKey) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h
index d5403d0c8fc..bfe5a52bdfc 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Parser.h
@@ -38,6 +38,9 @@ public:
CryptAlgorithm encAlgorithm = cryptRC4, int keyLength = 0,
int objNum = 0, int objGen = 0, int recursion = 0);
+ // Get stream index (for arrays of streams).
+ int getStreamIndex() { return lexer->getStreamIndex(); }
+
// Get stream.
Stream *getStream() { return lexer->getStream(); }
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc
index ced188ea376..cffdca76477 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.cc
@@ -13,6 +13,7 @@
#endif
#include <math.h>
+#include "gmempp.h"
#include "GlobalParams.h"
#include "Page.h"
#include "Gfx.h"
@@ -42,7 +43,7 @@ void PreScanOutputDev::stroke(GfxState *state) {
int dashLen;
double dashStart;
- check(state->getStrokeColorSpace(), state->getStrokeColor(),
+ check(state, state->getStrokeColorSpace(), state->getStrokeColor(),
state->getStrokeOpacity(), state->getBlendMode());
state->getLineDash(&dash, &dashLen, &dashStart);
if (dashLen != 0) {
@@ -51,25 +52,26 @@ void PreScanOutputDev::stroke(GfxState *state) {
}
void PreScanOutputDev::fill(GfxState *state) {
- check(state->getFillColorSpace(), state->getFillColor(),
+ check(state, state->getFillColorSpace(), state->getFillColor(),
state->getFillOpacity(), state->getBlendMode());
}
void PreScanOutputDev::eoFill(GfxState *state) {
- check(state->getFillColorSpace(), state->getFillColor(),
+ check(state, state->getFillColorSpace(), state->getFillColor(),
state->getFillOpacity(), state->getBlendMode());
}
void PreScanOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
Object *strRef,
- int paintType, Dict *resDict,
+ int paintType, int tilingType,
+ Dict *resDict,
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
double xStep, double yStep) {
if (paintType == 1) {
gfx->drawForm(strRef, resDict, mat, bbox);
} else {
- check(state->getFillColorSpace(), state->getFillColor(),
+ check(state, state->getFillColorSpace(), state->getFillColor(),
state->getFillOpacity(), state->getBlendMode());
}
}
@@ -133,11 +135,11 @@ void PreScanOutputDev::beginStringOp(GfxState *state) {
render = state->getRender();
if (!(render & 1)) {
- check(state->getFillColorSpace(), state->getFillColor(),
+ check(state, state->getFillColorSpace(), state->getFillColor(),
state->getFillOpacity(), state->getBlendMode());
}
if ((render & 3) == 1 || (render & 3) == 2) {
- check(state->getStrokeColorSpace(), state->getStrokeColor(),
+ check(state, state->getStrokeColorSpace(), state->getStrokeColor(),
state->getStrokeOpacity(), state->getBlendMode());
}
@@ -175,7 +177,7 @@ void PreScanOutputDev::endType3Char(GfxState *state) {
void PreScanOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
int width, int height, GBool invert,
GBool inlineImg, GBool interpolate) {
- check(state->getFillColorSpace(), state->getFillColor(),
+ check(state, state->getFillColorSpace(), state->getFillColor(),
state->getFillOpacity(), state->getBlendMode());
if (state->getFillColorSpace()->getMode() == csPattern) {
patternImgMask = gTrue;
@@ -259,7 +261,7 @@ void PreScanOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
Stream *maskStr,
int maskWidth, int maskHeight,
GfxImageColorMap *maskColorMap,
- GBool interpolate) {
+ double *matte, GBool interpolate) {
GfxColorSpace *colorSpace;
colorSpace = colorMap->getColorSpace();
@@ -284,7 +286,8 @@ void PreScanOutputDev::beginTransparencyGroup(
gdi = gFalse;
}
-void PreScanOutputDev::check(GfxColorSpace *colorSpace, GfxColor *color,
+void PreScanOutputDev::check(GfxState *state,
+ GfxColorSpace *colorSpace, GfxColor *color,
double opacity, GfxBlendMode blendMode) {
GfxRGB rgb;
@@ -293,7 +296,7 @@ void PreScanOutputDev::check(GfxColorSpace *colorSpace, GfxColor *color,
gray = gFalse;
gdi = gFalse;
} else {
- colorSpace->getRGB(color, &rgb);
+ colorSpace->getRGB(color, &rgb, state->getRenderingIntent());
if (rgb.r != rgb.g || rgb.g != rgb.b || rgb.b != rgb.r) {
mono = gFalse;
gray = gFalse;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h
index 6ca8b463432..882d8ef39f5 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PreScanOutputDev.h
@@ -68,7 +68,7 @@ public:
virtual void fill(GfxState *state);
virtual void eoFill(GfxState *state);
virtual void tilingPatternFill(GfxState *state, Gfx *gfx, Object *strRef,
- int paintType, Dict *resDict,
+ int paintType, int tilingType, Dict *resDict,
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
double xStep, double yStep);
@@ -107,7 +107,7 @@ public:
Stream *maskStr,
int maskWidth, int maskHeight,
GfxImageColorMap *maskColorMap,
- GBool interpolate);
+ double *matte, GBool interpolate);
//----- transparency groups and soft masks
virtual void beginTransparencyGroup(GfxState *state, double *bbox,
@@ -143,7 +143,7 @@ public:
private:
- void check(GfxColorSpace *colorSpace, GfxColor *color,
+ void check(GfxState *state, GfxColorSpace *colorSpace, GfxColor *color,
double opacity, GfxBlendMode blendMode);
GBool mono;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc
index 88f2b65b8f1..4ceddea0561 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc
@@ -12,15 +12,13 @@
#pragma implementation
#endif
+#include "gmempp.h"
#include "GString.h"
#include "PDFDoc.h"
#include "Decrypt.h"
#include "Error.h"
#include "GlobalParams.h"
#include "PDFCore.h"
-#ifdef ENABLE_PLUGINS
-# include "XpdfPluginAPI.h"
-#endif
#include "SecurityHandler.h"
//------------------------------------------------------------------------
@@ -30,25 +28,14 @@
SecurityHandler *SecurityHandler::make(PDFDoc *docA, Object *encryptDictA) {
Object filterObj;
SecurityHandler *secHdlr;
-#ifdef ENABLE_PLUGINS
- XpdfSecurityHandler *xsh;
-#endif
encryptDictA->dictLookup("Filter", &filterObj);
if (filterObj.isName("Standard")) {
secHdlr = new StandardSecurityHandler(docA, encryptDictA);
} else if (filterObj.isName()) {
-#ifdef ENABLE_PLUGINS
- if ((xsh = globalParams->getSecurityHandler(filterObj.getName()))) {
- secHdlr = new ExternalSecurityHandler(docA, encryptDictA, xsh);
- } else {
-#endif
- error(errSyntaxError, -1, "Couldn't find the '{0:s}' security handler",
- filterObj.getName());
- secHdlr = NULL;
-#ifdef ENABLE_PLUGINS
- }
-#endif
+ error(errSyntaxError, -1, "Couldn't find the '{0:s}' security handler",
+ filterObj.getName());
+ secHdlr = NULL;
} else {
error(errSyntaxError, -1,
"Missing or invalid 'Filter' entry in encryption dictionary");
@@ -139,6 +126,7 @@ StandardSecurityHandler::StandardSecurityHandler(PDFDoc *docA,
userEnc = NULL;
fileKeyLength = 0;
+ //--- get the main parameters
encryptDictA->dictLookup("V", &versionObj);
encryptDictA->dictLookup("R", &revisionObj);
encryptDictA->dictLookup("Length", &lengthObj);
@@ -148,137 +136,153 @@ StandardSecurityHandler::StandardSecurityHandler(PDFDoc *docA,
encryptDictA->dictLookup("UE", &userEncObj);
encryptDictA->dictLookup("P", &permObj);
doc->getXRef()->getTrailerDict()->dictLookup("ID", &fileIDObj);
- if (versionObj.isInt() &&
- revisionObj.isInt() &&
- permObj.isInt() &&
- ownerKeyObj.isString() &&
- userKeyObj.isString()) {
- encVersion = versionObj.getInt();
- encRevision = revisionObj.getInt();
- if ((encRevision <= 4 &&
- ownerKeyObj.getString()->getLength() == 32 &&
- userKeyObj.getString()->getLength() == 32) ||
- ((encRevision == 5 || encRevision == 6) &&
- // the spec says 48 bytes, but Acrobat pads them out longer
- ownerKeyObj.getString()->getLength() >= 48 &&
- userKeyObj.getString()->getLength() >= 48 &&
- ownerEncObj.isString() &&
- ownerEncObj.getString()->getLength() == 32 &&
- userEncObj.isString() &&
- userEncObj.getString()->getLength() == 32)) {
- encAlgorithm = cryptRC4;
- // revision 2 forces a 40-bit key - some buggy PDF generators
- // set the Length value incorrectly
- if (encRevision == 2 || !lengthObj.isInt()) {
- fileKeyLength = 5;
- } else {
- fileKeyLength = lengthObj.getInt() / 8;
- }
- encryptMetadata = gTrue;
- //~ this currently only handles a subset of crypt filter functionality
- //~ (in particular, it ignores the EFF entry in encryptDictA, and
- //~ doesn't handle the case where StmF, StrF, and EFF are not all the
- //~ same)
- if ((encVersion == 4 || encVersion == 5) &&
- (encRevision == 4 || encRevision == 5 || encRevision == 6)) {
- encryptDictA->dictLookup("CF", &cryptFiltersObj);
- encryptDictA->dictLookup("StmF", &streamFilterObj);
- encryptDictA->dictLookup("StrF", &stringFilterObj);
- if (cryptFiltersObj.isDict() &&
- streamFilterObj.isName() &&
- stringFilterObj.isName() &&
- !strcmp(streamFilterObj.getName(), stringFilterObj.getName())) {
- if (!strcmp(streamFilterObj.getName(), "Identity")) {
- // no encryption on streams or strings
- encVersion = encRevision = -1;
- } else {
- if (cryptFiltersObj.dictLookup(streamFilterObj.getName(),
- &cryptFilterObj)->isDict()) {
- cryptFilterObj.dictLookup("CFM", &cfmObj);
- if (cfmObj.isName("V2")) {
- encVersion = 2;
- encRevision = 3;
- if (cryptFilterObj.dictLookup("Length",
- &cfLengthObj)->isInt()) {
- //~ according to the spec, this should be cfLengthObj / 8
- fileKeyLength = cfLengthObj.getInt();
- }
- cfLengthObj.free();
- } else if (cfmObj.isName("AESV2")) {
- encVersion = 2;
- encRevision = 3;
- encAlgorithm = cryptAES;
- if (cryptFilterObj.dictLookup("Length",
- &cfLengthObj)->isInt()) {
- //~ according to the spec, this should be cfLengthObj / 8
- fileKeyLength = cfLengthObj.getInt();
- }
- cfLengthObj.free();
- } else if (cfmObj.isName("AESV3")) {
- encVersion = 5;
- if (encRevision != 5 && encRevision != 6) {
- encRevision = 6;
- }
- encAlgorithm = cryptAES256;
- if (cryptFilterObj.dictLookup("Length",
- &cfLengthObj)->isInt()) {
- //~ according to the spec, this should be cfLengthObj / 8
- fileKeyLength = cfLengthObj.getInt();
- }
- cfLengthObj.free();
- }
- cfmObj.free();
- }
- cryptFilterObj.free();
- }
- }
+ if (!versionObj.isInt() ||
+ !revisionObj.isInt() ||
+ !permObj.isInt() ||
+ !ownerKeyObj.isString() ||
+ !userKeyObj.isString()) {
+ error(errSyntaxError, -1, "Invalid encryption parameters");
+ goto done;
+ }
+ encVersion = versionObj.getInt();
+ encRevision = revisionObj.getInt();
+ encAlgorithm = cryptRC4;
+ // revision 2 forces a 40-bit key - some buggy PDF generators
+ // set the Length value incorrectly
+ if (encRevision == 2 || !lengthObj.isInt()) {
+ fileKeyLength = 5;
+ } else {
+ fileKeyLength = lengthObj.getInt() / 8;
+ }
+ encryptMetadata = gTrue;
+
+ //--- check for a crypt filter (which can modify the parameters)
+ //~ this currently only handles a subset of crypt filter functionality
+ //~ (in particular, it ignores the EFF entry in encryptDictA, and
+ //~ doesn't handle the case where StmF, StrF, and EFF are not all the
+ //~ same)
+ if ((encVersion == 4 || encVersion == 5) &&
+ (encRevision == 4 || encRevision == 5 || encRevision == 6)) {
+ encryptDictA->dictLookup("CF", &cryptFiltersObj);
+ encryptDictA->dictLookup("StmF", &streamFilterObj);
+ encryptDictA->dictLookup("StrF", &stringFilterObj);
+ if (cryptFiltersObj.isDict() &&
+ streamFilterObj.isName() &&
+ stringFilterObj.isName() &&
+ !strcmp(streamFilterObj.getName(), stringFilterObj.getName())) {
+ if (!strcmp(streamFilterObj.getName(), "Identity")) {
+ // no encryption on streams or strings
stringFilterObj.free();
streamFilterObj.free();
cryptFiltersObj.free();
- if (encryptDictA->dictLookup("EncryptMetadata",
- &encryptMetadataObj)->isBool()) {
- encryptMetadata = encryptMetadataObj.getBool();
- }
- encryptMetadataObj.free();
+ goto done;
}
- permFlags = permObj.getInt();
- ownerKey = ownerKeyObj.getString()->copy();
- userKey = userKeyObj.getString()->copy();
- if (encVersion >= 1 && encVersion <= 2 &&
- encRevision >= 2 && encRevision <= 3) {
- if (fileIDObj.isArray()) {
- if (fileIDObj.arrayGet(0, &fileIDObj1)->isString()) {
- fileID = fileIDObj1.getString()->copy();
+ if (cryptFiltersObj.dictLookup(streamFilterObj.getName(),
+ &cryptFilterObj)->isDict()) {
+ cryptFilterObj.dictLookup("CFM", &cfmObj);
+ if (cfmObj.isName("V2")) {
+ if (cryptFilterObj.dictLookup("Length",
+ &cfLengthObj)->isInt()) {
+ fileKeyLength = cfLengthObj.getInt();
+ }
+ cfLengthObj.free();
+ encVersion = 2;
+ encRevision = 3;
+ } else if (cfmObj.isName("AESV2")) {
+ if (cryptFilterObj.dictLookup("Length",
+ &cfLengthObj)->isInt()) {
+ fileKeyLength = cfLengthObj.getInt();
+ }
+ cfLengthObj.free();
+ encVersion = 2;
+ encRevision = 3;
+ encAlgorithm = cryptAES;
+ } else if (cfmObj.isName("AESV3")) {
+ if (cryptFilterObj.dictLookup("Length",
+ &cfLengthObj)->isInt()) {
+ fileKeyLength = cfLengthObj.getInt();
+ }
+ cfLengthObj.free();
+ if (fileKeyLength == 16) {
+ // this isn't allowed by the spec, but Adobe supports it
+ encVersion = 2;
+ encRevision = 3;
+ encAlgorithm = cryptAES;
} else {
- fileID = new GString();
+ encVersion = 5;
+ if (encRevision != 5 && encRevision != 6) {
+ encRevision = 6;
+ }
+ encAlgorithm = cryptAES256;
}
- fileIDObj1.free();
- } else {
- fileID = new GString();
- }
- if (fileKeyLength > 16 || fileKeyLength <= 0) {
- fileKeyLength = 16;
- }
- ok = gTrue;
- } else if (encVersion == 5 && (encRevision == 5 || encRevision == 6)) {
- fileID = new GString(); // unused for V=R=5
- ownerEnc = ownerEncObj.getString()->copy();
- userEnc = userEncObj.getString()->copy();
- if (fileKeyLength > 32 || fileKeyLength <= 0) {
- fileKeyLength = 32;
}
- ok = gTrue;
- } else if (!(encVersion == -1 && encRevision == -1)) {
- error(errUnimplemented, -1,
- "Unsupported version/revision ({0:d}/{1:d}) of Standard security handler",
- encVersion, encRevision);
+ cfmObj.free();
}
- } else {
+ cryptFilterObj.free();
+ }
+ stringFilterObj.free();
+ streamFilterObj.free();
+ cryptFiltersObj.free();
+ if (encryptDictA->dictLookup("EncryptMetadata",
+ &encryptMetadataObj)->isBool()) {
+ encryptMetadata = encryptMetadataObj.getBool();
+ }
+ encryptMetadataObj.free();
+ }
+
+ //--- version-specific parameters
+ if (encRevision <= 4) {
+ if (ownerKeyObj.getString()->getLength() != 32 ||
+ userKeyObj.getString()->getLength() != 32) {
+ error(errSyntaxError, -1, "Invalid encryption key length");
+ goto done;
+ }
+ } else if (encRevision <= 6) {
+ // the spec says 48 bytes, but Acrobat pads them out longer
+ if (ownerKeyObj.getString()->getLength() < 48 ||
+ userKeyObj.getString()->getLength() < 48 ||
+ !ownerEncObj.isString() ||
+ ownerEncObj.getString()->getLength() != 32 ||
+ !userEncObj.isString() ||
+ userEncObj.getString()->getLength() != 32) {
error(errSyntaxError, -1, "Invalid encryption key length");
+ goto done;
}
+ }
+ permFlags = permObj.getInt();
+ ownerKey = ownerKeyObj.getString()->copy();
+ userKey = userKeyObj.getString()->copy();
+ if (encVersion >= 1 && encVersion <= 2 &&
+ encRevision >= 2 && encRevision <= 3) {
+ if (fileIDObj.isArray()) {
+ if (fileIDObj.arrayGet(0, &fileIDObj1)->isString()) {
+ fileID = fileIDObj1.getString()->copy();
+ } else {
+ fileID = new GString();
+ }
+ fileIDObj1.free();
+ } else {
+ fileID = new GString();
+ }
+ if (fileKeyLength > 16 || fileKeyLength <= 0) {
+ fileKeyLength = 16;
+ }
+ ok = gTrue;
+ } else if (encVersion == 5 && (encRevision == 5 || encRevision == 6)) {
+ fileID = new GString(); // unused for V=R=5
+ ownerEnc = ownerEncObj.getString()->copy();
+ userEnc = userEncObj.getString()->copy();
+ if (fileKeyLength > 32 || fileKeyLength <= 0) {
+ fileKeyLength = 32;
+ }
+ ok = gTrue;
} else {
- error(errSyntaxError, -1, "Weird encryption info");
+ error(errUnimplemented, -1,
+ "Unsupported version/revision ({0:d}/{1:d}) of Standard security handler",
+ encVersion, encRevision);
}
+
+ done:
fileIDObj.free();
permObj.free();
userEncObj.free();
@@ -357,82 +361,3 @@ GBool StandardSecurityHandler::authorize(void *authData) {
}
return gTrue;
}
-
-#ifdef ENABLE_PLUGINS
-
-//------------------------------------------------------------------------
-// ExternalSecurityHandler
-//------------------------------------------------------------------------
-
-ExternalSecurityHandler::ExternalSecurityHandler(PDFDoc *docA,
- Object *encryptDictA,
- XpdfSecurityHandler *xshA):
- SecurityHandler(docA)
-{
- encryptDictA->copy(&encryptDict);
- xsh = xshA;
- encAlgorithm = cryptRC4; //~ this should be obtained via getKey
- ok = gFalse;
-
- if (!(*xsh->newDoc)(xsh->handlerData, (XpdfDoc)docA,
- (XpdfObject)encryptDictA, &docData)) {
- return;
- }
-
- ok = gTrue;
-}
-
-ExternalSecurityHandler::~ExternalSecurityHandler() {
- (*xsh->freeDoc)(xsh->handlerData, docData);
- encryptDict.free();
-}
-
-void *ExternalSecurityHandler::makeAuthData(GString *ownerPassword,
- GString *userPassword) {
- char *opw, *upw;
- void *authData;
-
- opw = ownerPassword ? ownerPassword->getCString() : (char *)NULL;
- upw = userPassword ? userPassword->getCString() : (char *)NULL;
- if (!(*xsh->makeAuthData)(xsh->handlerData, docData, opw, upw, &authData)) {
- return NULL;
- }
- return authData;
-}
-
-void *ExternalSecurityHandler::getAuthData() {
- void *authData;
-
- if (!(*xsh->getAuthData)(xsh->handlerData, docData, &authData)) {
- return NULL;
- }
- return authData;
-}
-
-void ExternalSecurityHandler::freeAuthData(void *authData) {
- (*xsh->freeAuthData)(xsh->handlerData, docData, authData);
-}
-
-GBool ExternalSecurityHandler::authorize(void *authData) {
- char *key;
- int length;
-
- if (!ok) {
- return gFalse;
- }
- permFlags = (*xsh->authorize)(xsh->handlerData, docData, authData);
- if (!(permFlags & xpdfPermissionOpen)) {
- return gFalse;
- }
- if (!(*xsh->getKey)(xsh->handlerData, docData, &key, &length, &encVersion)) {
- return gFalse;
- }
- if ((fileKeyLength = length) > 16) {
- fileKeyLength = 16;
- }
- memcpy(fileKey, key, fileKeyLength);
- (*xsh->freeKey)(xsh->handlerData, docData, key, length);
- return gTrue;
-}
-
-#endif // ENABLE_PLUGINS
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h b/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h
index 784a52e8017..63462339bff 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.h
@@ -124,42 +124,4 @@ private:
GBool ok;
};
-#ifdef ENABLE_PLUGINS
-//------------------------------------------------------------------------
-// ExternalSecurityHandler
-//------------------------------------------------------------------------
-
-class ExternalSecurityHandler: public SecurityHandler {
-public:
-
- ExternalSecurityHandler(PDFDoc *docA, Object *encryptDictA,
- XpdfSecurityHandler *xshA);
- virtual ~ExternalSecurityHandler();
-
- virtual void *makeAuthData(GString *ownerPassword,
- GString *userPassword);
- virtual void *getAuthData();
- virtual void freeAuthData(void *authData);
- virtual GBool authorize(void *authData);
- virtual int getPermissionFlags() { return permFlags; }
- virtual GBool getOwnerPasswordOk() { return gFalse; }
- virtual Guchar *getFileKey() { return fileKey; }
- virtual int getFileKeyLength() { return fileKeyLength; }
- virtual int getEncVersion() { return encVersion; }
- virtual CryptAlgorithm getEncAlgorithm() { return encAlgorithm; }
-
-private:
-
- Object encryptDict;
- XpdfSecurityHandler *xsh;
- void *docData;
- int permFlags;
- Guchar fileKey[16];
- int fileKeyLength;
- int encVersion;
- CryptAlgorithm encAlgorithm;
- GBool ok;
-};
-#endif // ENABLE_PLUGINS
-
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
index d9befecd253..72fe72e7647 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
@@ -15,6 +15,7 @@
#include <string.h>
#include <math.h>
#include <limits.h>
+#include "gmempp.h"
#include "gfile.h"
#include "GlobalParams.h"
#include "Error.h"
@@ -55,12 +56,13 @@ extern "C" int unlink(char *filename);
#define type3FontCacheMaxSets 8
#define type3FontCacheSize (128*1024)
-//------------------------------------------------------------------------
-
-// Divide a 16-bit value (in [0, 255*255]) by 255, returning an 8-bit result.
-static inline Guchar div255(int x) {
- return (Guchar)((x + (x >> 8) + 0x80) >> 8);
-}
+// Map StrokeAdjustMode (from GlobalParams) to SplashStrokeAdjustMode
+// (for Splash).
+static SplashStrokeAdjustMode mapStrokeAdjustMode[3] = {
+ splashStrokeAdjustOff,
+ splashStrokeAdjustNormal,
+ splashStrokeAdjustCAD
+};
//------------------------------------------------------------------------
// Blend functions
@@ -84,11 +86,13 @@ static void splashOutBlendScreen(SplashColorPtr src, SplashColorPtr dest,
}
}
+// note: this is the same os HardLight
static void splashOutBlendOverlay(SplashColorPtr src, SplashColorPtr dest,
SplashColorPtr blend, SplashColorMode cm) {
int i;
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
+ // the spec says "if Cs <= 0.5" -- note that 0x80 is 128/255=0.5020
blend[i] = dest[i] < 0x80
? (src[i] * 2 * dest[i]) / 255
: 255 - 2 * ((255 - src[i]) * (255 - dest[i])) / 255;
@@ -116,32 +120,30 @@ static void splashOutBlendLighten(SplashColorPtr src, SplashColorPtr dest,
static void splashOutBlendColorDodge(SplashColorPtr src, SplashColorPtr dest,
SplashColorPtr blend,
SplashColorMode cm) {
- int i, x;
+ int i;
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
if (dest[i] == 0) {
blend[i] = 0;
- } else if (src[i] == 255) {
+ } else if (dest[i] >= 255 - src[i]) {
blend[i] = 255;
} else {
- x = (dest[i] * 255) / (255 - src[i]);
- blend[i] = x <= 255 ? x : 255;
+ blend[i] = (dest[i] * 255) / (255 - src[i]);
}
}
}
static void splashOutBlendColorBurn(SplashColorPtr src, SplashColorPtr dest,
SplashColorPtr blend, SplashColorMode cm) {
- int i, x;
+ int i;
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
if (dest[i] == 255) {
blend[i] = 255;
- } else if (src[i] == 0) {
+ } else if (255 - dest[i] >= src[i]) {
blend[i] = 0;
} else {
- x = ((255 - dest[i]) * 255) / src[i];
- blend[i] = x <= 255 ? 255 - x : 0;
+ blend[i] = 255 - (((255 - dest[i]) * 255) / src[i]);
}
}
}
@@ -151,6 +153,7 @@ static void splashOutBlendHardLight(SplashColorPtr src, SplashColorPtr dest,
int i;
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
+ // the spec says "if Cs <= 0.5" -- note that 0x80 is 128/255=0.5020
blend[i] = src[i] < 0x80
? (dest[i] * 2 * src[i]) / 255
: 255 - 2 * ((255 - dest[i]) * (255 - src[i])) / 255;
@@ -162,10 +165,12 @@ static void splashOutBlendSoftLight(SplashColorPtr src, SplashColorPtr dest,
int i, x;
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
+ // the spec says "if Cs <= 0.5" -- note that 0x80 is 128/255=0.5020
if (src[i] < 0x80) {
blend[i] = dest[i] - (255 - 2 * src[i]) * dest[i] * (255 - dest[i]) /
(255 * 255);
} else {
+ // the spec says "if Cb <= 0.25" -- note that 0x40 is 64/255=0.2510
if (dest[i] < 0x40) {
x = (((((16 * dest[i] - 12 * 255) * dest[i]) / 255)
+ 4 * 255) * dest[i]) / 255;
@@ -219,7 +224,7 @@ static int getSat(int r, int g, int b) {
static void clipColor(int rIn, int gIn, int bIn,
Guchar *rOut, Guchar *gOut, Guchar *bOut) {
- int lum, rgbMin, rgbMax;
+ int lum, rgbMin, rgbMax, r, g, b;
lum = getLum(rIn, gIn, bIn);
rgbMin = rgbMax = rIn;
@@ -233,19 +238,22 @@ static void clipColor(int rIn, int gIn, int bIn,
} else if (bIn > rgbMax) {
rgbMax = bIn;
}
+ r = rIn;
+ g = gIn;
+ b = bIn;
if (rgbMin < 0) {
- *rOut = (Guchar)(lum + ((rIn - lum) * lum) / (lum - rgbMin));
- *gOut = (Guchar)(lum + ((gIn - lum) * lum) / (lum - rgbMin));
- *bOut = (Guchar)(lum + ((bIn - lum) * lum) / (lum - rgbMin));
- } else if (rgbMax > 255) {
- *rOut = (Guchar)(lum + ((rIn - lum) * (255 - lum)) / (rgbMax - lum));
- *gOut = (Guchar)(lum + ((gIn - lum) * (255 - lum)) / (rgbMax - lum));
- *bOut = (Guchar)(lum + ((bIn - lum) * (255 - lum)) / (rgbMax - lum));
- } else {
- *rOut = rIn;
- *gOut = gIn;
- *bOut = bIn;
- }
+ r = lum + ((r - lum) * lum) / (lum - rgbMin);
+ g = lum + ((g - lum) * lum) / (lum - rgbMin);
+ b = lum + ((b - lum) * lum) / (lum - rgbMin);
+ }
+ if (rgbMax > 255) {
+ r = lum + ((r - lum) * (255 - lum)) / (rgbMax - lum);
+ g = lum + ((g - lum) * (255 - lum)) / (rgbMax - lum);
+ b = lum + ((b - lum) * (255 - lum)) / (rgbMax - lum);
+ }
+ *rOut = (Guchar)r;
+ *gOut = (Guchar)g;
+ *bOut = (Guchar)b;
}
static void setLum(Guchar rIn, Guchar gIn, Guchar bIn, int lum,
@@ -279,7 +287,7 @@ static void setSat(Guchar rIn, Guchar gIn, Guchar bIn, int sat,
rgbMin = bIn; minOut = bOut;
}
if (rgbMax > rgbMin) {
- *midOut = (Guchar)((rgbMid - rgbMin) * sat) / (rgbMax - rgbMin);
+ *midOut = (Guchar)(((rgbMid - rgbMin) * sat) / (rgbMax - rgbMin));
*maxOut = (Guchar)sat;
} else {
*midOut = *maxOut = 0;
@@ -290,9 +298,6 @@ static void setSat(Guchar rIn, Guchar gIn, Guchar bIn, int sat,
static void splashOutBlendHue(SplashColorPtr src, SplashColorPtr dest,
SplashColorPtr blend, SplashColorMode cm) {
Guchar r0, g0, b0;
-#if SPLASH_CMYK
- Guchar r1, g1, b1;
-#endif
switch (cm) {
case splashModeMono1:
@@ -312,10 +317,7 @@ static void splashOutBlendHue(SplashColorPtr src, SplashColorPtr dest,
setSat(src[0], src[1], src[2], getSat(dest[0], dest[1], dest[2]),
&r0, &g0, &b0);
setLum(r0, g0, b0, getLum(dest[0], dest[1], dest[2]),
- &r1, &g1, &b1);
- blend[0] = r1;
- blend[1] = g1;
- blend[2] = b1;
+ &blend[0], &blend[1], &blend[2]);
blend[3] = dest[3];
break;
#endif
@@ -326,9 +328,6 @@ static void splashOutBlendSaturation(SplashColorPtr src, SplashColorPtr dest,
SplashColorPtr blend,
SplashColorMode cm) {
Guchar r0, g0, b0;
-#if SPLASH_CMYK
- Guchar r1, g1, b1;
-#endif
switch (cm) {
case splashModeMono1:
@@ -348,10 +347,7 @@ static void splashOutBlendSaturation(SplashColorPtr src, SplashColorPtr dest,
setSat(dest[0], dest[1], dest[2], getSat(src[0], src[1], src[2]),
&r0, &g0, &b0);
setLum(r0, g0, b0, getLum(dest[0], dest[1], dest[2]),
- &r1, &g1, &b1);
- blend[0] = r1;
- blend[1] = g1;
- blend[2] = b1;
+ &blend[0], &blend[1], &blend[2]);
blend[3] = dest[3];
break;
#endif
@@ -360,9 +356,6 @@ static void splashOutBlendSaturation(SplashColorPtr src, SplashColorPtr dest,
static void splashOutBlendColor(SplashColorPtr src, SplashColorPtr dest,
SplashColorPtr blend, SplashColorMode cm) {
-#if SPLASH_CMYK
- Guchar r, g, b;
-#endif
switch (cm) {
case splashModeMono1:
@@ -378,10 +371,7 @@ static void splashOutBlendColor(SplashColorPtr src, SplashColorPtr dest,
case splashModeCMYK8:
// NB: inputs have already been converted to additive mode
setLum(src[0], src[1], src[2], getLum(dest[0], dest[1], dest[2]),
- &r, &g, &b);
- blend[0] = r;
- blend[1] = g;
- blend[2] = b;
+ &blend[0], &blend[1], &blend[2]);
blend[3] = dest[3];
break;
#endif
@@ -391,9 +381,6 @@ static void splashOutBlendColor(SplashColorPtr src, SplashColorPtr dest,
static void splashOutBlendLuminosity(SplashColorPtr src, SplashColorPtr dest,
SplashColorPtr blend,
SplashColorMode cm) {
-#if SPLASH_CMYK
- Guchar r, g, b;
-#endif
switch (cm) {
case splashModeMono1:
@@ -409,10 +396,7 @@ static void splashOutBlendLuminosity(SplashColorPtr src, SplashColorPtr dest,
case splashModeCMYK8:
// NB: inputs have already been converted to additive mode
setLum(dest[0], dest[1], dest[2], getLum(src[0], src[1], src[2]),
- &r, &g, &b);
- blend[0] = r;
- blend[1] = g;
- blend[2] = b;
+ &blend[0], &blend[1], &blend[2]);
blend[3] = src[3];
break;
#endif
@@ -486,7 +470,7 @@ public:
T3FontCache(Ref *fontID, double m11A, double m12A,
double m21A, double m22A,
int glyphXA, int glyphYA, int glyphWA, int glyphHA,
- GBool aa, GBool validBBoxA);
+ GBool validBBoxA, GBool aa);
~T3FontCache();
GBool matches(Ref *idA, double m11A, double m12A,
double m21A, double m22A)
@@ -584,6 +568,7 @@ struct SplashTransparencyGroup {
//----- saved state
SplashBitmap *origBitmap;
Splash *origSplash;
+ SplashBitmap *backdropBitmap;
SplashTransparencyGroup *next;
};
@@ -619,7 +604,10 @@ SplashOutputDev::SplashOutputDev(SplashColorMode colorModeA,
colorMode != splashModeMono1, bitmapTopDown);
splash = new Splash(bitmap, vectorAntialias, &screenParams);
splash->setMinLineWidth(globalParams->getMinLineWidth());
- splash->setStrokeAdjust(globalParams->getStrokeAdjust());
+ splash->setStrokeAdjust(
+ mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
+ splash->setEnablePathSimplification(
+ globalParams->getEnablePathSimplification());
splash->clear(paperColor, 0);
fontEngine = NULL;
@@ -634,6 +622,9 @@ SplashOutputDev::SplashOutputDev(SplashColorMode colorModeA,
transpGroupStack = NULL;
nestCount = 0;
+
+ startPageCbk = NULL;
+ startPageCbkData = NULL;
}
void SplashOutputDev::setupScreenParams(double hDPI, double vDPI) {
@@ -712,7 +703,7 @@ void SplashOutputDev::startDoc(XRef *xrefA) {
delete fontEngine;
}
fontEngine = new SplashFontEngine(
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+#if HAVE_FREETYPE_H
globalParams->getEnableFreeType(),
globalParams->getDisableFreeTypeHinting()
? splashFTNoHinting : 0,
@@ -759,6 +750,8 @@ void SplashOutputDev::startPage(int pageNum, GfxState *state) {
}
splash = new Splash(bitmap, vectorAntialias, &screenParams);
splash->setMinLineWidth(globalParams->getMinLineWidth());
+ splash->setEnablePathSimplification(
+ globalParams->getEnablePathSimplification());
if (state) {
ctm = state->getCTM();
mat[0] = (SplashCoord)ctm[0];
@@ -793,8 +786,12 @@ void SplashOutputDev::startPage(int pageNum, GfxState *state) {
splash->setFlatness(1);
// the SA parameter supposedly defaults to false, but Acrobat
// apparently hardwires it to true
- splash->setStrokeAdjust(globalParams->getStrokeAdjust());
+ splash->setStrokeAdjust(
+ mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
splash->clear(paperColor, 0);
+ if (startPageCbk) {
+ (*startPageCbk)(startPageCbkData);
+ }
}
void SplashOutputDev::endPage() {
@@ -897,7 +894,15 @@ void SplashOutputDev::updateLineWidth(GfxState *state) {
void SplashOutputDev::updateStrokeAdjust(GfxState *state) {
#if 0 // the SA parameter supposedly defaults to false, but Acrobat
// apparently hardwires it to true
- splash->setStrokeAdjust(state->getStrokeAdjust());
+ if (state->getStrokeAdjust()) {
+ if (globalParams->getStrokeAdjustMode() == strokeAdjustCAD) {
+ splash->setStrokeAdjust(splashStrokeAdjustCAD);
+ } else {
+ splash->setStrokeAdjust(splashStrokeAdjustNormal);
+ }
+ } else {
+ splash->setStrokeAdjust(splashStrokeAdjustOff);
+ }
#endif
}
@@ -958,16 +963,36 @@ void SplashOutputDev::updateStrokeColor(GfxState *state) {
SplashPattern *SplashOutputDev::getColor(GfxGray gray) {
SplashColor color;
+ getColor(gray, color);
+ return new SplashSolidColor(color);
+}
+
+SplashPattern *SplashOutputDev::getColor(GfxRGB *rgb) {
+ SplashColor color;
+
+ getColor(rgb, color);
+ return new SplashSolidColor(color);
+}
+
+#if SPLASH_CMYK
+SplashPattern *SplashOutputDev::getColor(GfxCMYK *cmyk) {
+ SplashColor color;
+
+ getColor(cmyk, color);
+ return new SplashSolidColor(color);
+}
+#endif
+
+
+void SplashOutputDev::getColor(GfxGray gray, SplashColorPtr color) {
if (reverseVideo) {
gray = gfxColorComp1 - gray;
}
color[0] = colToByte(gray);
- return new SplashSolidColor(color);
}
-SplashPattern *SplashOutputDev::getColor(GfxRGB *rgb) {
+void SplashOutputDev::getColor(GfxRGB *rgb, SplashColorPtr color) {
GfxColorComp r, g, b;
- SplashColor color;
if (reverseVideo) {
r = gfxColorComp1 - rgb->r;
@@ -981,23 +1006,20 @@ SplashPattern *SplashOutputDev::getColor(GfxRGB *rgb) {
color[0] = colToByte(r);
color[1] = colToByte(g);
color[2] = colToByte(b);
- return new SplashSolidColor(color);
}
#if SPLASH_CMYK
-SplashPattern *SplashOutputDev::getColor(GfxCMYK *cmyk) {
- SplashColor color;
-
+void SplashOutputDev::getColor(GfxCMYK *cmyk, SplashColorPtr color) {
color[0] = colToByte(cmyk->c);
color[1] = colToByte(cmyk->m);
color[2] = colToByte(cmyk->y);
color[3] = colToByte(cmyk->k);
- return new SplashSolidColor(color);
}
#endif
-void SplashOutputDev::setOverprintMask(GfxColorSpace *colorSpace,
+void SplashOutputDev::setOverprintMask(GfxState *state,
+ GfxColorSpace *colorSpace,
GBool overprintFlag,
int overprintMode,
GfxColor *singleColor) {
@@ -1010,17 +1032,10 @@ void SplashOutputDev::setOverprintMask(GfxColorSpace *colorSpace,
// The OPM (overprintMode) setting is only relevant when the color
// space is DeviceCMYK or is "implicitly converted to DeviceCMYK".
// Per the PDF spec, this happens with ICCBased color spaces only
- // if the profile matches the output device -- Acrobat's output
- // preview mode does NOT honor OPM=1 for ICCBased CMYK color
- // spaces. To change the behavior here, use:
- // if (singleColor && overprintMode &&
- // (colorSpace->getMode() == csDeviceCMYK ||
- // (colorSpace->getMode() == csICCBased &&
- // colorSpace->getNComps() == 4 &&
- // <...the profile matches...>)))
+ // if the profile matches the output device.
if (singleColor && overprintMode &&
colorSpace->getMode() == csDeviceCMYK) {
- colorSpace->getCMYK(singleColor, &cmyk);
+ colorSpace->getCMYK(singleColor, &cmyk, state->getRenderingIntent());
if (cmyk.c == 0) {
mask &= ~1;
}
@@ -1053,6 +1068,11 @@ void SplashOutputDev::updateStrokeOpacity(GfxState *state) {
splash->setStrokeAlpha((SplashCoord)state->getStrokeOpacity());
}
+void SplashOutputDev::updateRenderingIntent(GfxState *state) {
+ updateFillColor(state);
+ updateStrokeColor(state);
+}
+
void SplashOutputDev::updateTransfer(GfxState *state) {
Function **transfer;
Guchar red[256], green[256], blue[256], gray[256];
@@ -1129,7 +1149,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
SplashCoord mat[4];
char *name;
Unicode uBuf[8];
- int substIdx, n, code, cmap, i;
+ int substIdx, n, code, cmap, cmapPlatform, cmapEncoding, i;
needFontUpdate = gFalse;
font = NULL;
@@ -1347,15 +1367,24 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
break;
case fontCIDType0:
case fontCIDType0C:
+ if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
+ n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+ codeToGID = (int *)gmallocn(n, sizeof(int));
+ memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
+ n * sizeof(int));
+ } else {
+ codeToGID = NULL;
+ n = 0;
+ }
if (!(fontFile = fontEngine->loadCIDFont(
id,
#if LOAD_FONTS_FROM_MEM
- fontBuf
+ fontBuf,
#else
fileName->getCString(),
- fileName == tmpFileName
+ fileName == tmpFileName,
#endif
- ))) {
+ codeToGID, n))) {
error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
gfxFont->getName() ? gfxFont->getName()->getCString()
@@ -1365,14 +1394,58 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
}
break;
case fontCIDType0COT:
- if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
- n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
- codeToGID = (int *)gmallocn(n, sizeof(int));
- memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
- n * sizeof(int));
- } else {
- codeToGID = NULL;
- n = 0;
+ codeToGID = NULL;
+ n = 0;
+ if (fontLoc->locType == gfxFontLocEmbedded) {
+ if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
+ n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+ codeToGID = (int *)gmallocn(n, sizeof(int));
+ memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
+ n * sizeof(int));
+ }
+ } else if (globalParams->getMapExtTrueTypeFontsViaUnicode()) {
+ // create a CID-to-GID mapping, via Unicode
+ if ((ctu = ((GfxCIDFont *)gfxFont)->getToUnicode())) {
+#if LOAD_FONTS_FROM_MEM
+ if ((ff = FoFiTrueType::make(fontBuf->getCString(),
+ fontBuf->getLength(), fontNum))) {
+#else
+ if ((ff = FoFiTrueType::load(fileName->getCString(), fontNum))) {
+#endif
+ // look for a Unicode cmap
+ for (cmap = 0; cmap < ff->getNumCmaps(); ++cmap) {
+ cmapPlatform = ff->getCmapPlatform(cmap);
+ cmapEncoding = ff->getCmapEncoding(cmap);
+ if ((cmapPlatform == 3 && cmapEncoding == 1) ||
+ (cmapPlatform == 0 && cmapEncoding <= 4)) {
+ break;
+ }
+ }
+ if (cmap < ff->getNumCmaps()) {
+ // map CID -> Unicode -> GID
+ if (ctu->isIdentity()) {
+ n = 65536;
+ } else {
+ n = ctu->getLength();
+ }
+ codeToGID = (int *)gmallocn(n, sizeof(int));
+ for (code = 0; code < n; ++code) {
+ if (ctu->mapToUnicode(code, uBuf, 8) > 0) {
+ codeToGID[code] = ff->mapCodeToGID(cmap, uBuf[0]);
+ } else {
+ codeToGID[code] = -1;
+ }
+ }
+ }
+ delete ff;
+ }
+ ctu->decRefCnt();
+ } else {
+ error(errSyntaxError, -1,
+ "Couldn't find a mapping to Unicode for font '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ }
}
if (!(fontFile = fontEngine->loadOpenTypeCFFFont(
id,
@@ -1401,10 +1474,7 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
n * sizeof(int));
}
- } else if (!globalParams->getMapExtTrueTypeFontsViaUnicode()) {
- codeToGID = NULL;
- n = 0;
- } else {
+ } else if (globalParams->getMapExtTrueTypeFontsViaUnicode()) {
// create a CID-to-GID mapping, via Unicode
if ((ctu = ((GfxCIDFont *)gfxFont)->getToUnicode())) {
#if LOAD_FONTS_FROM_MEM
@@ -1415,9 +1485,10 @@ void SplashOutputDev::doUpdateFont(GfxState *state) {
#endif
// look for a Unicode cmap
for (cmap = 0; cmap < ff->getNumCmaps(); ++cmap) {
- if ((ff->getCmapPlatform(cmap) == 3 &&
- ff->getCmapEncoding(cmap) == 1) ||
- ff->getCmapPlatform(cmap) == 0) {
+ cmapPlatform = ff->getCmapPlatform(cmap);
+ cmapEncoding = ff->getCmapEncoding(cmap);
+ if ((cmapPlatform == 3 && cmapEncoding == 1) ||
+ (cmapPlatform == 0 && cmapEncoding <= 4)) {
break;
}
}
@@ -1562,8 +1633,9 @@ void SplashOutputDev::stroke(GfxState *state) {
if (state->getStrokeColorSpace()->isNonMarking()) {
return;
}
- setOverprintMask(state->getStrokeColorSpace(), state->getStrokeOverprint(),
- state->getOverprintMode(), state->getStrokeColor());
+ setOverprintMask(state, state->getStrokeColorSpace(),
+ state->getStrokeOverprint(), state->getOverprintMode(),
+ state->getStrokeColor());
path = convertPath(state, state->getPath(), gFalse);
splash->stroke(path);
delete path;
@@ -1575,8 +1647,9 @@ void SplashOutputDev::fill(GfxState *state) {
if (state->getFillColorSpace()->isNonMarking()) {
return;
}
- setOverprintMask(state->getFillColorSpace(), state->getFillOverprint(),
- state->getOverprintMode(), state->getFillColor());
+ setOverprintMask(state, state->getFillColorSpace(),
+ state->getFillOverprint(), state->getOverprintMode(),
+ state->getFillColor());
path = convertPath(state, state->getPath(), gTrue);
splash->fill(path, gFalse);
delete path;
@@ -1588,8 +1661,9 @@ void SplashOutputDev::eoFill(GfxState *state) {
if (state->getFillColorSpace()->isNonMarking()) {
return;
}
- setOverprintMask(state->getFillColorSpace(), state->getFillOverprint(),
- state->getOverprintMode(), state->getFillColor());
+ setOverprintMask(state, state->getFillColorSpace(),
+ state->getFillOverprint(), state->getOverprintMode(),
+ state->getFillColor());
path = convertPath(state, state->getPath(), gTrue);
splash->fill(path, gTrue);
delete path;
@@ -1597,21 +1671,37 @@ void SplashOutputDev::eoFill(GfxState *state) {
void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
Object *strRef,
- int paintType, Dict *resDict,
+ int paintType, int tilingType,
+ Dict *resDict,
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
double xStep, double yStep) {
- double tileXMin, tileYMin, tileXMax, tileYMax, tx, ty;
- int tileX0, tileY0, tileW, tileH, tileSize;
SplashBitmap *origBitmap, *tileBitmap;
Splash *origSplash;
SplashColor color;
- double mat1[6];
- double xa, ya, xb, yb, xc, yc;
- int x, y, xx, yy, i;
+ double *ctm;
+ double ictm[6], tileMat[6], mat1[6], mat2[6];
+ double tileXMin, tileYMin, tileXMax, tileYMax;
+ double xStepX, xStepY, yStepX, yStepY;
+ double adjXMin, adjYMin;
+ double sx, sy;
+ double clipXMin, clipYMin, clipXMax, clipYMax;
+ double tx, ty, idet, txMin, tyMin, txMax, tyMax;
+ int tileW, tileH, tileSize;
+ int ixMin, ixMax, iyMin, iyMax, ix, iy, x, y;
+ int i;
- // transform the four corners of the bbox from pattern space to
- // device space and compute the device space bbox
+ // Notes:
+ // - PTM = pattern matrix = transform from pattern space to default
+ // user space (default for most recent page or form)
+ // - BTM = transform from default user space to device space
+ //
+ // This function is called with:
+ // - mat = PTM * BTM * iCTM = transform from pattern space to
+ // current user space
+
+ // transform the four corners of the pattern bbox from pattern space
+ // to device space and compute the device space bbox
state->transform(bbox[0] * mat[0] + bbox[1] * mat[2] + mat[4],
bbox[0] * mat[1] + bbox[1] * mat[3] + mat[5],
&tx, &ty);
@@ -1659,11 +1749,14 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
if (tileXMin == tileXMax || tileYMin == tileYMax) {
return;
}
-
- tileX0 = (int)floor(tileXMin);
- tileY0 = (int)floor(tileYMin);
- tileW = (int)ceil(tileXMax) - tileX0;
- tileH = (int)ceil(tileYMax) - tileY0;
+ tileW = (int)(tileXMax - tileXMin + 0.5);
+ tileH = (int)(tileYMax - tileYMin + 0.5);
+ if (tileW < 1) {
+ tileW = 1;
+ }
+ if (tileH < 1) {
+ tileH = 1;
+ }
// check for an excessively large tile size
tileSize = tileW * tileH;
@@ -1672,18 +1765,138 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
mat1[1] = mat[1];
mat1[2] = mat[2];
mat1[3] = mat[3];
- for (y = y0; y < y1; ++y) {
- for (x = x0; x < x1; ++x) {
- xa = x * xStep;
- ya = y * yStep;
- mat1[4] = xa * mat[0] + ya * mat[2] + mat[4];
- mat1[5] = xa * mat[1] + ya * mat[3] + mat[5];
+ for (iy = y0; iy < y1; ++iy) {
+ for (ix = x0; ix < x1; ++ix) {
+ tx = ix * xStep;
+ ty = iy * yStep;
+ mat1[4] = tx * mat[0] + ty * mat[2] + mat[4];
+ mat1[5] = tx * mat[1] + ty * mat[3] + mat[5];
gfx->drawForm(strRef, resDict, mat1, bbox);
}
}
return;
}
+ // transform XStep and YStep to device space
+ state->transformDelta(xStep * mat[0], xStep * mat[1], &xStepX, &xStepY);
+ state->transformDelta(yStep * mat[2], yStep * mat[3], &yStepX, &yStepY);
+
+ // compute tiling parameters
+ if (tilingType == 2) {
+ adjXMin = tileXMin;
+ adjYMin = tileYMin;
+ sx = 1;
+ sy = 1;
+ } else {
+ adjXMin = (int)floor(tileXMin + 0.5);
+ adjYMin = (int)floor(tileYMin + 0.5);
+ sx = tileW / (tileXMax - tileXMin);
+ sy = tileH / (tileYMax - tileYMin);
+ xStepX = (int)floor(sx * xStepX + 0.5);
+ xStepY = (int)floor(sy * xStepY + 0.5);
+ yStepX = (int)floor(sx * yStepX + 0.5);
+ yStepY = (int)floor(sy * yStepY + 0.5);
+ }
+
+ // compute tile matrix = PTM * BTM * Mtranslate * Mscale * iCTM
+ // = mat * CTM * Mtranslate * Mscale * iCTM
+ ctm = state->getCTM();
+ idet = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
+ ictm[0] = ctm[3] * idet;
+ ictm[1] = -ctm[1] * idet;
+ ictm[2] = -ctm[2] * idet;
+ ictm[3] = ctm[0] * idet;
+ ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * idet;
+ ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * idet;
+ // mat * CTM
+ mat1[0] = mat[0] * ctm[0] + mat[1] * ctm[2];
+ mat1[1] = mat[0] * ctm[1] + mat[1] * ctm[3];
+ mat1[2] = mat[2] * ctm[0] + mat[3] * ctm[2];
+ mat1[3] = mat[2] * ctm[1] + mat[3] * ctm[3];
+ mat1[4] = mat[4] * ctm[0] + mat[5] * ctm[2] + ctm[4];
+ mat1[5] = mat[4] * ctm[1] + mat[5] * ctm[3] + ctm[5];
+ // mat * CTM * (Mtranslate * Mscale)
+ mat2[0] = mat1[0] * sx;
+ mat2[1] = mat1[1] * sy;
+ mat2[2] = mat1[2] * sx;
+ mat2[3] = mat1[3] * sy;
+ mat2[4] = mat1[4] * sx - sx * tileXMin;
+ mat2[5] = mat1[5] * sy - sy * tileYMin;
+ // mat * CTM * (Mtranslate * Mscale) * iCTM
+ tileMat[0] = mat2[0] * ictm[0] + mat2[1] * ictm[2];
+ tileMat[1] = mat2[0] * ictm[1] + mat2[1] * ictm[3];
+ tileMat[2] = mat2[2] * ictm[0] + mat2[3] * ictm[2];
+ tileMat[3] = mat2[2] * ictm[1] + mat2[3] * ictm[3];
+ tileMat[4] = mat2[4] * ictm[0] + mat2[5] * ictm[2] + ictm[4];
+ tileMat[5] = mat2[4] * ictm[1] + mat2[5] * ictm[3] + ictm[5];
+
+ // compute tiling range:
+ // - look at the four corners of the clipping bbox
+ // - solve for the (ix,iy) tile position at each corner
+ // - take the min and max values for ix, iy
+ state->getClipBBox(&clipXMin, &clipYMin, &clipXMax, &clipYMax);
+ idet = xStepX * yStepY - xStepY * yStepX;
+ if (idet == 0) {
+ return;
+ }
+ idet = 1 / idet;
+ // LL corner
+ tx = idet * (yStepY * (clipXMin - tileW - 1 - adjXMin)
+ - yStepX * (clipYMax + 1 - adjYMin));
+ ty = idet * (xStepX * (clipYMax + 1 - adjYMin)
+ - xStepY * (clipXMin - tileW - 1 - adjXMin));
+ txMin = txMax = tx;
+ tyMin = tyMax = ty;
+ // LR corner
+ tx = idet * (yStepY * (clipXMax + 1 - adjXMin)
+ - yStepX * (clipYMax + 1 - adjYMin));
+ ty = idet * (xStepX * (clipYMax + 1 - adjYMin)
+ - xStepY * (clipXMax + 1 - adjXMin));
+ if (tx < txMin) {
+ txMin = tx;
+ } else if (tx > txMax) {
+ txMax = tx;
+ }
+ if (ty < tyMin) {
+ tyMin = ty;
+ } else if (ty > tyMax) {
+ tyMax = ty;
+ }
+ // UL corner
+ tx = idet * (yStepY * (clipXMin - tileW - 1 - adjXMin)
+ - yStepX * (clipYMin - tileH - 1 - adjYMin));
+ ty = idet * (xStepX * (clipYMin - tileH - 1 - adjYMin)
+ - xStepY * (clipXMin - tileW - 1 - adjXMin));
+ if (tx < txMin) {
+ txMin = tx;
+ } else if (tx > txMax) {
+ txMax = tx;
+ }
+ if (ty < tyMin) {
+ tyMin = ty;
+ } else if (ty > tyMax) {
+ tyMax = ty;
+ }
+ // UR corner
+ tx = idet * (yStepY * (clipXMax + 1 - adjXMin)
+ - yStepX * (clipYMin - tileH - 1 - adjYMin));
+ ty = idet * (xStepX * (clipYMin - tileH - 1 - adjYMin)
+ - xStepY * (clipXMax + 1 - adjXMin));
+ if (tx < txMin) {
+ txMin = tx;
+ } else if (tx > txMax) {
+ txMax = tx;
+ }
+ if (ty < tyMin) {
+ tyMin = ty;
+ } else if (ty > tyMax) {
+ tyMax = ty;
+ }
+ ixMin = (int)floor(txMin);
+ ixMax = (int)ceil(txMax);
+ iyMin = (int)floor(tyMin);
+ iyMax = (int)ceil(tyMax);
+
// create a temporary bitmap
origBitmap = bitmap;
origSplash = splash;
@@ -1691,7 +1904,10 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
colorMode, gTrue, bitmapTopDown);
splash = new Splash(bitmap, vectorAntialias, origSplash->getScreen());
splash->setMinLineWidth(globalParams->getMinLineWidth());
- splash->setStrokeAdjust(globalParams->getStrokeAdjust());
+ splash->setStrokeAdjust(
+ mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
+ splash->setEnablePathSimplification(
+ globalParams->getEnablePathSimplification());
for (i = 0; i < splashMaxColorComps; ++i) {
color[i] = 0;
}
@@ -1703,12 +1919,11 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
splash->setFillPattern(origSplash->getFillPattern()->copy());
splash->setStrokePattern(origSplash->getStrokePattern()->copy());
+ // reset the clip rectangle
+ state->resetDevClipRect(0, 0, tileW, tileH);
+
// render the tile
- state->shiftCTM(-tileX0, -tileY0);
- updateCTM(state, 0, 0, 0, 0, 0, 0);
- gfx->drawForm(strRef, resDict, mat, bbox);
- state->shiftCTM(tileX0, tileY0);
- updateCTM(state, 0, 0, 0, 0, 0, 0);
+ gfx->drawForm(strRef, resDict, tileMat, bbox);
// restore the original bitmap
--nestCount;
@@ -1718,16 +1933,11 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
splash->setOverprintMask(0xffffffff);
// draw the tiles
- for (y = y0; y < y1; ++y) {
- for (x = x0; x < x1; ++x) {
- xa = x * xStep;
- ya = y * yStep;
- xb = xa * mat[0] + ya * mat[2];
- yb = xa * mat[1] + ya * mat[3];
- state->transformDelta(xb, yb, &xc, &yc);
- xx = (int)(xc + tileX0 + 0.5);
- yy = (int)(yc + tileY0 + 0.5);
- splash->composite(tileBitmap, 0, 0, xx, yy, tileW, tileH,
+ for (iy = iyMin; iy < iyMax; ++iy) {
+ for (ix = ixMin; ix < ixMax; ++ix) {
+ x = (int)(adjXMin + ix * xStepX + iy * yStepX + 0.5);
+ y = (int)(adjYMin + ix * xStepY + iy * yStepY + 0.5);
+ splash->composite(tileBitmap, 0, 0, x, y, tileW, tileH,
gFalse, gFalse);
}
}
@@ -1735,6 +1945,707 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
delete tileBitmap;
}
+GBool SplashOutputDev::axialShadedFill(GfxState *state,
+ GfxAxialShading *shading) {
+ double x0, y0, x1, y1, t0, t1;
+ GBool ext0, ext1;
+ double uxMin, uyMin, uxMax, uyMax, det;
+ double *ctm;
+ double ictm[6];
+ double xMin, yMin, xMax, yMax, tx, ty, xx, yy;
+ double xx0, yy0, xx1, yy1, dx, dy, d, s, t;
+ GBool dZero, go;
+ int ixMin, iyMin, ixMax, iyMax, bitmapWidth, bitmapHeight, nColors;
+ SplashClipResult clipRes;
+ SplashColorMode srcMode;
+ SplashBitmap *tBitmap;
+ int nComps;
+ int x, y, i;
+ SplashColorPtr dataPtr;
+ Guchar *alphaPtr;
+ GfxColor color;
+ SplashColorPtr sColors, sColor;
+ SplashColor sColor0;
+
+ // get the shading parameters
+ shading->getCoords(&x0, &y0, &x1, &y1);
+ t0 = shading->getDomain0();
+ t1 = shading->getDomain1();
+ ext0 = shading->getExtend0();
+ ext1 = shading->getExtend1();
+ dx = x1 - x0;
+ dy = y1 - y0;
+ d = dx * dx + dy * dy;
+ dZero = fabs(d) < 0.0001;
+ if (!dZero) {
+ d = 1 / d;
+ }
+ if (dZero && !ext0 && !ext1) {
+ return gTrue;
+ }
+
+ // get clip region (in user space)
+ state->getUserClipBBox(&uxMin, &uyMin, &uxMax, &uyMax);
+ if (uxMin >= uxMax || uyMin >= uyMax) {
+ return gTrue;
+ }
+
+ // convert the region to device space
+ ctm = state->getCTM();
+ tx = uxMin * ctm[0] + uyMin * ctm[2] + ctm[4];
+ ty = uxMin * ctm[1] + uyMin * ctm[3] + ctm[5];
+ xMin = xMax = tx;
+ yMin = yMax = ty;
+ tx = uxMin * ctm[0] + uyMax * ctm[2] + ctm[4];
+ ty = uxMin * ctm[1] + uyMax * ctm[3] + ctm[5];
+ if (tx < xMin) {
+ xMin = tx;
+ } else if (tx > xMax) {
+ xMax = tx;
+ }
+ if (ty < yMin) {
+ yMin = ty;
+ } else if (ty > yMax) {
+ yMax = ty;
+ }
+ tx = uxMax * ctm[0] + uyMin * ctm[2] + ctm[4];
+ ty = uxMax * ctm[1] + uyMin * ctm[3] + ctm[5];
+ if (tx < xMin) {
+ xMin = tx;
+ } else if (tx > xMax) {
+ xMax = tx;
+ }
+ if (ty < yMin) {
+ yMin = ty;
+ } else if (ty > yMax) {
+ yMax = ty;
+ }
+ tx = uxMax * ctm[0] + uyMax * ctm[2] + ctm[4];
+ ty = uxMax * ctm[1] + uyMax * ctm[3] + ctm[5];
+ if (tx < xMin) {
+ xMin = tx;
+ } else if (tx > xMax) {
+ xMax = tx;
+ }
+ if (ty < yMin) {
+ yMin = ty;
+ } else if (ty > yMax) {
+ yMax = ty;
+ }
+ ixMin = (int)floor(xMin);
+ iyMin = (int)floor(yMin);
+ ixMax = (int)floor(xMax) + 1;
+ iyMax = (int)floor(yMax) + 1;
+ clipRes = splash->limitRectToClipRect(&ixMin, &iyMin, &ixMax, &iyMax);
+ if (clipRes == splashClipAllOutside) {
+ return gTrue;
+ }
+
+ // allocate a bitmap
+ if (colorMode == splashModeMono1) {
+ srcMode = splashModeMono8;
+ } else if (colorMode == splashModeBGR8) {
+ srcMode = splashModeRGB8;
+ } else {
+ srcMode = colorMode;
+ }
+ bitmapWidth = ixMax - ixMin;
+ bitmapHeight = iyMax - iyMin;
+ tBitmap = new SplashBitmap(bitmapWidth, bitmapHeight, 1,
+ srcMode, gTrue, gTrue);
+ memset(tBitmap->getAlphaPtr(), 0, bitmapWidth * bitmapHeight);
+ nComps = splashColorModeNComps[srcMode];
+
+ // compute the inverse CTM
+ det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
+ ictm[0] = ctm[3] * det;
+ ictm[1] = -ctm[1] * det;
+ ictm[2] = -ctm[2] * det;
+ ictm[3] = ctm[0] * det;
+ ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
+ ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
+
+ // render the shading into the bitmap
+ xx0 = x0 * ctm[0] + y0 * ctm[2] + ctm[4];
+ yy0 = x0 * ctm[1] + y0 * ctm[3] + ctm[5];
+ xx1 = x1 * ctm[0] + y1 * ctm[2] + ctm[4];
+ yy1 = x1 * ctm[1] + y1 * ctm[3] + ctm[5];
+ sColors = NULL;
+
+ // special case: zero-length axis
+ if (dZero) {
+ if (ext0) {
+ shading->getColor(t0, &color);
+ } else {
+ shading->getColor(t1, &color);
+ }
+ computeShadingColor(state, srcMode, &color, sColor0);
+ dataPtr = tBitmap->getDataPtr();
+ alphaPtr = tBitmap->getAlphaPtr();
+ for (y = 0; y < bitmapHeight; ++y) {
+ for (x = 0; x < bitmapWidth; ++x) {
+ for (i = 0; i < nComps; ++i) {
+ *dataPtr++ = sColor0[i];
+ }
+ *alphaPtr++ = 0xff;
+ }
+ }
+
+ // special case: horizontal axis (in device space)
+ } else if (fabs(yy0 - yy1) < 0.01) {
+ for (x = 0; x < bitmapWidth; ++x) {
+ dataPtr = tBitmap->getDataPtr() + x * nComps;
+ alphaPtr = tBitmap->getAlphaPtr() + x;
+ tx = ixMin + x + 0.5;
+ ty = iyMin + 0.5;
+ xx = tx * ictm[0] + ty * ictm[2] + ictm[4];
+ yy = tx * ictm[1] + ty * ictm[3] + ictm[5];
+ s = ((xx - x0) * dx + (yy - y0) * dy) * d;
+ go = gFalse;
+ if (s < 0) {
+ go = ext0;
+ } else if (s > 1) {
+ go = ext1;
+ } else {
+ go = gTrue;
+ }
+ if (!go) {
+ continue;
+ }
+ if (s <= 0) {
+ shading->getColor(t0, &color);
+ } else if (s >= 1) {
+ shading->getColor(t1, &color);
+ } else {
+ t = t0 + s * (t1 - t0);
+ shading->getColor(t, &color);
+ }
+ computeShadingColor(state, srcMode, &color, sColor0);
+ for (y = 0; y < bitmapHeight; ++y) {
+ for (i = 0; i < nComps; ++i) {
+ dataPtr[i] = sColor0[i];
+ }
+ *alphaPtr = 0xff;
+ dataPtr += tBitmap->getRowSize();
+ alphaPtr += bitmapWidth;
+ }
+ }
+
+ // special case: vertical axis (in device space)
+ } else if (fabs(xx0 - xx1) < 0.01) {
+ dataPtr = tBitmap->getDataPtr();
+ alphaPtr = tBitmap->getAlphaPtr();
+ for (y = 0; y < bitmapHeight; ++y) {
+ tx = ixMin + 0.5;
+ ty = iyMin + y + 0.5;
+ xx = tx * ictm[0] + ty * ictm[2] + ictm[4];
+ yy = tx * ictm[1] + ty * ictm[3] + ictm[5];
+ s = ((xx - x0) * dx + (yy - y0) * dy) * d;
+ go = gFalse;
+ if (s < 0) {
+ go = ext0;
+ } else if (s > 1) {
+ go = ext1;
+ } else {
+ go = gTrue;
+ }
+ if (!go) {
+ continue;
+ }
+ if (s <= 0) {
+ shading->getColor(t0, &color);
+ } else if (s >= 1) {
+ shading->getColor(t1, &color);
+ } else {
+ t = t0 + s * (t1 - t0);
+ shading->getColor(t, &color);
+ }
+ computeShadingColor(state, srcMode, &color, sColor0);
+ for (x = 0; x < bitmapWidth; ++x) {
+ for (i = 0; i < nComps; ++i) {
+ *dataPtr++ = sColor0[i];
+ }
+ *alphaPtr++ = 0xff;
+ }
+ }
+
+ // general case
+ } else {
+ // pre-compute colors along the axis
+ nColors = (int)(1.5 * sqrt((xx1 - xx0) * (xx1 - xx0)
+ + (yy1 - yy0) * (yy1 - yy0)));
+ if (nColors < 16) {
+ nColors = 16;
+ } else if (nColors > 1024) {
+ nColors = 1024;
+ }
+ sColors = (SplashColorPtr)gmallocn(nColors, nComps);
+ sColor = sColors;
+ for (i = 0; i < nColors; ++i) {
+ s = (double)i / (double)(nColors - 1);
+ t = t0 + s * (t1 - t0);
+ shading->getColor(t, &color);
+ computeShadingColor(state, srcMode, &color, sColor);
+ sColor += nComps;
+ }
+
+ dataPtr = tBitmap->getDataPtr();
+ alphaPtr = tBitmap->getAlphaPtr();
+ for (y = 0; y < bitmapHeight; ++y) {
+ for (x = 0; x < bitmapWidth; ++x) {
+
+ // convert coords to user space
+ tx = ixMin + x + 0.5;
+ ty = iyMin + y + 0.5;
+ xx = tx * ictm[0] + ty * ictm[2] + ictm[4];
+ yy = tx * ictm[1] + ty * ictm[3] + ictm[5];
+
+ // compute the position along the axis
+ s = ((xx - x0) * dx + (yy - y0) * dy) * d;
+ go = gFalse;
+ if (s < 0) {
+ go = ext0;
+ } else if (s > 1) {
+ go = ext1;
+ } else {
+ go = gTrue;
+ }
+ if (!go) {
+ dataPtr += nComps;
+ ++alphaPtr;
+ continue;
+ }
+ if (s <= 0) {
+ sColor = sColors;
+ } else if (s >= 1) {
+ sColor = sColors + (nColors - 1) * nComps;
+ } else {
+ i = (int)((nColors - 1) * s + 0.5);
+ sColor = sColors + i * nComps;
+ }
+ for (i = 0; i < nComps; ++i) {
+ *dataPtr++ = sColor[i];
+ }
+ *alphaPtr++ = 0xff;
+ }
+ }
+ }
+
+ // composite the bitmap
+ setOverprintMask(state, state->getFillColorSpace(),
+ state->getFillOverprint(), state->getOverprintMode(),
+ NULL);
+ splash->composite(tBitmap, 0, 0, ixMin, iyMin, bitmapWidth, bitmapHeight,
+ clipRes == splashClipAllInside, gFalse);
+
+ gfree(sColors);
+ delete tBitmap;
+
+ return gTrue;
+}
+
+GBool SplashOutputDev::radialShadedFill(GfxState *state,
+ GfxRadialShading *shading) {
+ double x0, y0, r0, x1, y1, r1, t0, t1, h;
+ GBool ext0, ext1, enclosed;
+ double uxMin, uyMin, uxMax, uyMax, det;
+ double *ctm;
+ double ictm[6];
+ double xMin, yMin, xMax, yMax, tx, ty, xx, yy;
+ double dx, dy, dr, r0dr, r02, a, a2, b, c, e, es, s, s0, s1, rs0, rs1, t;
+ GBool aIsZero, go;
+ int ixMin, iyMin, ixMax, iyMax, bitmapWidth, bitmapHeight, nColors;
+ int bxMin, byMin, bxMax, byMax;
+ SplashClipResult clipRes;
+ SplashColorMode srcMode;
+ SplashBitmap *tBitmap;
+ int nComps;
+ int x, y, i;
+ SplashColorPtr dataPtr;
+ Guchar *alphaPtr;
+ GfxColor color;
+ SplashColorPtr sColors, sColor;
+
+ // get the shading parameters
+ shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1);
+ t0 = shading->getDomain0();
+ t1 = shading->getDomain1();
+ ext0 = shading->getExtend0();
+ ext1 = shading->getExtend1();
+ h = sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
+ enclosed = fabs(r1 - r0) >= h;
+
+ // get clip region (in user space)
+ state->getUserClipBBox(&uxMin, &uyMin, &uxMax, &uyMax);
+ if (uxMin >= uxMax || uyMin >= uyMax) {
+ return gTrue;
+ }
+
+ // intersect with shading region (in user space): if the extend
+ // flags are false (or just the larger extend flag is false, in the
+ // "enclosed" case), we can use the bbox for the two circles
+ if ((!ext0 && !ext1) ||
+ (enclosed && !(r0 > r1 ? ext0 : ext1))) {
+ tx = (x0 - r0) < (x1 - r1) ? (x0 - r0) : (x1 - r1);
+ if (tx > uxMin) {
+ uxMin = tx;
+ }
+ tx = (x0 + r0) > (x1 + r1) ? (x0 + r0) : (x1 + r1);
+ if (tx < uxMax) {
+ uxMax = tx;
+ }
+ ty = (y0 - r0) < (y1 - r1) ? (y0 - r0) : (y1 - r1);
+ if (ty > uyMin) {
+ uyMin = ty;
+ }
+ ty = (y0 + r0) > (y1 + r1) ? (y0 + r0) : (y1 + r1);
+ if (ty < uyMax) {
+ uyMax = ty;
+ }
+ }
+ if (uxMin > uxMax || uyMin > uyMax) {
+ return gTrue;
+ }
+
+ // convert the region to device space
+ ctm = state->getCTM();
+ tx = uxMin * ctm[0] + uyMin * ctm[2] + ctm[4];
+ ty = uxMin * ctm[1] + uyMin * ctm[3] + ctm[5];
+ xMin = xMax = tx;
+ yMin = yMax = ty;
+ tx = uxMin * ctm[0] + uyMax * ctm[2] + ctm[4];
+ ty = uxMin * ctm[1] + uyMax * ctm[3] + ctm[5];
+ if (tx < xMin) {
+ xMin = tx;
+ } else if (tx > xMax) {
+ xMax = tx;
+ }
+ if (ty < yMin) {
+ yMin = ty;
+ } else if (ty > yMax) {
+ yMax = ty;
+ }
+ tx = uxMax * ctm[0] + uyMin * ctm[2] + ctm[4];
+ ty = uxMax * ctm[1] + uyMin * ctm[3] + ctm[5];
+ if (tx < xMin) {
+ xMin = tx;
+ } else if (tx > xMax) {
+ xMax = tx;
+ }
+ if (ty < yMin) {
+ yMin = ty;
+ } else if (ty > yMax) {
+ yMax = ty;
+ }
+ tx = uxMax * ctm[0] + uyMax * ctm[2] + ctm[4];
+ ty = uxMax * ctm[1] + uyMax * ctm[3] + ctm[5];
+ if (tx < xMin) {
+ xMin = tx;
+ } else if (tx > xMax) {
+ xMax = tx;
+ }
+ if (ty < yMin) {
+ yMin = ty;
+ } else if (ty > yMax) {
+ yMax = ty;
+ }
+ ixMin = (int)floor(xMin);
+ iyMin = (int)floor(yMin);
+ ixMax = (int)floor(xMax) + 1;
+ iyMax = (int)floor(yMax) + 1;
+ clipRes = splash->limitRectToClipRect(&ixMin, &iyMin, &ixMax, &iyMax);
+ if (clipRes == splashClipAllOutside) {
+ return gTrue;
+ }
+
+ // allocate a bitmap
+ if (colorMode == splashModeMono1) {
+ srcMode = splashModeMono8;
+ } else if (colorMode == splashModeBGR8) {
+ srcMode = splashModeRGB8;
+ } else {
+ srcMode = colorMode;
+ }
+ bitmapWidth = ixMax - ixMin;
+ bitmapHeight = iyMax - iyMin;
+ tBitmap = new SplashBitmap(bitmapWidth, bitmapHeight, 1,
+ srcMode, gTrue, gTrue);
+ memset(tBitmap->getAlphaPtr(), 0, bitmapWidth * bitmapHeight);
+ nComps = splashColorModeNComps[srcMode];
+
+ // compute the inverse CTM
+ det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
+ ictm[0] = ctm[3] * det;
+ ictm[1] = -ctm[1] * det;
+ ictm[2] = -ctm[2] * det;
+ ictm[3] = ctm[0] * det;
+ ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
+ ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
+
+ // pre-compute colors along the axis
+ nColors = (int)sqrt((double)(bitmapWidth * bitmapWidth
+ + bitmapHeight * bitmapHeight));
+ if (nColors < 16) {
+ nColors = 16;
+ } else if (nColors > 1024) {
+ nColors = 1024;
+ }
+ sColors = (SplashColorPtr)gmallocn(nColors, nComps);
+ sColor = sColors;
+ for (i = 0; i < nColors; ++i) {
+ s = (double)i / (double)(nColors - 1);
+ t = t0 + s * (t1 - t0);
+ shading->getColor(t, &color);
+ computeShadingColor(state, srcMode, &color, sColor);
+ sColor += nComps;
+ }
+
+ // special case: in the "enclosed" + extended case, we can fill the
+ // bitmap with the outer color and just render inside the larger
+ // circle
+ if (enclosed &&
+ ((r0 > r1 && ext0) || (r1 > r0 && ext1))) {
+ if (r0 > r1) {
+ sColor = sColors;
+ uxMin = x0 - r0;
+ uxMax = x0 + r0;
+ uyMin = y0 - r0;
+ uyMax = y0 + r0;
+ } else {
+ sColor = sColors + (nColors - 1) * nComps;
+ uxMin = x1 - r1;
+ uxMax = x1 + r1;
+ uyMin = y1 - r1;
+ uyMax = y1 + r1;
+ }
+
+ // convert bbox of larger circle to device space
+ tx = uxMin * ctm[0] + uyMin * ctm[2] + ctm[4];
+ ty = uxMin * ctm[1] + uyMin * ctm[3] + ctm[5];
+ xMin = xMax = tx;
+ yMin = yMax = ty;
+ tx = uxMin * ctm[0] + uyMax * ctm[2] + ctm[4];
+ ty = uxMin * ctm[1] + uyMax * ctm[3] + ctm[5];
+ if (tx < xMin) {
+ xMin = tx;
+ } else if (tx > xMax) {
+ xMax = tx;
+ }
+ if (ty < yMin) {
+ yMin = ty;
+ } else if (ty > yMax) {
+ yMax = ty;
+ }
+ tx = uxMax * ctm[0] + uyMin * ctm[2] + ctm[4];
+ ty = uxMax * ctm[1] + uyMin * ctm[3] + ctm[5];
+ if (tx < xMin) {
+ xMin = tx;
+ } else if (tx > xMax) {
+ xMax = tx;
+ }
+ if (ty < yMin) {
+ yMin = ty;
+ } else if (ty > yMax) {
+ yMax = ty;
+ }
+ tx = uxMax * ctm[0] + uyMax * ctm[2] + ctm[4];
+ ty = uxMax * ctm[1] + uyMax * ctm[3] + ctm[5];
+ if (tx < xMin) {
+ xMin = tx;
+ } else if (tx > xMax) {
+ xMax = tx;
+ }
+ if (ty < yMin) {
+ yMin = ty;
+ } else if (ty > yMax) {
+ yMax = ty;
+ }
+ bxMin = (int)floor(xMin - ixMin);
+ if (bxMin < 0) {
+ bxMin = 0;
+ }
+ byMin = (int)floor(yMin - iyMin);
+ if (byMin < 0) {
+ byMin = 0;
+ }
+ bxMax = (int)floor(xMax - ixMin) + 1;
+ if (bxMax > bitmapWidth) {
+ bxMax = bitmapWidth;
+ }
+ byMax = (int)floor(yMax - iyMin) + 1;
+ if (byMax > bitmapHeight) {
+ byMax = bitmapHeight;
+ }
+
+ // fill bitmap (except for the rectangle containing the larger circle)
+ dataPtr = tBitmap->getDataPtr();
+ alphaPtr = tBitmap->getAlphaPtr();
+ for (y = 0; y < bitmapHeight; ++y) {
+ for (x = 0; x < bitmapWidth; ++x) {
+ if (y >= byMin && y < byMax && x >= bxMin && x < bxMax) {
+ dataPtr += nComps;
+ ++alphaPtr;
+ } else {
+ for (i = 0; i < nComps; ++i) {
+ *dataPtr++ = sColor[i];
+ }
+ *alphaPtr++ = 0xff;
+ }
+ }
+ }
+
+ } else {
+ bxMin = 0;
+ byMin = 0;
+ bxMax = bitmapWidth;
+ byMax = bitmapHeight;
+ }
+
+ // render the shading into the bitmap
+ dx = x1 - x0;
+ dy = y1 - y0;
+ dr = r1 - r0;
+ r0dr = r0 * dr;
+ r02 = r0 * r0;
+ a = dx * dx + dy * dy - dr * dr;
+ if (fabs(a) < 0.00001) {
+ aIsZero = gTrue;
+ a2 = 0;
+ } else {
+ aIsZero = gFalse;
+ a2 = 1 / (2 * a);
+ }
+ for (y = byMin; y < byMax; ++y) {
+ dataPtr = tBitmap->getDataPtr()
+ + y * tBitmap->getRowSize() + bxMin * nComps;
+ alphaPtr = tBitmap->getAlphaPtr() + y * bitmapWidth + bxMin;
+ for (x = bxMin; x < bxMax; ++x) {
+
+ // convert coords to user space
+ tx = ixMin + x + 0.5;
+ ty = iyMin + y + 0.5;
+ xx = tx * ictm[0] + ty * ictm[2] + ictm[4];
+ yy = tx * ictm[1] + ty * ictm[3] + ictm[5];
+
+ // compute the radius of the circle at x,y
+ b = 2 * ((xx - x0) * dx + (yy - y0) * dy + r0dr);
+ c = (xx - x0) * (xx - x0) + (yy - y0) * (yy - y0) - r02;
+ s = 0;
+ go = gFalse;
+ if (aIsZero) {
+ if (fabs(b) < 0.000001) {
+ if (c <= 0) {
+ if (ext0) {
+ s = 0;
+ go = gTrue;
+ }
+ } else {
+ if (ext1) {
+ s = 1;
+ go = gTrue;
+ }
+ }
+ } else {
+ s0 = c / b;
+ rs0 = r0 + s0 * (r1 - r0);
+ if ((s0 >= 0 || ext0) && (s0 <= 1 || ext1) && rs0 >= 0) {
+ s = s0;
+ go = gTrue;
+ }
+ }
+ } else {
+ e = b*b - 4*a*c;
+ if (e >= 0) {
+ es = sqrt(e);
+ s0 = (b + es) * a2;
+ s1 = (b - es) * a2;
+ rs0 = r0 + s0 * (r1 - r0);
+ rs1 = r0 + s1 * (r1 - r0);
+ if (s0 > s1) {
+ if ((s0 >= 0 || ext0) && (s0 <= 1 || ext1) && rs0 >= 0) {
+ s = s0;
+ go = gTrue;
+ } else if ((s1 >= 0 || ext0) && (s1 <= 1 || ext1) && rs1 >= 0) {
+ s = s1;
+ go = gTrue;
+ }
+ } else {
+ if ((s1 >= 0 || ext0) && (s1 <= 1 || ext1) && rs1 >= 0) {
+ s = s1;
+ go = gTrue;
+ } else if ((s0 >= 0 || ext0) && (s0 <= 1 || ext1) && rs0 >= 0) {
+ s = s0;
+ go = gTrue;
+ }
+ }
+ }
+ }
+ if (!go) {
+ dataPtr += nComps;
+ ++alphaPtr;
+ continue;
+ }
+ if (s <= 0) {
+ sColor = sColors;
+ } else if (s >= 1) {
+ sColor = sColors + (nColors - 1) * nComps;
+ } else {
+ i = (int)((nColors - 1) * s + 0.5);
+ sColor = sColors + i * nComps;
+ }
+ for (i = 0; i < nComps; ++i) {
+ *dataPtr++ = sColor[i];
+ }
+ *alphaPtr++ = 0xff;
+ }
+ }
+
+ // composite the bitmap
+ setOverprintMask(state, state->getFillColorSpace(),
+ state->getFillOverprint(), state->getOverprintMode(),
+ NULL);
+ splash->composite(tBitmap, 0, 0, ixMin, iyMin, bitmapWidth, bitmapHeight,
+ clipRes == splashClipAllInside, gFalse);
+
+ gfree(sColors);
+ delete tBitmap;
+
+ return gTrue;
+}
+
+void SplashOutputDev::computeShadingColor(GfxState *state,
+ SplashColorMode mode,
+ GfxColor *color,
+ SplashColorPtr sColor) {
+ GfxGray gray;
+ GfxRGB rgb;
+#if SPLASH_CMYK
+ GfxCMYK cmyk;
+#endif
+
+ state->setFillColor(color);
+ switch (mode) {
+ case splashModeMono8:
+ state->getFillGray(&gray);
+ getColor(gray, sColor);
+ break;
+ case splashModeRGB8:
+ state->getFillRGB(&rgb);
+ getColor(&rgb, sColor);
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ state->getFillCMYK(&cmyk);
+ getColor(&cmyk, sColor);
+ break;
+#endif
+ case splashModeMono1:
+ case splashModeBGR8:
+ // mode cannot be Mono1 or BGR8
+ break;
+ }
+}
+
void SplashOutputDev::clip(GfxState *state) {
SplashPath *path;
@@ -1755,7 +2666,8 @@ void SplashOutputDev::clipToStrokePath(GfxState *state) {
SplashPath *path, *path2;
path = convertPath(state, state->getPath(), gFalse);
- path2 = splash->makeStrokePath(path, state->getLineWidth());
+ path2 = splash->makeStrokePath(path, state->getLineWidth(),
+ state->getLineCap(), state->getLineJoin());
delete path;
splash->clipToPath(path2, gFalse);
delete path2;
@@ -1805,7 +2717,8 @@ void SplashOutputDev::drawChar(GfxState *state, double x, double y,
Unicode *u, int uLen) {
SplashPath *path;
int render;
- GBool doFill, doStroke, doClip, strokeAdjust;
+ GBool doFill, doStroke, doClip;
+ SplashStrokeAdjustMode strokeAdjust;
double m[4];
GBool horiz;
@@ -1849,37 +2762,37 @@ void SplashOutputDev::drawChar(GfxState *state, double x, double y,
// don't use stroke adjustment when stroking text -- the results
// tend to be ugly (because characters with horizontal upper or
// lower edges get misaligned relative to the other characters)
- strokeAdjust = gFalse; // make gcc happy
+ strokeAdjust = splashStrokeAdjustOff; // make gcc happy
if (doStroke) {
strokeAdjust = splash->getStrokeAdjust();
- splash->setStrokeAdjust(gFalse);
+ splash->setStrokeAdjust(splashStrokeAdjustOff);
}
// fill and stroke
if (doFill && doStroke) {
if (path) {
- setOverprintMask(state->getFillColorSpace(), state->getFillOverprint(),
- state->getOverprintMode(), state->getFillColor());
+ setOverprintMask(state, state->getFillColorSpace(),
+ state->getFillOverprint(), state->getOverprintMode(),
+ state->getFillColor());
splash->fill(path, gFalse);
- setOverprintMask(state->getStrokeColorSpace(),
- state->getStrokeOverprint(),
- state->getOverprintMode(),
+ setOverprintMask(state, state->getStrokeColorSpace(),
+ state->getStrokeOverprint(), state->getOverprintMode(),
state->getStrokeColor());
splash->stroke(path);
}
// fill
} else if (doFill) {
- setOverprintMask(state->getFillColorSpace(), state->getFillOverprint(),
- state->getOverprintMode(), state->getFillColor());
+ setOverprintMask(state, state->getFillColorSpace(),
+ state->getFillOverprint(), state->getOverprintMode(),
+ state->getFillColor());
splash->fillChar((SplashCoord)x, (SplashCoord)y, code, font);
// stroke
} else if (doStroke) {
if (path) {
- setOverprintMask(state->getStrokeColorSpace(),
- state->getStrokeOverprint(),
- state->getOverprintMode(),
+ setOverprintMask(state, state->getStrokeColorSpace(),
+ state->getStrokeOverprint(), state->getOverprintMode(),
state->getStrokeColor());
splash->stroke(path);
}
@@ -1918,7 +2831,7 @@ GBool SplashOutputDev::beginType3Char(GfxState *state, double x, double y,
double m[4];
GBool horiz;
double x1, y1, xMin, yMin, xMax, yMax, xt, yt;
- int i, j;
+ int render, i, j;
if (skipHorizText || skipRotatedText) {
state->getFontTransMat(&m[0], &m[1], &m[2], &m[3]);
@@ -1929,6 +2842,12 @@ GBool SplashOutputDev::beginType3Char(GfxState *state, double x, double y,
}
}
+ // check for invisible text
+ render = state->getRender();
+ if (render == 3 || render == 7) {
+ return gTrue;
+ }
+
if (!(gfxFont = state->getFont())) {
return gFalse;
}
@@ -2070,6 +2989,11 @@ void SplashOutputDev::endType3Char(GfxState *state) {
}
void SplashOutputDev::type3D0(GfxState *state, double wx, double wy) {
+ if (!t3GlyphStack) {
+ error(errSyntaxError, -1,
+ "Encountered d0 operator outside of Type 3 CharProc");
+ return;
+ }
t3GlyphStack->haveDx = gTrue;
}
@@ -2081,6 +3005,12 @@ void SplashOutputDev::type3D1(GfxState *state, double wx, double wy,
double xt, yt, xMin, xMax, yMin, yMax, x1, y1;
int i, j;
+ if (!t3GlyphStack) {
+ error(errSyntaxError, -1,
+ "Encountered d1 operator outside of Type 3 CharProc");
+ return;
+ }
+
// ignore multiple d0/d1 operators
if (t3GlyphStack->haveDx) {
return;
@@ -2165,8 +3095,7 @@ void SplashOutputDev::type3D1(GfxState *state, double wx, double wy,
if (colorMode == splashModeMono1) {
bitmap = new SplashBitmap(t3Font->glyphW, t3Font->glyphH, 1,
splashModeMono1, gFalse);
- splash = new Splash(bitmap, gFalse,
- t3GlyphStack->origSplash->getScreen());
+ splash = new Splash(bitmap, gFalse, t3GlyphStack->origSplash->getScreen());
color[0] = 0;
splash->clear(color);
color[0] = 0xff;
@@ -2181,6 +3110,8 @@ void SplashOutputDev::type3D1(GfxState *state, double wx, double wy,
}
splash->setMinLineWidth(globalParams->getMinLineWidth());
splash->setStrokeAdjust(t3GlyphStack->origSplash->getStrokeAdjust());
+ splash->setEnablePathSimplification(
+ globalParams->getEnablePathSimplification());
splash->setFillPattern(new SplashSolidColor(color));
splash->setStrokePattern(new SplashSolidColor(color));
//~ this should copy other state from t3GlyphStack->origSplash?
@@ -2195,8 +3126,9 @@ void SplashOutputDev::drawType3Glyph(GfxState *state, T3FontCache *t3Font,
T3FontCacheTag *tag, Guchar *data) {
SplashGlyphBitmap glyph;
- setOverprintMask(state->getFillColorSpace(), state->getFillOverprint(),
- state->getOverprintMode(), state->getFillColor());
+ setOverprintMask(state, state->getFillColorSpace(),
+ state->getFillOverprint(), state->getOverprintMode(),
+ state->getFillColor());
glyph.x = -t3Font->glyphX;
glyph.y = -t3Font->glyphY;
glyph.w = t3Font->glyphW;
@@ -2249,8 +3181,9 @@ void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
if (state->getFillColorSpace()->isNonMarking()) {
return;
}
- setOverprintMask(state->getFillColorSpace(), state->getFillOverprint(),
- state->getOverprintMode(), state->getFillColor());
+ setOverprintMask(state, state->getFillColorSpace(),
+ state->getFillOverprint(), state->getOverprintMode(),
+ state->getFillColor());
ctm = state->getCTM();
mat[0] = ctm[0];
@@ -2312,7 +3245,10 @@ void SplashOutputDev::setSoftMaskFromImageMask(GfxState *state,
maskBitmap = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
1, splashModeMono8, gFalse);
maskSplash = new Splash(maskBitmap, gTrue);
- maskSplash->setStrokeAdjust(globalParams->getStrokeAdjust());
+ maskSplash->setStrokeAdjust(
+ mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
+ maskSplash->setEnablePathSimplification(
+ globalParams->getEnablePathSimplification());
clearMaskRegion(state, maskSplash, 0, 0, 1, 1);
maskColor[0] = 0xff;
maskSplash->setFillPattern(new SplashSolidColor(maskColor));
@@ -2327,6 +3263,7 @@ void SplashOutputDev::setSoftMaskFromImageMask(GfxState *state,
struct SplashOutImageData {
ImageStream *imgStr;
GfxImageColorMap *colorMap;
+ GfxRenderingIntent ri;
SplashColorPtr lookup;
int *maskColors;
SplashColorMode colorMode;
@@ -2338,7 +3275,7 @@ GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr colorLine,
SplashOutImageData *imgData = (SplashOutImageData *)data;
Guchar *p;
SplashColorPtr q, col;
- int nComps, x;
+ int x;
if (imgData->y == imgData->height ||
!(p = imgData->imgStr->getLine())) {
@@ -2347,8 +3284,6 @@ GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr colorLine,
return gFalse;
}
- nComps = imgData->colorMap->getNumPixelComps();
-
if (imgData->lookup) {
switch (imgData->colorMode) {
case splashModeMono1:
@@ -2382,15 +3317,18 @@ GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr colorLine,
switch (imgData->colorMode) {
case splashModeMono1:
case splashModeMono8:
- imgData->colorMap->getGrayByteLine(p, colorLine, imgData->width);
+ imgData->colorMap->getGrayByteLine(p, colorLine, imgData->width,
+ imgData->ri);
break;
case splashModeRGB8:
case splashModeBGR8:
- imgData->colorMap->getRGBByteLine(p, colorLine, imgData->width);
+ imgData->colorMap->getRGBByteLine(p, colorLine, imgData->width,
+ imgData->ri);
break;
#if SPLASH_CMYK
case splashModeCMYK8:
- imgData->colorMap->getCMYKByteLine(p, colorLine, imgData->width);
+ imgData->colorMap->getCMYKByteLine(p, colorLine, imgData->width,
+ imgData->ri);
break;
#endif
}
@@ -2462,19 +3400,19 @@ GBool SplashOutputDev::alphaImageSrc(void *data, SplashColorPtr colorLine,
switch (imgData->colorMode) {
case splashModeMono1:
case splashModeMono8:
- imgData->colorMap->getGray(p, &gray);
+ imgData->colorMap->getGray(p, &gray, imgData->ri);
*q++ = colToByte(gray);
break;
case splashModeRGB8:
case splashModeBGR8:
- imgData->colorMap->getRGB(p, &rgb);
+ imgData->colorMap->getRGB(p, &rgb, imgData->ri);
*q++ = colToByte(rgb.r);
*q++ = colToByte(rgb.g);
*q++ = colToByte(rgb.b);
break;
#if SPLASH_CMYK
case splashModeCMYK8:
- imgData->colorMap->getCMYK(p, &cmyk);
+ imgData->colorMap->getCMYK(p, &cmyk, imgData->ri);
*q++ = colToByte(cmyk.c);
*q++ = colToByte(cmyk.m);
*q++ = colToByte(cmyk.y);
@@ -2508,8 +3446,9 @@ void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
Guchar pix;
int n, i;
- setOverprintMask(colorMap->getColorSpace(), state->getFillOverprint(),
- state->getOverprintMode(), NULL);
+ setOverprintMask(state, colorMap->getColorSpace(),
+ state->getFillOverprint(), state->getOverprintMode(),
+ NULL);
ctm = state->getCTM();
mat[0] = ctm[0];
@@ -2526,6 +3465,7 @@ void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
colorMap->getBits());
imgData.imgStr->reset();
imgData.colorMap = colorMap;
+ imgData.ri = state->getRenderingIntent();
imgData.maskColors = maskColors;
imgData.colorMode = colorMode;
imgData.width = width;
@@ -2543,7 +3483,7 @@ void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
imgData.lookup = (SplashColorPtr)gmalloc(n);
for (i = 0; i < n; ++i) {
pix = (Guchar)i;
- colorMap->getGray(&pix, &gray);
+ colorMap->getGray(&pix, &gray, state->getRenderingIntent());
imgData.lookup[i] = colToByte(gray);
}
break;
@@ -2552,7 +3492,7 @@ void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
imgData.lookup = (SplashColorPtr)gmallocn(n, 3);
for (i = 0; i < n; ++i) {
pix = (Guchar)i;
- colorMap->getRGB(&pix, &rgb);
+ colorMap->getRGB(&pix, &rgb, state->getRenderingIntent());
imgData.lookup[3*i] = colToByte(rgb.r);
imgData.lookup[3*i+1] = colToByte(rgb.g);
imgData.lookup[3*i+2] = colToByte(rgb.b);
@@ -2563,7 +3503,7 @@ void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
imgData.lookup = (SplashColorPtr)gmallocn(n, 4);
for (i = 0; i < n; ++i) {
pix = (Guchar)i;
- colorMap->getCMYK(&pix, &cmyk);
+ colorMap->getCMYK(&pix, &cmyk, state->getRenderingIntent());
imgData.lookup[4*i] = colToByte(cmyk.c);
imgData.lookup[4*i+1] = colToByte(cmyk.m);
imgData.lookup[4*i+2] = colToByte(cmyk.y);
@@ -2599,6 +3539,7 @@ void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
struct SplashOutMaskedImageData {
ImageStream *imgStr;
GfxImageColorMap *colorMap;
+ GfxRenderingIntent ri;
SplashBitmap *mask;
SplashColorPtr lookup;
SplashColorMode colorMode;
@@ -2610,16 +3551,10 @@ GBool SplashOutputDev::maskedImageSrc(void *data, SplashColorPtr colorLine,
SplashOutMaskedImageData *imgData = (SplashOutMaskedImageData *)data;
Guchar *p, *aq;
SplashColorPtr q, col;
- GfxRGB rgb;
- GfxGray gray;
-#if SPLASH_CMYK
- GfxCMYK cmyk;
-#endif
static Guchar bitToByte[2] = {0x00, 0xff};
- Guchar alpha;
Guchar *maskPtr;
int maskShift;
- int nComps, x;
+ int x;
if (imgData->y == imgData->height ||
!(p = imgData->imgStr->getLine())) {
@@ -2629,66 +3564,74 @@ GBool SplashOutputDev::maskedImageSrc(void *data, SplashColorPtr colorLine,
return gFalse;
}
- nComps = imgData->colorMap->getNumPixelComps();
-
maskPtr = imgData->mask->getDataPtr() +
imgData->y * imgData->mask->getRowSize();
+ aq = alphaLine;
+ for (x = 0; x <= imgData->width - 8; x += 8) {
+ aq[0] = bitToByte[(*maskPtr >> 7) & 1];
+ aq[1] = bitToByte[(*maskPtr >> 6) & 1];
+ aq[2] = bitToByte[(*maskPtr >> 5) & 1];
+ aq[3] = bitToByte[(*maskPtr >> 4) & 1];
+ aq[4] = bitToByte[(*maskPtr >> 3) & 1];
+ aq[5] = bitToByte[(*maskPtr >> 2) & 1];
+ aq[6] = bitToByte[(*maskPtr >> 1) & 1];
+ aq[7] = bitToByte[*maskPtr & 1];
+ aq += 8;
+ ++maskPtr;
+ }
maskShift = 7;
- for (x = 0, q = colorLine, aq = alphaLine;
- x < imgData->width;
- ++x, p += nComps) {
- alpha = bitToByte[(*maskPtr >> maskShift) & 1];
- maskPtr += (8 - maskShift) >> 3;
- maskShift = (maskShift - 1) & 7;
- if (imgData->lookup) {
- switch (imgData->colorMode) {
- case splashModeMono1:
- case splashModeMono8:
+ for (; x < imgData->width; ++x) {
+ *aq++ = bitToByte[(*maskPtr >> maskShift) & 1];
+ --maskShift;
+ }
+
+ if (imgData->lookup) {
+ switch (imgData->colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ for (x = 0, q = colorLine; x < imgData->width; ++x, ++p) {
*q++ = imgData->lookup[*p];
- break;
- case splashModeRGB8:
- case splashModeBGR8:
+ }
+ break;
+ case splashModeRGB8:
+ case splashModeBGR8:
+ for (x = 0, q = colorLine; x < imgData->width; ++x, ++p) {
col = &imgData->lookup[3 * *p];
*q++ = col[0];
*q++ = col[1];
*q++ = col[2];
- break;
+ }
+ break;
#if SPLASH_CMYK
- case splashModeCMYK8:
+ case splashModeCMYK8:
+ for (x = 0, q = colorLine; x < imgData->width; ++x, ++p) {
col = &imgData->lookup[4 * *p];
*q++ = col[0];
*q++ = col[1];
*q++ = col[2];
*q++ = col[3];
- break;
-#endif
}
- *aq++ = alpha;
- } else {
- switch (imgData->colorMode) {
- case splashModeMono1:
- case splashModeMono8:
- imgData->colorMap->getGray(p, &gray);
- *q++ = colToByte(gray);
- break;
- case splashModeRGB8:
- case splashModeBGR8:
- imgData->colorMap->getRGB(p, &rgb);
- *q++ = colToByte(rgb.r);
- *q++ = colToByte(rgb.g);
- *q++ = colToByte(rgb.b);
- break;
+ break;
+#endif
+ }
+ } else {
+ switch (imgData->colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ imgData->colorMap->getGrayByteLine(p, colorLine, imgData->width,
+ imgData->ri);
+ break;
+ case splashModeRGB8:
+ case splashModeBGR8:
+ imgData->colorMap->getRGBByteLine(p, colorLine, imgData->width,
+ imgData->ri);
+ break;
#if SPLASH_CMYK
- case splashModeCMYK8:
- imgData->colorMap->getCMYK(p, &cmyk);
- *q++ = colToByte(cmyk.c);
- *q++ = colToByte(cmyk.m);
- *q++ = colToByte(cmyk.y);
- *q++ = colToByte(cmyk.k);
- break;
+ case splashModeCMYK8:
+ imgData->colorMap->getCMYKByteLine(p, colorLine, imgData->width,
+ imgData->ri);
+ break;
#endif
- }
- *aq++ = alpha;
}
}
@@ -2720,8 +3663,9 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
Guchar pix;
int n, i;
- setOverprintMask(colorMap->getColorSpace(), state->getFillOverprint(),
- state->getOverprintMode(), NULL);
+ setOverprintMask(state, colorMap->getColorSpace(),
+ state->getFillOverprint(), state->getOverprintMode(),
+ NULL);
ctm = state->getCTM();
reduceImageResolution(str, ctm, &width, &height);
@@ -2740,7 +3684,7 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
maskDecode.free();
drawSoftMaskedImage(state, ref, str, width, height, colorMap,
maskStr, maskWidth, maskHeight, maskColorMap,
- interpolate);
+ NULL, interpolate);
delete maskColorMap;
} else {
@@ -2761,7 +3705,10 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
imgMaskData.y = 0;
maskBitmap = new SplashBitmap(width, height, 1, splashModeMono1, gFalse);
maskSplash = new Splash(maskBitmap, gFalse);
- maskSplash->setStrokeAdjust(globalParams->getStrokeAdjust());
+ maskSplash->setStrokeAdjust(
+ mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
+ maskSplash->setEnablePathSimplification(
+ globalParams->getEnablePathSimplification());
maskColor[0] = 0;
maskSplash->clear(maskColor);
maskColor[0] = 0xff;
@@ -2787,6 +3734,7 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
colorMap->getBits());
imgData.imgStr->reset();
imgData.colorMap = colorMap;
+ imgData.ri = state->getRenderingIntent();
imgData.mask = maskBitmap;
imgData.colorMode = colorMode;
imgData.width = width;
@@ -2804,7 +3752,7 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
imgData.lookup = (SplashColorPtr)gmalloc(n);
for (i = 0; i < n; ++i) {
pix = (Guchar)i;
- colorMap->getGray(&pix, &gray);
+ colorMap->getGray(&pix, &gray, state->getRenderingIntent());
imgData.lookup[i] = colToByte(gray);
}
break;
@@ -2813,7 +3761,7 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
imgData.lookup = (SplashColorPtr)gmallocn(n, 3);
for (i = 0; i < n; ++i) {
pix = (Guchar)i;
- colorMap->getRGB(&pix, &rgb);
+ colorMap->getRGB(&pix, &rgb, state->getRenderingIntent());
imgData.lookup[3*i] = colToByte(rgb.r);
imgData.lookup[3*i+1] = colToByte(rgb.g);
imgData.lookup[3*i+2] = colToByte(rgb.b);
@@ -2824,7 +3772,7 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
imgData.lookup = (SplashColorPtr)gmallocn(n, 4);
for (i = 0; i < n; ++i) {
pix = (Guchar)i;
- colorMap->getCMYK(&pix, &cmyk);
+ colorMap->getCMYK(&pix, &cmyk, state->getRenderingIntent());
imgData.lookup[4*i] = colToByte(cmyk.c);
imgData.lookup[4*i+1] = colToByte(cmyk.m);
imgData.lookup[4*i+2] = colToByte(cmyk.y);
@@ -2852,20 +3800,118 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
}
}
+struct SplashOutSoftMaskMatteImageData {
+ ImageStream *imgStr;
+ ImageStream *maskStr;
+ GfxImageColorMap *colorMap;
+ GfxRenderingIntent ri;
+ Guchar matte[gfxColorMaxComps];
+ SplashColorPtr maskLookup;
+ SplashColorMode colorMode;
+ int width, height, y;
+};
+
+GBool SplashOutputDev::softMaskMatteImageSrc(void *data,
+ SplashColorPtr colorLine,
+ Guchar *alphaLine) {
+ SplashOutSoftMaskMatteImageData *imgData =
+ (SplashOutSoftMaskMatteImageData *)data;
+ Guchar *p, *ap, *aq;
+ SplashColorPtr q;
+ GfxRGB rgb;
+ GfxGray gray;
+#if SPLASH_CMYK
+ GfxCMYK cmyk;
+#endif
+ Guchar alpha;
+ int nComps, x;
+
+ if (imgData->y == imgData->height ||
+ !(p = imgData->imgStr->getLine()) ||
+ !(ap = imgData->maskStr->getLine())) {
+ memset(colorLine, 0,
+ imgData->width * splashColorModeNComps[imgData->colorMode]);
+ memset(alphaLine, 0, imgData->width);
+ return gFalse;
+ }
+
+ nComps = imgData->colorMap->getNumPixelComps();
+
+ for (x = 0, q = colorLine, aq = alphaLine;
+ x < imgData->width;
+ ++x, p += nComps, ++ap) {
+ alpha = *ap;
+ switch (imgData->colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ if (alpha) {
+ imgData->colorMap->getGray(p, &gray, imgData->ri);
+ *q++ = imgData->matte[0] + (255 * (colToByte(gray) -
+ imgData->matte[0])) / alpha;
+ } else {
+ *q++ = 0;
+ }
+ break;
+ case splashModeRGB8:
+ case splashModeBGR8:
+ if (alpha) {
+ imgData->colorMap->getRGB(p, &rgb, imgData->ri);
+ *q++ = imgData->matte[0] + (255 * (colToByte(rgb.r) -
+ imgData->matte[0])) / alpha;
+ *q++ = imgData->matte[1] + (255 * (colToByte(rgb.g) -
+ imgData->matte[1])) / alpha;
+ *q++ = imgData->matte[2] + (255 * (colToByte(rgb.b) -
+ imgData->matte[2])) / alpha;
+ } else {
+ *q++ = 0;
+ *q++ = 0;
+ *q++ = 0;
+ }
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ if (alpha) {
+ imgData->colorMap->getCMYK(p, &cmyk, imgData->ri);
+ *q++ = imgData->matte[0] + (255 * (colToByte(cmyk.c) -
+ imgData->matte[0])) / alpha;
+ *q++ = imgData->matte[1] + (255 * (colToByte(cmyk.m) -
+ imgData->matte[1])) / alpha;
+ *q++ = imgData->matte[2] + (255 * (colToByte(cmyk.y) -
+ imgData->matte[2])) / alpha;
+ *q++ = imgData->matte[3] + (255 * (colToByte(cmyk.k) -
+ imgData->matte[3])) / alpha;
+ } else {
+ *q++ = 0;
+ *q++ = 0;
+ *q++ = 0;
+ *q++ = 0;
+ }
+ break;
+#endif
+ }
+ *aq++ = alpha;
+ }
+
+ ++imgData->y;
+ return gTrue;
+}
+
void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
Stream *str, int width, int height,
GfxImageColorMap *colorMap,
Stream *maskStr,
int maskWidth, int maskHeight,
GfxImageColorMap *maskColorMap,
- GBool interpolate) {
+ double *matte, GBool interpolate) {
double *ctm;
SplashCoord mat[6];
SplashOutImageData imgData;
SplashOutImageData imgMaskData;
+ SplashOutSoftMaskMatteImageData matteImgData;
SplashColorMode srcMode;
SplashBitmap *maskBitmap;
Splash *maskSplash;
+ GfxColor matteColor;
GfxGray gray;
GfxRGB rgb;
#if SPLASH_CMYK
@@ -2874,8 +3920,9 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
Guchar pix;
int n, i;
- setOverprintMask(colorMap->getColorSpace(), state->getFillOverprint(),
- state->getOverprintMode(), NULL);
+ setOverprintMask(state, colorMap->getColorSpace(),
+ state->getFillOverprint(), state->getOverprintMode(),
+ NULL);
ctm = state->getCTM();
mat[0] = ctm[0];
@@ -2885,110 +3932,189 @@ void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
mat[4] = ctm[2] + ctm[4];
mat[5] = ctm[3] + ctm[5];
- reduceImageResolution(str, ctm, &width, &height);
- reduceImageResolution(maskStr, ctm, &maskWidth, &maskHeight);
-
- //----- set up the soft mask
-
- imgMaskData.imgStr = new ImageStream(maskStr, maskWidth,
- maskColorMap->getNumPixelComps(),
- maskColorMap->getBits());
- imgMaskData.imgStr->reset();
- imgMaskData.colorMap = maskColorMap;
- imgMaskData.maskColors = NULL;
- imgMaskData.colorMode = splashModeMono8;
- imgMaskData.width = maskWidth;
- imgMaskData.height = maskHeight;
- imgMaskData.y = 0;
- n = 1 << maskColorMap->getBits();
- imgMaskData.lookup = (SplashColorPtr)gmalloc(n);
- for (i = 0; i < n; ++i) {
- pix = (Guchar)i;
- maskColorMap->getGray(&pix, &gray);
- imgMaskData.lookup[i] = colToByte(gray);
+ if (colorMode == splashModeMono1) {
+ srcMode = splashModeMono8;
+ } else if (colorMode == splashModeBGR8) {
+ srcMode = splashModeRGB8;
+ } else {
+ srcMode = colorMode;
}
- maskBitmap = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
- 1, splashModeMono8, gFalse);
- maskSplash = new Splash(maskBitmap, vectorAntialias);
- maskSplash->setStrokeAdjust(globalParams->getStrokeAdjust());
- clearMaskRegion(state, maskSplash, 0, 0, 1, 1);
- maskSplash->drawImage(&imageSrc, &imgMaskData, splashModeMono8, gFalse,
- maskWidth, maskHeight, mat, interpolate);
- delete imgMaskData.imgStr;
- maskStr->close();
- gfree(imgMaskData.lookup);
- delete maskSplash;
- splash->setSoftMask(maskBitmap);
-
- //----- draw the source image
-
- imgData.imgStr = new ImageStream(str, width,
- colorMap->getNumPixelComps(),
- colorMap->getBits());
- imgData.imgStr->reset();
- imgData.colorMap = colorMap;
- imgData.maskColors = NULL;
- imgData.colorMode = colorMode;
- imgData.width = width;
- imgData.height = height;
- imgData.y = 0;
- // special case for one-channel (monochrome/gray/separation) images:
- // build a lookup table here
- imgData.lookup = NULL;
- if (colorMap->getNumPixelComps() == 1) {
- n = 1 << colorMap->getBits();
+ //----- handle a preblended image
+
+ if (matte && width == maskWidth && height == maskHeight) {
+
+ // the image and mask must be the same size, so don't call
+ // reduceImageResolution(), which might result in different
+ // reductions (e.g., if the image filter supports resolution
+ // reduction but the mask filter doesn't)
+
+ matteImgData.imgStr = new ImageStream(str, width,
+ colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ matteImgData.imgStr->reset();
+ matteImgData.maskStr = new ImageStream(maskStr, maskWidth,
+ maskColorMap->getNumPixelComps(),
+ maskColorMap->getBits());
+ matteImgData.maskStr->reset();
+ matteImgData.colorMap = colorMap;
+ matteImgData.ri = state->getRenderingIntent();
+ n = colorMap->getNumPixelComps();
+ for (i = 0; i < n; ++i) {
+ matteColor.c[i] = dblToCol(matte[i]);
+ }
switch (colorMode) {
case splashModeMono1:
case splashModeMono8:
- imgData.lookup = (SplashColorPtr)gmalloc(n);
- for (i = 0; i < n; ++i) {
- pix = (Guchar)i;
- colorMap->getGray(&pix, &gray);
- imgData.lookup[i] = colToByte(gray);
- }
+ colorMap->getColorSpace()->getGray(&matteColor, &gray,
+ state->getRenderingIntent());
+ matteImgData.matte[0] = colToByte(gray);
break;
case splashModeRGB8:
case splashModeBGR8:
- imgData.lookup = (SplashColorPtr)gmallocn(n, 3);
- for (i = 0; i < n; ++i) {
- pix = (Guchar)i;
- colorMap->getRGB(&pix, &rgb);
- imgData.lookup[3*i] = colToByte(rgb.r);
- imgData.lookup[3*i+1] = colToByte(rgb.g);
- imgData.lookup[3*i+2] = colToByte(rgb.b);
- }
+ colorMap->getColorSpace()->getRGB(&matteColor, &rgb,
+ state->getRenderingIntent());
+ matteImgData.matte[0] = colToByte(rgb.r);
+ matteImgData.matte[1] = colToByte(rgb.g);
+ matteImgData.matte[2] = colToByte(rgb.b);
break;
#if SPLASH_CMYK
case splashModeCMYK8:
- imgData.lookup = (SplashColorPtr)gmallocn(n, 4);
- for (i = 0; i < n; ++i) {
- pix = (Guchar)i;
- colorMap->getCMYK(&pix, &cmyk);
- imgData.lookup[4*i] = colToByte(cmyk.c);
- imgData.lookup[4*i+1] = colToByte(cmyk.m);
- imgData.lookup[4*i+2] = colToByte(cmyk.y);
- imgData.lookup[4*i+3] = colToByte(cmyk.k);
- }
+ colorMap->getColorSpace()->getCMYK(&matteColor, &cmyk,
+ state->getRenderingIntent());
+ matteImgData.matte[0] = colToByte(cmyk.c);
+ matteImgData.matte[1] = colToByte(cmyk.m);
+ matteImgData.matte[2] = colToByte(cmyk.y);
+ matteImgData.matte[3] = colToByte(cmyk.k);
break;
#endif
}
- }
+ //~ could add the matteImgData.lookup special case
+ n = 1 << maskColorMap->getBits();
+ matteImgData.maskLookup = (SplashColorPtr)gmalloc(n);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ maskColorMap->getGray(&pix, &gray,
+ state->getRenderingIntent());
+ matteImgData.maskLookup[i] = colToByte(gray);
+ }
+ matteImgData.colorMode = colorMode;
+ matteImgData.width = width;
+ matteImgData.height = height;
+ matteImgData.y = 0;
+ splash->drawImage(&softMaskMatteImageSrc, &matteImgData,
+ srcMode, gTrue, width, height, mat, interpolate);
+ gfree(matteImgData.maskLookup);
+ delete matteImgData.maskStr;
+ delete matteImgData.imgStr;
+ maskStr->close();
+ str->close();
- if (colorMode == splashModeMono1) {
- srcMode = splashModeMono8;
- } else if (colorMode == splashModeBGR8) {
- srcMode = splashModeRGB8;
} else {
- srcMode = colorMode;
- }
- splash->drawImage(&imageSrc, &imgData, srcMode, gFalse, width, height, mat,
- interpolate);
- splash->setSoftMask(NULL);
- gfree(imgData.lookup);
- delete imgData.imgStr;
- str->close();
+ reduceImageResolution(str, ctm, &width, &height);
+ reduceImageResolution(maskStr, ctm, &maskWidth, &maskHeight);
+
+ //----- set up the soft mask
+
+ imgMaskData.imgStr = new ImageStream(maskStr, maskWidth,
+ maskColorMap->getNumPixelComps(),
+ maskColorMap->getBits());
+ imgMaskData.imgStr->reset();
+ imgMaskData.colorMap = maskColorMap;
+ imgMaskData.ri = state->getRenderingIntent();
+ imgMaskData.maskColors = NULL;
+ imgMaskData.colorMode = splashModeMono8;
+ imgMaskData.width = maskWidth;
+ imgMaskData.height = maskHeight;
+ imgMaskData.y = 0;
+ n = 1 << maskColorMap->getBits();
+ imgMaskData.lookup = (SplashColorPtr)gmalloc(n);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ maskColorMap->getGray(&pix, &gray, state->getRenderingIntent());
+ imgMaskData.lookup[i] = colToByte(gray);
+ }
+ maskBitmap = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
+ 1, splashModeMono8, gFalse);
+ maskSplash = new Splash(maskBitmap, vectorAntialias);
+ maskSplash->setStrokeAdjust(
+ mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
+ maskSplash->setEnablePathSimplification(
+ globalParams->getEnablePathSimplification());
+ clearMaskRegion(state, maskSplash, 0, 0, 1, 1);
+ maskSplash->drawImage(&imageSrc, &imgMaskData, splashModeMono8, gFalse,
+ maskWidth, maskHeight, mat, interpolate);
+ delete imgMaskData.imgStr;
+ maskStr->close();
+ gfree(imgMaskData.lookup);
+ delete maskSplash;
+ splash->setSoftMask(maskBitmap);
+
+ //----- draw the source image
+
+ imgData.imgStr = new ImageStream(str, width,
+ colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgData.imgStr->reset();
+ imgData.colorMap = colorMap;
+ imgData.ri = state->getRenderingIntent();
+ imgData.maskColors = NULL;
+ imgData.colorMode = colorMode;
+ imgData.width = width;
+ imgData.height = height;
+ imgData.y = 0;
+
+ // special case for one-channel (monochrome/gray/separation) images:
+ // build a lookup table here
+ imgData.lookup = NULL;
+ if (colorMap->getNumPixelComps() == 1) {
+ n = 1 << colorMap->getBits();
+ switch (colorMode) {
+ case splashModeMono1:
+ case splashModeMono8:
+ imgData.lookup = (SplashColorPtr)gmalloc(n);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getGray(&pix, &gray, state->getRenderingIntent());
+ imgData.lookup[i] = colToByte(gray);
+ }
+ break;
+ case splashModeRGB8:
+ case splashModeBGR8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n, 3);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getRGB(&pix, &rgb, state->getRenderingIntent());
+ imgData.lookup[3*i] = colToByte(rgb.r);
+ imgData.lookup[3*i+1] = colToByte(rgb.g);
+ imgData.lookup[3*i+2] = colToByte(rgb.b);
+ }
+ break;
+#if SPLASH_CMYK
+ case splashModeCMYK8:
+ imgData.lookup = (SplashColorPtr)gmallocn(n, 4);
+ for (i = 0; i < n; ++i) {
+ pix = (Guchar)i;
+ colorMap->getCMYK(&pix, &cmyk, state->getRenderingIntent());
+ imgData.lookup[4*i] = colToByte(cmyk.c);
+ imgData.lookup[4*i+1] = colToByte(cmyk.m);
+ imgData.lookup[4*i+2] = colToByte(cmyk.y);
+ imgData.lookup[4*i+3] = colToByte(cmyk.k);
+ }
+ break;
+#endif
+ }
+ }
+
+ splash->drawImage(&imageSrc, &imgData, srcMode, gFalse, width, height, mat,
+ interpolate);
+
+ splash->setSoftMask(NULL);
+ gfree(imgData.lookup);
+ delete imgData.imgStr;
+ str->close();
+ }
}
void SplashOutputDev::reduceImageResolution(Stream *str, double *ctm,
@@ -3088,6 +4214,7 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
GBool isolated, GBool knockout,
GBool forSoftMask) {
SplashTransparencyGroup *transpGroup;
+ SplashBitmap *backdropBitmap;
SplashColor color;
double xMin, yMin, xMax, yMax, x, y;
int tx, ty, w, h, i;
@@ -3129,6 +4256,26 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
} else if (y > yMax) {
yMax = y;
}
+
+ // clip the box
+ x = splash->getClip()->getXMin();
+ if (x > xMin) {
+ xMin = x;
+ }
+ x = splash->getClip()->getXMax();
+ if (x < xMax) {
+ xMax = x;
+ }
+ y = splash->getClip()->getYMin();
+ if (y > yMin) {
+ yMin = y;
+ }
+ y = splash->getClip()->getYMax();
+ if (y < yMax) {
+ yMax = y;
+ }
+
+ // convert box coords to integers
tx = (int)floor(xMin);
if (tx < 0) {
tx = 0;
@@ -3200,7 +4347,10 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
splash = new Splash(bitmap, vectorAntialias,
transpGroup->origSplash->getScreen());
splash->setMinLineWidth(globalParams->getMinLineWidth());
- splash->setStrokeAdjust(globalParams->getStrokeAdjust());
+ splash->setStrokeAdjust(
+ mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
+ splash->setEnablePathSimplification(
+ globalParams->getEnablePathSimplification());
//~ Acrobat apparently copies at least the fill and stroke colors, and
//~ maybe other state(?) -- but not the clipping path (and not sure
//~ what else)
@@ -3208,6 +4358,9 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
splash->setFillPattern(transpGroup->origSplash->getFillPattern()->copy());
splash->setStrokePattern(
transpGroup->origSplash->getStrokePattern()->copy());
+ splash->setLineDash(transpGroup->origSplash->getLineDash(),
+ transpGroup->origSplash->getLineDashLength(),
+ transpGroup->origSplash->getLineDashPhase());
if (isolated) {
for (i = 0; i < splashMaxColorComps; ++i) {
color[i] = 0;
@@ -3216,8 +4369,24 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
} else {
splash->blitTransparent(transpGroup->origBitmap, tx, ty, 0, 0, w, h);
}
- splash->setInTransparencyGroup(transpGroup->origBitmap, tx, ty,
- !isolated, knockout);
+ if (!isolated &&
+ transpGroup->origBitmap->getAlphaPtr() &&
+ transpGroup->origSplash->getInNonIsolatedGroup()) {
+ // 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);
+ transpGroup->origSplash->blitCorrectedAlpha(backdropBitmap,
+ tx, ty, 0, 0, w, h);
+ transpGroup->backdropBitmap = backdropBitmap;
+ splash->setInTransparencyGroup(backdropBitmap, 0, 0,
+ !isolated, knockout);
+ } else {
+ backdropBitmap = transpGroup->origBitmap;
+ transpGroup->backdropBitmap = NULL;
+ splash->setInTransparencyGroup(backdropBitmap, tx, ty,
+ !isolated, knockout);
+ }
transpGroup->tBitmap = bitmap;
state->shiftCTM(-tx, -ty);
updateCTM(state, 0, 0, 0, 0, 0, 0);
@@ -3255,6 +4424,11 @@ void SplashOutputDev::paintTransparencyGroup(GfxState *state, double *bbox) {
gFalse, !isolated);
}
+ // free the temporary backdrop bitmap
+ if (transpGroupStack->backdropBitmap) {
+ delete transpGroupStack->backdropBitmap;
+ }
+
// pop the stack
transpGroup = transpGroupStack;
transpGroupStack = transpGroup->next;
@@ -3290,21 +4464,26 @@ void SplashOutputDev::setSoftMask(GfxState *state, double *bbox,
//~ space is given
tSplash = new Splash(tBitmap, vectorAntialias,
transpGroupStack->origSplash->getScreen());
- tSplash->setStrokeAdjust(globalParams->getStrokeAdjust());
+ tSplash->setStrokeAdjust(
+ mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
+ tSplash->setEnablePathSimplification(
+ globalParams->getEnablePathSimplification());
if (transpGroupStack->blendingColorSpace) {
switch (tBitmap->getMode()) {
case splashModeMono1:
// transparency is not supported in mono1 mode
break;
case splashModeMono8:
- transpGroupStack->blendingColorSpace->getGray(backdropColor, &gray);
+ transpGroupStack->blendingColorSpace->getGray(
+ backdropColor, &gray, state->getRenderingIntent());
backdrop = colToDbl(gray);
color[0] = colToByte(gray);
tSplash->compositeBackground(color);
break;
case splashModeRGB8:
case splashModeBGR8:
- transpGroupStack->blendingColorSpace->getRGB(backdropColor, &rgb);
+ transpGroupStack->blendingColorSpace->getRGB(
+ backdropColor, &rgb, state->getRenderingIntent());
backdrop = 0.3 * colToDbl(rgb.r) +
0.59 * colToDbl(rgb.g) +
0.11 * colToDbl(rgb.b);
@@ -3315,7 +4494,8 @@ void SplashOutputDev::setSoftMask(GfxState *state, double *bbox,
break;
#if SPLASH_CMYK
case splashModeCMYK8:
- transpGroupStack->blendingColorSpace->getCMYK(backdropColor, &cmyk);
+ transpGroupStack->blendingColorSpace->getCMYK(
+ backdropColor, &cmyk, state->getRenderingIntent());
backdrop = (1 - colToDbl(cmyk.k))
- 0.3 * colToDbl(cmyk.c)
- 0.59 * colToDbl(cmyk.m)
@@ -3389,6 +4569,11 @@ void SplashOutputDev::setSoftMask(GfxState *state, double *bbox,
}
splash->setSoftMask(softMask);
+ // free the temporary backdrop bitmap
+ if (transpGroupStack->backdropBitmap) {
+ delete transpGroupStack->backdropBitmap;
+ }
+
// pop the stack
transpGroup = transpGroupStack;
transpGroupStack = transpGroup->next;
@@ -3483,7 +4668,7 @@ SplashFont *SplashOutputDev::getFont(GString *name, SplashCoord *textMatA) {
Unicode u;
SplashCoord textMat[4];
SplashCoord oblique;
- int cmap, i;
+ int cmap, cmapPlatform, cmapEncoding, i;
for (i = 0; i < nBuiltinFonts; ++i) {
if (!name->cmp(builtinFonts[i].name)) {
@@ -3545,9 +4730,10 @@ SplashFont *SplashOutputDev::getFont(GString *name, SplashCoord *textMatA) {
return NULL;
}
for (cmap = 0; cmap < ff->getNumCmaps(); ++cmap) {
- if ((ff->getCmapPlatform(cmap) == 3 &&
- ff->getCmapEncoding(cmap) == 1) ||
- ff->getCmapPlatform(cmap) == 0) {
+ cmapPlatform = ff->getCmapPlatform(cmap);
+ cmapEncoding = ff->getCmapEncoding(cmap);
+ if ((cmapPlatform == 3 && cmapEncoding == 1) ||
+ (cmapPlatform == 0 && cmapEncoding <= 4)) {
break;
}
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
index ebbf8a1bb4e..6f26c7eeb2b 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.h
@@ -68,6 +68,11 @@ public:
// operations.
virtual GBool useTilingPatternFill() { return gTrue; }
+ // Does this device use functionShadedFill(), axialShadedFill(), and
+ // radialShadedFill()? If this returns false, these shaded fills
+ // will be reduced to a series of other drawing operations.
+ virtual GBool useShadedFills() { return gTrue; }
+
// Does this device use beginType3Char/endType3Char? Otherwise,
// text in Type 3 fonts will be drawn with drawChar/drawString.
virtual GBool interpretType3Chars() { return gTrue; }
@@ -101,6 +106,7 @@ public:
virtual void updateBlendMode(GfxState *state);
virtual void updateFillOpacity(GfxState *state);
virtual void updateStrokeOpacity(GfxState *state);
+ virtual void updateRenderingIntent(GfxState *state);
virtual void updateTransfer(GfxState *state);
//----- update text state
@@ -111,10 +117,12 @@ public:
virtual void fill(GfxState *state);
virtual void eoFill(GfxState *state);
virtual void tilingPatternFill(GfxState *state, Gfx *gfx, Object *strRef,
- int paintType, Dict *resDict,
+ int paintType, int tilingType, Dict *resDict,
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
double xStep, double yStep);
+ virtual GBool axialShadedFill(GfxState *state, GfxAxialShading *shading);
+ virtual GBool radialShadedFill(GfxState *state, GfxRadialShading *shading);
//----- path clipping
virtual void clip(GfxState *state);
@@ -154,7 +162,7 @@ public:
Stream *maskStr,
int maskWidth, int maskHeight,
GfxImageColorMap *maskColorMap,
- GBool interpolate);
+ double *matte, GBool interpolate);
//----- Type 3 font operators
virtual void type3D0(GfxState *state, double wx, double wy);
@@ -176,6 +184,9 @@ public:
// Called to indicate that a new PDF document has been loaded.
void startDoc(XRef *xrefA);
+
+ void setStartPageCallback(void (*cbk)(void *data), void *data)
+ { startPageCbk = cbk; startPageCbkData = data; }
void setPaperColor(SplashColorPtr paperColorA);
@@ -224,6 +235,9 @@ public:
int getNestCount() { return nestCount; }
+ // Get the screen parameters.
+ SplashScreenParams *getScreenParams() { return &screenParams; }
+
#if 1 //~tmp: turn off anti-aliasing temporarily
virtual void setInShading(GBool sh);
#endif
@@ -236,8 +250,18 @@ private:
#if SPLASH_CMYK
SplashPattern *getColor(GfxCMYK *cmyk);
#endif
- void setOverprintMask(GfxColorSpace *colorSpace, GBool overprintFlag,
- int overprintMode, GfxColor *singleColor);
+ void getColor(GfxGray gray, SplashColorPtr color);
+ void getColor(GfxRGB *rgb, SplashColorPtr color);
+#if SPLASH_CMYK
+ void getColor(GfxCMYK *cmyk, SplashColorPtr color);
+#endif
+ void setOverprintMask(GfxState *state, GfxColorSpace *colorSpace,
+ GBool overprintFlag, int overprintMode,
+ GfxColor *singleColor);
+ void computeShadingColor(GfxState *state,
+ SplashColorMode mode,
+ GfxColor *color,
+ SplashColorPtr sColor);
SplashPath *convertPath(GfxState *state, GfxPath *path,
GBool dropEmptySubpaths);
void doUpdateFont(GfxState *state);
@@ -250,6 +274,9 @@ private:
Guchar *alphaLine);
static GBool maskedImageSrc(void *data, SplashColorPtr line,
Guchar *alphaLine);
+ static GBool softMaskMatteImageSrc(void *data,
+ SplashColorPtr colorLine,
+ Guchar *alphaLine);
void reduceImageResolution(Stream *str, double *mat,
int *width, int *height);
void clearMaskRegion(GfxState *state,
@@ -289,6 +316,9 @@ private:
transpGroupStack;
int nestCount;
+
+ void (*startPageCbk)(void *data);
+ void *startPageCbkData;
};
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
index 71029669e1f..a4a626f9798 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.cc
@@ -16,13 +16,19 @@
#include <stdlib.h>
#include <stddef.h>
#include <limits.h>
-#ifndef _WIN32
+#ifdef _WIN32
+#include <io.h>
+#else
#include <unistd.h>
#endif
#include <string.h>
#include <ctype.h>
#include "gmem.h"
+#include "gmempp.h"
#include "gfile.h"
+#if MULTITHREADED
+#include "GMutex.h"
+#endif
#include "config.h"
#include "Error.h"
#include "Object.h"
@@ -50,7 +56,6 @@ static GBool setDJSYSFLAGS = gFalse;
//------------------------------------------------------------------------
Stream::Stream() {
- ref = 1;
}
Stream::~Stream() {
@@ -653,24 +658,132 @@ GBool StreamPredictor::getNextLine() {
}
//------------------------------------------------------------------------
+// SharedFile
+//------------------------------------------------------------------------
+
+class SharedFile {
+public:
+
+ SharedFile(FILE *fA);
+ SharedFile *copy();
+ void free();
+ int readBlock(char *buf, GFileOffset pos, int size);
+ GFileOffset getSize();
+
+private:
+
+ ~SharedFile();
+
+ FILE *f;
+ int refCnt;
+#if MULTITHREADED
+ GMutex mutex;
+#endif
+};
+
+SharedFile::SharedFile(FILE *fA) {
+ f = fA;
+ refCnt = 1;
+#if MULTITHREADED
+ gInitMutex(&mutex);
+#endif
+}
+
+SharedFile::~SharedFile() {
+#if MULTITHREADED
+ gDestroyMutex(&mutex);
+#endif
+}
+
+SharedFile *SharedFile::copy() {
+#if MULTITHREADED
+ gLockMutex(&mutex);
+#endif
+ ++refCnt;
+#if MULTITHREADED
+ gUnlockMutex(&mutex);
+#endif
+ return this;
+}
+
+void SharedFile::free() {
+ int newCount;
+
+#if MULTITHREADED
+ gLockMutex(&mutex);
+#endif
+ newCount = --refCnt;
+#if MULTITHREADED
+ gUnlockMutex(&mutex);
+#endif
+ if (newCount == 0) {
+ delete this;
+ }
+}
+
+int SharedFile::readBlock(char *buf, GFileOffset pos, int size) {
+ int n;
+
+#if MULTITHREADED
+ gLockMutex(&mutex);
+#endif
+ gfseek(f, pos, SEEK_SET);
+ n = (int)fread(buf, 1, size, f);
+#if MULTITHREADED
+ gUnlockMutex(&mutex);
+#endif
+ return n;
+}
+
+GFileOffset SharedFile::getSize() {
+ GFileOffset size;
+
+#if MULTITHREADED
+ gLockMutex(&mutex);
+#endif
+ gfseek(f, 0, SEEK_END);
+ size = gftell(f);
+#if MULTITHREADED
+ gUnlockMutex(&mutex);
+#endif
+ return size;
+}
+
+//------------------------------------------------------------------------
// FileStream
//------------------------------------------------------------------------
FileStream::FileStream(FILE *fA, GFileOffset startA, GBool limitedA,
GFileOffset lengthA, Object *dictA):
BaseStream(dictA) {
- f = fA;
+ f = new SharedFile(fA);
+ start = startA;
+ limited = limitedA;
+ length = lengthA;
+ bufPtr = bufEnd = buf;
+ bufPos = start;
+}
+
+FileStream::FileStream(SharedFile *fA, GFileOffset startA, GBool limitedA,
+ GFileOffset lengthA, Object *dictA):
+ BaseStream(dictA) {
+ f = fA->copy();
start = startA;
limited = limitedA;
length = lengthA;
bufPtr = bufEnd = buf;
bufPos = start;
- savePos = 0;
- saved = gFalse;
}
FileStream::~FileStream() {
- close();
+ f->free();
+}
+
+Stream *FileStream::copy() {
+ Object dictA;
+
+ dict.copy(&dictA);
+ return new FileStream(f, start, limited, length, &dictA);
}
Stream *FileStream::makeSubStream(GFileOffset startA, GBool limitedA,
@@ -679,20 +792,10 @@ Stream *FileStream::makeSubStream(GFileOffset startA, GBool limitedA,
}
void FileStream::reset() {
- savePos = gftell(f);
- gfseek(f, start, SEEK_SET);
- saved = gTrue;
bufPtr = bufEnd = buf;
bufPos = start;
}
-void FileStream::close() {
- if (saved) {
- gfseek(f, savePos, SEEK_SET);
- saved = gFalse;
- }
-}
-
int FileStream::getBlock(char *blk, int size) {
int n, m;
@@ -727,7 +830,7 @@ GBool FileStream::fillBuf() {
} else {
n = fileStreamBufSize;
}
- n = (int)fread(buf, 1, n, f);
+ n = f->readBlock(buf, bufPos, n);
bufEnd = buf + n;
if (bufPtr >= bufEnd) {
return gFalse;
@@ -739,16 +842,14 @@ void FileStream::setPos(GFileOffset pos, int dir) {
GFileOffset size;
if (dir >= 0) {
- gfseek(f, pos, SEEK_SET);
bufPos = pos;
} else {
- gfseek(f, 0, SEEK_END);
- size = gftell(f);
- if (pos > size) {
- pos = size;
+ size = f->getSize();
+ if (pos <= size) {
+ bufPos = size - pos;
+ } else {
+ bufPos = 0;
}
- gfseek(f, -pos, SEEK_END);
- bufPos = gftell(f);
}
bufPtr = bufEnd = buf;
}
@@ -779,6 +880,13 @@ MemStream::~MemStream() {
}
}
+Stream *MemStream::copy() {
+ Object dictA;
+
+ dict.copy(&dictA);
+ return new MemStream(buf, start, length, &dictA);
+}
+
Stream *MemStream::makeSubStream(GFileOffset startA, GBool limited,
GFileOffset lengthA, Object *dictA) {
MemStream *subStr;
@@ -860,6 +968,13 @@ EmbedStream::EmbedStream(Stream *strA, Object *dictA,
EmbedStream::~EmbedStream() {
}
+Stream *EmbedStream::copy() {
+ Object dictA;
+
+ dict.copy(&dictA);
+ return new EmbedStream(str, &dictA, limited, length);
+}
+
Stream *EmbedStream::makeSubStream(GFileOffset start, GBool limitedA,
GFileOffset lengthA, Object *dictA) {
error(errInternal, -1, "Called makeSubStream() on EmbedStream");
@@ -888,6 +1003,7 @@ int EmbedStream::getBlock(char *blk, int size) {
if (limited && length < (Guint)size) {
size = (int)length;
}
+ length -= size;
return str->getBlock(blk, size);
}
@@ -918,6 +1034,10 @@ ASCIIHexStream::~ASCIIHexStream() {
delete str;
}
+Stream *ASCIIHexStream::copy() {
+ return new ASCIIHexStream(str->copy());
+}
+
void ASCIIHexStream::reset() {
str->reset();
buf = EOF;
@@ -1010,6 +1130,10 @@ ASCII85Stream::~ASCII85Stream() {
delete str;
}
+Stream *ASCII85Stream::copy() {
+ return new ASCII85Stream(str->copy());
+}
+
void ASCII85Stream::reset() {
str->reset();
index = n = 0;
@@ -1106,6 +1230,16 @@ LZWStream::~LZWStream() {
delete str;
}
+Stream *LZWStream::copy() {
+ if (pred) {
+ return new LZWStream(str->copy(), pred->getPredictor(),
+ pred->getWidth(), pred->getNComps(),
+ pred->getNBits(), early);
+ } else {
+ return new LZWStream(str->copy(), 1, 0, 0, 0, early);
+ }
+}
+
int LZWStream::getChar() {
if (pred) {
return pred->getChar();
@@ -1312,6 +1446,10 @@ RunLengthStream::~RunLengthStream() {
delete str;
}
+Stream *RunLengthStream::copy() {
+ return new RunLengthStream(str->copy());
+}
+
void RunLengthStream::reset() {
str->reset();
bufPtr = bufEnd = buf;
@@ -1402,6 +1540,7 @@ CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
rows = rowsA;
endOfBlock = endOfBlockA;
black = blackA;
+ blackXOR = black ? 0xff : 0x00;
// 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = columns
// ---> max codingLine size = columns + 1
// refLine has one extra guard entry at the end
@@ -1414,10 +1553,8 @@ CCITTFaxStream::CCITTFaxStream(Stream *strA, int encodingA, GBool endOfLineA,
nextLine2D = encoding < 0;
inputBits = 0;
codingLine[0] = columns;
+ nextCol = columns;
a0i = 0;
- outputBits = 0;
-
- buf = EOF;
}
CCITTFaxStream::~CCITTFaxStream() {
@@ -1426,6 +1563,11 @@ CCITTFaxStream::~CCITTFaxStream() {
gfree(codingLine);
}
+Stream *CCITTFaxStream::copy() {
+ return new CCITTFaxStream(str->copy(), encoding, endOfLine,
+ byteAlign, columns, rows, endOfBlock, black);
+}
+
void CCITTFaxStream::reset() {
int code1;
@@ -1435,9 +1577,8 @@ void CCITTFaxStream::reset() {
nextLine2D = encoding < 0;
inputBits = 0;
codingLine[0] = columns;
+ nextCol = columns;
a0i = 0;
- outputBits = 0;
- buf = EOF;
// skip any initial zero bits and end-of-line marker, and get the 2D
// encoding tag
@@ -1454,6 +1595,130 @@ void CCITTFaxStream::reset() {
}
}
+int CCITTFaxStream::getChar() {
+ int c, bitsNeeded, bitsAvail, bitsUsed;
+
+ if (nextCol >= columns) {
+ if (eof) {
+ return EOF;
+ }
+ if (!readRow()) {
+ return EOF;
+ }
+ }
+ bitsAvail = codingLine[a0i] - nextCol;
+ if (bitsAvail > 8) {
+ c = (a0i & 1) ? 0x00 : 0xff;
+ } else {
+ c = 0;
+ bitsNeeded = 8;
+ do {
+ bitsUsed = (bitsAvail < bitsNeeded) ? bitsAvail : bitsNeeded;
+ c <<= bitsUsed;
+ if (!(a0i & 1)) {
+ c |= 0xff >> (8 - bitsUsed);
+ }
+ bitsAvail -= bitsUsed;
+ bitsNeeded -= bitsUsed;
+ if (bitsAvail == 0) {
+ if (codingLine[a0i] >= columns) {
+ c <<= bitsNeeded;
+ break;
+ }
+ ++a0i;
+ bitsAvail = codingLine[a0i] - codingLine[a0i - 1];
+ }
+ } while (bitsNeeded > 0);
+ }
+ nextCol += 8;
+ c ^= blackXOR;
+ return c;
+}
+
+int CCITTFaxStream::lookChar() {
+ int c, bitsNeeded, bitsAvail, bitsUsed, i;
+
+ if (nextCol >= columns) {
+ if (eof) {
+ return EOF;
+ }
+ if (!readRow()) {
+ return EOF;
+ }
+ }
+ bitsAvail = codingLine[a0i] - nextCol;
+ if (bitsAvail >= 8) {
+ c = (a0i & 1) ? 0x00 : 0xff;
+ } else {
+ i = a0i;
+ c = 0;
+ bitsNeeded = 8;
+ do {
+ bitsUsed = (bitsAvail < bitsNeeded) ? bitsAvail : bitsNeeded;
+ c <<= bitsUsed;
+ if (!(i & 1)) {
+ c |= 0xff >> (8 - bitsUsed);
+ }
+ bitsAvail -= bitsUsed;
+ bitsNeeded -= bitsUsed;
+ if (bitsAvail == 0) {
+ if (codingLine[i] >= columns) {
+ c <<= bitsNeeded;
+ break;
+ }
+ ++i;
+ bitsAvail = codingLine[i] - codingLine[i - 1];
+ }
+ } while (bitsNeeded > 0);
+ }
+ c ^= blackXOR;
+ return c;
+}
+
+int CCITTFaxStream::getBlock(char *blk, int size) {
+ int bytesRead, bitsAvail, bitsNeeded, bitsUsed, byte, c;
+
+ bytesRead = 0;
+ while (bytesRead < size) {
+ if (nextCol >= columns) {
+ if (eof) {
+ break;
+ }
+ if (!readRow()) {
+ break;
+ }
+ }
+ bitsAvail = codingLine[a0i] - nextCol;
+ byte = (a0i & 1) ? 0x00 : 0xff;
+ if (bitsAvail > 8) {
+ c = byte;
+ bitsAvail -= 8;
+ } else {
+ c = 0;
+ bitsNeeded = 8;
+ do {
+ bitsUsed = (bitsAvail < bitsNeeded) ? bitsAvail : bitsNeeded;
+ c <<= bitsUsed;
+ c |= byte >> (8 - bitsUsed);
+ bitsAvail -= bitsUsed;
+ bitsNeeded -= bitsUsed;
+ if (bitsAvail == 0) {
+ if (codingLine[a0i] >= columns) {
+ c <<= bitsNeeded;
+ break;
+ }
+ ++a0i;
+ bitsAvail = codingLine[a0i] - codingLine[a0i - 1];
+ byte ^= 0xff;
+ }
+ } while (bitsNeeded > 0);
+ }
+ nextCol += 8;
+ blk[bytesRead++] = c ^ blackXOR;
+ }
+ return bytesRead;
+}
+
inline void CCITTFaxStream::addPixels(int a1, int blackPixels) {
if (a1 > codingLine[a0i]) {
if (a1 > columns) {
@@ -1494,351 +1759,301 @@ inline void CCITTFaxStream::addPixelsNeg(int a1, int blackPixels) {
}
}
-int CCITTFaxStream::lookChar() {
+GBool CCITTFaxStream::readRow() {
int code1, code2, code3;
- int b1i, blackPixels, i, bits;
+ int b1i, blackPixels, i;
GBool gotEOL;
- if (buf != EOF) {
- return buf;
+ // if at eof just return EOF
+ if (eof) {
+ return gFalse;
}
- // read the next row
- if (outputBits == 0) {
-
- // if at eof just return EOF
- if (eof) {
- return EOF;
- }
-
- err = gFalse;
-
- // 2-D encoding
- if (nextLine2D) {
- for (i = 0; codingLine[i] < columns; ++i) {
- refLine[i] = codingLine[i];
- }
- refLine[i++] = columns;
- refLine[i] = columns;
- codingLine[0] = 0;
- a0i = 0;
- b1i = 0;
- blackPixels = 0;
- // invariant:
- // refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1]
- // <= columns
- // exception at left edge:
- // codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
- // exception at right edge:
- // refLine[b1i] = refLine[b1i+1] = columns is possible
- while (codingLine[a0i] < columns) {
- code1 = getTwoDimCode();
- switch (code1) {
- case twoDimPass:
- addPixels(refLine[b1i + 1], blackPixels);
- if (refLine[b1i + 1] < columns) {
+ err = gFalse;
+
+ // 2-D encoding
+ if (nextLine2D) {
+ for (i = 0; codingLine[i] < columns; ++i) {
+ refLine[i] = codingLine[i];
+ }
+ refLine[i++] = columns;
+ refLine[i] = columns;
+ codingLine[0] = 0;
+ a0i = 0;
+ b1i = 0;
+ blackPixels = 0;
+ // invariant:
+ // refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1]
+ // <= columns
+ // exception at left edge:
+ // codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
+ // exception at right edge:
+ // refLine[b1i] = refLine[b1i+1] = columns is possible
+ while (codingLine[a0i] < columns) {
+ code1 = getTwoDimCode();
+ switch (code1) {
+ case twoDimPass:
+ addPixels(refLine[b1i + 1], blackPixels);
+ if (refLine[b1i + 1] < columns) {
+ b1i += 2;
+ }
+ break;
+ case twoDimHoriz:
+ code1 = code2 = 0;
+ if (blackPixels) {
+ do {
+ code1 += code3 = getBlackCode();
+ } while (code3 >= 64);
+ do {
+ code2 += code3 = getWhiteCode();
+ } while (code3 >= 64);
+ } else {
+ do {
+ code1 += code3 = getWhiteCode();
+ } while (code3 >= 64);
+ do {
+ code2 += code3 = getBlackCode();
+ } while (code3 >= 64);
+ }
+ addPixels(codingLine[a0i] + code1, blackPixels);
+ if (codingLine[a0i] < columns) {
+ addPixels(codingLine[a0i] + code2, blackPixels ^ 1);
+ }
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
+ }
+ break;
+ case twoDimVertR3:
+ addPixels(refLine[b1i] + 3, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ ++b1i;
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
b1i += 2;
}
- break;
- case twoDimHoriz:
- code1 = code2 = 0;
- if (blackPixels) {
- do {
- code1 += code3 = getBlackCode();
- } while (code3 >= 64);
- do {
- code2 += code3 = getWhiteCode();
- } while (code3 >= 64);
- } else {
- do {
- code1 += code3 = getWhiteCode();
- } while (code3 >= 64);
- do {
- code2 += code3 = getBlackCode();
- } while (code3 >= 64);
- }
- addPixels(codingLine[a0i] + code1, blackPixels);
- if (codingLine[a0i] < columns) {
- addPixels(codingLine[a0i] + code2, blackPixels ^ 1);
+ }
+ break;
+ case twoDimVertR2:
+ addPixels(refLine[b1i] + 2, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ ++b1i;
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
}
+ }
+ break;
+ case twoDimVertR1:
+ addPixels(refLine[b1i] + 1, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ ++b1i;
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
b1i += 2;
}
- break;
- case twoDimVertR3:
- addPixels(refLine[b1i] + 3, blackPixels);
- blackPixels ^= 1;
- if (codingLine[a0i] < columns) {
- ++b1i;
- while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
- b1i += 2;
- }
+ }
+ break;
+ case twoDimVert0:
+ addPixels(refLine[b1i], blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ ++b1i;
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
}
- break;
- case twoDimVertR2:
- addPixels(refLine[b1i] + 2, blackPixels);
- blackPixels ^= 1;
- if (codingLine[a0i] < columns) {
+ }
+ break;
+ case twoDimVertL3:
+ addPixelsNeg(refLine[b1i] - 3, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ if (b1i > 0) {
+ --b1i;
+ } else {
++b1i;
- while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
- b1i += 2;
- }
}
- break;
- case twoDimVertR1:
- addPixels(refLine[b1i] + 1, blackPixels);
- blackPixels ^= 1;
- if (codingLine[a0i] < columns) {
- ++b1i;
- while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
- b1i += 2;
- }
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
}
- break;
- case twoDimVert0:
- addPixels(refLine[b1i], blackPixels);
- blackPixels ^= 1;
- if (codingLine[a0i] < columns) {
+ }
+ break;
+ case twoDimVertL2:
+ addPixelsNeg(refLine[b1i] - 2, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ if (b1i > 0) {
+ --b1i;
+ } else {
++b1i;
- while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
- b1i += 2;
- }
}
- break;
- case twoDimVertL3:
- addPixelsNeg(refLine[b1i] - 3, blackPixels);
- blackPixels ^= 1;
- if (codingLine[a0i] < columns) {
- if (b1i > 0) {
- --b1i;
- } else {
- ++b1i;
- }
- while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
- b1i += 2;
- }
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
}
- break;
- case twoDimVertL2:
- addPixelsNeg(refLine[b1i] - 2, blackPixels);
- blackPixels ^= 1;
- if (codingLine[a0i] < columns) {
- if (b1i > 0) {
- --b1i;
- } else {
- ++b1i;
- }
- while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
- b1i += 2;
- }
+ }
+ break;
+ case twoDimVertL1:
+ addPixelsNeg(refLine[b1i] - 1, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ if (b1i > 0) {
+ --b1i;
+ } else {
+ ++b1i;
}
- break;
- case twoDimVertL1:
- addPixelsNeg(refLine[b1i] - 1, blackPixels);
- blackPixels ^= 1;
- if (codingLine[a0i] < columns) {
- if (b1i > 0) {
- --b1i;
- } else {
- ++b1i;
- }
- while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
- b1i += 2;
- }
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
}
- break;
- case EOF:
- addPixels(columns, 0);
- eof = gTrue;
- break;
- default:
- error(errSyntaxError, getPos(),
- "Bad 2D code {0:04x} in CCITTFax stream", code1);
- addPixels(columns, 0);
- err = gTrue;
- break;
}
+ break;
+ case EOF:
+ addPixels(columns, 0);
+ err = gTrue;
+ break;
+ default:
+ error(errSyntaxError, getPos(),
+ "Bad 2D code {0:04x} in CCITTFax stream", code1);
+ addPixels(columns, 0);
+ err = gTrue;
+ break;
}
+ }
- // 1-D encoding
- } else {
- codingLine[0] = 0;
- a0i = 0;
- blackPixels = 0;
- while (codingLine[a0i] < columns) {
- code1 = 0;
- if (blackPixels) {
- do {
- code1 += code3 = getBlackCode();
- } while (code3 >= 64);
- } else {
- do {
- code1 += code3 = getWhiteCode();
- } while (code3 >= 64);
- }
- addPixels(codingLine[a0i] + code1, blackPixels);
- blackPixels ^= 1;
+ // 1-D encoding
+ } else {
+ codingLine[0] = 0;
+ a0i = 0;
+ blackPixels = 0;
+ while (codingLine[a0i] < columns) {
+ code1 = 0;
+ if (blackPixels) {
+ do {
+ code1 += code3 = getBlackCode();
+ } while (code3 >= 64);
+ } else {
+ do {
+ code1 += code3 = getWhiteCode();
+ } while (code3 >= 64);
}
+ addPixels(codingLine[a0i] + code1, blackPixels);
+ blackPixels ^= 1;
}
+ }
- // check for end-of-line marker, skipping over any extra zero bits
- // (if EncodedByteAlign is true and EndOfLine is false, there can
- // be "false" EOL markers -- i.e., if the last n unused bits in
- // row i are set to zero, and the first 11-n bits in row i+1
- // happen to be zero -- so we don't look for EOL markers in this
- // case)
- gotEOL = gFalse;
- if (!endOfBlock && row == rows - 1) {
- eof = gTrue;
- } else if (endOfLine || !byteAlign) {
- code1 = lookBits(12);
- if (endOfLine) {
- while (code1 != EOF && code1 != 0x001) {
- eatBits(1);
- code1 = lookBits(12);
- }
- } else {
- while (code1 == 0) {
- eatBits(1);
- code1 = lookBits(12);
- }
+ // check for end-of-line marker, skipping over any extra zero bits
+ // (if EncodedByteAlign is true and EndOfLine is false, there can
+ // be "false" EOL markers -- i.e., if the last n unused bits in
+ // row i are set to zero, and the first 11-n bits in row i+1
+ // happen to be zero -- so we don't look for EOL markers in this
+ // case)
+ gotEOL = gFalse;
+ if (!endOfBlock && row == rows - 1) {
+ eof = gTrue;
+ } else if (endOfLine || !byteAlign) {
+ code1 = lookBits(12);
+ if (endOfLine) {
+ while (code1 != EOF && code1 != 0x001) {
+ eatBits(1);
+ code1 = lookBits(12);
}
- if (code1 == 0x001) {
- eatBits(12);
- gotEOL = gTrue;
+ } else {
+ while (code1 == 0) {
+ eatBits(1);
+ code1 = lookBits(12);
}
}
-
- // byte-align the row
- // (Adobe apparently doesn't do byte alignment after EOL markers
- // -- I've seen CCITT image data streams in two different formats,
- // both with the byteAlign flag set:
- // 1. xx:x0:01:yy:yy
- // 2. xx:00:1y:yy:yy
- // where xx is the previous line, yy is the next line, and colons
- // separate bytes.)
- if (byteAlign && !gotEOL) {
- inputBits &= ~7;
+ if (code1 == 0x001) {
+ eatBits(12);
+ gotEOL = gTrue;
}
+ }
- // check for end of stream
- if (lookBits(1) == EOF) {
- eof = gTrue;
- }
+ // byte-align the row
+ // (Adobe apparently doesn't do byte alignment after EOL markers
+ // -- I've seen CCITT image data streams in two different formats,
+ // both with the byteAlign flag set:
+ // 1. xx:x0:01:yy:yy
+ // 2. xx:00:1y:yy:yy
+ // where xx is the previous line, yy is the next line, and colons
+ // separate bytes.)
+ if (byteAlign && !gotEOL) {
+ inputBits &= ~7;
+ }
- // get 2D encoding tag
- if (!eof && encoding > 0) {
- nextLine2D = !lookBits(1);
- eatBits(1);
- }
+ // check for end of stream
+ if (lookBits(1) == EOF) {
+ eof = gTrue;
+ }
- // check for end-of-block marker
- if (endOfBlock && !endOfLine && byteAlign) {
- // in this case, we didn't check for an EOL code above, so we
- // need to check here
- code1 = lookBits(24);
- if (code1 == 0x001001) {
- eatBits(12);
- gotEOL = gTrue;
- }
+ // get 2D encoding tag
+ if (!eof && encoding > 0) {
+ nextLine2D = !lookBits(1);
+ eatBits(1);
+ }
+
+ // check for end-of-block marker
+ if (endOfBlock && !endOfLine && byteAlign) {
+ // in this case, we didn't check for an EOL code above, so we
+ // need to check here
+ code1 = lookBits(24);
+ if (code1 == 0x001001) {
+ eatBits(12);
+ gotEOL = gTrue;
}
- if (endOfBlock && gotEOL) {
- code1 = lookBits(12);
- if (code1 == 0x001) {
- eatBits(12);
- if (encoding > 0) {
- lookBits(1);
- eatBits(1);
- }
- if (encoding >= 0) {
- for (i = 0; i < 4; ++i) {
- code1 = lookBits(12);
- if (code1 != 0x001) {
- error(errSyntaxError, getPos(),
- "Bad RTC code in CCITTFax stream");
- }
- eatBits(12);
- if (encoding > 0) {
- lookBits(1);
- eatBits(1);
- }
+ }
+ if (endOfBlock && gotEOL) {
+ code1 = lookBits(12);
+ if (code1 == 0x001) {
+ eatBits(12);
+ if (encoding > 0) {
+ lookBits(1);
+ eatBits(1);
+ }
+ if (encoding >= 0) {
+ for (i = 0; i < 4; ++i) {
+ code1 = lookBits(12);
+ if (code1 != 0x001) {
+ error(errSyntaxError, getPos(),
+ "Bad RTC code in CCITTFax stream");
+ }
+ eatBits(12);
+ if (encoding > 0) {
+ lookBits(1);
+ eatBits(1);
}
}
- eof = gTrue;
}
+ eof = gTrue;
+ }
- // look for an end-of-line marker after an error -- we only do
- // this if we know the stream contains end-of-line markers because
- // the "just plow on" technique tends to work better otherwise
- } else if (err && endOfLine) {
- while (1) {
- code1 = lookBits(13);
- if (code1 == EOF) {
- eof = gTrue;
- return EOF;
- }
- if ((code1 >> 1) == 0x001) {
- break;
- }
- eatBits(1);
+ // look for an end-of-line marker after an error -- we only do
+ // this if we know the stream contains end-of-line markers because
+ // the "just plow on" technique tends to work better otherwise
+ } else if (err && endOfLine) {
+ while (1) {
+ code1 = lookBits(13);
+ if (code1 == EOF) {
+ eof = gTrue;
+ return gFalse;
}
- eatBits(12);
- if (encoding > 0) {
- eatBits(1);
- nextLine2D = !(code1 & 1);
+ if ((code1 >> 1) == 0x001) {
+ break;
}
+ eatBits(1);
}
-
- // set up for output
- if (codingLine[0] > 0) {
- outputBits = codingLine[a0i = 0];
- } else {
- outputBits = codingLine[a0i = 1];
+ eatBits(12);
+ if (encoding > 0) {
+ eatBits(1);
+ nextLine2D = !(code1 & 1);
}
-
- ++row;
}
- // get a byte
- if (outputBits >= 8) {
- buf = (a0i & 1) ? 0x00 : 0xff;
- outputBits -= 8;
- if (outputBits == 0 && codingLine[a0i] < columns) {
- ++a0i;
- outputBits = codingLine[a0i] - codingLine[a0i - 1];
- }
- } else {
- bits = 8;
- buf = 0;
- do {
- if (outputBits > bits) {
- buf <<= bits;
- if (!(a0i & 1)) {
- buf |= 0xff >> (8 - bits);
- }
- outputBits -= bits;
- bits = 0;
- } else {
- buf <<= outputBits;
- if (!(a0i & 1)) {
- buf |= 0xff >> (8 - outputBits);
- }
- bits -= outputBits;
- outputBits = 0;
- if (codingLine[a0i] < columns) {
- ++a0i;
- outputBits = codingLine[a0i] - codingLine[a0i - 1];
- } else if (bits > 0) {
- buf <<= bits;
- bits = 0;
- }
- }
- } while (bits);
- }
- if (black) {
- buf ^= 0xff;
- }
- return buf;
+ // set up for output
+ nextCol = 0;
+ a0i = (codingLine[0] > 0) ? 0 : 1;
+
+ ++row;
+
+ return gTrue;
}
short CCITTFaxStream::getTwoDimCode() {
@@ -2074,17 +2289,250 @@ GBool CCITTFaxStream::isBinary(GBool last) {
// DCTStream
//------------------------------------------------------------------------
-// IDCT constants (20.12 fixed point format)
-#define dctSqrt2 5793 // sqrt(2)
-#define dctSqrt2Cos6 2217 // sqrt(2) * cos(6*pi/16)
-#define dctSqrt2Cos6PSin6 7568 // sqrt(2) * (cos(6*pi/16) + sin(6*pi/16))
-#define dctSqrt2Sin6MCos6 3135 // sqrt(2) * (sin(6*pi/16) - cos(6*pi/16))
-#define dctCos3 3406 // cos(3*pi/16)
-#define dctCos3PSin3 5681 // cos(3*pi/16) + sin(3*pi/16)
-#define dctSin3MCos3 -1130 // sin(3*pi/16) - cos(3*pi/16)
-#define dctCos1 4017 // cos(pi/16)
-#define dctCos1PSin1 4816 // cos(pi/16) + sin(pi/16)
-#define dctSin1MCos1 -3218 // sin(pi/16) - cos(pi/16)
+#if HAVE_JPEGLIB
+
+DCTStream::DCTStream(Stream *strA, GBool colorXformA):
+ FilterStream(strA) {
+ colorXform = colorXformA;
+ lineBuf = NULL;
+ inlineImage = str->isEmbedStream();
+}
+
+DCTStream::~DCTStream() {
+ delete str;
+}
+
+Stream *DCTStream::copy() {
+ return new DCTStream(str->copy(), colorXform);
+}
+
+void DCTStream::reset() {
+ int i;
+
+ lineBuf = NULL;
+ error = gFalse;
+
+ str->reset();
+
+ // initialize the libjpeg decompression object
+ decomp.err = jpeg_std_error(&errorMgr.err);
+ errorMgr.err.error_exit = &errorExit;
+ errorMgr.err.output_message = &errorMessage;
+ if (setjmp(errorMgr.setjmpBuf)) {
+ error = gTrue;
+ return;
+ }
+ jpeg_create_decompress(&decomp);
+
+ // set up the data source manager
+ sourceMgr.src.next_input_byte = NULL;
+ sourceMgr.src.bytes_in_buffer = 0;
+ sourceMgr.src.init_source = &initSourceCbk;
+ sourceMgr.src.fill_input_buffer = &fillInputBufferCbk;
+ sourceMgr.src.skip_input_data = &skipInputDataCbk;
+ sourceMgr.src.resync_to_restart = &jpeg_resync_to_restart;
+ sourceMgr.src.term_source = &termSourceCbk;
+ sourceMgr.str = this;
+ decomp.src = &sourceMgr.src;
+
+ // read the header
+ jpeg_read_header(&decomp, TRUE);
+ jpeg_calc_output_dimensions(&decomp);
+
+ // set up the color transform
+ if (!decomp.saw_Adobe_marker && colorXform >= 0) {
+ if (decomp.num_components == 3) {
+ decomp.jpeg_color_space = colorXform ? JCS_YCbCr : JCS_RGB;
+ decomp.out_color_space = JCS_RGB;
+ decomp.out_color_components = 3;
+ } else if (decomp.num_components == 4) {
+ decomp.jpeg_color_space = colorXform ? JCS_YCCK : JCS_CMYK;
+ decomp.out_color_space = JCS_CMYK;
+ decomp.out_color_components = 4;
+ }
+ }
+
+ // allocate a line buffer
+ if ((lineBufHeight = decomp.rec_outbuf_height) > 4) {
+ lineBufHeight = 4;
+ }
+ lineBuf = (char *)gmallocn(lineBufHeight * decomp.out_color_components,
+ decomp.output_width);
+ for (i = 0; i < lineBufHeight; ++i) {
+ lineBufRows[i] = lineBuf +
+ i * decomp.out_color_components * decomp.output_width;
+ }
+ bufPtr = bufEnd = lineBuf;
+
+ // start up the decompression process
+ jpeg_start_decompress(&decomp);
+}
+
+void DCTStream::close() {
+ // we don't call jpeg_finish_decompress() here because it will report
+ // an error if the full image wasn't read
+ if (setjmp(errorMgr.setjmpBuf)) {
+ goto skip;
+ }
+ jpeg_destroy_decompress(&decomp);
+ skip:
+ gfree(lineBuf);
+ FilterStream::close();
+}
+
+int DCTStream::getChar() {
+ if (error) {
+ return EOF;
+ }
+ if (bufPtr == bufEnd) {
+ if (!fillBuf()) {
+ return EOF;
+ }
+ }
+ return *bufPtr++ & 0xff;
+}
+
+int DCTStream::lookChar() {
+ if (error) {
+ return EOF;
+ }
+ if (bufPtr == bufEnd) {
+ if (!fillBuf()) {
+ return EOF;
+ }
+ }
+ return *bufPtr & 0xff;
+}
+
+int DCTStream::getBlock(char *blk, int size) {
+ int nRead, nAvail, n;
+
+ if (error) {
+ return 0;
+ }
+ nRead = 0;
+ while (nRead < size) {
+ if (bufPtr == bufEnd) {
+ if (!fillBuf()) {
+ break;
+ }
+ }
+ nAvail = bufEnd - bufPtr;
+ n = (nAvail < size - nRead) ? nAvail : size - nRead;
+ memcpy(blk + nRead, bufPtr, n);
+ bufPtr += n;
+ nRead += n;
+ }
+ return nRead;
+}
+
+GBool DCTStream::fillBuf() {
+ int nLines;
+
+ if (setjmp(errorMgr.setjmpBuf)) {
+ error = gTrue;
+ return gFalse;
+ }
+ nLines = jpeg_read_scanlines(&decomp, (JSAMPARRAY)lineBufRows,
+ lineBufHeight);
+ bufPtr = lineBuf;
+ bufEnd = lineBuf +
+ nLines * decomp.out_color_components * decomp.output_width;
+ return nLines > 0;
+}
+
+void DCTStream::errorExit(j_common_ptr d) {
+ DCTErrorMgr *errMgr = (DCTErrorMgr *)d->err;
+ longjmp(errMgr->setjmpBuf, 1);
+}
+
+void DCTStream::errorMessage(j_common_ptr d) {
+#if 0 // for debugging
+ char buf[JMSG_LENGTH_MAX];
+
+ (*d->err->format_message)(d, buf);
+ fprintf(stderr, "%s\n", buf);
+#endif
+}
+
+void DCTStream::initSourceCbk(j_decompress_ptr d) {
+ DCTSourceMgr *sourceMgr = (DCTSourceMgr *)d->src;
+
+ sourceMgr->src.next_input_byte = NULL;
+ sourceMgr->src.bytes_in_buffer = 0;
+}
+
+boolean DCTStream::fillInputBufferCbk(j_decompress_ptr d) {
+ DCTSourceMgr *sourceMgr = (DCTSourceMgr *)d->src;
+ int c, n;
+
+ // for inline images, we need to read one byte at a time so we don't
+ // read past the end of the input data
+ if (sourceMgr->str->inlineImage) {
+ c = sourceMgr->str->str->getChar();
+ if (c == EOF) {
+ sourceMgr->buf[0] = (char)0xff;
+ sourceMgr->buf[1] = (char)JPEG_EOI;
+ sourceMgr->src.bytes_in_buffer = 2;
+ } else {
+ sourceMgr->buf[0] = (char)c;
+ sourceMgr->src.bytes_in_buffer = 1;
+ }
+ } else {
+ n = sourceMgr->str->str->getBlock(sourceMgr->buf, dctStreamBufSize);
+ if (n > 0) {
+ sourceMgr->src.bytes_in_buffer = (size_t)n;
+ } else {
+ sourceMgr->buf[0] = (char)0xff;
+ sourceMgr->buf[1] = (char)JPEG_EOI;
+ sourceMgr->src.bytes_in_buffer = 2;
+ }
+ }
+ sourceMgr->src.next_input_byte = (JOCTET *)sourceMgr->buf;
+ return TRUE;
+}
+
+void DCTStream::skipInputDataCbk(j_decompress_ptr d, long numBytes) {
+ DCTSourceMgr *sourceMgr = (DCTSourceMgr *)d->src;
+
+ if (numBytes > 0) {
+ if ((long)sourceMgr->src.bytes_in_buffer < numBytes) {
+ sourceMgr->str->str->discardChars(
+ (Guint)(numBytes - sourceMgr->src.bytes_in_buffer));
+ sourceMgr->src.bytes_in_buffer = 0;
+ } else {
+ sourceMgr->src.bytes_in_buffer -= numBytes;
+ sourceMgr->src.next_input_byte += numBytes;
+ }
+ }
+}
+
+void DCTStream::termSourceCbk(j_decompress_ptr d) {
+}
+
+#else // HAVE_JPEGLIB
+
+#define idctScaleA 1024
+#define idctScaleB 1138
+#define idctScaleC 1730
+#define idctScaleD 1609
+#define idctScaleE 1264
+#define idctScaleF 1922
+#define idctScaleG 1788
+#define idctScaleH 2923
+#define idctScaleI 2718
+#define idctScaleJ 2528
+
+static int idctScaleMat[64] = {
+ idctScaleA, idctScaleB, idctScaleC, idctScaleD, idctScaleA, idctScaleD, idctScaleC, idctScaleB,
+ idctScaleB, idctScaleE, idctScaleF, idctScaleG, idctScaleB, idctScaleG, idctScaleF, idctScaleE,
+ idctScaleC, idctScaleF, idctScaleH, idctScaleI, idctScaleC, idctScaleI, idctScaleH, idctScaleF,
+ idctScaleD, idctScaleG, idctScaleI, idctScaleJ, idctScaleD, idctScaleJ, idctScaleI, idctScaleG,
+ idctScaleA, idctScaleB, idctScaleC, idctScaleD, idctScaleA, idctScaleD, idctScaleC, idctScaleB,
+ idctScaleD, idctScaleG, idctScaleI, idctScaleJ, idctScaleD, idctScaleJ, idctScaleI, idctScaleG,
+ idctScaleC, idctScaleF, idctScaleH, idctScaleI, idctScaleC, idctScaleI, idctScaleH, idctScaleF,
+ idctScaleB, idctScaleE, idctScaleF, idctScaleG, idctScaleB, idctScaleG, idctScaleF, idctScaleE
+};
// color conversion parameters (16.16 fixed point format)
#define dctCrToR 91881 // 1.4020
@@ -2179,6 +2627,10 @@ DCTStream::~DCTStream() {
delete str;
}
+Stream *DCTStream::copy() {
+ return new DCTStream(str->copy(), colorXform);
+}
+
void DCTStream::reset() {
int i;
@@ -2267,6 +2719,12 @@ void DCTStream::reset() {
} else {
+ if (scanInfo.numComps != numComps) {
+ error(errSyntaxError, getPos(), "Invalid scan in sequential DCT stream");
+ y = height;
+ return;
+ }
+
// allocate a buffer for one row of MCUs
bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
rowBuf = (Guchar *)gmallocn(numComps * mcuHeight, bufWidth);
@@ -2343,6 +2801,50 @@ int DCTStream::lookChar() {
}
}
+int DCTStream::getBlock(char *blk, int size) {
+ int nRead, nAvail, n;
+
+ if (progressive || !interleaved) {
+ if (y >= height) {
+ return 0;
+ }
+ for (nRead = 0; nRead < size; ++nRead) {
+ blk[nRead] = (char)frameBuf[comp][y * bufWidth + x];
+ if (++comp == numComps) {
+ comp = 0;
+ if (++x == width) {
+ x = 0;
+ ++y;
+ if (y >= height) {
+ ++nRead;
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ nRead = 0;
+ while (nRead < size) {
+ if (rowBufPtr == rowBufEnd) {
+ if (y + mcuHeight >= height) {
+ break;
+ }
+ y += mcuHeight;
+ if (!readMCURow()) {
+ y = height;
+ break;
+ }
+ }
+ nAvail = (int)(rowBufEnd - rowBufPtr);
+ n = (nAvail < size - nRead) ? nAvail : size - nRead;
+ memcpy(blk + nRead, rowBufPtr, n);
+ rowBufPtr += n;
+ nRead += n;
+ }
+ }
+ return nRead;
+}
+
void DCTStream::restart() {
int i;
@@ -2931,16 +3433,22 @@ void DCTStream::decodeImage() {
// Transform one data unit -- this performs the dequantization and
// IDCT steps. This IDCT algorithm is taken from:
+// Y. A. Reznik, A. T. Hinds, L. Yu, Z. Ni, and C-X. Zhang,
+// "Efficient fixed-point approximations of the 8x8 inverse discrete
+// cosine transform" (invited paper), Proc. SPIE Vol. 6696, Sep. 24,
+// 2007.
+// which is based on:
// Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz,
// "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
// IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
// 988-991.
-// The stage numbers mentioned in the comments refer to Figure 1 in this
-// paper.
+// The stage numbers mentioned in the comments refer to Figure 1 in the
+// Loeffler paper.
void DCTStream::transformDataUnit(Gushort *quantTable,
int dataIn[64], Guchar dataOut[64]) {
- int v0, v1, v2, v3, v4, v5, v6, v7, t0, t1, t2;
- int *p;
+ int v0, v1, v2, v3, v4, v5, v6, v7;
+ int t0, t1, t2, t3, t4, t5, t6, t7;
+ int *p, *scale;
Gushort *q;
int i;
@@ -2948,11 +3456,15 @@ void DCTStream::transformDataUnit(Gushort *quantTable,
for (i = 0; i < 64; i += 8) {
p = dataIn + i;
q = quantTable + i;
+ scale = idctScaleMat + i;
// check for all-zero AC coefficients
if (p[1] == 0 && p[2] == 0 && p[3] == 0 &&
p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] == 0) {
- t0 = p[0] * q[0];
+ t0 = p[0] * q[0] * scale[0];
+ if (i == 0) {
+ t0 += 1 << 12; // rounding bias
+ }
p[0] = t0;
p[1] = t0;
p[2] = t0;
@@ -2965,26 +3477,34 @@ void DCTStream::transformDataUnit(Gushort *quantTable,
}
// stage 4
- v0 = p[0] * q[0];
- v1 = p[4] * q[4];
- v2 = p[2] * q[2];
- v3 = p[6] * q[6];
- t0 = p[1] * q[1];
- t1 = p[7] * q[7];
+ v0 = p[0] * q[0] * scale[0];
+ if (i == 0) {
+ v0 += 1 << 12; // rounding bias
+ }
+ v1 = p[4] * q[4] * scale[4];
+ v2 = p[2] * q[2] * scale[2];
+ v3 = p[6] * q[6] * scale[6];
+ t0 = p[1] * q[1] * scale[1];
+ t1 = p[7] * q[7] * scale[7];
v4 = t0 - t1;
v7 = t0 + t1;
- v5 = (dctSqrt2 * p[3] * q[3]) >> 12;
- v6 = (dctSqrt2 * p[5] * q[5]) >> 12;
+ v5 = p[3] * q[3] * scale[3];
+ v6 = p[5] * q[5] * scale[5];
// stage 3
t0 = v0 - v1;
v0 = v0 + v1;
v1 = t0;
- t0 = dctSqrt2Cos6 * (v2 + v3);
- t1 = dctSqrt2Cos6PSin6 * v3;
- t2 = dctSqrt2Sin6MCos6 * v2;
- v2 = (t0 - t1) >> 12;
- v3 = (t0 + t2) >> 12;
+ t0 = v2 + (v2 >> 5);
+ t1 = t0 >> 2;
+ t2 = t1 + (v2 >> 4); // 41/128 * v2
+ t3 = t0 - t1; // 99/128 * v2
+ t4 = v3 + (v3 >> 5);
+ t5 = t4 >> 2;
+ t6 = t5 + (v3 >> 4); // 41/128 * v3
+ t7 = t4 - t5; // 99/128 * v3
+ v2 = t2 - t7;
+ v3 = t3 + t6;
t0 = v4 - v6;
v4 = v4 + v6;
v6 = t0;
@@ -2999,16 +3519,24 @@ void DCTStream::transformDataUnit(Gushort *quantTable,
t0 = v1 - v2;
v1 = v1 + v2;
v2 = t0;
- t0 = dctCos3 * (v4 + v7);
- t1 = dctCos3PSin3 * v7;
- t2 = dctSin3MCos3 * v4;
- v4 = (t0 - t1) >> 12;
- v7 = (t0 + t2) >> 12;
- t0 = dctCos1 * (v5 + v6);
- t1 = dctCos1PSin1 * v6;
- t2 = dctSin1MCos1 * v5;
- v5 = (t0 - t1) >> 12;
- v6 = (t0 + t2) >> 12;
+ t0 = (v4 >> 9) - v4;
+ t1 = v4 >> 1; // 1/2 * v4
+ t2 = (t0 >> 2) - t0; // 1533/2048 * v4
+ t3 = (v7 >> 9) - v7;
+ t4 = v7 >> 1; // 1/2 * v7
+ t5 = (t3 >> 2) - t3; // 1533/2048 * v7
+ v4 = t2 - t4;
+ v7 = t1 + t5;
+ t0 = (v5 >> 3) - (v5 >> 7);
+ t1 = t0 - (v5 >> 11);
+ t2 = t0 + (t1 >> 1); // 719/4096 * v5
+ t3 = v5 - t0; // 113/256 * v5
+ t4 = (v6 >> 3) - (v6 >> 7);
+ t5 = t4 - (v6 >> 11);
+ t6 = t4 + (t5 >> 1); // 719/4096 * v6
+ t7 = v6 - t4; // 113/256 * v6
+ v5 = t3 - t6;
+ v6 = t2 + t7;
// stage 1
p[0] = v0 + v7;
@@ -3044,20 +3572,27 @@ void DCTStream::transformDataUnit(Gushort *quantTable,
v1 = p[4*8];
v2 = p[2*8];
v3 = p[6*8];
- v4 = p[1*8] - p[7*8];
- v7 = p[1*8] + p[7*8];
- v5 = (dctSqrt2 * p[3*8]) >> 12;
- v6 = (dctSqrt2 * p[5*8]) >> 12;
+ t0 = p[1*8];
+ t1 = p[7*8];
+ v4 = t0 - t1;
+ v7 = t0 + t1;
+ v5 = p[3*8];
+ v6 = p[5*8];
// stage 3
t0 = v0 - v1;
v0 = v0 + v1;
v1 = t0;
- t0 = dctSqrt2Cos6 * (v2 + v3);
- t1 = dctSqrt2Cos6PSin6 * v3;
- t2 = dctSqrt2Sin6MCos6 * v2;
- v2 = (t0 - t1) >> 12;
- v3 = (t0 + t2) >> 12;
+ t0 = v2 + (v2 >> 5);
+ t1 = t0 >> 2;
+ t2 = t1 + (v2 >> 4); // 41/128 * v2
+ t3 = t0 - t1; // 99/128 * v2
+ t4 = v3 + (v3 >> 5);
+ t5 = t4 >> 2;
+ t6 = t5 + (v3 >> 4); // 41/128 * v3
+ t7 = t4 - t5; // 99/128 * v3
+ v2 = t2 - t7;
+ v3 = t3 + t6;
t0 = v4 - v6;
v4 = v4 + v6;
v6 = t0;
@@ -3072,16 +3607,24 @@ void DCTStream::transformDataUnit(Gushort *quantTable,
t0 = v1 - v2;
v1 = v1 + v2;
v2 = t0;
- t0 = dctCos3 * (v4 + v7);
- t1 = dctCos3PSin3 * v7;
- t2 = dctSin3MCos3 * v4;
- v4 = (t0 - t1) >> 12;
- v7 = (t0 + t2) >> 12;
- t0 = dctCos1 * (v5 + v6);
- t1 = dctCos1PSin1 * v6;
- t2 = dctSin1MCos1 * v5;
- v5 = (t0 - t1) >> 12;
- v6 = (t0 + t2) >> 12;
+ t0 = (v4 >> 9) - v4;
+ t1 = v4 >> 1; // 1/2 * v4
+ t2 = (t0 >> 2) - t0; // 1533/2048 * v4
+ t3 = (v7 >> 9) - v7;
+ t4 = v7 >> 1; // 1/2 * v7
+ t5 = (t3 >> 2) - t3; // 1533/2048 * v7
+ v4 = t2 - t4;
+ v7 = t1 + t5;
+ t0 = (v5 >> 3) - (v5 >> 7);
+ t1 = t0 - (v5 >> 11);
+ t2 = t0 + (t1 >> 1); // 719/4096 * v5
+ t3 = v5 - t0; // 113/256 * v5
+ t4 = (v6 >> 3) - (v6 >> 7);
+ t5 = t4 - (v6 >> 11);
+ t6 = t4 + (t5 >> 1); // 719/4096 * v6
+ t7 = v6 - t4; // 113/256 * v6
+ v5 = t3 - t6;
+ v6 = t2 + t7;
// stage 1
p[0*8] = v0 + v7;
@@ -3096,7 +3639,7 @@ void DCTStream::transformDataUnit(Gushort *quantTable,
// convert to 8-bit integers
for (i = 0; i < 64; ++i) {
- dataOut[i] = dctClip(128 + (dataIn[i] >> 3));
+ dataOut[i] = dctClip(128 + (dataIn[i] >> 13));
}
}
@@ -3361,6 +3904,11 @@ GBool DCTStream::readScanInfo() {
return gFalse;
}
}
+ if (scanInfo.comp[j]) {
+ error(errSyntaxError, getPos(),
+ "Invalid DCT component ID in scan info block");
+ return gFalse;
+ }
scanInfo.comp[j] = gTrue;
c = str->getChar();
scanInfo.dcHuffTable[j] = (c >> 4) & 0x0f;
@@ -3514,11 +4062,10 @@ GBool DCTStream::readAdobeMarker() {
}
buf[i] = c;
}
- if (strncmp(buf, "Adobe", 5)) {
- goto err;
+ if (!strncmp(buf, "Adobe", 5)) {
+ colorXform = buf[11];
+ gotAdobeMarker = gTrue;
}
- colorXform = buf[11];
- gotAdobeMarker = gTrue;
for (i = 14; i < length; ++i) {
if (str->getChar() == EOF) {
goto err;
@@ -3566,6 +4113,8 @@ int DCTStream::read16() {
return (c1 << 8) + c2;
}
+#endif // HAVE_JPEGLIB
+
GString *DCTStream::getPSFilter(int psLevel, const char *indent) {
GString *s;
@@ -4246,6 +4795,16 @@ FlateStream::~FlateStream() {
delete str;
}
+Stream *FlateStream::copy() {
+ if (pred) {
+ return new FlateStream(str->copy(), pred->getPredictor(),
+ pred->getWidth(), pred->getNComps(),
+ pred->getNBits());
+ } else {
+ return new FlateStream(str->copy(), 1, 0, 0, 0);
+ }
+}
+
void FlateStream::reset() {
int cmf, flg;
@@ -4710,6 +5269,10 @@ EOFStream::~EOFStream() {
delete str;
}
+Stream *EOFStream::copy() {
+ return new EOFStream(str->copy());
+}
+
//------------------------------------------------------------------------
// BufStream
//------------------------------------------------------------------------
@@ -4724,6 +5287,10 @@ BufStream::~BufStream() {
delete str;
}
+Stream *BufStream::copy() {
+ return new BufStream(str->copy(), bufSize);
+}
+
void BufStream::reset() {
int i;
@@ -4771,6 +5338,11 @@ FixedLengthEncoder::~FixedLengthEncoder() {
delete str;
}
+Stream *FixedLengthEncoder::copy() {
+ error(errInternal, -1, "Called copy() on FixedLengthEncoder");
+ return NULL;
+}
+
void FixedLengthEncoder::reset() {
str->reset();
count = 0;
@@ -4810,6 +5382,11 @@ ASCIIHexEncoder::~ASCIIHexEncoder() {
}
}
+Stream *ASCIIHexEncoder::copy() {
+ error(errInternal, -1, "Called copy() on ASCIIHexEncoder");
+ return NULL;
+}
+
void ASCIIHexEncoder::reset() {
str->reset();
bufPtr = bufEnd = buf;
@@ -4856,6 +5433,11 @@ ASCII85Encoder::~ASCII85Encoder() {
delete str;
}
+Stream *ASCII85Encoder::copy() {
+ error(errInternal, -1, "Called copy() on ASCII85Encoder");
+ return NULL;
+}
+
void ASCII85Encoder::reset() {
str->reset();
bufPtr = bufEnd = buf;
@@ -4947,6 +5529,11 @@ RunLengthEncoder::~RunLengthEncoder() {
delete str;
}
+Stream *RunLengthEncoder::copy() {
+ error(errInternal, -1, "Called copy() on RunLengthEncoder");
+ return NULL;
+}
+
void RunLengthEncoder::reset() {
str->reset();
bufPtr = bufEnd = nextEnd = buf;
@@ -5044,6 +5631,7 @@ GBool RunLengthEncoder::fillBuf() {
LZWEncoder::LZWEncoder(Stream *strA):
FilterStream(strA)
{
+ inBufStart = 0;
inBufLen = 0;
outBufLen = 0;
}
@@ -5054,6 +5642,11 @@ LZWEncoder::~LZWEncoder() {
}
}
+Stream *LZWEncoder::copy() {
+ error(errInternal, -1, "Called copy() on LZWEncoder");
+ return NULL;
+}
+
void LZWEncoder::reset() {
int i;
@@ -5070,6 +5663,7 @@ void LZWEncoder::reset() {
// initialize input buffer
inBufLen = str->getBlock((char *)inBuf, sizeof(inBuf));
+ inBufStart = 0;
// initialize output buffer with a clear-table code
outBuf = 256;
@@ -5125,11 +5719,11 @@ void LZWEncoder::fillBuf() {
}
// find longest matching sequence (if any)
- p0 = table + inBuf[0];
+ p0 = table + inBuf[inBufStart];
seqLen = 1;
while (inBufLen > seqLen) {
for (p1 = p0->children; p1; p1 = p1->next) {
- if (p1->byte == inBuf[seqLen]) {
+ if (p1->byte == inBuf[inBufStart + seqLen]) {
break;
}
}
@@ -5146,7 +5740,7 @@ void LZWEncoder::fillBuf() {
outBufLen += codeLen;
// update the table
- table[nextSeq].byte = seqLen < inBufLen ? inBuf[seqLen] : 0;
+ table[nextSeq].byte = seqLen < inBufLen ? inBuf[inBufStart + seqLen] : 0;
table[nextSeq].children = NULL;
if (table[code].children) {
table[nextSeq].next = table[code].children;
@@ -5157,10 +5751,14 @@ void LZWEncoder::fillBuf() {
++nextSeq;
// update the input buffer
- memmove(inBuf, inBuf + seqLen, inBufLen - seqLen);
+ inBufStart += seqLen;
inBufLen -= seqLen;
- inBufLen += str->getBlock((char *)inBuf + inBufLen,
- sizeof(inBuf) - inBufLen);
+ if (inBufStart >= 4096 && inBufStart + inBufLen == sizeof(inBuf)) {
+ memcpy(inBuf, inBuf + inBufStart, inBufLen);
+ inBufStart = 0;
+ inBufLen += str->getBlock((char *)inBuf + inBufLen,
+ sizeof(inBuf) - inBufLen);
+ }
// increment codeLen; generate clear-table code
if (nextSeq == (1 << codeLen)) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
index c55d8023969..2515c15ea39 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Stream.h
@@ -16,11 +16,16 @@
#endif
#include <stdio.h>
+#if HAVE_JPEGLIB
+#include <jpeglib.h>
+#include <setjmp.h>
+#endif
#include "gtypes.h"
#include "gfile.h"
#include "Object.h"
class BaseStream;
+class SharedFile;
//------------------------------------------------------------------------
@@ -68,13 +73,13 @@ public:
// Destructor.
virtual ~Stream();
- // Reference counting.
- int incRef() { return ++ref; }
- int decRef() { return --ref; }
+ virtual Stream *copy() = 0;
// Get kind of stream.
virtual StreamKind getKind() = 0;
+ virtual GBool isEmbedStream() { return gFalse; }
+
// Reset stream to beginning.
virtual void reset() = 0;
@@ -144,8 +149,6 @@ public:
private:
Stream *makeFilter(char *name, Stream *str, Object *params, int recursion);
-
- int ref; // reference count
};
//------------------------------------------------------------------------
@@ -172,7 +175,7 @@ public:
virtual GFileOffset getStart() = 0;
virtual void moveStart(int delta) = 0;
-private:
+protected:
Object dict;
};
@@ -267,6 +270,11 @@ public:
int getChar();
int getBlock(char *blk, int size);
+ int getPredictor() { return predictor; }
+ int getWidth() { return width; }
+ int getNComps() { return nComps; }
+ int getNBits() { return nBits; }
+
private:
GBool getNextLine();
@@ -296,11 +304,11 @@ public:
FileStream(FILE *fA, GFileOffset startA, GBool limitedA,
GFileOffset lengthA, Object *dictA);
virtual ~FileStream();
+ virtual Stream *copy();
virtual Stream *makeSubStream(GFileOffset startA, GBool limitedA,
GFileOffset lengthA, Object *dictA);
virtual StreamKind getKind() { return strFile; }
virtual void reset();
- virtual void close();
virtual int getChar()
{ return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); }
virtual int lookChar()
@@ -313,9 +321,11 @@ public:
private:
+ FileStream(SharedFile *fA, GFileOffset startA, GBool limitedA,
+ GFileOffset lengthA, Object *dictA);
GBool fillBuf();
- FILE *f;
+ SharedFile *f;
GFileOffset start;
GBool limited;
GFileOffset length;
@@ -323,8 +333,6 @@ private:
char *bufPtr;
char *bufEnd;
GFileOffset bufPos;
- GFileOffset savePos;
- GBool saved;
};
//------------------------------------------------------------------------
@@ -336,6 +344,7 @@ public:
MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA);
virtual ~MemStream();
+ virtual Stream *copy();
virtual Stream *makeSubStream(GFileOffset start, GBool limited,
GFileOffset lengthA, Object *dictA);
virtual StreamKind getKind() { return strWeird; }
@@ -376,9 +385,11 @@ public:
EmbedStream(Stream *strA, Object *dictA, GBool limitedA, GFileOffset lengthA);
virtual ~EmbedStream();
+ virtual Stream *copy();
virtual Stream *makeSubStream(GFileOffset start, GBool limitedA,
GFileOffset lengthA, Object *dictA);
virtual StreamKind getKind() { return str->getKind(); }
+ virtual GBool isEmbedStream() { return gTrue; }
virtual void reset() {}
virtual int getChar();
virtual int lookChar();
@@ -404,6 +415,7 @@ public:
ASCIIHexStream(Stream *strA);
virtual ~ASCIIHexStream();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strASCIIHex; }
virtual void reset();
virtual int getChar()
@@ -427,6 +439,7 @@ public:
ASCII85Stream(Stream *strA);
virtual ~ASCII85Stream();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strASCII85; }
virtual void reset();
virtual int getChar()
@@ -453,6 +466,7 @@ public:
LZWStream(Stream *strA, int predictor, int columns, int colors,
int bits, int earlyA);
virtual ~LZWStream();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strLZW; }
virtual void reset();
virtual int getChar();
@@ -497,6 +511,7 @@ public:
RunLengthStream(Stream *strA);
virtual ~RunLengthStream();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strRunLength; }
virtual void reset();
virtual int getChar()
@@ -530,11 +545,12 @@ public:
GBool byteAlignA, int columnsA, int rowsA,
GBool endOfBlockA, GBool blackA);
virtual ~CCITTFaxStream();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strCCITTFax; }
virtual void reset();
- virtual int getChar()
- { int c = lookChar(); buf = EOF; return c; }
+ virtual int getChar();
virtual int lookChar();
+ virtual int getBlock(char *blk, int size);
virtual GString *getPSFilter(int psLevel, const char *indent);
virtual GBool isBinary(GBool last = gTrue);
@@ -547,6 +563,7 @@ private:
int rows; // 'Rows' parameter
GBool endOfBlock; // 'EndOfBlock' parameter
GBool black; // 'BlackIs1' parameter
+ int blackXOR;
GBool eof; // true if at eof
GBool nextLine2D; // true if next line uses 2D encoding
int row; // current row
@@ -554,13 +571,13 @@ private:
int inputBits; // number of bits in input buffer
int *codingLine; // coding line changing elements
int *refLine; // reference line changing elements
+ int nextCol; // next column to read
int a0i; // index into codingLine
GBool err; // error on current line
- int outputBits; // remaining ouput bits
- int buf; // character buffer
void addPixels(int a1, int blackPixels);
void addPixelsNeg(int a1, int blackPixels);
+ GBool readRow();
short getTwoDimCode();
short getWhiteCode();
short getBlackCode();
@@ -572,6 +589,25 @@ private:
// DCTStream
//------------------------------------------------------------------------
+#if HAVE_JPEGLIB
+
+class DCTStream;
+
+#define dctStreamBufSize 4096
+
+struct DCTSourceMgr {
+ jpeg_source_mgr src;
+ DCTStream *str;
+ char buf[dctStreamBufSize];
+};
+
+struct DCTErrorMgr {
+ struct jpeg_error_mgr err;
+ jmp_buf setjmpBuf;
+};
+
+#else // HAVE_JPEGLIB
+
// DCT component info
struct DCTCompInfo {
int id; // component ID
@@ -598,22 +634,52 @@ struct DCTHuffTable {
Guchar sym[256]; // symbols
};
+#endif // HAVE_JPEGLIB
+
class DCTStream: public FilterStream {
public:
DCTStream(Stream *strA, int colorXformA);
virtual ~DCTStream();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strDCT; }
virtual void reset();
virtual void close();
virtual int getChar();
virtual int lookChar();
+ virtual int getBlock(char *blk, int size);
virtual GString *getPSFilter(int psLevel, const char *indent);
virtual GBool isBinary(GBool last = gTrue);
Stream *getRawStream() { return str; }
private:
+#if HAVE_JPEGLIB
+
+ int colorXform; // color transform: -1 = unspecified
+ // 0 = none
+ // 1 = YUV/YUVK -> RGB/CMYK
+ jpeg_decompress_struct decomp;
+ DCTErrorMgr errorMgr;
+ DCTSourceMgr sourceMgr;
+ GBool error;
+ char *lineBuf;
+ int lineBufHeight;
+ char *lineBufRows[4];
+ char *bufPtr;
+ char *bufEnd;
+ GBool inlineImage;
+
+ GBool fillBuf();
+ static void errorExit(j_common_ptr d);
+ static void errorMessage(j_common_ptr d);
+ static void initSourceCbk(j_decompress_ptr d);
+ static boolean fillInputBufferCbk(j_decompress_ptr d);
+ static void skipInputDataCbk(j_decompress_ptr d, long numBytes);
+ static void termSourceCbk(j_decompress_ptr d);
+
+#else // HAVE_JPEGLIB
+
GBool progressive; // set if in progressive mode
GBool interleaved; // set if in interleaved mode
int width, height; // image size
@@ -672,6 +738,8 @@ private:
GBool readTrailer();
int readMarker();
int read16();
+
+#endif // HAVE_JPEGLIB
};
//------------------------------------------------------------------------
@@ -708,6 +776,7 @@ public:
FlateStream(Stream *strA, int predictor, int columns,
int colors, int bits);
virtual ~FlateStream();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strFlate; }
virtual void reset();
virtual int getChar();
@@ -763,6 +832,7 @@ public:
EOFStream(Stream *strA);
virtual ~EOFStream();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strWeird; }
virtual void reset() {}
virtual int getChar() { return EOF; }
@@ -782,6 +852,7 @@ public:
BufStream(Stream *strA, int bufSizeA);
virtual ~BufStream();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strWeird; }
virtual void reset();
virtual int getChar();
@@ -807,6 +878,7 @@ public:
FixedLengthEncoder(Stream *strA, int lengthA);
~FixedLengthEncoder();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strWeird; }
virtual void reset();
virtual int getChar();
@@ -831,6 +903,7 @@ public:
ASCIIHexEncoder(Stream *strA);
virtual ~ASCIIHexEncoder();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strWeird; }
virtual void reset();
virtual int getChar()
@@ -862,6 +935,7 @@ public:
ASCII85Encoder(Stream *strA);
virtual ~ASCII85Encoder();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strWeird; }
virtual void reset();
virtual int getChar()
@@ -893,6 +967,7 @@ public:
RunLengthEncoder(Stream *strA);
virtual ~RunLengthEncoder();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strWeird; }
virtual void reset();
virtual int getChar()
@@ -930,6 +1005,7 @@ public:
LZWEncoder(Stream *strA);
virtual ~LZWEncoder();
+ virtual Stream *copy();
virtual StreamKind getKind() { return strWeird; }
virtual void reset();
virtual int getChar();
@@ -944,7 +1020,8 @@ private:
LZWEncoderNode table[4096];
int nextSeq;
int codeLen;
- Guchar inBuf[4096];
+ Guchar inBuf[8192];
+ int inBufStart;
int inBufLen;
int outBuf;
int outBufLen;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
index be1fad2a2e9..025c34c16c0 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.cc
@@ -22,6 +22,7 @@
#include <io.h> // for setmode
#endif
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "GList.h"
#include "config.h"
@@ -97,7 +98,7 @@
// If the space between two lines is greater than
// paragraphSpacingThreshold * avgLineSpacing, start a new paragraph.
-#define paragraphSpacingThreshold 1.2
+#define paragraphSpacingThreshold 1.25
// If font size changes by at least this much (measured in points)
// between lines, start a new paragraph.
@@ -107,6 +108,10 @@
// (as a multiple of font size).
#define physLayoutSpaceWidth 0.33
+// In simple layout mode, lines are broken at gaps larger than this
+// value multiplied by font size.
+#define simpleLayoutGapThreshold 0.4
+
// Table cells (TextColumns) are allowed to overlap by this much
// in table layout mode (as a fraction of cell width or height).
#define tableCellOverlapSlack 0.05
@@ -142,6 +147,14 @@
// fraction of font size).
#define hyperlinkSlack 0.2
+// Text is considered diagonal if abs(tan(angle)) > diagonalThreshold.
+// (Or 1/tan(angle) for 90/270 degrees.)
+#define diagonalThreshold 0.1
+
+// This value is used as the ascent when computing selection
+// rectangles, in order to work around flakey ascent values in fonts.
+#define selectionAscent 0.8
+
//------------------------------------------------------------------------
// TextChar
//------------------------------------------------------------------------
@@ -165,6 +178,7 @@ public:
Guchar rot;
char clipped;
char invisible;
+ char spaceAfter;
TextFontInfo *font;
double fontSize;
double colorR,
@@ -194,9 +208,25 @@ TextChar::TextChar(Unicode cA, int charPosA, int charLenA,
if (yMin > yMax) {
t = yMin; yMin = yMax; yMax = t;
}
+ // TextPage::findGaps uses integer coordinates, so clip the char
+ // bbox to fit in a 32-bit int (this is generally only a problem in
+ // damaged PDF files)
+ if (xMin < -1e8) {
+ xMin = -1e8;
+ }
+ if (xMax > 1e8) {
+ xMax = 1e8;
+ }
+ if (yMin < -1e8) {
+ yMin = -1e8;
+ }
+ if (yMax > 1e8) {
+ yMax = 1e8;
+ }
rot = (Guchar)rotA;
clipped = (char)clippedA;
invisible = (char)invisibleA;
+ spaceAfter = (char)gFalse;
font = fontA;
fontSize = fontSizeA;
colorR = colorRA;
@@ -243,6 +273,7 @@ enum TextBlockType {
enum TextBlockTag {
blkTagMulticolumn,
blkTagColumn,
+ blkTagSuperLine,
blkTagLine
};
@@ -252,7 +283,7 @@ public:
TextBlock(TextBlockType typeA, int rotA);
~TextBlock();
void addChild(TextBlock *child);
- void addChild(TextChar *child);
+ void addChild(TextChar *child, GBool updateBox);
void prependChild(TextChar *child);
void updateBounds(int childIdx);
@@ -306,24 +337,26 @@ void TextBlock::addChild(TextBlock *child) {
children->append(child);
}
-void TextBlock::addChild(TextChar *child) {
- if (children->getLength() == 0) {
- xMin = child->xMin;
- yMin = child->yMin;
- xMax = child->xMax;
- yMax = child->yMax;
- } else {
- if (child->xMin < xMin) {
+void TextBlock::addChild(TextChar *child, GBool updateBox) {
+ if (updateBox) {
+ if (children->getLength() == 0) {
xMin = child->xMin;
- }
- if (child->yMin < yMin) {
yMin = child->yMin;
- }
- if (child->xMax > xMax) {
xMax = child->xMax;
- }
- if (child->yMax > yMax) {
yMax = child->yMax;
+ } else {
+ if (child->xMin < xMin) {
+ xMin = child->xMin;
+ }
+ if (child->yMin < yMin) {
+ yMin = child->yMin;
+ }
+ if (child->xMax > xMax) {
+ xMax = child->xMax;
+ }
+ if (child->yMax > yMax) {
+ yMax = child->yMax;
+ }
}
}
children->append(child);
@@ -371,6 +404,57 @@ void TextBlock::updateBounds(int childIdx) {
}
//------------------------------------------------------------------------
+// TextGap
+//------------------------------------------------------------------------
+
+class TextGap {
+public:
+
+ TextGap(double aXY, double aW): xy(aXY), w(aW) {}
+
+ double xy; // center of gap: x for vertical gaps,
+ // y for horizontal gaps
+ double w; // width of gap
+};
+
+//------------------------------------------------------------------------
+// TextSuperLine
+//------------------------------------------------------------------------
+
+class TextSuperLine {
+public:
+
+ TextSuperLine(GList *linesA);
+ ~TextSuperLine();
+
+ GList *lines; // [TextLine]
+ double yMin, yMax;
+ double fontSize;
+};
+
+TextSuperLine::TextSuperLine(GList *linesA) {
+ TextLine *line;
+ int i;
+
+ lines = linesA;
+ yMin = yMax = 0;
+ fontSize = ((TextLine *)lines->get(0))->fontSize;
+ for (i = 0; i < lines->getLength(); ++i) {
+ line = (TextLine *)lines->get(i);
+ if (i == 0 || line->yMin < yMin) {
+ yMin = line->yMin;
+ }
+ if (i == 0 || line->yMax > yMax) {
+ yMax = line->yMax;
+ }
+ }
+}
+
+TextSuperLine::~TextSuperLine() {
+ deleteGList(lines, TextLine);
+}
+
+//------------------------------------------------------------------------
// TextUnderline
//------------------------------------------------------------------------
@@ -417,6 +501,10 @@ TextOutputControl::TextOutputControl() {
fixedLineSpacing = 0;
html = gFalse;
clipText = gFalse;
+ discardDiagonalText = gFalse;
+ discardInvisibleText = gFalse;
+ discardClippedText = gFalse;
+ insertBOM = gFalse;
}
@@ -489,7 +577,7 @@ GBool TextFontInfo::matches(GfxState *state) {
// Build a TextWord object, using chars[start .. start+len-1].
// (If rot >= 2, the chars list is in reverse order.)
TextWord::TextWord(GList *chars, int start, int lenA,
- int rotA, GBool spaceAfterA) {
+ int rotA, int dirA, GBool spaceAfterA) {
TextChar *ch;
int i;
@@ -498,40 +586,20 @@ TextWord::TextWord(GList *chars, int start, int lenA,
text = (Unicode *)gmallocn(len, sizeof(Unicode));
edge = (double *)gmallocn(len + 1, sizeof(double));
charPos = (int *)gmallocn(len + 1, sizeof(int));
- switch (rot) {
- case 0:
- default:
- ch = (TextChar *)chars->get(start);
- xMin = ch->xMin;
- yMin = ch->yMin;
- yMax = ch->yMax;
- ch = (TextChar *)chars->get(start + len - 1);
- xMax = ch->xMax;
- break;
- case 1:
+ if (rot & 1) {
ch = (TextChar *)chars->get(start);
xMin = ch->xMin;
xMax = ch->xMax;
yMin = ch->yMin;
ch = (TextChar *)chars->get(start + len - 1);
yMax = ch->yMax;
- break;
- case 2:
+ } else {
ch = (TextChar *)chars->get(start);
- xMax = ch->xMax;
+ xMin = ch->xMin;
yMin = ch->yMin;
yMax = ch->yMax;
ch = (TextChar *)chars->get(start + len - 1);
- xMin = ch->xMin;
- break;
- case 3:
- ch = (TextChar *)chars->get(start);
- xMin = ch->xMin;
xMax = ch->xMax;
- yMax = ch->yMax;
- ch = (TextChar *)chars->get(start + len - 1);
- yMin = ch->yMin;
- break;
}
for (i = 0; i < len; ++i) {
ch = (TextChar *)chars->get(rot >= 2 ? start + len - 1 - i : start + i);
@@ -571,6 +639,7 @@ TextWord::TextWord(GList *chars, int start, int lenA,
ch = (TextChar *)chars->get(start);
font = ch->font;
fontSize = ch->fontSize;
+ dir = dirA;
spaceAfter = spaceAfterA;
underlined = gFalse;
link = NULL;
@@ -596,48 +665,6 @@ TextWord::~TextWord() {
gfree(charPos);
}
-// This is used to append a clipped character to a word.
-void TextWord::appendChar(TextChar *ch) {
- if (ch->xMin < xMin) {
- xMin = ch->xMin;
- }
- if (ch->xMax > xMax) {
- xMax = ch->xMax;
- }
- if (ch->yMin < yMin) {
- yMin = ch->yMin;
- }
- if (ch->yMax > yMax) {
- yMax = ch->yMax;
- }
- text = (Unicode *)greallocn(text, len + 1, sizeof(Unicode));
- edge = (double *)greallocn(edge, len + 2, sizeof(double));
- charPos = (int *)greallocn(charPos, len + 2, sizeof(int));
- text[len] = ch->c;
- charPos[len] = ch->charPos;
- charPos[len+1] = ch->charPos + ch->charLen;
- switch (rot) {
- case 0:
- default:
- edge[len] = ch->xMin;
- edge[len+1] = ch->xMax;
- break;
- case 1:
- edge[len] = ch->yMin;
- edge[len+1] = ch->yMax;
- break;
- case 2:
- edge[len] = ch->xMax;
- edge[len+1] = ch->xMin;
- break;
- case 3:
- edge[len] = ch->yMax;
- edge[len+1] = ch->yMin;
- break;
- }
- ++len;
-}
-
int TextWord::cmpYX(const void *p1, const void *p2) {
const TextWord *word1 = *(const TextWord **)p1;
const TextWord *word2 = *(const TextWord **)p2;
@@ -784,19 +811,19 @@ TextLine::~TextLine() {
}
double TextLine::getBaseline() {
- TextWord *word0;
+ return ((TextWord *)words->get(0))->getBaseline();
+}
- word0 = (TextWord *)words->get(0);
- switch (rot) {
- case 0:
- default:
- return yMax + fontSize * word0->font->descent;
- case 1:
- return xMin - fontSize * word0->font->descent;
- case 2:
- return yMin - fontSize * word0->font->descent;
- case 3:
- return xMax + fontSize * word0->font->descent;
+int TextLine::cmpX(const void *p1, const void *p2) {
+ const TextLine *line1 = *(const TextLine **)p1;
+ const TextLine *line2 = *(const TextLine **)p2;
+
+ if (line1->xMin < line2->xMin) {
+ return -1;
+ } else if (line1->xMin > line2->xMin) {
+ return 1;
+ } else {
+ return 0;
}
}
@@ -804,11 +831,12 @@ double TextLine::getBaseline() {
// TextParagraph
//------------------------------------------------------------------------
-TextParagraph::TextParagraph(GList *linesA) {
+TextParagraph::TextParagraph(GList *linesA, GBool dropCapA) {
TextLine *line;
int i;
lines = linesA;
+ dropCap = dropCapA;
xMin = yMin = xMax = yMax = 0;
for (i = 0; i < lines->getLength(); ++i) {
line = (TextLine *)lines->get(i);
@@ -850,6 +878,15 @@ TextColumn::~TextColumn() {
deleteGList(paragraphs, TextParagraph);
}
+int TextColumn::getRotation() {
+ TextParagraph *par;
+ TextLine *line;
+
+ par = (TextParagraph *)paragraphs->get(0);
+ line = (TextLine *)par->getLines()->get(0);
+ return line->getRotation();
+}
+
int TextColumn::cmpX(const void *p1, const void *p2) {
const TextColumn *col1 = *(const TextColumn **)p1;
const TextColumn *col2 = *(const TextColumn **)p2;
@@ -893,8 +930,9 @@ int TextColumn::cmpPX(const void *p1, const void *p2) {
// TextWordList
//------------------------------------------------------------------------
-TextWordList::TextWordList(GList *wordsA) {
+TextWordList::TextWordList(GList *wordsA, GBool primaryLRA) {
words = wordsA;
+ primaryLR = primaryLRA;
}
TextWordList::~TextWordList() {
@@ -913,6 +951,44 @@ TextWord *TextWordList::get(int idx) {
}
//------------------------------------------------------------------------
+// TextPosition
+//------------------------------------------------------------------------
+
+int TextPosition::operator==(TextPosition pos) {
+ return colIdx == pos.colIdx &&
+ parIdx == pos.parIdx &&
+ lineIdx == pos.lineIdx &&
+ charIdx == pos.charIdx;
+}
+
+int TextPosition::operator!=(TextPosition pos) {
+ return colIdx != pos.colIdx ||
+ parIdx != pos.parIdx ||
+ lineIdx != pos.lineIdx ||
+ charIdx != pos.charIdx;
+}
+
+int TextPosition::operator<(TextPosition pos) {
+ return colIdx < pos.colIdx ||
+ (colIdx == pos.colIdx &&
+ (parIdx < pos.parIdx ||
+ (parIdx == pos.parIdx &&
+ (lineIdx < pos.lineIdx ||
+ (lineIdx == pos.lineIdx &&
+ charIdx < pos.charIdx)))));
+}
+
+int TextPosition::operator>(TextPosition pos) {
+ return colIdx > pos.colIdx ||
+ (colIdx == pos.colIdx &&
+ (parIdx > pos.parIdx ||
+ (parIdx == pos.parIdx &&
+ (lineIdx > pos.lineIdx ||
+ (lineIdx == pos.lineIdx &&
+ charIdx > pos.charIdx)))));
+}
+
+//------------------------------------------------------------------------
// TextPage
//------------------------------------------------------------------------
@@ -923,6 +999,7 @@ TextPage::TextPage(TextOutputControl *controlA) {
curFont = NULL;
curFontSize = 0;
curRot = 0;
+ diagonal = gFalse;
nTinyChars = 0;
actualText = NULL;
actualTextLen = 0;
@@ -939,9 +1016,10 @@ TextPage::TextPage(TextOutputControl *controlA) {
links = new GList();
findCols = NULL;
- findLR = gTrue;
lastFindXMin = lastFindYMin = 0;
haveLastFind = gFalse;
+
+ problematic = gFalse;
}
TextPage::~TextPage() {
@@ -971,6 +1049,7 @@ void TextPage::clear() {
curFont = NULL;
curFontSize = 0;
curRot = 0;
+ diagonal = gFalse;
nTinyChars = 0;
gfree(actualText);
actualText = NULL;
@@ -989,9 +1068,10 @@ void TextPage::clear() {
deleteGList(findCols, TextColumn);
findCols = NULL;
}
- findLR = gTrue;
lastFindXMin = lastFindYMin = 0;
haveLastFind = gFalse;
+
+ problematic = gFalse;
}
void TextPage::updateFont(GfxState *state) {
@@ -1015,6 +1095,9 @@ void TextPage::updateFont(GfxState *state) {
if (!curFont) {
curFont = new TextFontInfo(state);
fonts->append(curFont);
+ if (state->getFont() && state->getFont()->problematicForUnicode()) {
+ problematic = gTrue;
+ }
}
// adjust the font size
@@ -1075,10 +1158,20 @@ void TextPage::updateFont(GfxState *state) {
m[2] = m2[2];
m[3] = m2[3];
}
- if (fabs(m[0] * m[3]) > fabs(m[1] * m[2])) {
- curRot = (m[0] > 0 || m[3] < 0) ? 0 : 2;
+ if (fabs(m[0]) >= fabs(m[1])) {
+ if (m[0] > 0) {
+ curRot = 0;
+ } else {
+ curRot = 2;
+ }
+ diagonal = fabs(m[1]) > diagonalThreshold * fabs(m[0]);
} else {
- curRot = (m[2] > 0) ? 1 : 3;
+ if (m[1] > 0) {
+ curRot = 1;
+ } else {
+ curRot = 3;
+ }
+ diagonal = fabs(m[0]) > diagonalThreshold * fabs(m[1]);
}
}
@@ -1086,9 +1179,10 @@ void TextPage::addChar(GfxState *state, double x, double y,
double dx, double dy,
CharCode c, int nBytes, Unicode *u, int uLen) {
double x1, y1, x2, y2, w1, h1, dx2, dy2, ascent, descent, sp;
- double xMin, yMin, xMax, yMax;
+ double xMin, yMin, xMax, yMax, xMid, yMid;
double clipXMin, clipYMin, clipXMax, clipYMax;
GfxRGB rgb;
+ double alpha;
GBool clipped, rtl;
int i, j;
@@ -1105,6 +1199,12 @@ void TextPage::addChar(GfxState *state, double x, double y,
return;
}
+ // throw away diagonal chars
+ if (control.discardDiagonalText && diagonal) {
+ charPos += nBytes;
+ return;
+ }
+
// subtract char and word spacing from the dx,dy values
sp = state->getCharSpace();
if (c == (CharCode)0x20) {
@@ -1134,20 +1234,16 @@ void TextPage::addChar(GfxState *state, double x, double y,
}
}
- // skip space characters
- if (uLen == 1 && u[0] == (Unicode)0x20) {
+ // skip space, tab, and non-breaking space characters
+ if (uLen == 1 && (u[0] == (Unicode)0x20 ||
+ u[0] == (Unicode)0x09 ||
+ u[0] == (Unicode)0xa0)) {
charPos += nBytes;
- return;
- }
-
- // check for clipping
- clipped = gFalse;
- if (control.clipText) {
- state->getClipBBox(&clipXMin, &clipYMin, &clipXMax, &clipYMax);
- if (x1 + 0.1 * w1 < clipXMin || x1 + 0.9 * w1 > clipXMax ||
- y1 + 0.1 * h1 < clipYMin || y1 + 0.9 * h1 > clipYMax) {
- clipped = gTrue;
+ if (chars->getLength() > 0) {
+ ((TextChar *)chars->get(chars->getLength() - 1))->spaceAfter =
+ (char)gTrue;
}
+ return;
}
// add the characters
@@ -1168,6 +1264,7 @@ void TextPage::addChar(GfxState *state, double x, double y,
rtl = gFalse;
}
+ // compute the bounding box
w1 /= uLen;
h1 /= uLen;
ascent = curFont->ascent * curFontSize;
@@ -1202,10 +1299,25 @@ void TextPage::addChar(GfxState *state, double x, double y,
yMax = y2;
break;
}
+
+ // check for clipping
+ clipped = gFalse;
+ if (control.clipText || control.discardClippedText) {
+ state->getClipBBox(&clipXMin, &clipYMin, &clipXMax, &clipYMax);
+ xMid = 0.5 * (xMin + xMax);
+ yMid = 0.5 * (yMin + yMax);
+ if (xMid < clipXMin || xMid > clipXMax ||
+ yMid < clipYMin || yMid > clipYMax) {
+ clipped = gTrue;
+ }
+ }
+
if ((state->getRender() & 3) == 1) {
state->getStrokeRGB(&rgb);
+ alpha = state->getStrokeOpacity();
} else {
state->getFillRGB(&rgb);
+ alpha = state->getFillOpacity();
}
if (rtl) {
j = uLen - 1 - i;
@@ -1214,7 +1326,7 @@ void TextPage::addChar(GfxState *state, double x, double y,
}
chars->append(new TextChar(u[j], charPos, nBytes, xMin, yMin, xMax, yMax,
curRot, clipped,
- state->getRender() == 3,
+ state->getRender() == 3 || alpha < 0.001,
curFont, curFontSize,
colToDbl(rgb.r), colToDbl(rgb.g),
colToDbl(rgb.b)));
@@ -1312,6 +1424,10 @@ void TextPage::write(void *outputStream, TextOutputFunc outputFunc) {
writePhysLayout(outputStream, outputFunc, uMap, space, spaceLen,
eol, eolLen);
break;
+ case textOutSimpleLayout:
+ writeSimpleLayout(outputStream, outputFunc, uMap, space, spaceLen,
+ eol, eolLen);
+ break;
case textOutLinePrinter:
writeLinePrinter(outputStream, outputFunc, uMap, space, spaceLen,
eol, eolLen);
@@ -1355,7 +1471,7 @@ void TextPage::writeReadingOrder(void *outputStream,
unrotateChars(chars, rot);
return;
}
- columns = buildColumns(tree);
+ columns = buildColumns(tree, primaryLR);
delete tree;
unrotateChars(chars, rot);
if (control.html) {
@@ -1395,14 +1511,20 @@ void TextPage::writeReadingOrder(void *outputStream,
GList *TextPage::makeColumns() {
TextBlock *tree;
GList *columns;
+ GBool primaryLR;
+ int rot;
- tree = splitChars(chars);
- if (!tree) {
+ rot = rotateChars(chars);
+ primaryLR = checkPrimaryLR(chars);
+ if ((tree = splitChars(chars))) {
+ columns = buildColumns(tree, primaryLR);
+ delete tree;
+ } else {
// no text
- return new GList();
+ columns = new GList();
}
- columns = buildColumns(tree);
- delete tree;
+ unrotateChars(chars, rot);
+ unrotateColumns(columns, rot);
if (control.html) {
generateUnderlinesAndLinks(columns);
}
@@ -1428,6 +1550,9 @@ void TextPage::writePhysLayout(void *outputStream,
#if 0 //~debug
dumpChars(chars);
#endif
+#if 0 //~debug
+ dumpUnderlines();
+#endif
rot = rotateChars(chars);
primaryLR = checkPrimaryLR(chars);
tree = splitChars(chars);
@@ -1439,7 +1564,8 @@ void TextPage::writePhysLayout(void *outputStream,
unrotateChars(chars, rot);
return;
}
- columns = buildColumns(tree);
+ //~ this doesn't correctly handle the right-to-left case
+ columns = buildColumns(tree, gTrue);
delete tree;
unrotateChars(chars, rot);
if (control.html) {
@@ -1501,6 +1627,66 @@ void TextPage::writePhysLayout(void *outputStream,
deleteGList(columns, TextColumn);
}
+void TextPage::writeSimpleLayout(void *outputStream,
+ TextOutputFunc outputFunc,
+ UnicodeMap *uMap,
+ char *space, int spaceLen,
+ char *eol, int eolLen) {
+ TextBlock *tree;
+ TextSuperLine *superLine0, *superLine1;
+ TextLine *line;
+ GList *superLines;
+ GString *out;
+ GBool primaryLR;
+ int rot, x, i, j;
+
+#if 0 //~debug
+ dumpChars(chars);
+#endif
+ rot = rotateChars(chars);
+ primaryLR = checkPrimaryLR(chars);
+ tree = splitChars(chars);
+#if 0 //~debug
+ dumpTree(tree);
+#endif
+ if (!tree) {
+ // no text
+ unrotateChars(chars, rot);
+ return;
+ }
+ superLines = new GList();
+ buildSuperLines(tree, superLines);
+ delete tree;
+ unrotateChars(chars, rot);
+ assignSimpleLayoutPositions(superLines, uMap);
+
+ for (i = 0; i < superLines->getLength(); ++i) {
+ superLine0 = (TextSuperLine *)superLines->get(i);
+ out = new GString();
+ x = 0;
+ for (j = 0; j < superLine0->lines->getLength(); ++j) {
+ line = (TextLine *)superLine0->lines->get(j);
+ while (x < line->px) {
+ out->append(space, spaceLen);
+ ++x;
+ }
+ encodeFragment(line->text, line->len, uMap, primaryLR, out);
+ x += line->pw;
+ }
+ (*outputFunc)(outputStream, out->getCString(), out->getLength());
+ delete out;
+ (*outputFunc)(outputStream, eol, eolLen);
+ if (i + 1 < superLines->getLength()) {
+ superLine1 = (TextSuperLine *)superLines->get(i + 1);
+ if (superLine1->yMin - superLine0->yMax > 1.0 * superLine0->fontSize) {
+ (*outputFunc)(outputStream, eol, eolLen);
+ }
+ }
+ }
+
+ deleteGList(superLines, TextSuperLine);
+}
+
void TextPage::writeLinePrinter(void *outputStream,
TextOutputFunc outputFunc,
UnicodeMap *uMap,
@@ -2027,7 +2213,7 @@ void TextPage::unrotateColumns(GList *columns, int rot) {
TextParagraph *par;
TextLine *line;
TextWord *word;
- double xMin, yMin, xMax, yMax, t;
+ double xMin, yMin, xMax, yMax;
int colIdx, parIdx, lineIdx, wordIdx, i;
switch (rot) {
@@ -2036,9 +2222,8 @@ void TextPage::unrotateColumns(GList *columns, int rot) {
// no transform
break;
case 1:
- t = pageWidth;
- pageWidth = pageHeight;
- pageHeight = t;
+ // NB: this is called after unrotateChars(), which will have
+ // swapped pageWidth and pageHeight already.
for (colIdx = 0; colIdx < columns->getLength(); ++colIdx) {
col = (TextColumn *)columns->get(colIdx);
xMin = pageWidth - col->yMax;
@@ -2074,6 +2259,11 @@ void TextPage::unrotateColumns(GList *columns, int rot) {
line->yMin = yMin;
line->yMax = yMax;
line->rot = (line->rot + 1) & 3;
+ if (!(line->rot & 1)) {
+ for (i = 0; i <= line->len; ++i) {
+ line->edge[i] = pageWidth - line->edge[i];
+ }
+ }
for (wordIdx = 0; wordIdx < line->words->getLength(); ++wordIdx) {
word = (TextWord *)line->words->get(wordIdx);
xMin = pageWidth - word->yMax;
@@ -2085,6 +2275,11 @@ void TextPage::unrotateColumns(GList *columns, int rot) {
word->yMin = yMin;
word->yMax = yMax;
word->rot = (word->rot + 1) & 3;
+ if (!(word->rot & 1)) {
+ for (i = 0; i <= word->len; ++i) {
+ word->edge[i] = pageWidth - word->edge[i];
+ }
+ }
}
}
}
@@ -2126,8 +2321,14 @@ void TextPage::unrotateColumns(GList *columns, int rot) {
line->yMin = yMin;
line->yMax = yMax;
line->rot = (line->rot + 2) & 3;
- for (i = 0; i <= line->len; ++i) {
- line->edge[i] = pageWidth - line->edge[i];
+ if (line->rot & 1) {
+ for (i = 0; i <= line->len; ++i) {
+ line->edge[i] = pageHeight - line->edge[i];
+ }
+ } else {
+ for (i = 0; i <= line->len; ++i) {
+ line->edge[i] = pageWidth - line->edge[i];
+ }
}
for (wordIdx = 0; wordIdx < line->words->getLength(); ++wordIdx) {
word = (TextWord *)line->words->get(wordIdx);
@@ -2140,8 +2341,14 @@ void TextPage::unrotateColumns(GList *columns, int rot) {
word->yMin = yMin;
word->yMax = yMax;
word->rot = (word->rot + 2) & 3;
- for (i = 0; i <= word->len; ++i) {
- word->edge[i] = pageWidth - word->edge[i];
+ if (word->rot & 1) {
+ for (i = 0; i <= word->len; ++i) {
+ word->edge[i] = pageHeight - word->edge[i];
+ }
+ } else {
+ for (i = 0; i <= word->len; ++i) {
+ word->edge[i] = pageWidth - word->edge[i];
+ }
}
}
}
@@ -2149,9 +2356,8 @@ void TextPage::unrotateColumns(GList *columns, int rot) {
}
break;
case 3:
- t = pageWidth;
- pageWidth = pageHeight;
- pageHeight = t;
+ // NB: this is called after unrotateChars(), which will have
+ // swapped pageWidth and pageHeight already.
for (colIdx = 0; colIdx < columns->getLength(); ++colIdx) {
col = (TextColumn *)columns->get(colIdx);
xMin = col->yMin;
@@ -2187,8 +2393,10 @@ void TextPage::unrotateColumns(GList *columns, int rot) {
line->yMin = yMin;
line->yMax = yMax;
line->rot = (line->rot + 3) & 3;
- for (i = 0; i <= line->len; ++i) {
- line->edge[i] = pageHeight - line->edge[i];
+ if (line->rot & 1) {
+ for (i = 0; i <= line->len; ++i) {
+ line->edge[i] = pageHeight - line->edge[i];
+ }
}
for (wordIdx = 0; wordIdx < line->words->getLength(); ++wordIdx) {
word = (TextWord *)line->words->get(wordIdx);
@@ -2201,8 +2409,10 @@ void TextPage::unrotateColumns(GList *columns, int rot) {
word->yMin = yMin;
word->yMax = yMax;
word->rot = (word->rot + 3) & 3;
- for (i = 0; i <= word->len; ++i) {
- word->edge[i] = pageHeight - word->edge[i];
+ if (word->rot & 1) {
+ for (i = 0; i <= word->len; ++i) {
+ word->edge[i] = pageHeight - word->edge[i];
+ }
}
}
}
@@ -2234,6 +2444,11 @@ void TextPage::unrotateWords(GList *words, int rot) {
word->yMin = yMin;
word->yMax = yMax;
word->rot = (word->rot + 1) & 3;
+ if (!(word->rot & 1)) {
+ for (j = 0; j <= word->len; ++j) {
+ word->edge[j] = pageWidth - word->edge[j];
+ }
+ }
}
break;
case 2:
@@ -2248,8 +2463,14 @@ void TextPage::unrotateWords(GList *words, int rot) {
word->yMin = yMin;
word->yMax = yMax;
word->rot = (word->rot + 2) & 3;
- for (j = 0; j <= word->len; ++j) {
- word->edge[j] = pageWidth - word->edge[j];
+ if (word->rot & 1) {
+ for (j = 0; j <= word->len; ++j) {
+ word->edge[j] = pageHeight - word->edge[j];
+ }
+ } else {
+ for (j = 0; j <= word->len; ++j) {
+ word->edge[j] = pageWidth - word->edge[j];
+ }
}
}
break;
@@ -2265,8 +2486,10 @@ void TextPage::unrotateWords(GList *words, int rot) {
word->yMin = yMin;
word->yMax = yMax;
word->rot = (word->rot + 3) & 3;
- for (j = 0; j <= word->len; ++j) {
- word->edge[j] = pageHeight - word->edge[j];
+ if (word->rot & 1) {
+ for (j = 0; j <= word->len; ++j) {
+ word->edge[j] = pageHeight - word->edge[j];
+ }
}
}
break;
@@ -2313,6 +2536,9 @@ void TextPage::removeDuplicates(GList *charsA, int rot) {
fabs(ch2->xMin - ch->xMin) < xDelta &&
fabs(ch2->xMax - ch->xMax) < xDelta &&
fabs(ch2->yMax - ch->yMax) < yDelta) {
+ if (ch2->spaceAfter) {
+ ch->spaceAfter = (char)gTrue;
+ }
charsA->del(j);
} else {
++j;
@@ -2358,7 +2584,9 @@ TextBlock *TextPage::splitChars(GList *charsA) {
chars2 = new GList();
for (i = 0; i < charsA->getLength(); ++i) {
ch = (TextChar *)charsA->get(i);
- if (ch->rot == rot) {
+ if (ch->rot == rot &&
+ !(control.discardInvisibleText && ch->invisible) &&
+ !(control.discardClippedText && ch->clipped)) {
chars2->append(ch);
}
}
@@ -2388,6 +2616,14 @@ TextBlock *TextPage::splitChars(GList *charsA) {
// if the page contains no (unclipped) text, just leave an empty
// column list
if (!tree[0]) {
+ // normally tree[0] is empty only if there is no text at all, but
+ // if the caller didn't do rotation, the rotated trees may be
+ // non-empty, so we need to free them
+ for (rot = 1; rot < 4; ++rot) {
+ if (tree[rot]) {
+ delete tree[rot];
+ }
+ }
delete clippedChars;
return NULL;
}
@@ -2425,177 +2661,83 @@ TextBlock *TextPage::splitChars(GList *charsA) {
TextBlock *TextPage::split(GList *charsA, int rot) {
TextBlock *blk;
GList *chars2, *chars3;
- int *horizProfile, *vertProfile;
- double xMin, yMin, xMax, yMax;
- int xMinI, yMinI, xMaxI, yMaxI;
- int xMinI2, yMinI2, xMaxI2, yMaxI2;
+ GList *horizGaps, *vertGaps;
+ TextGap *gap;
TextChar *ch;
- double minFontSize, avgFontSize, splitPrecision;
- double nLines, vertGapThreshold, ascentAdjust, descentAdjust, minChunk;
- int horizGapSize, vertGapSize;
- double horizGapSize2, vertGapSize2;
- int minHorizChunkWidth, minVertChunkWidth, nHorizGaps, nVertGaps;
+ double xMin, yMin, xMax, yMax, avgFontSize;
+ double horizGapSize, vertGapSize, minHorizChunkWidth, minVertChunkWidth;
+ double nLines, vertGapThreshold, minChunk;
double largeCharSize;
- int nLargeChars;
+ double x0, x1, y0, y1;
+ int nHorizGaps, nVertGaps, nLargeChars;
+ int i;
GBool doHorizSplit, doVertSplit, smallSplit;
- int i, x, y, prev, start;
-
- //----- compute bbox, min font size, average font size, and
- // split precision for this block
-
- xMin = yMin = xMax = yMax = 0; // make gcc happy
- minFontSize = avgFontSize = 0;
- for (i = 0; i < charsA->getLength(); ++i) {
- ch = (TextChar *)charsA->get(i);
- if (i == 0 || ch->xMin < xMin) {
- xMin = ch->xMin;
- }
- if (i == 0 || ch->yMin < yMin) {
- yMin = ch->yMin;
- }
- if (i == 0 || ch->xMax > xMax) {
- xMax = ch->xMax;
- }
- if (i == 0 || ch->yMax > yMax) {
- yMax = ch->yMax;
- }
- avgFontSize += ch->fontSize;
- if (i == 0 || ch->fontSize < minFontSize) {
- minFontSize = ch->fontSize;
- }
- }
- avgFontSize /= charsA->getLength();
- splitPrecision = splitPrecisionMul * minFontSize;
- if (splitPrecision < minSplitPrecision) {
- splitPrecision = minSplitPrecision;
- }
- //----- compute the horizontal and vertical profiles
+ //----- find all horizontal and vertical gaps
- // 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));
- 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);
- ascentAdjust = ascentAdjustFactor * (ch->yMax - ch->yMin);
- yMinI2 = (int)floor((ch->yMin + ascentAdjust) / splitPrecision);
- descentAdjust = descentAdjustFactor * (ch->yMax - ch->yMin);
- yMaxI2 = (int)floor((ch->yMax - descentAdjust) / splitPrecision);
- break;
- case 1:
- descentAdjust = descentAdjustFactor * (ch->xMax - ch->xMin);
- xMinI2 = (int)floor((ch->xMin + descentAdjust) / splitPrecision);
- 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);
- break;
- case 2:
- xMinI2 = (int)floor(ch->xMin / splitPrecision);
- xMaxI2 = (int)floor(ch->xMax / splitPrecision);
- descentAdjust = descentAdjustFactor * (ch->yMax - ch->yMin);
- yMinI2 = (int)floor((ch->yMin + descentAdjust) / splitPrecision);
- ascentAdjust = ascentAdjustFactor * (ch->yMax - ch->yMin);
- yMaxI2 = (int)floor((ch->yMax - ascentAdjust) / splitPrecision);
- break;
- case 3:
- ascentAdjust = ascentAdjustFactor * (ch->xMax - ch->xMin);
- xMinI2 = (int)floor((ch->xMin + ascentAdjust) / splitPrecision);
- 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);
- break;
- }
- for (y = yMinI2; y <= yMaxI2; ++y) {
- ++horizProfile[y - yMinI];
- }
- for (x = xMinI2; x <= xMaxI2; ++x) {
- ++vertProfile[x - xMinI];
- }
- }
+ horizGaps = new GList();
+ vertGaps = new GList();
+ findGaps(charsA, rot, &xMin, &yMin, &xMax, &yMax, &avgFontSize,
+ horizGaps, vertGaps);
- //----- find the largest gaps in the horizontal and vertical profiles
+ //----- find the largest horizontal and vertical gaps
horizGapSize = 0;
- for (start = yMinI; start < yMaxI && !horizProfile[start - yMinI]; ++start) ;
- for (y = start; y < yMaxI; ++y) {
- if (horizProfile[y - yMinI] && !horizProfile[y + 1 - yMinI]) {
- start = y;
- } else if (!horizProfile[y - yMinI] && horizProfile[y + 1 - yMinI]) {
- if (y - start > horizGapSize) {
- horizGapSize = y - start;
- }
+ for (i = 0; i < horizGaps->getLength(); ++i) {
+ gap = (TextGap *)horizGaps->get(i);
+ if (gap->w > horizGapSize) {
+ horizGapSize = gap->w;
}
}
vertGapSize = 0;
- for (start = xMinI; start < xMaxI && !vertProfile[start - xMinI]; ++start) ;
- for (x = start; x < xMaxI; ++x) {
- if (vertProfile[x - xMinI] && !vertProfile[x + 1 - xMinI]) {
- start = x;
- } else if (!vertProfile[x - xMinI] && vertProfile[x + 1 - xMinI]) {
- if (x - start > vertGapSize) {
- vertGapSize = x - start;
- }
+ for (i = 0; i < vertGaps->getLength(); ++i) {
+ gap = (TextGap *)vertGaps->get(i);
+ if (gap->w > vertGapSize) {
+ vertGapSize = gap->w;
}
}
- horizGapSize2 = horizGapSize - splitGapSlack * avgFontSize / splitPrecision;
- if (horizGapSize2 < 0.99) {
- horizGapSize2 = 0.99;
- }
- vertGapSize2 = vertGapSize - splitGapSlack * avgFontSize / splitPrecision;
- if (vertGapSize2 < 0.99) {
- vertGapSize2 = 0.99;
- }
//----- count horiz/vert gaps equivalent to largest gaps
- minHorizChunkWidth = yMaxI - yMinI;
+ minHorizChunkWidth = yMax - yMin;
nHorizGaps = 0;
- for (start = yMinI; start < yMaxI && !horizProfile[start - yMinI]; ++start) ;
- prev = start - 1;
- for (y = start; y < yMaxI; ++y) {
- if (horizProfile[y - yMinI] && !horizProfile[y + 1 - yMinI]) {
- start = y;
- } else if (!horizProfile[y - yMinI] && horizProfile[y + 1 - yMinI]) {
- if (y - start > horizGapSize2) {
+ if (horizGaps->getLength() > 0) {
+ y0 = yMin;
+ for (i = 0; i < horizGaps->getLength(); ++i) {
+ gap = (TextGap *)horizGaps->get(i);
+ if (gap->w > horizGapSize - splitGapSlack * avgFontSize) {
++nHorizGaps;
- if (start - prev < minHorizChunkWidth) {
- minHorizChunkWidth = start - prev;
+ y1 = gap->xy - 0.5 * gap->w;
+ if (y1 - y0 < minHorizChunkWidth) {
+ minHorizChunkWidth = y1 - y0;
}
- prev = y;
+ y0 = y1 + gap->w;
}
}
+ y1 = yMax;
+ if (y1 - y0 < minHorizChunkWidth) {
+ minHorizChunkWidth = y1 - y0;
+ }
}
- minVertChunkWidth = xMaxI - xMinI;
+ minVertChunkWidth = xMax - xMin;
nVertGaps = 0;
- for (start = xMinI; start < xMaxI && !vertProfile[start - xMinI]; ++start) ;
- prev = start - 1;
- for (x = start; x < xMaxI; ++x) {
- if (vertProfile[x - xMinI] && !vertProfile[x + 1 - xMinI]) {
- start = x;
- } else if (!vertProfile[x - xMinI] && vertProfile[x + 1 - xMinI]) {
- if (x - start > vertGapSize2) {
+ if (vertGaps->getLength() > 0) {
+ x0 = xMin;
+ for (i = 0; i < vertGaps->getLength(); ++i) {
+ gap = (TextGap *)vertGaps->get(i);
+ if (gap->w > vertGapSize - splitGapSlack * avgFontSize) {
++nVertGaps;
- if (start - prev < minVertChunkWidth) {
- minVertChunkWidth = start - prev;
+ x1 = gap->xy - 0.5 * gap->w;
+ if (x1 - x0 < minVertChunkWidth) {
+ minVertChunkWidth = x1 - x0;
}
- prev = x;
+ x0 = x1 + gap->w;
}
}
+ x1 = xMax;
+ if (x1 - x0 < minVertChunkWidth) {
+ minVertChunkWidth = x1 - x0;
+ }
}
//----- compute splitting parameters
@@ -2617,19 +2759,21 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
if (vertGapThreshold < vertGapThresholdTableMin) {
vertGapThreshold = vertGapThresholdTableMin;
}
+ } else if (control.mode == textOutSimpleLayout) {
+ vertGapThreshold = simpleLayoutGapThreshold;
} else {
vertGapThreshold = vertGapThresholdMax + vertGapThresholdSlope * nLines;
if (vertGapThreshold < vertGapThresholdMin) {
vertGapThreshold = vertGapThresholdMin;
}
}
- vertGapThreshold = vertGapThreshold * avgFontSize / splitPrecision;
+ vertGapThreshold = vertGapThreshold * avgFontSize;
// compute the minimum allowed chunk width
if (control.mode == textOutTableLayout) {
minChunk = 0;
} else {
- minChunk = vertSplitChunkThreshold * avgFontSize / splitPrecision;
+ minChunk = vertSplitChunkThreshold * avgFontSize;
}
// look for large chars
@@ -2651,10 +2795,19 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
doHorizSplit = doVertSplit = gFalse;
smallSplit = gFalse;
if (rot & 1) {
- if (nHorizGaps > 0 &&
- (horizGapSize > vertGapSize || control.mode == textOutTableLayout) &&
- horizGapSize > vertGapThreshold &&
- minHorizChunkWidth > minChunk) {
+ if (control.mode == textOutSimpleLayout) {
+ if (nVertGaps > 0) {
+ doVertSplit = gTrue;
+ } else if (nHorizGaps > 0) {
+ doHorizSplit = gTrue;
+ smallSplit = horizGapSize <= vertGapThreshold;
+ }
+ } else if (nHorizGaps > 0 &&
+ (horizGapSize > vertGapSize ||
+ control.mode == textOutTableLayout) &&
+ horizGapSize > vertGapThreshold &&
+ (minHorizChunkWidth > minChunk ||
+ nVertGaps == 0)) {
doHorizSplit = gTrue;
} else if (nVertGaps > 0) {
doVertSplit = gTrue;
@@ -2663,10 +2816,19 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
smallSplit = gTrue;
}
} else {
- if (nVertGaps > 0 &&
- (vertGapSize > horizGapSize || control.mode == textOutTableLayout) &&
- vertGapSize > vertGapThreshold &&
- minVertChunkWidth > minChunk) {
+ if (control.mode == textOutSimpleLayout) {
+ if (nHorizGaps > 0) {
+ doHorizSplit = gTrue;
+ } else if (nVertGaps > 0) {
+ doVertSplit = gTrue;
+ smallSplit = vertGapSize <= vertGapThreshold;
+ }
+ } else if (nVertGaps > 0 &&
+ (vertGapSize > horizGapSize ||
+ control.mode == textOutTableLayout) &&
+ vertGapSize > vertGapThreshold &&
+ (minVertChunkWidth > minChunk ||
+ nHorizGaps == 0)) {
doVertSplit = gTrue;
} else if (nHorizGaps > 0) {
doHorizSplit = gTrue;
@@ -2683,56 +2845,68 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
// split vertically
if (doVertSplit) {
+#if 0 //~debug
+ 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);
+ }
+ }
+#endif
blk = new TextBlock(blkVertSplit, rot);
blk->smallSplit = smallSplit;
- for (start = xMinI; start < xMaxI && !vertProfile[start - xMinI]; ++start) ;
- prev = start - 1;
- for (x = start; x < xMaxI; ++x) {
- if (vertProfile[x - xMinI] && !vertProfile[x + 1 - xMinI]) {
- start = x;
- } else if (!vertProfile[x - xMinI] && vertProfile[x + 1 - xMinI]) {
- if (x - start > vertGapSize2) {
- chars2 = getChars(charsA, (prev + 0.5) * splitPrecision, yMin - 1,
- (start + 1.5) * splitPrecision, yMax + 1);
- blk->addChild(split(chars2, rot));
- delete chars2;
- prev = x;
- }
+ x0 = xMin - 1;
+ for (i = 0; i < vertGaps->getLength(); ++i) {
+ gap = (TextGap *)vertGaps->get(i);
+ if (gap->w > vertGapSize - splitGapSlack * avgFontSize) {
+ x1 = gap->xy;
+ chars2 = getChars(charsA, x0, yMin - 1, x1, yMax + 1);
+ blk->addChild(split(chars2, rot));
+ delete chars2;
+ x0 = x1;
}
}
- chars2 = getChars(charsA, (prev + 0.5) * splitPrecision, yMin - 1,
- xMax + 1, yMax + 1);
+ chars2 = getChars(charsA, x0, yMin - 1, xMax + 1, yMax + 1);
blk->addChild(split(chars2, rot));
delete chars2;
// split horizontally
} else if (doHorizSplit) {
+#if 0 //~debug
+ 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);
+ }
+ }
+#endif
blk = new TextBlock(blkHorizSplit, rot);
blk->smallSplit = smallSplit;
- for (start = yMinI;
- start < yMaxI && !horizProfile[start - yMinI];
- ++start) ;
- prev = start - 1;
- for (y = start; y < yMaxI; ++y) {
- if (horizProfile[y - yMinI] && !horizProfile[y + 1 - yMinI]) {
- start = y;
- } else if (!horizProfile[y - yMinI] && horizProfile[y + 1 - yMinI]) {
- if (y - start > horizGapSize2) {
- chars2 = getChars(charsA, xMin - 1, (prev + 0.5) * splitPrecision,
- xMax + 1, (start + 1.5) * splitPrecision);
- blk->addChild(split(chars2, rot));
- delete chars2;
- prev = y;
- }
+ y0 = yMin - 1;
+ for (i = 0; i < horizGaps->getLength(); ++i) {
+ gap = (TextGap *)horizGaps->get(i);
+ if (gap->w > horizGapSize - splitGapSlack * avgFontSize) {
+ y1 = gap->xy;
+ chars2 = getChars(charsA, xMin - 1, y0, xMax + 1, y1);
+ blk->addChild(split(chars2, rot));
+ delete chars2;
+ y0 = y1;
}
}
- chars2 = getChars(charsA, xMin - 1, (prev + 0.5) * splitPrecision,
- xMax + 1, yMax + 1);
+ chars2 = getChars(charsA, xMin - 1, y0, xMax + 1, yMax + 1);
blk->addChild(split(chars2, rot));
delete chars2;
// split into larger and smaller chars
} else if (nLargeChars > 0) {
+#if 0 //~debug
+ printf("large char split xMin=%g yMin=%g xMax=%g yMax=%g\n",
+ xMin, pageHeight - yMax, xMax, pageHeight - yMin);
+#endif
chars2 = new GList();
chars3 = new GList();
for (i = 0; i < charsA->getLength(); ++i) {
@@ -2750,14 +2924,18 @@ TextBlock *TextPage::split(GList *charsA, int rot) {
// create a leaf node
} else {
+#if 0 //~debug
+ printf("leaf xMin=%g yMin=%g xMax=%g yMax=%g\n",
+ xMin, pageHeight - yMax, xMax, pageHeight - yMin);
+#endif
blk = new TextBlock(blkLeaf, rot);
for (i = 0; i < charsA->getLength(); ++i) {
- blk->addChild((TextChar *)charsA->get(i));
+ blk->addChild((TextChar *)charsA->get(i), gTrue);
}
}
- gfree(horizProfile);
- gfree(vertProfile);
+ deleteGList(horizGaps, TextGap);
+ deleteGList(vertGaps, TextGap);
tagBlock(blk);
@@ -2787,6 +2965,148 @@ GList *TextPage::getChars(GList *charsA, double xMin, double yMin,
return ret;
}
+void TextPage::findGaps(GList *charsA, int rot,
+ double *xMinOut, double *yMinOut,
+ double *xMaxOut, double *yMaxOut,
+ double *avgFontSizeOut,
+ GList *horizGaps, GList *vertGaps) {
+ TextChar *ch;
+ int *horizProfile, *vertProfile;
+ double xMin, yMin, xMax, yMax, w;
+ double minFontSize, avgFontSize, splitPrecision, ascentAdjust, descentAdjust;
+ int xMinI, yMinI, xMaxI, yMaxI, xMinI2, yMinI2, xMaxI2, yMaxI2;
+ int start, x, y, i;
+
+ //----- compute bbox, min font size, average font size, and split precision
+
+ xMin = yMin = xMax = yMax = 0; // make gcc happy
+ minFontSize = avgFontSize = 0;
+ for (i = 0; i < charsA->getLength(); ++i) {
+ ch = (TextChar *)charsA->get(i);
+ if (i == 0 || ch->xMin < xMin) {
+ xMin = ch->xMin;
+ }
+ if (i == 0 || ch->yMin < yMin) {
+ yMin = ch->yMin;
+ }
+ if (i == 0 || ch->xMax > xMax) {
+ xMax = ch->xMax;
+ }
+ if (i == 0 || ch->yMax > yMax) {
+ yMax = ch->yMax;
+ }
+ avgFontSize += ch->fontSize;
+ if (i == 0 || ch->fontSize < minFontSize) {
+ minFontSize = ch->fontSize;
+ }
+ }
+ avgFontSize /= charsA->getLength();
+ splitPrecision = splitPrecisionMul * minFontSize;
+ if (splitPrecision < minSplitPrecision) {
+ splitPrecision = minSplitPrecision;
+ }
+ *xMinOut = xMin;
+ *yMinOut = yMin;
+ *xMaxOut = xMax;
+ *yMaxOut = yMax;
+ *avgFontSizeOut = avgFontSize;
+
+ //----- compute the horizontal and vertical profiles
+
+ // 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));
+ 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);
+ ascentAdjust = ascentAdjustFactor * (ch->yMax - ch->yMin);
+ yMinI2 = (int)floor((ch->yMin + ascentAdjust) / splitPrecision);
+ descentAdjust = descentAdjustFactor * (ch->yMax - ch->yMin);
+ yMaxI2 = (int)floor((ch->yMax - descentAdjust) / splitPrecision);
+ break;
+ case 1:
+ descentAdjust = descentAdjustFactor * (ch->xMax - ch->xMin);
+ xMinI2 = (int)floor((ch->xMin + descentAdjust) / splitPrecision);
+ 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);
+ break;
+ case 2:
+ xMinI2 = (int)floor(ch->xMin / splitPrecision);
+ xMaxI2 = (int)floor(ch->xMax / splitPrecision);
+ descentAdjust = descentAdjustFactor * (ch->yMax - ch->yMin);
+ yMinI2 = (int)floor((ch->yMin + descentAdjust) / splitPrecision);
+ ascentAdjust = ascentAdjustFactor * (ch->yMax - ch->yMin);
+ yMaxI2 = (int)floor((ch->yMax - ascentAdjust) / splitPrecision);
+ break;
+ case 3:
+ ascentAdjust = ascentAdjustFactor * (ch->xMax - ch->xMin);
+ xMinI2 = (int)floor((ch->xMin + ascentAdjust) / splitPrecision);
+ 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);
+ break;
+ }
+ for (y = yMinI2; y <= yMaxI2; ++y) {
+ ++horizProfile[y - yMinI];
+ }
+ for (x = xMinI2; x <= xMaxI2; ++x) {
+ ++vertProfile[x - xMinI];
+ }
+ }
+
+ //----- build the list of horizontal gaps
+
+ for (start = yMinI; start < yMaxI && !horizProfile[start - yMinI]; ++start) ;
+ for (y = start; y < yMaxI; ++y) {
+ if (horizProfile[y - yMinI]) {
+ if (!horizProfile[y + 1 - yMinI]) {
+ start = y;
+ }
+ } else {
+ if (horizProfile[y + 1 - yMinI]) {
+ w = (y - start) * splitPrecision;
+ horizGaps->append(new TextGap((start + 1) * splitPrecision + 0.5 * w,
+ w));
+ }
+ }
+ }
+
+ //----- build the list of vertical gaps
+
+ for (start = xMinI; start < xMaxI && !vertProfile[start - xMinI]; ++start) ;
+ for (x = start; x < xMaxI; ++x) {
+ if (vertProfile[x - xMinI]) {
+ if (!vertProfile[x + 1 - xMinI]) {
+ start = x;
+ }
+ } else {
+ if (vertProfile[x + 1 - xMinI]) {
+ w = (x - start) * splitPrecision;
+ vertGaps->append(new TextGap((start + 1) * splitPrecision + 0.5 * w,
+ w));
+ }
+ }
+ }
+
+ gfree(horizProfile);
+ gfree(vertProfile);
+}
+
// Decide whether this block is a line, column, or multiple columns:
// - all leaf nodes are lines
// - horiz split nodes whose children are lines or columns are columns
@@ -2798,6 +3118,11 @@ GList *TextPage::getChars(GList *charsA, double xMin, double yMin,
// - all leaf nodes are lines
// - vert split nodes, with small gaps, whose children are lines are lines
// - everything else is multiple columns
+// In simple layout mode:
+// - all leaf nodes are lines
+// - vert split nodes with small gaps are lines
+// - vert split nodes with large gaps are super-lines
+// - horiz split nodes are columns
void TextPage::tagBlock(TextBlock *blk) {
TextBlock *child;
int i;
@@ -2821,6 +3146,17 @@ void TextPage::tagBlock(TextBlock *blk) {
return;
}
+ if (control.mode == textOutSimpleLayout) {
+ if (blk->type == blkLeaf) {
+ blk->tag = blkTagLine;
+ } else if (blk->type == ((blk->rot & 1) ? blkHorizSplit : blkVertSplit)) {
+ blk->tag = blk->smallSplit ? blkTagLine : blkTagSuperLine;
+ } else {
+ blk->tag = blkTagColumn;
+ }
+ return;
+ }
+
if (blk->type == blkLeaf) {
blk->tag = blkTagLine;
@@ -2855,33 +3191,23 @@ void TextPage::tagBlock(TextBlock *blk) {
void TextPage::insertLargeChars(GList *largeChars, TextBlock *blk) {
TextChar *ch, *ch2;
GBool singleLine;
- double xLimit, yLimit, minOverlap;
+ double minOverlap;
int i;
//~ this currently works only for characters in the primary rotation
- // check to see if the large chars are a single line, in the
- // upper-left corner of blk (this is just a rough estimate)
- xLimit = blk->xMin + 0.5 * (blk->xMin + blk->xMax);
- yLimit = blk->yMin + 0.5 * (blk->yMin + blk->yMax);
+ // check to see if the large chars are a single line
singleLine = gTrue;
- // note: largeChars are already sorted by x
- for (i = 0; i < largeChars->getLength(); ++i) {
+ for (i = 1; i < largeChars->getLength(); ++i) {
+ ch = (TextChar *)largeChars->get(i-1);
ch2 = (TextChar *)largeChars->get(i);
- if (ch2->xMax > xLimit || ch2->yMax > yLimit) {
+ minOverlap = 0.5 * (ch->fontSize < ch2->fontSize ? ch->fontSize
+ : ch2->fontSize);
+ if (ch->yMax - ch2->yMin < minOverlap ||
+ ch2->yMax - ch->yMin < minOverlap) {
singleLine = gFalse;
break;
}
- if (i > 0) {
- ch = (TextChar *)largeChars->get(i-1);
- minOverlap = 0.5 * (ch->fontSize < ch2->fontSize ? ch->fontSize
- : ch2->fontSize);
- if (ch->yMax - ch2->yMin < minOverlap ||
- ch2->yMax - ch->yMin < minOverlap) {
- singleLine = gFalse;
- break;
- }
- }
}
if (singleLine) {
@@ -3043,7 +3369,7 @@ void TextPage::insertClippedChars(GList *clippedChars, TextBlock *tree) {
if (!(leaf = findClippedCharLeaf(ch, tree))) {
continue;
}
- leaf->addChild(ch);
+ leaf->addChild(ch, gFalse);
i = 0;
while (i < clippedChars->getLength()) {
ch2 = (TextChar *)clippedChars->get(i);
@@ -3053,7 +3379,7 @@ void TextPage::insertClippedChars(GList *clippedChars, TextBlock *tree) {
y = 0.5 * (ch2->yMin + ch2->yMax);
if (y > leaf->yMin && y < leaf->yMax) {
ch2 = (TextChar *)clippedChars->del(i);
- leaf->addChild(ch2);
+ leaf->addChild(ch2, gFalse);
ch = ch2;
} else {
++i;
@@ -3091,28 +3417,39 @@ TextBlock *TextPage::findClippedCharLeaf(TextChar *ch, TextBlock *tree) {
}
// Convert the tree of TextBlocks into a list of TextColumns.
-GList *TextPage::buildColumns(TextBlock *tree) {
+GList *TextPage::buildColumns(TextBlock *tree, GBool primaryLR) {
GList *columns;
columns = new GList();
- buildColumns2(tree, columns);
+ buildColumns2(tree, columns, primaryLR);
return columns;
}
-void TextPage::buildColumns2(TextBlock *blk, GList *columns) {
+void TextPage::buildColumns2(TextBlock *blk, GList *columns, GBool primaryLR) {
TextColumn *col;
int i;
switch (blk->tag) {
+ case blkTagSuperLine: // should never happen
case blkTagLine:
case blkTagColumn:
col = buildColumn(blk);
columns->append(col);
break;
case blkTagMulticolumn:
- for (i = 0; i < blk->children->getLength(); ++i) {
- buildColumns2((TextBlock *)blk->children->get(i), columns);
+#if 0 //~tmp
+ if (!primaryLR && blk->type == blkVertSplit) {
+ for (i = blk->children->getLength() - 1; i >= 0; --i) {
+ buildColumns2((TextBlock *)blk->children->get(i), columns, primaryLR);
+ }
+ } else {
+#endif
+ for (i = 0; i < blk->children->getLength(); ++i) {
+ buildColumns2((TextBlock *)blk->children->get(i), columns, primaryLR);
+ }
+#if 0 //~tmp
}
+#endif
break;
}
}
@@ -3121,6 +3458,7 @@ TextColumn *TextPage::buildColumn(TextBlock *blk) {
GList *lines, *parLines;
GList *paragraphs;
TextLine *line0, *line1;
+ GBool dropCap;
double spaceThresh, indent0, indent1, fontSize0, fontSize1;
int i;
@@ -3132,6 +3470,9 @@ TextColumn *TextPage::buildColumn(TextBlock *blk) {
//~ could look for bulleted lists here: look for the case where
//~ all out-dented lines start with the same char
+ //~ this doesn't handle right-to-left scripts (need to look for indents
+ //~ on the right instead of left, etc.)
+
// build the paragraphs
paragraphs = new GList();
i = 0;
@@ -3139,6 +3480,7 @@ TextColumn *TextPage::buildColumn(TextBlock *blk) {
// get the first line of the paragraph
parLines = new GList();
+ dropCap = gFalse;
line0 = (TextLine *)lines->get(i);
parLines->append(line0);
++i;
@@ -3177,6 +3519,7 @@ TextColumn *TextPage::buildColumn(TextBlock *blk) {
} else if (fontSize0 > largeCharThreshold * fontSize1 &&
indent1 - indent0 > minParagraphIndent * fontSize1 &&
getLineSpacing(line0, line1) < 0) {
+ dropCap = gTrue;
parLines->append(line1);
fontSize0 = fontSize1;
for (++i; i < lines->getLength(); ++i) {
@@ -3232,7 +3575,7 @@ TextColumn *TextPage::buildColumn(TextBlock *blk) {
}
}
- paragraphs->append(new TextParagraph(parLines));
+ paragraphs->append(new TextParagraph(parLines, dropCap));
}
delete lines;
@@ -3302,6 +3645,7 @@ void TextPage::buildLines(TextBlock *blk, GList *lines) {
lines->append(line);
}
break;
+ case blkTagSuperLine:
case blkTagColumn:
case blkTagMulticolumn: // multicolumn should never happen here
for (i = 0; i < blk->children->getLength(); ++i) {
@@ -3317,7 +3661,8 @@ TextLine *TextPage::buildLine(TextBlock *blk) {
TextChar *ch, *ch2;
TextWord *word;
double wordSp, lineFontSize, sp;
- GBool spaceAfter, spaceAfter2;
+ int dir, dir2;
+ GBool spaceAfter, spaceBefore;
int i, j;
charsA = new GList();
@@ -3327,27 +3672,42 @@ TextLine *TextPage::buildLine(TextBlock *blk) {
words = new GList();
lineFontSize = 0;
- spaceAfter = gFalse;
+ spaceBefore = gFalse;
i = 0;
while (i < charsA->getLength()) {
sp = wordSp - 1;
+ spaceAfter = gFalse;
+ dir = getCharDirection((TextChar *)charsA->get(i));
for (j = i+1; j < charsA->getLength(); ++j) {
ch = (TextChar *)charsA->get(j-1);
ch2 = (TextChar *)charsA->get(j);
sp = (blk->rot & 1) ? (ch2->yMin - ch->yMax) : (ch2->xMin - ch->xMax);
- if (sp > wordSp ||
- ch->font != ch2->font ||
+ if (sp > wordSp) {
+ spaceAfter = gTrue;
+ break;
+ }
+ // look for significant overlaps, which can happen with clipped
+ // characters (among other things)
+ if (sp < -ch->fontSize) {
+ spaceAfter = gTrue;
+ break;
+ }
+ dir2 = getCharDirection(ch2);
+ if (ch->font != ch2->font ||
fabs(ch->fontSize - ch2->fontSize) > 0.01 ||
+ (dir && dir2 && dir2 != dir) ||
(control.mode == textOutRawOrder &&
ch2->charPos != ch->charPos + ch->charLen)) {
break;
}
+ if (!dir && dir2) {
+ dir = dir2;
+ }
sp = wordSp - 1;
}
- spaceAfter2 = spaceAfter;
- spaceAfter = sp > wordSp;
- word = new TextWord(charsA, i, j - i, blk->rot,
- (blk->rot >= 2) ? spaceAfter2 : spaceAfter);
+ word = new TextWord(charsA, i, j - i, blk->rot, dir,
+ (blk->rot >= 2) ? spaceBefore : spaceAfter);
+ spaceBefore = spaceAfter;
i = j;
if (blk->rot >= 2) {
words->insert(0, word);
@@ -3382,47 +3742,96 @@ void TextPage::getLineChars(TextBlock *blk, GList *charsA) {
// spaces.
double TextPage::computeWordSpacingThreshold(GList *charsA, int rot) {
TextChar *ch, *ch2;
- double avgFontSize, minSp, maxSp, sp;
+ double avgFontSize;
+ double minAdjGap, maxAdjGap, minSpGap, maxSpGap, minGap, maxGap, gap, gap2;
int i;
avgFontSize = 0;
- minSp = maxSp = 0;
+ minGap = maxGap = 0;
+ minAdjGap = minSpGap = 1;
+ maxAdjGap = maxSpGap = 0;
for (i = 0; i < charsA->getLength(); ++i) {
ch = (TextChar *)charsA->get(i);
avgFontSize += ch->fontSize;
if (i < charsA->getLength() - 1) {
ch2 = (TextChar *)charsA->get(i+1);
- sp = (rot & 1) ? (ch2->yMin - ch->yMax) : (ch2->xMin - ch->xMax);
- if (i == 0 || sp < minSp) {
- minSp = sp;
+ gap = (rot & 1) ? (ch2->yMin - ch->yMax) : (ch2->xMin - ch->xMax);
+ if (ch->spaceAfter) {
+ if (minSpGap > maxSpGap) {
+ minSpGap = maxSpGap = gap;
+ } else if (gap < minSpGap) {
+ minSpGap = gap;
+ } else if (gap > maxSpGap) {
+ maxSpGap = gap;
+ }
+ } else {
+ if (minAdjGap > maxAdjGap) {
+ minAdjGap = maxAdjGap = gap;
+ } else if (gap < minAdjGap) {
+ minAdjGap = gap;
+ } else if (gap > maxAdjGap) {
+ maxAdjGap = gap;
+ }
}
- if (sp > maxSp) {
- maxSp = sp;
+ if (i == 0 || gap < minGap) {
+ minGap = gap;
+ }
+ if (gap > maxGap) {
+ maxGap = gap;
}
}
}
avgFontSize /= charsA->getLength();
- if (minSp < 0) {
- minSp = 0;
+ if (minGap < 0) {
+ minGap = 0;
}
- // if spacing is completely uniform, assume it's a single word
- // (technically it could be either "ABC" or "A B C", but it's
+ // 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 (maxSp - minSp < uniformSpacing * avgFontSize) {
- return maxSp + 1;
+ if (maxGap - minGap < uniformSpacing * avgFontSize) {
+ if (minAdjGap <= maxAdjGap &&
+ minSpGap <= maxSpGap &&
+ minSpGap - maxAdjGap > 0.01) {
+ return 0.5 * (maxAdjGap + minSpGap);
+ } else {
+ return maxGap + 1;
+ }
// if there is some variation in spacing, but it's small, assume
// there are some inter-word spaces
- } else if (maxSp - minSp < wordSpacing * avgFontSize) {
- return 0.5 * (minSp + maxSp);
-
- // otherwise, assume a reasonable threshold for inter-word spacing
- // (we can't use something like 0.5*(minSp+maxSp) here because there
- // can be outliers at the high end)
+ } else if (maxGap - minGap < wordSpacing * avgFontSize) {
+ return 0.5 * (minGap + maxGap);
+
+ // if there is a large variation in spacing, use the SpGap/AdjGap
+ // values if they look reasonable, otherwise, assume a reasonable
+ // threshold for inter-word spacing (we can't use something like
+ // 0.5*(minGap+maxGap) here because there can be outliers at the
+ // high end)
} else {
- return minSp + wordSpacing * avgFontSize;
+ if (minAdjGap <= maxAdjGap &&
+ minSpGap <= maxSpGap &&
+ minSpGap - maxAdjGap > uniformSpacing * avgFontSize) {
+ gap = wordSpacing * avgFontSize;
+ gap2 = 0.5 * (minSpGap - minGap);
+ return minGap + (gap < gap2 ? gap : gap2);
+ } else {
+ return minGap + wordSpacing * avgFontSize;
+ }
+ }
+}
+
+// Check the characters direction: returns 1 for L or Num; -1 for R; 0
+// for others.
+int TextPage::getCharDirection(TextChar *ch) {
+ if (unicodeTypeL(ch->c) || unicodeTypeNum(ch->c)) {
+ return 1;
+ }
+ if (unicodeTypeR(ch->c)) {
+ return -1;
}
+ return 0;
}
int TextPage::assignPhysLayoutPositions(GList *columns) {
@@ -3567,6 +3976,66 @@ int TextPage::assignColumnPhysPositions(GList *columns) {
return ph;
}
+void TextPage::buildSuperLines(TextBlock *blk, GList *superLines) {
+ GList *lines;
+ int i;
+
+ if (blk->tag == blkTagLine) {
+ lines = new GList();
+ buildLines(blk, lines);
+ superLines->append(new TextSuperLine(lines));
+ } else if (blk->tag == blkTagSuperLine) {
+ lines = new GList();
+ for (i = 0; i < blk->children->getLength(); ++i) {
+ buildLines((TextBlock *)blk->children->get(i), lines);
+ }
+ superLines->append(new TextSuperLine(lines));
+ } else {
+ for (i = 0; i < blk->children->getLength(); ++i) {
+ buildSuperLines((TextBlock *)blk->children->get(i), superLines);
+ }
+ }
+}
+
+void TextPage::assignSimpleLayoutPositions(GList *superLines,
+ UnicodeMap *uMap) {
+ GList *lines;
+ TextLine *line0, *line1;
+ double xMin;
+ int px, sp, i, j;
+
+ // build a list of lines and sort by x
+ lines = new GList();
+ for (i = 0; i < superLines->getLength(); ++i) {
+ lines->append(((TextSuperLine *)superLines->get(i))->lines);
+ }
+ lines->sort(&TextLine::cmpX);
+
+ // assign positions
+ xMin = ((TextLine *)lines->get(0))->xMin;
+ 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));
+ 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;
+ }
+ px = line1->px + line1->pw + sp;
+ if (px > line0->px) {
+ line0->px = px;
+ }
+ }
+ }
+ }
+
+ delete lines;
+}
+
void TextPage::generateUnderlinesAndLinks(GList *columns) {
TextColumn *col;
TextParagraph *par;
@@ -3639,7 +4108,6 @@ GBool TextPage::findText(Unicode *s, int len,
GBool wholeWord,
double *xMin, double *yMin,
double *xMax, double *yMax) {
- TextBlock *tree;
TextColumn *column;
TextParagraph *par;
TextLine *line;
@@ -3649,22 +4117,12 @@ GBool TextPage::findText(Unicode *s, int len,
double xMin0, yMin0, xMax0, yMax0;
double xMin1, yMin1, xMax1, yMax1;
GBool found;
- int txtSize, m, rot, colIdx, parIdx, lineIdx, i, j, k;
+ int txtSize, m, colIdx, parIdx, lineIdx, i, j, k;
//~ need to handle right-to-left text
+ //~ - pass primaryLR to buildColumns
- if (!findCols) {
- rot = rotateChars(chars);
- if ((tree = splitChars(chars))) {
- findCols = buildColumns(tree);
- delete tree;
- } else {
- // no text
- findCols = new GList();
- }
- unrotateChars(chars, rot);
- unrotateColumns(findCols, rot);
- }
+ buildFindCols();
// convert the search string to uppercase
if (!caseSensitive) {
@@ -3870,7 +4328,7 @@ GBool TextPage::findText(Unicode *s, int len,
}
GString *TextPage::getText(double xMin, double yMin,
- double xMax, double yMax) {
+ double xMax, double yMax, GBool forceEOL) {
UnicodeMap *uMap;
char space[8], eol[16];
int spaceLen, eolLen;
@@ -3933,7 +4391,7 @@ GString *TextPage::getText(double xMin, double yMin,
#if 0 //~debug
dumpTree(tree);
#endif
- columns = buildColumns(tree);
+ columns = buildColumns(tree, primaryLR);
delete tree;
ph = assignPhysLayoutPositions(columns);
#if 0 //~debug
@@ -3984,7 +4442,7 @@ GString *TextPage::getText(double xMin, double yMin,
ret->append(out[i]);
delete out[i];
}
- if (ph > 1) {
+ if (ph > 1 || forceEOL) {
ret->append(eol, eolLen);
}
}
@@ -4039,6 +4497,216 @@ GBool TextPage::findCharRange(int pos, int length,
return gTrue;
}
+GBool TextPage::findPointInside(double x, double y, TextPosition *pos) {
+ TextColumn *col;
+ int colIdx;
+
+ buildFindCols();
+
+ //~ this doesn't handle RtL, vertical, or rotated text
+ //~ this doesn't handle drop caps
+
+ for (colIdx = 0; colIdx < findCols->getLength(); ++colIdx) {
+ col = (TextColumn *)findCols->get(colIdx);
+ if (col->getRotation() != 0) {
+ continue;
+ }
+ if (x >= col->getXMin() && x <= col->getXMax() &&
+ y >= col->getYMin() && y <= col->getYMax()) {
+ pos->colIdx = colIdx;
+ findPointInColumn(col, x, y, pos);
+ return gTrue;
+ }
+ }
+ return gFalse;
+}
+
+GBool TextPage::findPointNear(double x, double y, TextPosition *pos) {
+ TextColumn *col;
+ double nearestDist, dx, dy;
+ int nearestColIdx, colIdx;
+
+ buildFindCols();
+
+ //~ this doesn't handle RtL, vertical, or rotated text
+ //~ this doesn't handle drop caps
+
+ nearestColIdx = -1;
+ nearestDist = 0;
+ for (colIdx = 0; colIdx < findCols->getLength(); ++colIdx) {
+ col = (TextColumn *)findCols->get(colIdx);
+ if (col->getRotation() != 0) {
+ continue;
+ }
+ if (x < col->getXMin()) {
+ dx = col->getXMin() - x;
+ } else if (x > col->getXMax()) {
+ dx = x - col->getXMax();
+ } else {
+ dx = 0;
+ }
+ if (y < col->getYMin()) {
+ dy = col->getYMin() - y;
+ } else if (y > col->getYMax()) {
+ dy = y - col->getYMax();
+ } else {
+ dy = 0;
+ }
+ if (nearestColIdx < 0 || dx + dy < nearestDist) {
+ nearestColIdx = colIdx;
+ nearestDist = dx + dy;
+ }
+ }
+ if (nearestColIdx < 0) {
+ return gFalse;
+ }
+ pos->colIdx = nearestColIdx;
+ col = (TextColumn *)findCols->get(nearestColIdx);
+ findPointInColumn(col, x, y, pos);
+ return gTrue;
+}
+
+// Find the position in [col] corresponding to [x],[y]. The column,
+// [col], was found by findPointInside() or findPointNear().
+void TextPage::findPointInColumn(TextColumn *col, double x, double y,
+ TextPosition *pos) {
+ TextParagraph *par;
+ TextLine *line;
+ GList *pars, *lines;
+ int parIdx, lineIdx, charIdx;
+
+ //~ this doesn't handle RtL, vertical, or rotated text
+ //~ this doesn't handle drop caps
+
+ pars = col->getParagraphs();
+ //~ could use a binary search here
+ for (parIdx = 0; parIdx < pars->getLength() - 1; ++parIdx) {
+ par = (TextParagraph *)pars->get(parIdx);
+ if (y <= par->getYMax()) {
+ break;
+ }
+ }
+ par = (TextParagraph *)pars->get(parIdx);
+
+ lines = par->getLines();
+ //~ could use a binary search here
+ for (lineIdx = 0; lineIdx < lines->getLength() - 1; ++lineIdx) {
+ line = (TextLine *)lines->get(lineIdx);
+ if (y <= line->getYMax()) {
+ break;
+ }
+ }
+ line = (TextLine *)lines->get(lineIdx);
+
+ //~ could use a binary search here
+ for (charIdx = 0; charIdx < line->getLength(); ++charIdx) {
+ if (x <= 0.5 * (line->getEdge(charIdx) + line->getEdge(charIdx + 1))) {
+ break;
+ }
+ }
+
+ pos->parIdx = parIdx;
+ pos->lineIdx = lineIdx;
+ pos->charIdx = charIdx;
+}
+
+void TextPage::convertPosToPointUpper(TextPosition *pos,
+ double *x, double *y) {
+ TextColumn *col;
+ TextParagraph *par;
+ TextLine *line;
+
+ buildFindCols();
+ col = (TextColumn *)findCols->get(pos->colIdx);
+ par = (TextParagraph *)col->getParagraphs()->get(pos->parIdx);
+ line = (TextLine *)par->getLines()->get(pos->lineIdx);
+ *x = line->getEdge(pos->charIdx);
+ *y = line->getBaseline() - selectionAscent * line->fontSize;
+}
+
+void TextPage::convertPosToPointLower(TextPosition *pos,
+ double *x, double *y) {
+ TextColumn *col;
+ TextParagraph *par;
+ TextLine *line;
+
+ buildFindCols();
+ col = (TextColumn *)findCols->get(pos->colIdx);
+ par = (TextParagraph *)col->getParagraphs()->get(pos->parIdx);
+ line = (TextLine *)par->getLines()->get(pos->lineIdx);
+ *x = line->getEdge(pos->charIdx);
+ *y = line->getYMax();
+}
+
+void TextPage::convertPosToPointLeftEdge(TextPosition *pos,
+ double *x, double *y) {
+ TextColumn *col;
+ TextParagraph *par;
+ TextLine *line;
+
+ buildFindCols();
+ col = (TextColumn *)findCols->get(pos->colIdx);
+ par = (TextParagraph *)col->getParagraphs()->get(pos->parIdx);
+ line = (TextLine *)par->getLines()->get(pos->lineIdx);
+ *x = col->getXMin();
+ *y = line->getBaseline() - selectionAscent * line->fontSize;
+}
+
+void TextPage::convertPosToPointRightEdge(TextPosition *pos,
+ double *x, double *y) {
+ TextColumn *col;
+ TextParagraph *par;
+ TextLine *line;
+
+ buildFindCols();
+ col = (TextColumn *)findCols->get(pos->colIdx);
+ par = (TextParagraph *)col->getParagraphs()->get(pos->parIdx);
+ line = (TextLine *)par->getLines()->get(pos->lineIdx);
+ *x = col->getXMax();
+ *y = line->getYMax();
+}
+
+void TextPage::getColumnUpperRight(int colIdx, double *x, double *y) {
+ TextColumn *col;
+ TextParagraph *par0;
+ TextLine *line0;
+
+ buildFindCols();
+ col = (TextColumn *)findCols->get(colIdx);
+ *x = col->getXMax();
+ par0 = (TextParagraph *)col->paragraphs->get(0);
+ line0 = (TextLine *)par0->lines->get(0);
+ *y = line0->getBaseline() - selectionAscent * line0->fontSize;
+}
+
+void TextPage::getColumnLowerLeft(int colIdx, double *x, double *y) {
+ TextColumn *col;
+
+ buildFindCols();
+ col = (TextColumn *)findCols->get(colIdx);
+ *x = col->getXMin();
+ *y = col->getYMax();
+}
+
+void TextPage::buildFindCols() {
+ TextBlock *tree;
+ int rot;
+
+ if (findCols) {
+ return;
+ }
+ rot = rotateChars(chars);
+ if ((tree = splitChars(chars))) {
+ findCols = buildColumns(tree, gFalse);
+ delete tree;
+ } else {
+ // no text
+ findCols = new GList();
+ }
+ unrotateChars(chars, rot);
+ unrotateColumns(findCols, rot);
+}
+
TextWordList *TextPage::makeWordList() {
TextBlock *tree;
GList *columns;
@@ -4047,16 +4715,21 @@ TextWordList *TextPage::makeWordList() {
TextLine *line;
TextWord *word;
GList *words;
+ GBool primaryLR;
int rot, colIdx, parIdx, lineIdx, wordIdx;
rot = rotateChars(chars);
+ primaryLR = checkPrimaryLR(chars);
tree = splitChars(chars);
if (!tree) {
// no text
unrotateChars(chars, rot);
- return new TextWordList(new GList());
+ return new TextWordList(new GList(), gTrue);
}
- columns = buildColumns(tree);
+ columns = buildColumns(tree, primaryLR);
+#if 0 //~debug
+ dumpColumns(columns, gTrue);
+#endif
delete tree;
unrotateChars(chars, rot);
if (control.html) {
@@ -4084,6 +4757,7 @@ TextWordList *TextPage::makeWordList() {
// already in reading order
break;
case textOutPhysLayout:
+ case textOutSimpleLayout:
case textOutTableLayout:
case textOutLinePrinter:
words->sort(&TextWord::cmpYX);
@@ -4094,12 +4768,15 @@ TextWordList *TextPage::makeWordList() {
}
// this has to be done after sorting with cmpYX
- unrotateColumns(columns, rot);
unrotateWords(words, rot);
deleteGList(columns, TextColumn);
- return new TextWordList(words);
+ return new TextWordList(words, primaryLR);
+}
+
+GBool TextPage::primaryDirectionIsLR() {
+ return checkPrimaryLR(chars);
}
//------------------------------------------------------------------------
@@ -4114,9 +4791,9 @@ void TextPage::dumpChars(GList *charsA) {
for (i = 0; i < charsA->getLength(); ++i) {
ch = (TextChar *)charsA->get(i);
- printf("char: U+%04x '%c' xMin=%g yMin=%g xMax=%g yMax=%g fontSize=%g rot=%d\n",
+ printf("char: U+%04x '%c' xMin=%g yMin=%g xMax=%g yMax=%g fontSize=%g rot=%d charPos=%d charLen=%d\n",
ch->c, ch->c & 0xff, ch->xMin, ch->yMin, ch->xMax, ch->yMax,
- ch->fontSize, ch->rot);
+ ch->fontSize, ch->rot, ch->charPos, ch->charLen);
}
}
@@ -4147,11 +4824,12 @@ void TextPage::dumpTree(TextBlock *tree, int indent) {
}
}
-void TextPage::dumpColumns(GList *columns) {
+void TextPage::dumpColumns(GList *columns, GBool dumpWords) {
TextColumn *col;
TextParagraph *par;
TextLine *line;
- int colIdx, parIdx, lineIdx, i;
+ TextWord *word;
+ int colIdx, parIdx, lineIdx, wordIdx, i;
for (colIdx = 0; colIdx < columns->getLength(); ++colIdx) {
col = (TextColumn *)columns->get(colIdx);
@@ -4166,16 +4844,40 @@ void TextPage::dumpColumns(GList *columns) {
printf(" line: xMin=%g yMin=%g xMax=%g yMax=%g px=%d pw=%d rot=%d\n",
line->xMin, line->yMin, line->xMax, line->yMax,
line->px, line->pw, line->rot);
- printf(" ");
- for (i = 0; i < line->len; ++i) {
- printf("%c", line->text[i] & 0xff);
+ if (dumpWords) {
+ for (wordIdx = 0; wordIdx < line->words->getLength(); ++wordIdx) {
+ word = (TextWord *)line->words->get(wordIdx);
+ printf(" word: xMin=%g yMin=%g xMax=%g yMax=%g\n",
+ word->xMin, word->yMin, word->xMax, word->yMax);
+ printf(" ");
+ for (i = 0; i < word->len; ++i) {
+ printf("%c", word->text[i] & 0xff);
+ }
+ printf("\n");
+ }
+ } else {
+ printf(" ");
+ for (i = 0; i < line->len; ++i) {
+ printf("%c", line->text[i] & 0xff);
+ }
+ printf("\n");
}
- printf("\n");
}
}
}
}
+void TextPage::dumpUnderlines() {
+ TextUnderline *u;
+ int i;
+
+ printf("underlines:\n");
+ for (i = 0; i < underlines->getLength(); ++i) {
+ u = (TextUnderline *)underlines->get(i);
+ printf(" horiz=%d x0=%g y0=%g x1=%g y1=%g\n",
+ u->horiz, u->x0, u->y0, u->x1, u->y1);
+ }
+}
#endif //~debug
//------------------------------------------------------------------------
@@ -4215,6 +4917,7 @@ TextOutputDev::TextOutputDev(char *fileName, TextOutputControl *controlA,
// set up text object
text = new TextPage(&control);
+ generateBOM();
}
TextOutputDev::TextOutputDev(TextOutputFunc func, void *stream,
@@ -4224,6 +4927,7 @@ TextOutputDev::TextOutputDev(TextOutputFunc func, void *stream,
needClose = gFalse;
control = *controlA;
text = new TextPage(&control);
+ generateBOM();
ok = gTrue;
}
@@ -4236,6 +4940,22 @@ TextOutputDev::~TextOutputDev() {
}
}
+void TextOutputDev::generateBOM() {
+ UnicodeMap *uMap;
+ char bom[8];
+ int bomLen;
+
+ // insert Unicode BOM
+ if (control.insertBOM && outputStream) {
+ if (!(uMap = globalParams->getTextEncoding())) {
+ return;
+ }
+ bomLen = uMap->mapUnicode(0xfeff, bom, sizeof(bom));
+ uMap->decRefCnt();
+ (*outputFunc)(outputStream, bom, bomLen);
+ }
+}
+
void TextOutputDev::startPage(int pageNum, GfxState *state) {
text->startPage(state);
}
@@ -4282,7 +5002,7 @@ void TextOutputDev::endActualText(GfxState *state) {
void TextOutputDev::stroke(GfxState *state) {
GfxPath *path;
GfxSubpath *subpath;
- double x[2], y[2];
+ double x[2], y[2], t;
if (!control.html) {
return;
@@ -4300,6 +5020,12 @@ void TextOutputDev::stroke(GfxState *state) {
// look for a vertical or horizontal line
if (x[0] == x[1] || y[0] == y[1]) {
+ if (x[0] > x[1]) {
+ t = x[0]; x[0] = x[1]; x[1] = t;
+ }
+ if (y[0] > y[1]) {
+ t = y[0]; y[0] = y[1]; y[1] = t;
+ }
text->addUnderline(x[0], y[0], x[1], y[1]);
}
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
index 4399029ea31..ca39e1ed4fa 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TextOutputDev.h
@@ -39,6 +39,7 @@ typedef void (*TextOutputFunc)(void *stream, const char *text, int len);
enum TextOutputMode {
textOutReadingOrder, // format into reading order
textOutPhysLayout, // maintain original physical layout
+ textOutSimpleLayout, // simple one-column physical layout
textOutTableLayout, // similar to PhysLayout, but optimized
// for tables
textOutLinePrinter, // strict fixed-pitch/height layout
@@ -61,6 +62,12 @@ public:
GBool html; // enable extra processing for HTML
GBool clipText; // separate clipped text and add it back
// in after forming columns
+ GBool discardDiagonalText; // discard all text that's not close to
+ // 0/90/180/270 degrees
+ GBool discardInvisibleText; // discard all invisible characters
+ GBool discardClippedText; // discard all clipped characters
+ GBool insertBOM; // insert a Unicode BOM at the start of
+ // the text output
};
//------------------------------------------------------------------------
@@ -88,6 +95,8 @@ public:
// Get the width of the 'm' character, if available.
double getMWidth() { return mWidth; }
+ Ref getFontID() { return fontID; }
+
private:
Ref fontID;
@@ -109,7 +118,7 @@ class TextWord {
public:
TextWord(GList *chars, int start, int lenA,
- int rotA, GBool spaceAfterA);
+ int rotA, int dirA, GBool spaceAfterA);
~TextWord();
TextWord *copy() { return new TextWord(this); }
@@ -131,6 +140,7 @@ public:
int getRotation() { return rot; }
int getCharPos() { return charPos[0]; }
int getCharLen() { return charPos[len] - charPos[0]; }
+ int getDirection() { return dir; }
GBool getSpaceAfter() { return spaceAfter; }
double getBaseline();
GBool isUnderlined() { return underlined; }
@@ -139,7 +149,6 @@ public:
private:
TextWord(TextWord *word);
- void appendChar(TextChar *ch);
static int cmpYX(const void *p1, const void *p2);
static int cmpCharPos(const void *p1, const void *p2);
@@ -156,6 +165,8 @@ private:
int len; // number of characters
TextFontInfo *font; // font information
double fontSize; // font size
+ int dir; // character direction (+1 = left-to-right;
+ // -1 = right-to-left; 0 = neither)
GBool spaceAfter; // set if there is a space between this
// word and the next word on the line
@@ -185,12 +196,18 @@ public:
double getXMin() { return xMin; }
double getYMin() { return yMin; }
+ double getXMax() { return xMax; }
+ double getYMax() { return yMax; }
double getBaseline();
int getRotation() { return rot; }
GList *getWords() { return words; }
+ int getLength() { return len; }
+ double getEdge(int idx) { return edge[idx]; }
private:
+ static int cmpX(const void *p1, const void *p2);
+
GList *words; // [TextWord]
int rot; // rotation, multiple of 90 degrees
// (0, 1, 2, or 3)
@@ -208,6 +225,7 @@ private:
int pw; // line width (in characters) in physical
// layout mode
+ friend class TextSuperLine;
friend class TextPage;
friend class TextParagraph;
};
@@ -219,15 +237,23 @@ private:
class TextParagraph {
public:
- TextParagraph(GList *linesA);
+ TextParagraph(GList *linesA, GBool dropCapA);
~TextParagraph();
// Get the list of TextLine objects.
GList *getLines() { return lines; }
+ GBool hasDropCap() { return dropCap; }
+
+ double getXMin() { return xMin; }
+ double getYMin() { return yMin; }
+ double getXMax() { return xMax; }
+ double getYMax() { return yMax; }
+
private:
GList *lines; // [TextLine]
+ GBool dropCap; // paragraph starts with a drop capital
double xMin, xMax; // bounding box x coordinates
double yMin, yMax; // bounding box y coordinates
@@ -248,6 +274,13 @@ public:
// Get the list of TextParagraph objects.
GList *getParagraphs() { return paragraphs; }
+ double getXMin() { return xMin; }
+ double getYMin() { return yMin; }
+ double getXMax() { return xMax; }
+ double getYMax() { return yMax; }
+
+ int getRotation();
+
private:
static int cmpX(const void *p1, const void *p2);
@@ -272,7 +305,7 @@ private:
class TextWordList {
public:
- TextWordList(GList *wordsA);
+ TextWordList(GList *wordsA, GBool primaryLRA);
~TextWordList();
@@ -282,9 +315,36 @@ public:
// Return the <idx>th word from the list.
TextWord *get(int idx);
+ // Returns true if primary direction is left-to-right, or false if
+ // right-to-left.
+ GBool getPrimaryLR() { return primaryLR; }
+
private:
GList *words; // [TextWord]
+ GBool primaryLR;
+};
+
+//------------------------------------------------------------------------
+// TextPosition
+//------------------------------------------------------------------------
+
+// Position within a TextColumn tree. The position is in column
+// [colIdx], paragraph [parIdx], line [lineIdx], before character
+// [charIdx].
+class TextPosition {
+public:
+
+ TextPosition(): colIdx(0), parIdx(0), lineIdx(0), charIdx(0) {}
+ TextPosition(int colIdxA, int parIdxA, int lineIdxA, int charIdxA):
+ colIdx(colIdxA), parIdx(parIdxA), lineIdx(lineIdxA), charIdx(charIdxA) {}
+
+ int operator==(TextPosition pos);
+ int operator!=(TextPosition pos);
+ int operator<(TextPosition pos);
+ int operator>(TextPosition pos);
+
+ int colIdx, parIdx, lineIdx, charIdx;
};
//------------------------------------------------------------------------
@@ -315,9 +375,13 @@ public:
double *xMin, double *yMin,
double *xMax, double *yMax);
- // Get the text which is inside the specified rectangle.
+ // Get the text which is inside the specified rectangle. Multi-line
+ // text always includes end-of-line markers at the end of each line.
+ // If <forceEOL> is true, an end-of-line marker will be appended to
+ // single-line text as well.
GString *getText(double xMin, double yMin,
- double xMax, double yMax);
+ double xMax, double yMax,
+ GBool forceEOL = gFalse);
// Find a string by character position and length. If found, sets
// the text bounding rectangle and returns true; otherwise returns
@@ -326,6 +390,32 @@ public:
double *xMin, double *yMin,
double *xMax, double *yMax);
+ // Find a point inside a column. Returns false if x,y fall outside
+ // all columns.
+ GBool findPointInside(double x, double y, TextPosition *pos);
+
+ // Find a point in the nearest column. Returns false only if there
+ // are no columns.
+ GBool findPointNear(double x, double y, TextPosition *pos);
+
+ // Get the upper point of a TextPosition.
+ void convertPosToPointUpper(TextPosition *pos, double *x, double *y);
+
+ // Get the lower point of a TextPosition.
+ void convertPosToPointLower(TextPosition *pos, double *x, double *y);
+
+ // Get the upper left corner of the line containing a TextPosition.
+ void convertPosToPointLeftEdge(TextPosition *pos, double *x, double *y);
+
+ // Get the lower right corner of the line containing a TextPosition.
+ void convertPosToPointRightEdge(TextPosition *pos, double *x, double *y);
+
+ // Get the upper right corner of a column.
+ void getColumnUpperRight(int colIdx, double *x, double *y);
+
+ // Get the lower left corner of a column.
+ void getColumnLowerLeft(int colIdx, double *x, double *y);
+
// Create and return a list of TextColumn objects.
GList *makeColumns();
@@ -335,6 +425,14 @@ public:
// Build a flat word list, in the specified ordering.
TextWordList *makeWordList();
+ // Returns true if the primary character direction is left-to-right,
+ // false if it is right-to-left.
+ GBool primaryDirectionIsLR();
+
+ // Returns true if any of the fonts used on this page are likely to
+ // be problematic when converting text to Unicode.
+ GBool problematicForUnicode() { return problematic; }
+
private:
void startPage(GfxState *state);
@@ -361,6 +459,11 @@ private:
UnicodeMap *uMap,
char *space, int spaceLen,
char *eol, int eolLen);
+ void writeSimpleLayout(void *outputStream,
+ TextOutputFunc outputFunc,
+ UnicodeMap *uMap,
+ char *space, int spaceLen,
+ char *eol, int eolLen);
void writeLinePrinter(void *outputStream,
TextOutputFunc outputFunc,
UnicodeMap *uMap,
@@ -386,6 +489,11 @@ private:
TextBlock *split(GList *charsA, int rot);
GList *getChars(GList *charsA, double xMin, double yMin,
double xMax, double yMax);
+ void findGaps(GList *charsA, int rot,
+ double *xMinOut, double *yMinOut,
+ double *xMaxOut, double *yMaxOut,
+ double *avgFontSizeOut,
+ GList *horizGaps, GList *vertGaps);
void tagBlock(TextBlock *blk);
void insertLargeChars(GList *largeChars, TextBlock *blk);
void insertLargeCharsInFirstLeaf(GList *largeChars, TextBlock *blk);
@@ -394,8 +502,8 @@ private:
void insertColumnIntoTree(TextBlock *column, TextBlock *tree);
void insertClippedChars(GList *clippedChars, TextBlock *tree);
TextBlock *findClippedCharLeaf(TextChar *ch, TextBlock *tree);
- GList *buildColumns(TextBlock *tree);
- void buildColumns2(TextBlock *blk, GList *columns);
+ GList *buildColumns(TextBlock *tree, GBool primaryLR);
+ void buildColumns2(TextBlock *blk, GList *columns, GBool primaryLR);
TextColumn *buildColumn(TextBlock *tree);
double getLineIndent(TextLine *line, TextBlock *blk);
double getAverageLineSpacing(GList *lines);
@@ -404,17 +512,24 @@ private:
TextLine *buildLine(TextBlock *blk);
void getLineChars(TextBlock *blk, GList *charsA);
double computeWordSpacingThreshold(GList *charsA, int rot);
+ int getCharDirection(TextChar *ch);
int assignPhysLayoutPositions(GList *columns);
void assignLinePhysPositions(GList *columns);
void computeLinePhysWidth(TextLine *line, UnicodeMap *uMap);
int assignColumnPhysPositions(GList *columns);
+ void buildSuperLines(TextBlock *blk, GList *superLines);
+ void assignSimpleLayoutPositions(GList *superLines, UnicodeMap *uMap);
void generateUnderlinesAndLinks(GList *columns);
+ void findPointInColumn(TextColumn *col, double x, double y,
+ TextPosition *pos);
+ void buildFindCols();
// debug
#if 0 //~debug
void dumpChars(GList *charsA);
void dumpTree(TextBlock *tree, int indent = 0);
- void dumpColumns(GList *columns);
+ void dumpColumns(GList *columns, GBool dumpWords = gFalse);
+ void dumpUnderlines();
#endif
TextOutputControl control; // formatting parameters
@@ -425,6 +540,8 @@ private:
TextFontInfo *curFont; // current font
double curFontSize; // current font size
int curRot; // current rotation
+ GBool diagonal; // set if rotation is not close to
+ // 0/90/180/270 degrees
int nTinyChars; // number of "tiny" chars seen so far
Unicode *actualText; // current "ActualText" span
int actualTextLen;
@@ -441,14 +558,16 @@ private:
GList *underlines; // [TextUnderline]
GList *links; // [TextLink]
- GList *findCols; // text used by the findText function
- // [TextColumn]
- GBool findLR; // primary text direction, used by the
- // findText function
+ GList *findCols; // text used by the findText**/findPoint**
+ // functions [TextColumn]
double lastFindXMin, // coordinates of the last "find" result
lastFindYMin;
GBool haveLastFind;
+ GBool problematic; // true if any of the fonts used on this
+ // page are marked as problematic for
+ // Unicode conversion
+
friend class TextOutputDev;
};
@@ -576,6 +695,8 @@ public:
private:
+ void generateBOM();
+
TextOutputFunc outputFunc; // output function
void *outputStream; // output stream
GBool needClose; // need to close the output file?
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.cc
index 5bc9de2fab0..4701fed98eb 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.cc
@@ -14,8 +14,10 @@
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "PDFDocEncoding.h"
+#include "UTF8.h"
#include "TextString.h"
//------------------------------------------------------------------------
@@ -53,26 +55,7 @@ TextString *TextString::append(Unicode c) {
}
TextString *TextString::append(GString *s) {
- int n, i;
-
- if ((s->getChar(0) & 0xff) == 0xfe &&
- (s->getChar(1) & 0xff) == 0xff) {
- n = (s->getLength() - 2) / 2;
- expand(n);
- for (i = 0; i < n; ++i) {
- u[len + i] = ((s->getChar(2 + 2*i) & 0xff) << 8) |
- (s->getChar(3 + 2*i) & 0xff);
- }
- len += n;
- } else {
- n = s->getLength();
- expand(n);
- for (i = 0; i < n; ++i) {
- u[len + i] = pdfDocEncoding[s->getChar(i) & 0xff];
- }
- len += n;
- }
- return this;
+ return insert(len, s);
}
TextString *TextString::insert(int idx, Unicode c) {
@@ -87,22 +70,78 @@ TextString *TextString::insert(int idx, Unicode c) {
return this;
}
+TextString *TextString::insert(int idx, Unicode *u2, int n) {
+ if (idx >= 0 && idx <= len) {
+ expand(n);
+ if (idx < len) {
+ memmove(u + idx + n, u + idx, (len - idx) * sizeof(Unicode));
+ }
+ memcpy(u + idx, u2, n * sizeof(Unicode));
+ len += n;
+ }
+ return this;
+}
+
TextString *TextString::insert(int idx, GString *s) {
+ Unicode uBuf[100];
int n, i;
if (idx >= 0 && idx <= len) {
+ // look for a UTF-16BE BOM
if ((s->getChar(0) & 0xff) == 0xfe &&
(s->getChar(1) & 0xff) == 0xff) {
- n = (s->getLength() - 2) / 2;
- expand(n);
- if (idx < len) {
- memmove(u + idx + n, u + idx, (len - idx) * sizeof(Unicode));
+ i = 2;
+ n = 0;
+ while (getUTF16BE(s, &i, uBuf + n)) {
+ ++n;
+ if (n == sizeof(uBuf) / sizeof(Unicode)) {
+ insert(idx, uBuf, n);
+ idx += n;
+ n = 0;
+ }
}
- for (i = 0; i < n; ++i) {
- u[idx + i] = ((s->getChar(2 + 2*i) & 0xff) << 8) |
- (s->getChar(3 + 2*i) & 0xff);
+ if (n > 0) {
+ insert(idx, uBuf, n);
}
- len += n;
+
+ // look for a UTF-16LE BOM
+ // (technically, this isn't allowed by the PDF spec, but some
+ // PDF files use it)
+ } else if ((s->getChar(0) & 0xff) == 0xff &&
+ (s->getChar(1) & 0xff) == 0xfe) {
+ i = 2;
+ n = 0;
+ while (getUTF16LE(s, &i, uBuf + n)) {
+ ++n;
+ if (n == sizeof(uBuf) / sizeof(Unicode)) {
+ insert(idx, uBuf, n);
+ idx += n;
+ n = 0;
+ }
+ }
+ if (n > 0) {
+ insert(idx, uBuf, n);
+ }
+
+ // look for a UTF-8 BOM
+ } else if ((s->getChar(0) & 0xff) == 0xef &&
+ (s->getChar(1) & 0xff) == 0xbb &&
+ (s->getChar(2) & 0xff) == 0xbf) {
+ i = 3;
+ n = 0;
+ while (getUTF8(s, &i, uBuf + n)) {
+ ++n;
+ if (n == sizeof(uBuf) / sizeof(Unicode)) {
+ insert(idx, uBuf, n);
+ idx += n;
+ n = 0;
+ }
+ }
+ if (n > 0) {
+ insert(idx, uBuf, n);
+ }
+
+ // otherwise, use PDFDocEncoding
} else {
n = s->getLength();
expand(n);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h b/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h
index fac15e94319..c5e7e613af8 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TextString.h
@@ -43,8 +43,10 @@ public:
TextString *append(Unicode c);
TextString *append(GString *s);
- // Insert a Unicode character or PDF text string in this TextString.
+ // Insert a Unicode character, sequence of Unicode characters, or
+ // PDF text string in this TextString.
TextString *insert(int idx, Unicode c);
+ TextString *insert(int idx, Unicode *u2, int n);
TextString *insert(int idx, GString *s);
// Get the Unicode characters in the TextString.
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.cc
new file mode 100644
index 00000000000..ff002ed46fc
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.cc
@@ -0,0 +1,562 @@
+//========================================================================
+//
+// TileCache.cc
+//
+// Copyright 2014 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include "gmem.h"
+#include "gmempp.h"
+#include "GList.h"
+#include "GMutex.h"
+#ifdef _WIN32
+# include <windows.h>
+#else
+# include <pthread.h>
+# include <unistd.h>
+#endif
+#include "Object.h"
+#include "PDFDoc.h"
+#include "SplashBitmap.h"
+#include "SplashOutputDev.h"
+#include "DisplayState.h"
+#include "GfxState.h"
+#include "TileMap.h"
+#include "TileCache.h"
+
+//------------------------------------------------------------------------
+// CachedTileDesc
+//------------------------------------------------------------------------
+
+enum CachedTileState {
+ cachedTileUnstarted, // worker thread hasn't started
+ // rasterization yet
+ cachedTileStarted, // worker thread is rasterizing the tile
+ cachedTileFinished, // rasterization is done
+ cachedTileCanceled // worker thread should stop rasterizing
+ // and remove this tile from the cache
+};
+
+class CachedTileDesc: public TileDesc {
+public:
+
+ CachedTileDesc(TileDesc *tile):
+ TileDesc(tile->page, tile->rotate, tile->dpi,
+ tile->tx, tile->ty, tile->tw, tile->th),
+ state(cachedTileUnstarted), active(gTrue),
+ bitmap(NULL), freeBitmap(gFalse) {}
+ ~CachedTileDesc();
+
+ CachedTileState state;
+ GBool active;
+ SplashBitmap *bitmap;
+ GBool freeBitmap;
+};
+
+CachedTileDesc::~CachedTileDesc() {
+ if (freeBitmap) {
+ delete bitmap;
+ }
+}
+
+//------------------------------------------------------------------------
+// OS-dependent threading support code
+//
+// NB: This wrapper code is not meant to be general purpose. Pthreads
+// condition objects are not equivalent to Windows event objects, in
+// general.
+//------------------------------------------------------------------------
+
+//-------------------- Windows --------------------
+#ifdef _WIN32
+
+typedef HANDLE GThreadID;
+typedef DWORD (WINAPI *GThreadFunc)(void *);
+#define GThreadReturn DWORD WINAPI
+
+static void gCreateThread(GThreadID *thr, GThreadFunc threadFunc,
+ void *data) {
+ *thr = CreateThread(NULL, 0, threadFunc, data, 0, NULL);
+}
+
+static void gJoinThread(GThreadID thr) {
+ WaitForSingleObject(thr, INFINITE);
+ CloseHandle(thr);
+}
+
+typedef HANDLE GCondition;
+
+static void gInitCondition(GCondition *c) {
+ *c = CreateEvent(NULL, TRUE, FALSE, NULL);
+}
+
+static void gDestroyCondition(GCondition *c) {
+ CloseHandle(*c);
+}
+
+static void gSignalCondition(GCondition *c) {
+ SetEvent(*c);
+}
+
+static void gClearCondition(GCondition *c) {
+ ResetEvent(*c);
+}
+
+static void gWaitCondition(GCondition *c, GMutex *m) {
+ LeaveCriticalSection(m);
+ WaitForSingleObject(*c, INFINITE);
+ EnterCriticalSection(m);
+}
+
+//-------------------- pthreads --------------------
+#else
+
+typedef pthread_t GThreadID;
+typedef void *(*GThreadFunc)(void *);
+#define GThreadReturn void*
+
+static void gCreateThread(GThreadID *thr, GThreadFunc threadFunc,
+ void *data) {
+ pthread_create(thr, NULL, threadFunc, data);
+}
+
+static void gJoinThread(GThreadID thr) {
+ pthread_join(thr, NULL);
+}
+
+typedef pthread_cond_t GCondition;
+
+static void gInitCondition(GCondition *c) {
+ pthread_cond_init(c, NULL);
+}
+
+static void gDestroyCondition(GCondition *c) {
+ pthread_cond_destroy(c);
+}
+
+static void gSignalCondition(GCondition *c) {
+ pthread_cond_broadcast(c);
+}
+
+static void gClearCondition(GCondition *c) {
+}
+
+static void gWaitCondition(GCondition *c, GMutex *m) {
+ pthread_cond_wait(c, m);
+}
+
+#endif
+
+//------------------------------------------------------------------------
+// TileCacheThreadPool
+//------------------------------------------------------------------------
+
+class TileCacheThreadPool {
+public:
+
+ TileCacheThreadPool(TileCache *tileCacheA, int nThreadsA);
+ ~TileCacheThreadPool();
+
+ // Called by the client when one or more jobs have been added to the
+ // queue. This must be called with the mutex unlocked.
+ void jobAdded();
+
+ // Wait for at least one job to be finished. This must be called
+ // with the mutex locked.
+ void waitForFinishedJob();
+
+ // The client should use the mutex to protect the queue data
+ // structure.
+ void lockMutex() { gLockMutex(&mutex); }
+ void unlockMutex() { gUnlockMutex(&mutex); }
+
+private:
+
+ static GThreadReturn threadFunc(void *arg);
+ void worker();
+
+ TileCache *tileCache;
+ int nThreads;
+ GThreadID *threads;
+ GBool quit;
+ GMutex mutex;
+ GCondition cond; // signalled when a job is added to the
+ // queue and when the quit flag is set
+ GCondition finishCond; // signalled whenever a worker thread
+ // finishes rasterizing a tile
+};
+
+TileCacheThreadPool::TileCacheThreadPool(TileCache *tileCacheA,
+ int nThreadsA) {
+ int i;
+
+ tileCache = tileCacheA;
+ nThreads = nThreadsA;
+ quit = gFalse;
+ gInitMutex(&mutex);
+ gInitCondition(&cond);
+ gInitCondition(&finishCond);
+ threads = (GThreadID *)gmallocn(nThreads, sizeof(GThreadID));
+ for (i = 0; i < nThreads; ++i) {
+ gCreateThread(&threads[i], &threadFunc, this);
+ }
+}
+
+TileCacheThreadPool::~TileCacheThreadPool() {
+ int i;
+
+ gLockMutex(&mutex);
+ quit = true;
+ gSignalCondition(&cond);
+ gUnlockMutex(&mutex);
+ for (i = 0; i < nThreads; ++i) {
+ gJoinThread(threads[i]);
+ }
+ gDestroyCondition(&cond);
+ gDestroyCondition(&finishCond);
+ gDestroyMutex(&mutex);
+ gfree(threads);
+}
+
+void TileCacheThreadPool::jobAdded() {
+ gLockMutex(&mutex);
+ gSignalCondition(&cond);
+ gUnlockMutex(&mutex);
+}
+
+GThreadReturn TileCacheThreadPool::threadFunc(void *arg) {
+ ((TileCacheThreadPool *)arg)->worker();
+ return 0;
+}
+
+void TileCacheThreadPool::worker() {
+ CachedTileDesc *ct;
+
+ while (1) {
+ gLockMutex(&mutex);
+ while (!quit && !(ct = tileCache->getUnstartedTile())) {
+ gWaitCondition(&cond, &mutex);
+ }
+ if (quit) {
+ gUnlockMutex(&mutex);
+ break;
+ }
+ if (!tileCache->hasUnstartedTiles()) {
+ gClearCondition(&cond);
+ }
+ gUnlockMutex(&mutex);
+ tileCache->rasterizeTile(ct);
+ gSignalCondition(&finishCond);
+ }
+}
+
+void TileCacheThreadPool::waitForFinishedJob() {
+ gWaitCondition(&finishCond, &mutex);
+}
+
+//------------------------------------------------------------------------
+// TileCache
+//------------------------------------------------------------------------
+
+TileCache::TileCache(DisplayState *stateA) {
+ state = stateA;
+ state->setTileCache(this);
+ cache = new GList();
+ threadPool = new TileCacheThreadPool(this, state->getNWorkerThreads());
+ tileDoneCbk = NULL;
+ tileDoneCbkData = NULL;
+}
+
+TileCache::~TileCache() {
+ flushCache(gFalse);
+ delete threadPool;
+ delete cache;
+}
+
+void TileCache::setActiveTileList(GList *tiles) {
+ TileDesc *tile;
+ CachedTileDesc *ct;
+ int tileIdx, cacheIdx;
+ GBool newTiles;
+
+ threadPool->lockMutex();
+
+ // remove any unstarted tiles not on the new active list;
+ // cancel any started tiles not on the new active list;
+ // mark all other tiles as inactive (active tiles will be marked later)
+ cacheIdx = 0;
+ while (cacheIdx < cache->getLength()) {
+ ct = (CachedTileDesc *)cache->get(cacheIdx);
+ if (ct->state == cachedTileUnstarted && findTile(ct, tiles) < 0) {
+ delete (CachedTileDesc *)cache->del(cacheIdx);
+ } else if (ct->state == cachedTileStarted && findTile(ct, tiles) < 0) {
+ ct->state = cachedTileCanceled;
+ ++cacheIdx;
+ } else {
+ ct->active = gFalse;
+ ++cacheIdx;
+ }
+ }
+
+ // mark cached tiles as active; add any new tiles to the cache
+ newTiles = gFalse;
+ for (tileIdx = 0; tileIdx < tiles->getLength(); ++tileIdx) {
+ tile = (TileDesc *)tiles->get(tileIdx);
+ cacheIdx = findTile(tile, cache);
+ if (cacheIdx >= 0) {
+ ct = (CachedTileDesc *)cache->del(cacheIdx);
+ } else {
+ ct = new CachedTileDesc(tile);
+ newTiles = gTrue;
+ }
+ ct->active = gTrue;
+ cache->insert(0, ct);
+ }
+
+ cleanCache();
+
+ threadPool->unlockMutex();
+
+ if (newTiles) {
+ threadPool->jobAdded();
+ }
+}
+
+SplashBitmap *TileCache::getTileBitmap(TileDesc *tile, GBool *finished) {
+ CachedTileDesc *ct;
+ SplashBitmap *bitmap;
+ int cacheIdx;
+
+ threadPool->lockMutex();
+ cacheIdx = findTile(tile, cache);
+ if (cacheIdx < 0) {
+ threadPool->unlockMutex();
+ return NULL;
+ }
+ ct = (CachedTileDesc *)cache->get(cacheIdx);
+ if (ct->state != cachedTileCanceled) {
+ bitmap = ct->bitmap;
+ } else {
+ bitmap = NULL;
+ }
+ if (finished) {
+ *finished = ct->state == cachedTileFinished;
+ }
+ threadPool->unlockMutex();
+ return bitmap;
+}
+
+void TileCache::paperColorChanged() {
+ flushCache(gFalse);
+}
+
+void TileCache::reverseVideoChanged() {
+ flushCache(gFalse);
+}
+
+void TileCache::optionalContentChanged() {
+ flushCache(gFalse);
+}
+
+void TileCache::docChanged() {
+ flushCache(gTrue);
+}
+
+
+void TileCache::forceRedraw() {
+ flushCache(gFalse);
+}
+
+// Search for <tile> on <tileList>, and return its index if found, or
+// -1 if not found. If <tile> is part of the cache, or if <tileList>
+// is the cache, the caller must have locked the ThreadPool mutex.
+int TileCache::findTile(TileDesc *tile, GList *tileList) {
+ TileDesc *t;
+ int i;
+
+ for (i = 0; i < tileList->getLength(); ++i) {
+ t = (TileDesc *)tileList->get(i);
+ if (t->matches(tile)) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+// If there are too many tiles in the cache, remove the least recently
+// used tiles. Never removes active tiles. The caller must have
+// locked the ThreadPool mutex.
+void TileCache::cleanCache() {
+ CachedTileDesc *ct;
+ int n, i;
+
+ // count the number of non-canceled tiles
+ n = 0;
+ for (i = 0; i < cache->getLength(); ++i) {
+ ct = (CachedTileDesc *)cache->get(i);
+ if (ct->state != cachedTileCanceled) {
+ ++n;
+ }
+ }
+
+ // if there are too many non-canceled tiles, remove tiles
+ i = cache->getLength() - 1;
+ while (n > state->getTileCacheSize() && i >= 0) {
+ ct = (CachedTileDesc *)cache->get(i);
+ if (ct->active) {
+ break;
+ }
+ // any non-active tiles with state == cachedTileUnstarted should
+ // already have been removed by setActiveTileList()
+ if (ct->state == cachedTileFinished) {
+ delete (CachedTileDesc *)cache->del(i);
+ --n;
+ --i;
+ } else {
+ --i;
+ }
+ }
+}
+
+// Remove all cached tiles. For tiles that are being rasterized, sets
+// state to canceled. If <wait> is true, this function won't return
+// until the cache is empty, i.e., until all possible users of the
+// PDFDoc are done.
+void TileCache::flushCache(GBool wait) {
+ CachedTileDesc *ct;
+ int i;
+
+ threadPool->lockMutex();
+ i = 0;
+ while (i < cache->getLength()) {
+ ct = (CachedTileDesc *)cache->get(i);
+ switch (ct->state) {
+ case cachedTileUnstarted:
+ case cachedTileFinished:
+ delete (CachedTileDesc *)cache->del(i);
+ break;
+ case cachedTileStarted:
+ ct->state = cachedTileCanceled;
+ ++i;
+ break;
+ case cachedTileCanceled:
+ default:
+ ++i;
+ break;
+ }
+ }
+ if (wait) {
+ while (cache->getLength() > 0) {
+ threadPool->waitForFinishedJob();
+ }
+ }
+ threadPool->unlockMutex();
+}
+
+// Remove a tile from the cache and delete it. This will be called
+// with the TileCacheThreadPool mutex locked.
+void TileCache::removeTile(CachedTileDesc *ct) {
+ int i;
+
+ for (i = 0; i < cache->getLength(); ++i) {
+ if (cache->get(i) == ct) {
+ delete (CachedTileDesc *)cache->del(i);
+ break;
+ }
+ }
+}
+
+// Return true if there are one or more unstarted tiles. This will be
+// called with the TileCacheThreadPool mutex locked.
+GBool TileCache::hasUnstartedTiles() {
+ CachedTileDesc *ct;
+ int i;
+
+ for (i = 0; i < cache->getLength(); ++i) {
+ ct = (CachedTileDesc *)cache->get(i);
+ if (ct->state == cachedTileUnstarted) {
+ return gTrue;
+ }
+ }
+ return gFalse;
+}
+
+// Return the next unstarted tile, changing its state to
+// cachedTileStarted. If there are no unstarted tiles, return NULL.
+// This will be called with the TileCacheThreadPool mutex locked.
+CachedTileDesc *TileCache::getUnstartedTile() {
+ CachedTileDesc *ct;
+ int i;
+
+ for (i = 0; i < cache->getLength(); ++i) {
+ ct = (CachedTileDesc *)cache->get(i);
+ if (ct->state == cachedTileUnstarted) {
+ ct->state = cachedTileStarted;
+ return ct;
+ }
+ }
+ return NULL;
+}
+
+struct TileCacheStartPageInfo {
+ TileCache *tileCache;
+ CachedTileDesc *ct;
+ SplashOutputDev *out;
+};
+
+void TileCache::startPageCbk(void *data) {
+ TileCacheStartPageInfo *info = (TileCacheStartPageInfo *)data;
+
+ info->tileCache->threadPool->lockMutex();
+ info->ct->bitmap = info->out->getBitmap();
+ info->ct->freeBitmap = gFalse;
+ info->tileCache->threadPool->unlockMutex();
+}
+
+// Rasterize <tile>. The state has already been set to
+// cachedTileStarted.
+void TileCache::rasterizeTile(CachedTileDesc *ct) {
+ SplashOutputDev *out;
+ TileCacheStartPageInfo info;
+
+
+ out = new SplashOutputDev(state->getColorMode(), 1, state->getReverseVideo(),
+ state->getPaperColor());
+ info.tileCache = this;
+ info.ct = ct;
+ info.out = out;
+ out->setStartPageCallback(&TileCache::startPageCbk, &info);
+ out->startDoc(state->getDoc()->getXRef());
+ state->getDoc()->displayPageSlice(out, ct->page, ct->dpi, ct->dpi, ct->rotate,
+ gFalse, gTrue, gFalse,
+ ct->tx, ct->ty, ct->tw, ct->th,
+ &abortCheckCbk, ct);
+ if (ct->state == cachedTileCanceled) {
+ threadPool->lockMutex();
+ removeTile(ct);
+ threadPool->unlockMutex();
+ } else {
+ threadPool->lockMutex();
+ ct->bitmap = out->takeBitmap();
+ ct->freeBitmap = gTrue;
+ ct->state = cachedTileFinished;
+ threadPool->unlockMutex();
+ if (tileDoneCbk) {
+ (*tileDoneCbk)(tileDoneCbkData);
+ }
+ }
+ delete out;
+}
+
+
+GBool TileCache::abortCheckCbk(void *data) {
+ CachedTileDesc *ct = (CachedTileDesc *)data;
+ return ct->state == cachedTileCanceled;
+}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.h b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.h
new file mode 100644
index 00000000000..bea58c4c8fc
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCache.h
@@ -0,0 +1,78 @@
+//========================================================================
+//
+// TileCache.h
+//
+// Copyright 2014 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef TILECACHE_H
+#define TILECACHE_H
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include "gtypes.h"
+#include "SplashTypes.h"
+
+class SplashBitmap;
+class SplashOutputDev;
+class DisplayState;
+class CachedTileDesc;
+class TileCacheThreadPool;
+class TileDesc;
+
+//------------------------------------------------------------------------
+
+class TileCache {
+public:
+
+ TileCache(DisplayState *stateA);
+ ~TileCache();
+
+ // Set the list of currently displayed tiles (TileDesc objects).
+ void setActiveTileList(GList *tiles);
+
+ // Return the bitmap for a tile. The tile must be on the current
+ // active list. This can return NULL if tile rasterization hasn't
+ // started yet. If <finished> is non-NULL, *<finished> will be set
+ // to true if rasterization of this bitmap is finished, false
+ // otherwise.
+ SplashBitmap *getTileBitmap(TileDesc *tile, GBool *finished);
+
+ // Set a callback to be called whenever a tile rasterization is
+ // finished. NB: this callback will be called from a worker thread.
+ void setTileDoneCbk(void (*cbk)(void *data), void *data)
+ { tileDoneCbk = cbk; tileDoneCbkData = data; }
+
+ void paperColorChanged();
+ void reverseVideoChanged();
+ void optionalContentChanged();
+ void docChanged();
+ void forceRedraw();
+
+private:
+
+ int findTile(TileDesc *tile, GList *tileList);
+ void cleanCache();
+ void flushCache(GBool wait);
+ void removeTile(CachedTileDesc *ct);
+ GBool hasUnstartedTiles();
+ CachedTileDesc *getUnstartedTile();
+ static void startPageCbk(void *data);
+ void rasterizeTile(CachedTileDesc *tile);
+ static GBool abortCheckCbk(void *data);
+
+ DisplayState *state;
+ GList *cache; // [CachedTileDesc]
+ TileCacheThreadPool *threadPool;
+ void (*tileDoneCbk)(void *data);
+ void *tileDoneCbkData;
+
+ friend class TileCacheThreadPool;
+};
+
+#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc
new file mode 100644
index 00000000000..d0f5f1ea401
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.cc
@@ -0,0 +1,447 @@
+//========================================================================
+//
+// TileCompositor.cc
+//
+// Copyright 2014 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include <string.h>
+#include <math.h>
+#include "gmempp.h"
+#include "GString.h"
+#include "GList.h"
+#include "SplashBitmap.h"
+#include "GlobalParams.h"
+#include "DisplayState.h"
+#include "TileMap.h"
+#include "TileCache.h"
+#include "TileCompositor.h"
+
+//------------------------------------------------------------------------
+
+// Divide a 16-bit value (in [0, 255*255]) by 255, returning an 8-bit result.
+static inline Guchar div255(int x) {
+ return (Guchar)((x + (x >> 8) + 0x80) >> 8);
+}
+
+//------------------------------------------------------------------------
+
+TileCompositor::TileCompositor(DisplayState *stateA,
+ TileMap *tileMapA,
+ TileCache *tileCacheA) {
+ state = stateA;
+ state->setTileCompositor(this);
+ tileMap = tileMapA;
+ tileCache = tileCacheA;
+ bitmap = NULL;
+ bitmapValid = gFalse;
+}
+
+TileCompositor::~TileCompositor() {
+ delete bitmap;
+}
+
+SplashBitmap *TileCompositor::getBitmap(GBool *finished) {
+ GList *tiles;
+ PlacedTileDesc *tile;
+ SplashBitmap *tileBitmap;
+ GBool allTilesFinished, tileFinished;
+ int xSrc, ySrc, xDest, yDest, w, h, i;
+
+ if (bitmapValid) {
+ *finished = gTrue;
+ return bitmap;
+ }
+ if (!bitmap ||
+ bitmap->getWidth() != state->getWinW() ||
+ bitmap->getHeight() != state->getWinH()) {
+ if (bitmap) {
+ delete bitmap;
+ }
+ bitmap = new SplashBitmap(state->getWinW(), state->getWinH(),
+ state->getBitmapRowPad(), state->getColorMode(),
+ gFalse);
+ }
+ clearBitmap();
+
+ //--- PDF content
+ allTilesFinished = gTrue;
+ tiles = tileMap->getTileList();
+ tileCache->setActiveTileList(tiles);
+ for (i = 0; i < tiles->getLength(); ++i) {
+ tile = (PlacedTileDesc *)tiles->get(i);
+ if (tile->px >= 0) {
+ xSrc = 0;
+ xDest = tile->px;
+ w = tile->tw;
+ } else {
+ xSrc = -tile->px;
+ xDest = 0;
+ w = tile->tw + tile->px;
+ }
+ if (xDest + w > state->getWinW()) {
+ w = state->getWinW() - xDest;
+ }
+ if (tile->py >= 0) {
+ ySrc = 0;
+ yDest = tile->py;
+ h = tile->th;
+ } else {
+ ySrc = -tile->py;
+ yDest = 0;
+ h = tile->th + tile->py;
+ }
+ if (yDest + h > state->getWinH()) {
+ h = state->getWinH() - yDest;
+ }
+ if (w > 0 && h > 0) {
+ if ((tileBitmap = tileCache->getTileBitmap(tile, &tileFinished))) {
+ blit(tileBitmap, xSrc, ySrc,
+ bitmap, xDest, yDest, w, h, !tileFinished);
+ } else {
+ fill(xDest, yDest, w, h, state->getPaperColor());
+ }
+ allTilesFinished &= tileFinished;
+ }
+ }
+
+
+ //--- selection
+ if (state->hasSelection()) {
+ drawSelection();
+ }
+
+ if (finished) {
+ *finished = allTilesFinished;
+ }
+ bitmapValid = allTilesFinished;
+
+ return bitmap;
+}
+
+void TileCompositor::drawSelection() {
+ SelectRect *rect;
+ int x0, y0, x1, y1, t, i;
+
+ for (i = 0; i < state->getNumSelectRects(); ++i) {
+ rect = state->getSelectRect(i);
+ tileMap->cvtUserToWindow(rect->page, rect->x0, rect->y0, &x0, &y0);
+ tileMap->cvtUserToWindow(rect->page, rect->x1, rect->y1, &x1, &y1);
+ if (x0 > x1) {
+ t = x0; x0 = x1; x1 = t;
+ }
+ if (y0 > y1) {
+ t = y0; y0 = y1; y1 = t;
+ }
+ if (x0 < 0) {
+ x0 = 0;
+ } else if (x0 > state->getWinW()) {
+ x0 = state->getWinW();
+ }
+ if (y0 < 0) {
+ y0 = 0;
+ } else if (y0 > state->getWinH()) {
+ y0 = state->getWinH();
+ }
+ if (x1 < 0) {
+ x1 = 0;
+ } else if (x1 > state->getWinW()) {
+ x1 = state->getWinW();
+ }
+ if (y1 < 0) {
+ y1 = 0;
+ } else if (y1 > state->getWinH()) {
+ y1 = state->getWinH();
+ }
+ // NB: in any of the non-continuous modes, if selectPage isn't
+ // displayed, cvtUserToWindow will return 0,0 -- so we need to
+ // check for x0 < x1 and y0 < y1 here
+ if (x0 < x1 && y0 < y1) {
+ applySelection(x0, y0, x1 - x0, y1 - y0, state->getSelectColor());
+ }
+ }
+}
+
+
+void TileCompositor::paperColorChanged() {
+ bitmapValid = gFalse;
+}
+
+void TileCompositor::matteColorChanged() {
+ bitmapValid = gFalse;
+}
+
+void TileCompositor::selectColorChanged() {
+ bitmapValid = gFalse;
+}
+
+void TileCompositor::reverseVideoChanged() {
+ bitmapValid = gFalse;
+}
+
+void TileCompositor::docChanged() {
+ bitmapValid = gFalse;
+}
+
+void TileCompositor::windowSizeChanged() {
+ bitmapValid = gFalse;
+}
+
+void TileCompositor::displayModeChanged() {
+ bitmapValid = gFalse;
+}
+
+void TileCompositor::zoomChanged() {
+ bitmapValid = gFalse;
+}
+
+void TileCompositor::rotateChanged() {
+ bitmapValid = gFalse;
+}
+
+void TileCompositor::scrollPositionChanged() {
+ bitmapValid = gFalse;
+}
+
+void TileCompositor::selectionChanged() {
+ bitmapValid = gFalse;
+}
+
+void TileCompositor::regionsChanged() {
+ bitmapValid = gFalse;
+}
+
+void TileCompositor::optionalContentChanged() {
+ bitmapValid = gFalse;
+}
+
+
+void TileCompositor::forceRedraw() {
+ bitmapValid = gFalse;
+}
+
+// Clear the bitmap to matteColor. This only supports the RGB8 and
+// BGR8 color modes.
+void TileCompositor::clearBitmap() {
+ SplashColorPtr data, row, p;
+ int rowSize, w, h, x, y;
+
+ w = bitmap->getWidth();
+ h = bitmap->getHeight();
+ rowSize = bitmap->getRowSize();
+ data = bitmap->getDataPtr();
+
+ switch (state->getColorMode()) {
+ case splashModeRGB8:
+ if (state->getMatteColor()[0] == state->getMatteColor()[1] &&
+ state->getMatteColor()[1] == state->getMatteColor()[2]) {
+ if (rowSize < 0) {
+ memset(data + rowSize * (h - 1), state->getMatteColor()[0],
+ -rowSize * h);
+ } else {
+ memset(data, state->getMatteColor()[0], rowSize * h);
+ }
+ } else {
+ row = data;
+ for (y = 0; y < h; ++y) {
+ p = row;
+ for (x = 0; x < w; ++x) {
+ *p++ = state->getMatteColor()[0];
+ *p++ = state->getMatteColor()[1];
+ *p++ = state->getMatteColor()[2];
+ }
+ row += rowSize;
+ }
+ }
+ break;
+ case splashModeBGR8:
+ if (state->getMatteColor()[0] == state->getMatteColor()[1] &&
+ state->getMatteColor()[1] == state->getMatteColor()[2]) {
+ if (rowSize < 0) {
+ memset(data + rowSize * (h - 1), state->getMatteColor()[0],
+ -rowSize * h);
+ } else {
+ memset(data, state->getMatteColor()[0], rowSize * h);
+ }
+ } else {
+ row = data;
+ for (y = 0; y < h; ++y) {
+ p = row;
+ for (x = 0; x < w; ++x) {
+ *p++ = state->getMatteColor()[2];
+ *p++ = state->getMatteColor()[1];
+ *p++ = state->getMatteColor()[0];
+ }
+ row += rowSize;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+// Copy [xSrc, ySrc, w, h] from srcBitmap to [xDest, yDest] in
+// destBitmap. This only supports the RGB8 and BGR8 color modes.
+// If [compositeWithPaper] is true, composites the source bitmap
+// with the paper color (used for incremental updates).
+void TileCompositor::blit(SplashBitmap *srcBitmap, int xSrc, int ySrc,
+ SplashBitmap *destBitmap, int xDest, int yDest,
+ int w, int h, GBool compositeWithPaper) {
+ SplashColorPtr srcData, destData, srcP, destP;
+ SplashColorPtr paperColor;
+ Guchar *alphaData, *alphaP;
+ Guchar alpha, alpha1;
+ int srcRowSize, destRowSize, alphaRowSize, x, y;
+
+ srcData = srcBitmap->getDataPtr();
+ srcRowSize = srcBitmap->getRowSize();
+ destData = destBitmap->getDataPtr();
+ destRowSize = destBitmap->getRowSize();
+
+ if (compositeWithPaper && (alphaData = srcBitmap->getAlphaPtr())) {
+ alphaRowSize = srcBitmap->getWidth();
+ paperColor = state->getPaperColor();
+ for (y = 0; y < h; ++y) {
+ destP = &destData[(yDest + y) * destRowSize + 3 * xDest];
+ srcP = &srcData[(ySrc + y) * srcRowSize + 3 * xSrc];
+ alphaP = &alphaData[(ySrc + y) * alphaRowSize + xSrc];
+ for (x = 0; x < w; ++x) {
+ alpha = *alphaP++;
+ //~ this needs to swap paperColor 0/1/2 in BGR8 mode (?)
+ if (alpha == 255) {
+ destP[0] = srcP[0];
+ destP[1] = srcP[1];
+ destP[2] = srcP[2];
+ } else if (alpha == 0) {
+ destP[0] = paperColor[0];
+ destP[1] = paperColor[1];
+ destP[2] = paperColor[2];
+ } else {
+ alpha1 = 255 - alpha;
+ destP[0] = div255(alpha1 * paperColor[0] + alpha * srcP[0]);
+ destP[1] = div255(alpha1 * paperColor[1] + alpha * srcP[1]);
+ destP[2] = div255(alpha1 * paperColor[2] + alpha * srcP[2]);
+ }
+ srcP += 3;
+ destP += 3;
+ }
+ }
+ } else {
+ for (y = 0; y < h; ++y) {
+ destP = &destData[(yDest + y) * destRowSize + 3 * xDest];
+ srcP = &srcData[(ySrc + y) * srcRowSize + 3 * xSrc];
+ memcpy(destP, srcP, 3 * w);
+ }
+ }
+}
+
+// Fill [xDest, yDest, w, h] with color. This only supports the RGB8
+// and BGR8 color modes.
+void TileCompositor::fill(int xDest, int yDest, int w, int h,
+ SplashColorPtr color) {
+ SplashColorPtr data, p;
+ Guchar c0, c1, c2;
+ int rowSize, x, y;
+
+ if (xDest < 0) {
+ w += xDest;
+ xDest = 0;
+ }
+ if (xDest + w > state->getWinW()) {
+ w = state->getWinW() - xDest;
+ }
+ if (w <= 0) {
+ return;
+ }
+ if (yDest < 0) {
+ h += yDest;
+ yDest = 0;
+ }
+ if (yDest + h > state->getWinH()) {
+ h = state->getWinH() - yDest;
+ }
+ if (h <= 0) {
+ return;
+ }
+ data = bitmap->getDataPtr();
+ rowSize = bitmap->getRowSize();
+ if (bitmap->getMode() == splashModeRGB8) {
+ c0 = color[0];
+ c1 = color[1];
+ c2 = color[2];
+ } else {
+ c0 = color[2];
+ c1 = color[1];
+ c2 = color[0];
+ }
+ for (y = 0; y < h; ++y) {
+ p = &data[(yDest + y) * rowSize + 3 * xDest];
+ for (x = 0; x < w; ++x) {
+ p[0] = c0;
+ p[1] = c1;
+ p[2] = c2;
+ p += 3;
+ }
+ }
+}
+
+// Apply a selection of <color> to the specified rectangle. This only
+// supports the RGB8 and BGR8 color modes.
+void TileCompositor::applySelection(int xDest, int yDest, int w, int h,
+ SplashColorPtr color) {
+ SplashColorPtr data, p;
+ Guchar c0, c1, c2;
+ int rowSize, x, y;
+
+ if (xDest < 0) {
+ w += xDest;
+ xDest = 0;
+ }
+ if (xDest + w > state->getWinW()) {
+ w = state->getWinW() - xDest;
+ }
+ if (w <= 0) {
+ return;
+ }
+ if (yDest < 0) {
+ h += yDest;
+ yDest = 0;
+ }
+ if (yDest + h > state->getWinH()) {
+ h = state->getWinH() - yDest;
+ }
+ if (h <= 0) {
+ return;
+ }
+ data = bitmap->getDataPtr();
+ rowSize = bitmap->getRowSize();
+ if (bitmap->getMode() == splashModeRGB8) {
+ c0 = color[0];
+ c1 = color[1];
+ c2 = color[2];
+ } else {
+ c0 = color[2];
+ c1 = color[1];
+ c2 = color[0];
+ }
+ for (y = 0; y < h; ++y) {
+ p = &data[(yDest + y) * rowSize + 3 * xDest];
+ for (x = 0; x < w; ++x) {
+ p[0] = (3 * p[0] + c0) / 4;
+ p[1] = (3 * p[1] + c1) / 4;
+ p[2] = (3 * p[2] + c2) / 4;
+ p += 3;
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.h b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.h
new file mode 100644
index 00000000000..aa06c9da7bd
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileCompositor.h
@@ -0,0 +1,77 @@
+//========================================================================
+//
+// TileCompositor.h
+//
+// Copyright 2014 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef TILECOMPOSITOR_H
+#define TILECOMPOSITOR_H
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include "SplashTypes.h"
+
+class GList;
+class SplashBitmap;
+class DisplayState;
+class TileCache;
+
+//------------------------------------------------------------------------
+
+class TileCompositor {
+public:
+
+ TileCompositor(DisplayState *stateA,
+ TileMap *tileMapA, TileCache *tileCacheA);
+ ~TileCompositor();
+
+ // Returns the window bitmap. The returned bitmap is owned by the
+ // TileCompositor object (and may be reused) -- the caller should
+ // not modify or free it. If <finished> is is non-NULL, *<finished>
+ // will be set to true if all of the needed tiles are finished,
+ // i.e., if the returned bitmap is complete.
+ SplashBitmap *getBitmap(GBool *finished);
+
+ void paperColorChanged();
+ void matteColorChanged();
+ void selectColorChanged();
+ void reverseVideoChanged();
+ void docChanged();
+ void windowSizeChanged();
+ void displayModeChanged();
+ void zoomChanged();
+ void rotateChanged();
+ void scrollPositionChanged();
+ void selectionChanged();
+ void regionsChanged();
+ void optionalContentChanged();
+ void forceRedraw();
+
+private:
+
+ void clearBitmap();
+ void blit(SplashBitmap *srcBitmap, int xSrc, int ySrc,
+ SplashBitmap *destBitmap, int xDest, int yDest,
+ int w, int h, GBool compositeWithPaper);
+ void fill(int xDest, int yDest, int w, int h,
+ SplashColorPtr color);
+ void drawSelection();
+ void applySelection(int xDest, int yDest, int w, int h,
+ SplashColorPtr color);
+
+ DisplayState *state;
+ TileMap *tileMap;
+ TileCache *tileCache;
+
+ SplashBitmap *bitmap;
+ GBool bitmapValid;
+
+};
+
+#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
new file mode 100644
index 00000000000..7e042cbb307
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.cc
@@ -0,0 +1,1614 @@
+//========================================================================
+//
+// TileMap.cc
+//
+// Copyright 2014 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include "gmem.h"
+#include "gmempp.h"
+#include "GList.h"
+#include "PDFDoc.h"
+#include "DisplayState.h"
+#include "TileMap.h"
+
+//------------------------------------------------------------------------
+
+// Number of pixels of matte color between pages (above and below each
+// other) in continuous mode.
+#define continuousPageSpacing 3
+
+// Number of pixels of matte color between facing pages (left and
+// right of each other) in side-by-side mode.
+#define sideBySidePageSpacing 3
+
+// Number of pixels of matte color between pages (left and right of
+// each other) in horizontal continuous mode.
+#define horizContinuousPageSpacing 3
+
+//------------------------------------------------------------------------
+
+TileMap::TileMap(DisplayState *stateA) {
+ state = stateA;
+ state->setTileMap(this);
+ pageDPI = NULL;
+ pageW = pageH = NULL;
+ tileW = tileH = NULL;
+ pageBoxW = pageBoxH = NULL;
+ pageX = pageY = NULL;
+ tiles = NULL;
+}
+
+TileMap::~TileMap() {
+ clearPageParams();
+ clearContinuousModeParams();
+ gfree(pageBoxW);
+ gfree(pageBoxH);
+ if (tiles) {
+ deleteGList(tiles, PlacedTileDesc);
+ }
+}
+
+GList *TileMap::getTileList() {
+ double pageDPI1, pageDPI2;
+ int pageW1, pageH1, tileW1, tileH1, pageW2, pageH2, tileW2, tileH2;
+ int offsetX, offsetY, offsetX2;
+ int x0, y0, x1, y1, x, y, tx, ty, tw, th, page;
+
+ if (tiles) {
+ return tiles;
+ }
+
+ tiles = new GList();
+
+ if (!state->getDoc() || !state->getDoc()->getNumPages()) {
+ return tiles;
+ }
+
+ updatePageParams();
+ updateContinuousModeParams();
+
+ switch (state->getDisplayMode()) {
+
+ case displaySingle:
+ page = state->getScrollPage();
+ pageDPI1 = pageDPI[page - 1];
+ pageW1 = pageW[page - 1];
+ pageH1 = pageH[page - 1];
+ tileW1 = tileW[page - 1];
+ tileH1 = tileH[page - 1];
+ if (pageW1 < state->getWinW()) {
+ offsetX = (state->getWinW() - pageW1) / 2;
+ } else {
+ offsetX = 0;
+ }
+ if (pageH1 < state->getWinH()) {
+ offsetY = (state->getWinH() - pageH1) / 2;
+ } else {
+ offsetY = 0;
+ }
+ if ((x0 = state->getScrollX() - offsetX) < 0) {
+ x0 = 0;
+ }
+ if ((y0 = state->getScrollY() - offsetY) < 0) {
+ y0 = 0;
+ }
+ if ((x1 = state->getScrollX() + state->getWinW() - 1 - offsetX) >= pageW1) {
+ x1 = pageW1 - 1;
+ }
+ if ((y1 = state->getScrollY() + state->getWinH() - 1 - offsetY) >= pageH1) {
+ y1 = pageH1 - 1;
+ }
+ for (y = y0 / tileH1; y <= y1 / tileH1; ++y) {
+ for (x = x0 / tileW1; x <= x1 / tileW1; ++x) {
+ tx = x * tileW1;
+ ty = y * tileH1;
+ tw = tileW1;
+ if (tx + tw > pageW1) {
+ tw = pageW1 - tx;
+ }
+ th = tileH1;
+ if (ty + th > pageH1) {
+ th = pageH1 - ty;
+ }
+ tiles->append(new PlacedTileDesc(page, state->getRotate(), pageDPI1,
+ tx, ty, tw, th,
+ tx - state->getScrollX() + offsetX,
+ ty - state->getScrollY() + offsetY));
+ }
+ }
+ break;
+
+ case displayContinuous:
+ if (totalH < state->getWinH()) {
+ offsetY = (state->getWinH() - totalH) / 2;
+ } else {
+ offsetY = 0;
+ }
+ page = findContinuousPage(state->getScrollY());
+ while (page <= state->getDoc()->getNumPages() &&
+ pageY[page - 1] < state->getScrollY() + state->getWinH()) {
+ pageDPI1 = pageDPI[page - 1];
+ pageW1 = pageW[page - 1];
+ pageH1 = pageH[page - 1];
+ tileW1 = tileW[page - 1];
+ tileH1 = tileH[page - 1];
+ if (maxW < state->getWinW()) {
+ offsetX = (state->getWinW() - maxW) / 2;
+ } else {
+ offsetX = 0;
+ }
+ offsetX += (maxW - pageW1) / 2;
+ if ((x0 = state->getScrollX() - offsetX) < 0) {
+ x0 = 0;
+ }
+ if ((y0 = state->getScrollY() - pageY[page - 1] - offsetY) < 0) {
+ y0 = 0;
+ }
+ if ((x1 = state->getScrollX() + state->getWinW() - 1 - offsetX)
+ >= pageW1) {
+ x1 = pageW1 - 1;
+ }
+ if ((y1 = state->getScrollY() - pageY[page - 1]
+ + state->getWinH() - 1 - offsetY)
+ >= pageH1) {
+ y1 = pageH1 - 1;
+ }
+ for (y = y0 / tileH1; y <= y1 / tileH1; ++y) {
+ for (x = x0 / tileW1; x <= x1 / tileW1; ++x) {
+ tx = x * tileW1;
+ ty = y * tileH1;
+ tw = tileW1;
+ if (tx + tw > pageW1) {
+ tw = pageW1 - tx;
+ }
+ th = tileH1;
+ if (ty + th > pageH1) {
+ th = pageH1 - ty;
+ }
+ tiles->append(new PlacedTileDesc(
+ page, state->getRotate(), pageDPI1,
+ tx, ty, tw, th,
+ tx - state->getScrollX() + offsetX,
+ ty - state->getScrollY() + pageY[page - 1]
+ + offsetY));
+ }
+ }
+ ++page;
+ }
+ break;
+
+ case displaySideBySideSingle:
+ page = state->getScrollPage();
+ pageDPI1 = pageDPI[page - 1];
+ pageW1 = pageW[page - 1];
+ pageH1 = pageH[page - 1];
+ tileW1 = tileW[page - 1];
+ tileH1 = tileH[page - 1];
+ if (page + 1 <= state->getDoc()->getNumPages()) {
+ pageDPI2 = pageDPI[page];
+ pageW2 = pageW[page];
+ pageH2 = pageH[page];
+ tileW2 = tileW[page];
+ tileH2 = tileH[page];
+ } else {
+ // display a single page as though there were a blank facing
+ // page of the same size
+ pageDPI2 = pageDPI1;
+ pageW2 = pageW1;
+ pageH2 = pageH1;
+ tileW2 = tileW1;
+ tileH2 = tileH1;
+ }
+ if (pageW1 + sideBySidePageSpacing + pageW2 < state->getWinW()) {
+ offsetX = (state->getWinW() -
+ (pageW1 + sideBySidePageSpacing + pageW2)) / 2;
+ } else {
+ offsetX = 0;
+ }
+ offsetX2 = offsetX + pageW1 + sideBySidePageSpacing;
+ if (pageH1 < state->getWinH() && pageH2 < state->getWinH()) {
+ if (pageH1 > pageH2) {
+ offsetY = (state->getWinH() - pageH1) / 2;
+ } else {
+ offsetY = (state->getWinH() - pageH2) / 2;
+ }
+ } else {
+ offsetY = 0;
+ }
+ // left page
+ if ((x0 = state->getScrollX() - offsetX) < 0) {
+ x0 = 0;
+ }
+ if ((y0 = state->getScrollY() - offsetY) < 0) {
+ y0 = 0;
+ }
+ if ((x1 = state->getScrollX() + state->getWinW() - 1 - offsetX) >= pageW1) {
+ x1 = pageW1 - 1;
+ } else if (x1 < 0) {
+ x1 = -tileW2;
+ }
+ if ((y1 = state->getScrollY() + state->getWinH() - 1 - offsetY) >= pageH1) {
+ y1 = pageH1 - 1;
+ } else if (y1 < 0) {
+ y1 = -tileH2;
+ }
+ for (y = y0 / tileH1; y <= y1 / tileH1; ++y) {
+ for (x = x0 / tileW1; x <= x1 / tileW1; ++x) {
+ tx = x * tileW1;
+ ty = y * tileH1;
+ tw = tileW1;
+ if (tx + tw > pageW1) {
+ tw = pageW1 - tx;
+ }
+ th = tileH1;
+ if (ty + th > pageH1) {
+ th = pageH1 - ty;
+ }
+ tiles->append(new PlacedTileDesc(page,
+ state->getRotate(), pageDPI1,
+ tx, ty, tw, th,
+ tx - state->getScrollX() + offsetX,
+ ty - state->getScrollY() + offsetY));
+ }
+ }
+ // right page
+ if (page + 1 <= state->getDoc()->getNumPages()) {
+ if ((x0 = state->getScrollX() - offsetX2) < 0) {
+ x0 = 0;
+ }
+ if ((y0 = state->getScrollY() - offsetY) < 0) {
+ y0 = 0;
+ }
+ if ((x1 = state->getScrollX() + state->getWinW() - 1 - offsetX2)
+ >= pageW2) {
+ x1 = pageW2 - 1;
+ } else if (x1 < 0) {
+ x1 = -tileW2;
+ }
+ if ((y1 = state->getScrollY() + state->getWinH() - 1 - offsetY)
+ >= pageH2) {
+ y1 = pageH2 - 1;
+ } else if (y1 < 0) {
+ y1 = -tileH2;
+ }
+ for (y = y0 / tileH2; y <= y1 / tileH2; ++y) {
+ for (x = x0 / tileW2; x <= x1 / tileW2; ++x) {
+ tx = x * tileW2;
+ ty = y * tileH2;
+ tw = tileW2;
+ if (tx + tw > pageW2) {
+ tw = pageW2 - tx;
+ }
+ th = tileH2;
+ if (ty + th > pageH2) {
+ th = pageH2 - ty;
+ }
+ tiles->append(new PlacedTileDesc(page + 1,
+ state->getRotate(), pageDPI2,
+ tx, ty, tw, th,
+ tx - state->getScrollX() + offsetX2,
+ ty - state->getScrollY() + offsetY));
+ }
+ }
+ }
+ break;
+
+ case displaySideBySideContinuous:
+ if (totalH < state->getWinH()) {
+ offsetY = (state->getWinH() - totalH) / 2;
+ } else {
+ offsetY = 0;
+ }
+ page = findSideBySideContinuousPage(state->getScrollY());
+ while (page <= state->getDoc()->getNumPages() &&
+ (pageY[page - 1] < state->getScrollY() + state->getWinH() ||
+ (page + 1 <= state->getDoc()->getNumPages() &&
+ pageY[page] < state->getScrollY() + state->getWinH()))) {
+ pageDPI1 = pageDPI[page - 1];
+ pageW1 = pageW[page - 1];
+ pageH1 = pageH[page - 1];
+ tileW1 = tileW[page - 1];
+ tileH1 = tileH[page - 1];
+ if (page + 1 <= state->getDoc()->getNumPages()) {
+ pageDPI2 = pageDPI[page];
+ pageW2 = pageW[page];
+ pageH2 = pageH[page];
+ tileW2 = tileW[page];
+ tileH2 = tileH[page];
+ } else {
+ // display a single page as though there were a blank facing
+ // page of the same size
+ pageDPI2 = pageDPI1;
+ pageW2 = pageW1;
+ pageH2 = pageH1;
+ tileW2 = tileW1;
+ tileH2 = tileH1;
+ }
+ if (maxW + sideBySidePageSpacing + maxW2 < state->getWinW()) {
+ offsetX = (state->getWinW() -
+ (maxW + sideBySidePageSpacing + maxW2)) / 2;
+ } else {
+ offsetX = 0;
+ }
+ offsetX += maxW - pageW1;
+ offsetX2 = offsetX + pageW1 + sideBySidePageSpacing;
+ // left page
+ if ((x0 = state->getScrollX() - offsetX) < 0) {
+ x0 = 0;
+ }
+ if ((y0 = state->getScrollY() - pageY[page - 1] - offsetY) < 0) {
+ y0 = 0;
+ }
+ if ((x1 = state->getScrollX() + state->getWinW() - 1 - offsetX)
+ >= pageW1) {
+ x1 = pageW1 - 1;
+ } else if (x1 < 0) {
+ x1 = -tileW2;
+ }
+ if ((y1 = state->getScrollY() - pageY[page - 1]
+ + state->getWinH() - 1 - offsetY)
+ >= pageH1) {
+ y1 = pageH1 - 1;
+ } else if (y1 < 0) {
+ y1 = -tileH2;
+ }
+ for (y = y0 / tileH1; y <= y1 / tileH1; ++y) {
+ for (x = x0 / tileW1; x <= x1 / tileW1; ++x) {
+ tx = x * tileW1;
+ ty = y * tileH1;
+ tw = tileW1;
+ if (tx + tw > pageW1) {
+ tw = pageW1 - tx;
+ }
+ th = tileH1;
+ if (ty + th > pageH1) {
+ th = pageH1 - ty;
+ }
+ tiles->append(new PlacedTileDesc(
+ page, state->getRotate(), pageDPI1,
+ tx, ty, tw, th,
+ tx - state->getScrollX() + offsetX,
+ ty - state->getScrollY() + pageY[page - 1]
+ + offsetY));
+ }
+ }
+ ++page;
+ // right page
+ if (page <= state->getDoc()->getNumPages()) {
+ if ((x0 = state->getScrollX() - offsetX2) < 0) {
+ x0 = 0;
+ }
+ if ((y0 = state->getScrollY() - pageY[page - 1] - offsetY) < 0) {
+ y0 = 0;
+ }
+ if ((x1 = state->getScrollX() + state->getWinW() - 1 - offsetX2)
+ >= pageW2) {
+ x1 = pageW2 - 1;
+ } else if (x1 < 0) {
+ x1 = -tileW2;
+ }
+ if ((y1 = state->getScrollY() - pageY[page - 1]
+ + state->getWinH() - 1 - offsetY)
+ >= pageH2) {
+ y1 = pageH2 - 1;
+ } else if (y1 < 0) {
+ y1 = -tileH2;
+ }
+ for (y = y0 / tileH2; y <= y1 / tileH2; ++y) {
+ for (x = x0 / tileW2; x <= x1 / tileW2; ++x) {
+ tx = x * tileW2;
+ ty = y * tileH2;
+ tw = tileW2;
+ if (tx + tw > pageW2) {
+ tw = pageW2 - tx;
+ }
+ th = tileH2;
+ if (ty + th > pageH2) {
+ th = pageH2 - ty;
+ }
+ tiles->append(new PlacedTileDesc(
+ page, state->getRotate(), pageDPI2,
+ tx, ty, tw, th,
+ tx - state->getScrollX() + offsetX2,
+ ty - state->getScrollY() + pageY[page - 1]
+ + offsetY));
+ }
+ }
+ }
+ ++page;
+ }
+ break;
+
+ case displayHorizontalContinuous:
+ if (totalW < state->getWinW()) {
+ offsetX = (state->getWinW() - totalW) / 2;
+ } else {
+ offsetX = 0;
+ }
+ page = findHorizContinuousPage(state->getScrollX());
+ while (page <= state->getDoc()->getNumPages() &&
+ pageX[page - 1] < state->getScrollX() + state->getWinW()) {
+ pageDPI1 = pageDPI[page - 1];
+ pageW1 = pageW[page - 1];
+ pageH1 = pageH[page - 1];
+ tileW1 = tileW[page - 1];
+ tileH1 = tileH[page - 1];
+ if (maxH < state->getWinH()) {
+ offsetY = (state->getWinH() - maxH) / 2;
+ } else {
+ offsetY = 0;
+ }
+ if ((x0 = state->getScrollX() - pageX[page - 1] - offsetX) < 0) {
+ x0 = 0;
+ }
+ if ((y0 = state->getScrollY() - offsetY) < 0) {
+ y0 = 0;
+ }
+ if ((x1 = state->getScrollX() - pageX[page - 1]
+ + state->getWinW() - 1 - offsetX)
+ >= pageW1) {
+ x1 = pageW1 - 1;
+ }
+ if ((y1 = state->getScrollY() + state->getWinH() - 1 - offsetY)
+ >= pageH1) {
+ y1 = pageH1 - 1;
+ }
+ for (y = y0 / tileH1; y <= y1 / tileH1; ++y) {
+ for (x = x0 / tileW1; x <= x1 / tileW1; ++x) {
+ tx = x * tileW1;
+ ty = y * tileH1;
+ tw = tileW1;
+ if (tx + tw > pageW1) {
+ tw = pageW1 - tx;
+ }
+ th = tileH1;
+ if (ty + th > pageH1) {
+ th = pageH1 - ty;
+ }
+ tiles->append(new PlacedTileDesc(
+ page, state->getRotate(), pageDPI1,
+ tx, ty, tw, th,
+ tx - state->getScrollX() + pageX[page - 1]
+ + offsetX,
+ ty - state->getScrollY() + offsetY));
+ }
+ }
+ ++page;
+ }
+ break;
+ }
+
+ return tiles;
+}
+
+void TileMap::getScrollLimits(int *horizMax, int *vertMax) {
+ int pageW1, pageH1, pageW2, pageH2;
+
+ if (!state->getDoc() || !state->getDoc()->getNumPages()) {
+ *horizMax = *vertMax = 0;
+ return;
+ }
+
+ updatePageParams();
+ updateContinuousModeParams();
+
+ switch (state->getDisplayMode()) {
+ case displaySingle:
+ *horizMax = pageW[state->getScrollPage() - 1];
+ *vertMax = pageH[state->getScrollPage() - 1];
+ break;
+ case displayContinuous:
+ *horizMax = maxW;
+ *vertMax = totalH;
+ break;
+ case displaySideBySideSingle:
+ pageW1 = pageW[state->getScrollPage() - 1];
+ pageH1 = pageH[state->getScrollPage() - 1];
+ if (state->getScrollPage() + 1 <= state->getDoc()->getNumPages()) {
+ pageW2 = pageW[state->getScrollPage()];
+ pageH2 = pageH[state->getScrollPage()];
+ } else {
+ pageW2 = pageW1;
+ pageH2 = pageH1;
+ }
+ *horizMax = pageW1 + sideBySidePageSpacing + pageW2;
+ *vertMax = pageH1 > pageH2 ? pageH1 : pageH2;
+ break;
+ case displaySideBySideContinuous:
+ *horizMax = maxW + sideBySidePageSpacing + maxW2;
+ *vertMax = totalH;
+ break;
+ case displayHorizontalContinuous:
+ *horizMax = totalW;
+ *vertMax = maxH;
+ break;
+ default: // should never happen
+ *horizMax = *vertMax = 0;
+ break;
+ }
+}
+
+GBool TileMap::cvtWindowToUser(int xw, int yw,
+ int *pg, double *xu, double *yu) {
+ GBool ok;
+ int xd, yd;
+
+ if (!state->getDoc() || !state->getDoc()->getNumPages()) {
+ *pg = 0;
+ *xu = *yu = 0;
+ return gFalse;
+ }
+
+ ok = cvtWindowToDev(xw, yw, pg, &xd, &yd);
+ cvtDevToUser(*pg, xd, yd, xu, yu);
+ return ok;
+}
+
+GBool TileMap::cvtWindowToDev(int xw, int yw,
+ int *pg, int *xd, int *yd) {
+ int pageW1, pageH1, pageW2, pageH2, offsetX, offsetX2, offsetY;
+
+ if (!state->getDoc() || !state->getDoc()->getNumPages()) {
+ *pg = 0;
+ *xd = *yd = 0;
+ return gFalse;
+ }
+
+ updatePageParams();
+ updateContinuousModeParams();
+
+ switch (state->getDisplayMode()) {
+
+ case displaySingle:
+ *pg = state->getScrollPage();
+ pageW1 = pageW[*pg - 1];
+ pageH1 = pageH[*pg - 1];
+ if (pageW1 < state->getWinW()) {
+ offsetX = (state->getWinW() - pageW1) / 2;
+ } else {
+ offsetX = 0;
+ }
+ if (pageH1 < state->getWinH()) {
+ offsetY = (state->getWinH() - pageH1) / 2;
+ } else {
+ offsetY = 0;
+ }
+ *xd = xw - offsetX + state->getScrollX();
+ *yd = yw - offsetY + state->getScrollY();
+ return *xd >= 0 && *xd < pageW1 && *yd >= 0 && *yd < pageH1;
+
+ case displayContinuous:
+ if (totalH < state->getWinH()) {
+ offsetY = (state->getWinH() - totalH) / 2;
+ } else {
+ offsetY = 0;
+ }
+ *pg = findContinuousPage(yw - offsetY + state->getScrollY());
+ pageW1 = pageW[*pg - 1];
+ pageH1 = pageH[*pg - 1];
+ if (maxW < state->getWinW()) {
+ offsetX = (state->getWinW() - maxW) / 2;
+ } else {
+ offsetX = 0;
+ }
+ offsetX += (maxW - pageW1) / 2;
+ *xd = xw - offsetX + state->getScrollX();
+ *yd = yw - offsetY - pageY[*pg - 1] + state->getScrollY();
+ return *xd >= 0 && *xd < pageW1 && *yd >= 0 && *yd < pageH1;
+
+ case displaySideBySideSingle:
+ pageW1 = pageW[state->getScrollPage() - 1];
+ pageH1 = pageH[state->getScrollPage() - 1];
+ if (state->getScrollPage() + 1 <= state->getDoc()->getNumPages()) {
+ pageW2 = pageW[state->getScrollPage()];
+ pageH2 = pageH[state->getScrollPage()];
+ } else {
+ // display a single page as though there were a blank facing
+ // page of the same size
+ pageW2 = pageW1;
+ pageH2 = pageH1;
+ }
+ if (pageW1 + sideBySidePageSpacing + pageW2 < state->getWinW()) {
+ offsetX = (state->getWinW() -
+ (pageW1 + sideBySidePageSpacing + pageW2)) / 2;
+ } else {
+ offsetX = 0;
+ }
+ offsetX2 = offsetX + pageW1 + sideBySidePageSpacing;
+ if (pageH1 < state->getWinH() && pageH2 < state->getWinH()) {
+ if (pageH1 > pageH2) {
+ offsetY = (state->getWinH() - pageH1) / 2;
+ } else {
+ offsetY = (state->getWinH() - pageH2) / 2;
+ }
+ } else {
+ offsetY = 0;
+ }
+ if (xw + state->getScrollX() < offsetX2) {
+ *pg = state->getScrollPage();
+ *xd = xw - offsetX + state->getScrollX();
+ *yd = yw - offsetY + state->getScrollY();
+ return *xd >= 0 && *xd < pageW1 && *yd >= 0 && *yd < pageH1;
+ } else {
+ if (state->getScrollPage() + 1 > state->getDoc()->getNumPages()) {
+ *pg = *xd = *yd = 0;
+ return gFalse;
+ }
+ *pg = state->getScrollPage() + 1;
+ *xd = xw - offsetX2 + state->getScrollX();
+ *yd = yw - offsetY + state->getScrollY();
+ return *xd >= 0 && *xd < pageW2 && *yd >= 0 && *yd < pageH2;
+ }
+
+ case displaySideBySideContinuous:
+ if (totalH < state->getWinH()) {
+ offsetY = (state->getWinH() - totalH) / 2;
+ } else {
+ offsetY = 0;
+ }
+ *pg = findSideBySideContinuousPage(yw - offsetY + state->getScrollY());
+ pageW1 = pageW[*pg - 1];
+ pageH1 = pageH[*pg - 1];
+ if (*pg + 1 <= state->getDoc()->getNumPages()) {
+ pageW2 = pageW[*pg];
+ pageH2 = pageH[*pg];
+ } else {
+ pageW2 = pageH2 = 0;
+ }
+ if (maxW + sideBySidePageSpacing + maxW2 < state->getWinW()) {
+ offsetX = (state->getWinW() -
+ (maxW + sideBySidePageSpacing + maxW2)) / 2;
+ } else {
+ offsetX = 0;
+ }
+ offsetX += maxW - pageW1;
+ offsetX2 = offsetX + pageW1 + sideBySidePageSpacing;
+ if (xw + state->getScrollX() < offsetX2) {
+ *xd = xw - offsetX + state->getScrollX();
+ *yd = yw - offsetY - pageY[*pg - 1] + state->getScrollY();
+ return *xd >= 0 && *xd < pageW1 && *yd >= 0 && *yd < pageH1;
+ } else {
+ if (*pg + 1 > state->getDoc()->getNumPages()) {
+ *pg = *xd = *yd = 0;
+ return false;
+ }
+ ++*pg;
+ *xd = xw - offsetX2 + state->getScrollX();
+ *yd = yw - offsetY - pageY[*pg - 1] + state->getScrollY();
+ return *xd >= 0 && *xd < pageW2 && *yd >= 0 && *yd < pageH2;
+ }
+
+ case displayHorizontalContinuous:
+ if (totalW < state->getWinW()) {
+ offsetX = (state->getWinW() - totalW) / 2;
+ } else {
+ offsetX = 0;
+ }
+ *pg = findHorizContinuousPage(xw - offsetX + state->getScrollX());
+ pageW1 = pageW[*pg - 1];
+ pageH1 = pageH[*pg - 1];
+ if (maxH < state->getWinH()) {
+ offsetY = (state->getWinH() - maxH) / 2;
+ } else {
+ offsetY = 0;
+ }
+ *xd = xw - offsetX - pageX[*pg - 1] + state->getScrollX();
+ *yd = yw - offsetY + state->getScrollY();
+ return *xd >= 0 && *xd < pageW1 && *yd >= 0 && *yd < pageH1;
+ }
+
+ return gFalse;
+}
+
+GBool TileMap::cvtUserToWindow(int pg, double xu, double yu,
+ int *xw, int *yw) {
+ int xd, yd;
+
+ cvtUserToDev(pg, xu, yu, &xd, &yd);
+ return cvtDevToWindow(pg, xd, yd, xw, yw);
+}
+
+GBool TileMap::cvtDevToWindow(int pg, int xd, int yd,
+ int *xw, int *yw) {
+ int leftPg, pageW1, pageH1, pageW2, pageH2, offsetX, offsetX2, offsetY;
+
+ if (!state->getDoc() ||
+ pg < 1 || pg > state->getDoc()->getNumPages()) {
+ *xw = *yw = 0;
+ return gFalse;
+ }
+
+ updatePageParams();
+ updateContinuousModeParams();
+
+ switch (state->getDisplayMode()) {
+
+ case displaySingle:
+ if (pg != state->getScrollPage()) {
+ *xw = *yw = 0;
+ return gFalse;
+ }
+ pageW1 = pageW[pg - 1];
+ pageH1 = pageH[pg - 1];
+ if (pageW1 < state->getWinW()) {
+ offsetX = (state->getWinW() - pageW1) / 2;
+ } else {
+ offsetX = 0;
+ }
+ if (pageH1 < state->getWinH()) {
+ offsetY = (state->getWinH() - pageH1) / 2;
+ } else {
+ offsetY = 0;
+ }
+ *xw = xd + offsetX - state->getScrollX();
+ *yw = yd + offsetY - state->getScrollY();
+ break;
+
+ case displayContinuous:
+ pageW1 = pageW[pg - 1];
+ pageH1 = pageH[pg - 1];
+ if (maxW < state->getWinW()) {
+ offsetX = (state->getWinW() - maxW) / 2;
+ } else {
+ offsetX = 0;
+ }
+ offsetX += (maxW - pageW1) / 2;
+ if (totalH < state->getWinH()) {
+ offsetY = (state->getWinH() - totalH) / 2;
+ } else {
+ offsetY = 0;
+ }
+ *xw = xd + offsetX - state->getScrollX();
+ *yw = pageY[pg - 1] + yd + offsetY - state->getScrollY();
+ break;
+
+ case displaySideBySideSingle:
+ if (!(pg == state->getScrollPage() ||
+ (pg == state->getScrollPage() + 1 &&
+ state->getScrollPage() + 1 <= state->getDoc()->getNumPages()))) {
+ *xw = *yw = 0;
+ return gFalse;
+ }
+ pageW1 = pageW[state->getScrollPage() - 1];
+ pageH1 = pageH[state->getScrollPage() - 1];
+ if (state->getScrollPage() + 1 <= state->getDoc()->getNumPages()) {
+ pageW2 = pageW[state->getScrollPage()];
+ pageH2 = pageH[state->getScrollPage()];
+ } else {
+ // display a single page as though there were a blank facing
+ // page of the same size
+ pageW2 = pageW1;
+ pageH2 = pageH1;
+ }
+ if (pageW1 + sideBySidePageSpacing + pageW2 < state->getWinW()) {
+ offsetX = (state->getWinW() -
+ (pageW1 + sideBySidePageSpacing + pageW2)) / 2;
+ } else {
+ offsetX = 0;
+ }
+ offsetX2 = offsetX + pageW1 + sideBySidePageSpacing;
+ if (pageH1 < state->getWinH() && pageH2 < state->getWinH()) {
+ if (pageH1 > pageH2) {
+ offsetY = (state->getWinH() - pageH1) / 2;
+ } else {
+ offsetY = (state->getWinH() - pageH2) / 2;
+ }
+ } else {
+ offsetY = 0;
+ }
+ if (pg == state->getScrollPage()) {
+ *xw = xd + offsetX - state->getScrollX();
+ *yw = yd + offsetY - state->getScrollY();
+ } else {
+ *xw = xd + offsetX2 - state->getScrollX();
+ *yw = yd + offsetY - state->getScrollY();
+ }
+ break;
+
+ case displaySideBySideContinuous:
+ leftPg = (pg - 1) | 1;
+ pageW1 = pageW[leftPg - 1];
+ pageH1 = pageH[leftPg - 1];
+ if (maxW + sideBySidePageSpacing + maxW2 < state->getWinW()) {
+ offsetX = (state->getWinW() -
+ (maxW + sideBySidePageSpacing + maxW2)) / 2;
+ } else {
+ offsetX = 0;
+ }
+ offsetX += maxW - pageW1;
+ offsetX2 = offsetX + pageW1 + sideBySidePageSpacing;
+ if (totalH < state->getWinH()) {
+ offsetY = (state->getWinH() - totalH) / 2;
+ } else {
+ offsetY = 0;
+ }
+ if (pg == leftPg) {
+ *xw = xd + offsetX - state->getScrollX();
+ } else {
+ *xw = xd + offsetX2 - state->getScrollX();
+ }
+ *yw = pageY[pg - 1] + yd + offsetY - state->getScrollY();
+ break;
+
+ case displayHorizontalContinuous:
+ if (totalW < state->getWinW()) {
+ offsetX = (state->getWinW() - totalW) / 2;
+ } else {
+ offsetX = 0;
+ }
+ if (maxH < state->getWinH()) {
+ offsetY = (state->getWinH() - maxH) / 2;
+ } else {
+ offsetY = 0;
+ }
+ *xw = pageX[pg - 1] + xd + offsetX - state->getScrollX();
+ *yw = yd + offsetY - state->getScrollY();
+ break;
+ }
+
+ return gTrue;
+}
+
+void TileMap::cvtUserToDev(int pg, double xu, double yu, int *xd, int *yd) {
+ double m[6];
+
+ if (!state->getDoc() ||
+ pg < 1 || pg > state->getDoc()->getNumPages()) {
+ *xd = *yd = 0;
+ return;
+ }
+
+ computePageMatrix(pg, m);
+ *xd = (int)(xu * m[0] + yu * m[2] + m[4] + 0.5);
+ *yd = (int)(xu * m[1] + yu * m[3] + m[5] + 0.5);
+}
+
+void TileMap::cvtDevToUser(int pg, int xd, int yd, double *xu, double *yu) {
+ double m[6], im[6];
+
+ if (!state->getDoc() ||
+ pg < 1 || pg > state->getDoc()->getNumPages()) {
+ *xu = *yu = 0;
+ return;
+ }
+
+ computePageMatrix(pg, m);
+ invertMatrix(m, im);
+ *xu = xd * im[0] + yd * im[2] + im[4];
+ *yu = xd * im[1] + yd * im[3] + im[5];
+}
+
+void TileMap::getWindowPageRange(int x, int y, int w, int h,
+ int *firstPage, int *lastPage) {
+ GList *tiles;
+ PlacedTileDesc *tile;
+ int i;
+
+ if (!state->getDoc() || !state->getDoc()->getNumPages()) {
+ *firstPage = *lastPage = 0;
+ return;
+ }
+ *firstPage = state->getDoc()->getNumPages();
+ *lastPage = 0;
+ tiles = getTileList();
+ for (i = 0; i < tiles->getLength(); ++i) {
+ tile = (PlacedTileDesc *)tiles->get(i);
+ if (tile->px < x + w &&
+ tile->px + tile->tw > x &&
+ tile->py < y + h &&
+ tile->py + tile->th > y) {
+ if (tile->page < *firstPage) {
+ *firstPage = tile->page;
+ }
+ if (tile->page > *lastPage) {
+ *lastPage = tile->page;
+ }
+ }
+ }
+}
+
+int TileMap::getPageTopY(int page) {
+ if (!state->getDoc() || !state->getDoc()->getNumPages()) {
+ return 0;
+ }
+
+ updateContinuousModeParams();
+
+ switch (state->getDisplayMode()) {
+ case displaySingle:
+ case displaySideBySideSingle:
+ case displayHorizontalContinuous:
+ default:
+ return 0;
+ case displayContinuous:
+ case displaySideBySideContinuous:
+ return pageY[page - 1];
+ }
+}
+
+int TileMap::getPageBottomY(int page) {
+ if (!state->getDoc() || !state->getDoc()->getNumPages()) {
+ return 0;
+ }
+
+ updatePageParams();
+ updateContinuousModeParams();
+
+ switch (state->getDisplayMode()) {
+ case displaySingle:
+ case displaySideBySideSingle:
+ case displayHorizontalContinuous:
+ default:
+ return pageH[page - 1] - state->getWinH();
+ case displayContinuous:
+ case displaySideBySideContinuous:
+ return pageY[page - 1] + pageH[page - 1] - state->getWinH();
+ }
+}
+
+int TileMap::getPageLeftX(int page) {
+ int leftPage, rightPage, pageW1, pageW2, offsetX, offsetX2;
+
+ if (!state->getDoc() || !state->getDoc()->getNumPages()) {
+ return 0;
+ }
+
+ updatePageParams();
+ updateContinuousModeParams();
+
+ switch (state->getDisplayMode()) {
+ case displaySingle:
+ default:
+ return 0;
+ case displayContinuous:
+ return (maxW - pageW[page - 1]) / 2;
+ case displaySideBySideSingle:
+ leftPage = ((page - 1) & ~1) + 1;
+ rightPage = leftPage + 1;
+ pageW1 = pageW[leftPage - 1];
+ if (rightPage <= state->getDoc()->getNumPages()) {
+ pageW2 = pageW[rightPage - 1];
+ } else {
+ // display a single page as though there were a blank facing
+ // page of the same size
+ pageW2 = pageW1;
+ }
+ if (pageW1 + sideBySidePageSpacing + pageW2 < state->getWinW()) {
+ offsetX = (state->getWinW() -
+ (pageW1 + sideBySidePageSpacing + pageW2)) / 2;
+ } else {
+ offsetX = 0;
+ }
+ offsetX2 = offsetX + pageW1 + sideBySidePageSpacing;
+ return (page == leftPage) ? offsetX : offsetX2;
+ return 0;
+ case displaySideBySideContinuous:
+ leftPage = ((page - 1) & ~1) + 1;
+ rightPage = leftPage + 1;
+ pageW1 = pageW[leftPage - 1];
+ if (maxW + sideBySidePageSpacing + maxW2 < state->getWinW()) {
+ offsetX = (state->getWinW() -
+ (maxW + sideBySidePageSpacing + maxW2)) / 2;
+ } else {
+ offsetX = 0;
+ }
+ offsetX += maxW - pageW1;
+ offsetX2 = offsetX + pageW1 + sideBySidePageSpacing;
+ return (page == leftPage) ? offsetX : offsetX2;
+ case displayHorizontalContinuous:
+ return pageX[page - 1];
+ }
+}
+
+int TileMap::getFirstPage() {
+ updateContinuousModeParams();
+ switch (state->getDisplayMode()) {
+ case displaySingle:
+ default:
+ return state->getScrollPage();
+ case displayContinuous:
+ return findContinuousPage(state->getScrollY());
+ case displaySideBySideSingle:
+ return state->getScrollPage();
+ case displaySideBySideContinuous:
+ return findSideBySideContinuousPage(state->getScrollY());
+ case displayHorizontalContinuous:
+ return findHorizContinuousPage(state->getScrollX());
+ }
+}
+
+int TileMap::getFirstPageTop() {
+ int page;
+
+ updateContinuousModeParams();
+ switch (state->getDisplayMode()) {
+ case displaySingle:
+ default:
+ return state->getScrollPage();
+ case displayContinuous:
+ page = findContinuousPage(state->getScrollY());
+ if (page < state->getDoc()->getNumPages() &&
+ pageY[page - 1] < state->getScrollY()) {
+ return page + 1;
+ } else {
+ return page;
+ }
+ case displaySideBySideSingle:
+ return state->getScrollPage();
+ case displaySideBySideContinuous:
+ page = findSideBySideContinuousPage(state->getScrollY());
+ if (page < state->getDoc()->getNumPages() &&
+ pageY[page - 1] < state->getScrollY()) {
+ return page + 1;
+ } else {
+ return page;
+ }
+ case displayHorizontalContinuous:
+ page = findHorizContinuousPage(state->getScrollX());
+ if (page < state->getDoc()->getNumPages() &&
+ pageX[page - 1] < state->getScrollX()) {
+ return page + 1;
+ } else {
+ return page;
+ }
+ }
+}
+
+int TileMap::getMidPage() {
+ int wx, wy, pg, x, y;
+
+ wx = state->getWinW() / 2;
+ wy = state->getWinH() / 2;
+ if (!cvtWindowToDev(wx, wy, &pg, &x, &y)) {
+ if (state->getDisplayMode() == displayContinuous) {
+ wy += continuousPageSpacing;
+ } else if (state->getDisplayMode() == displaySideBySideContinuous) {
+ wx += sideBySidePageSpacing;
+ wy += continuousPageSpacing;
+ } else if (state->getDisplayMode() == displayHorizontalContinuous) {
+ wx += horizContinuousPageSpacing;
+ } else {
+ return state->getScrollPage();
+ }
+ if (!cvtWindowToDev(wx, wy, &pg, &x, &y)) {
+ return 1;
+ }
+ }
+ return pg;
+}
+
+int TileMap::getLastPage() {
+ int pg, x, y, n;
+
+ switch (state->getDisplayMode()) {
+ case displaySingle:
+ default:
+ return state->getScrollPage();
+ case displayContinuous:
+ if (!cvtWindowToDev(state->getWinW() / 2, state->getWinH() - 1,
+ &pg, &x, &y)) {
+ return state->getDoc()->getNumPages();
+ }
+ return pg;
+ case displaySideBySideSingle:
+ pg = state->getScrollPage() + 1;
+ n = state->getDoc()->getNumPages();
+ if (pg > n) {
+ pg = n;
+ }
+ return pg;
+ case displaySideBySideContinuous:
+ if (!cvtWindowToDev(state->getWinW() / 2, state->getWinH() - 1,
+ &pg, &x, &y)) {
+ return state->getScrollPage();
+ }
+ pg = ((pg - 1) & ~1) + 2;
+ n = state->getDoc()->getNumPages();
+ if (pg > n) {
+ pg = n;
+ }
+ return pg;
+ case displayHorizontalContinuous:
+ x = state->getWinW() - 1;
+ y = state->getWinH() / 2;
+ if (!cvtWindowToDev(state->getWinW() - 1, state->getWinH() / 2,
+ &pg, &x, &y)) {
+ return state->getDoc()->getNumPages();
+ }
+ return pg;
+ }
+}
+
+double TileMap::getDPI(int page) {
+ if (page < 1 || page > state->getDoc()->getNumPages()) {
+ return 0;
+ }
+ updatePageParams();
+ return pageDPI[page - 1];
+}
+
+double TileMap::getPageBoxWidth(int page) {
+ return pageBoxW[page - 1];
+}
+
+double TileMap::getPageBoxHeight(int page) {
+ return pageBoxH[page - 1];
+}
+
+int TileMap::getContinuousPageSpacing() {
+ return continuousPageSpacing;
+}
+
+int TileMap::getSideBySidePageSpacing() {
+ return sideBySidePageSpacing;
+}
+
+int TileMap::getHorizContinuousPageSpacing() {
+ return horizContinuousPageSpacing;
+}
+
+void TileMap::docChanged() {
+ PDFDoc *doc;
+ int nPages, pg, rot;
+
+ doc = state->getDoc();
+
+ if (doc) {
+ nPages = doc->getNumPages();
+ } else {
+ nPages = 0;
+ }
+ pageBoxW = (double *)greallocn(pageBoxW, nPages, sizeof(double));
+ pageBoxH = (double *)greallocn(pageBoxH, nPages, sizeof(double));
+ for (pg = 1; pg <= nPages; ++pg) {
+ rot = doc->getPageRotate(pg);
+ if (rot == 0 || rot == 180) {
+ pageBoxW[pg - 1] = doc->getPageCropWidth(pg);
+ pageBoxH[pg - 1] = doc->getPageCropHeight(pg);
+ } else {
+ pageBoxW[pg - 1] = doc->getPageCropHeight(pg);
+ pageBoxH[pg - 1] = doc->getPageCropWidth(pg);
+ }
+ }
+
+ clearPageParams();
+ clearContinuousModeParams();
+ if (tiles) {
+ deleteGList(tiles, PlacedTileDesc);
+ tiles = NULL;
+ }
+}
+
+void TileMap::windowSizeChanged() {
+ clearPageParams();
+ clearContinuousModeParams();
+ if (tiles) {
+ deleteGList(tiles, PlacedTileDesc);
+ tiles = NULL;
+ }
+}
+
+void TileMap::displayModeChanged() {
+ clearPageParams();
+ clearContinuousModeParams();
+ if (tiles) {
+ deleteGList(tiles, PlacedTileDesc);
+ tiles = NULL;
+ }
+}
+
+void TileMap::zoomChanged() {
+ clearPageParams();
+ clearContinuousModeParams();
+ if (tiles) {
+ deleteGList(tiles, PlacedTileDesc);
+ tiles = NULL;
+ }
+}
+
+void TileMap::rotateChanged() {
+ clearPageParams();
+ clearContinuousModeParams();
+ if (tiles) {
+ deleteGList(tiles, PlacedTileDesc);
+ tiles = NULL;
+ }
+}
+
+void TileMap::scrollPositionChanged() {
+ if (tiles) {
+ deleteGList(tiles, PlacedTileDesc);
+ tiles = NULL;
+ }
+}
+
+
+void TileMap::forceRedraw() {
+ clearPageParams();
+ clearContinuousModeParams();
+ if (tiles) {
+ deleteGList(tiles, PlacedTileDesc);
+ tiles = NULL;
+ }
+}
+
+void TileMap::clearPageParams() {
+ gfree(pageDPI);
+ gfree(pageW);
+ gfree(pageH);
+ gfree(tileW);
+ gfree(tileH);
+ pageDPI = NULL;
+ pageW = pageH = NULL;
+ tileW = tileH = NULL;
+}
+
+void TileMap::updatePageParams() {
+ double rotPageBoxW, rotPageBoxW2, rotPageBoxH, rotPageBoxH2, rotPageBoxHMax;
+ double hDPI, vDPI, dpi;
+ int page, otherPage, nxTiles, nyTiles;
+
+ //--- check to see if the continuous mode params have already been updated
+ if (pageDPI) {
+ return;
+ }
+
+ //--- allocate memory
+ pageDPI = (double *)gmallocn(state->getDoc()->getNumPages(), sizeof(double));
+ pageW = (int *)gmallocn(state->getDoc()->getNumPages(), sizeof(int));
+ pageH = (int *)gmallocn(state->getDoc()->getNumPages(), sizeof(int));
+ tileW = (int *)gmallocn(state->getDoc()->getNumPages(), sizeof(int));
+ tileH = (int *)gmallocn(state->getDoc()->getNumPages(), sizeof(int));
+
+ for (page = 1; page <= state->getDoc()->getNumPages(); ++page) {
+
+ //--- special handling for side-by-side modes
+ if (state->displayModeIsSideBySide()) {
+
+ // rotate the page boxes
+ if (page & 1) {
+ otherPage = page + 1;
+ if (otherPage >= state->getDoc()->getNumPages()) {
+ otherPage = page;
+ }
+ } else {
+ otherPage = page - 1;
+ if (otherPage < 1) {
+ otherPage = page;
+ }
+ }
+ if (state->getRotate() == 0 || state->getRotate() == 180) {
+ rotPageBoxW = pageBoxW[page - 1];
+ rotPageBoxW2 = pageBoxW[otherPage - 1];
+ rotPageBoxH = pageBoxH[page - 1];
+ rotPageBoxH2 = pageBoxH[otherPage - 1];
+ } else {
+ rotPageBoxW = pageBoxH[page - 1];
+ rotPageBoxW2 = pageBoxH[otherPage - 1];
+ rotPageBoxH = pageBoxW[page - 1];
+ rotPageBoxH2 = pageBoxW[otherPage - 1];
+ }
+ rotPageBoxHMax = (rotPageBoxH > rotPageBoxH2) ? rotPageBoxH
+ : rotPageBoxH2;
+
+ // compute resolution
+ if (state->getZoom() == zoomPage) {
+ hDPI = ((state->getWinW() - sideBySidePageSpacing) /
+ (rotPageBoxW + rotPageBoxW2)) * 72.0;
+ vDPI = (state->getWinH() / rotPageBoxHMax) * 72.0;
+ dpi = hDPI < vDPI ? hDPI : vDPI;
+ // allow for some floating point jitter
+ dpi -= 0.01;
+ } else if (state->getZoom() == zoomWidth) {
+ dpi = ((state->getWinW() - sideBySidePageSpacing) /
+ (rotPageBoxW + rotPageBoxW2)) * 72.0;
+ // allow for some floating point jitter
+ dpi -= 0.01;
+ } else if (state->getZoom() == zoomHeight) {
+ dpi = (state->getWinH() / rotPageBoxHMax) * 72.0;
+ // allow for some floating point jitter
+ dpi -= 0.01;
+ } else {
+ dpi = 0.01 * state->getZoom() * 72.0;
+ }
+
+ //--- all other (non-side-by-side) modes
+ } else {
+
+ // rotate the page boxes
+ if (state->getRotate() == 0 || state->getRotate() == 180) {
+ rotPageBoxW = pageBoxW[page - 1];
+ rotPageBoxH = pageBoxH[page - 1];
+ } else {
+ rotPageBoxW = pageBoxH[page - 1];
+ rotPageBoxH = pageBoxW[page - 1];
+ }
+
+ // compute resolution
+ if (state->getZoom() == zoomPage) {
+ hDPI = (state->getWinW() / rotPageBoxW) * 72.0;
+ vDPI = (state->getWinH() / rotPageBoxH) * 72.0;
+ dpi = hDPI < vDPI ? hDPI : vDPI;
+ // allow for some floating point jitter
+ dpi -= 0.01;
+ } else if (state->getZoom() == zoomWidth) {
+ dpi = (state->getWinW() / rotPageBoxW) * 72.0;
+ // allow for some floating point jitter
+ dpi -= 0.01;
+ } else if (state->getZoom() == zoomHeight) {
+ dpi = (state->getWinH() / rotPageBoxH) * 72.0;
+ // allow for some floating point jitter
+ dpi -= 0.01;
+ } else {
+ dpi = 0.01 * state->getZoom() * 72.0;
+ }
+
+ }
+ pageDPI[page - 1] = dpi;
+
+ // compute bitmap size
+ pageW[page - 1] = (int)((rotPageBoxW * dpi / 72.0) + 0.5);
+ if (pageW[page - 1] < 1) {
+ pageW[page - 1] = 1;
+ }
+ pageH[page - 1] = (int)((rotPageBoxH * dpi / 72.0) + 0.5);
+ if (pageH[page - 1] < 1) {
+ pageH[page - 1] = 1;
+ }
+
+ // compute tile size
+ // (tile width and height are rounded up -- the bottom and right
+ // tiles may be slightly smaller than the computed size)
+ if (pageW[page - 1] <= state->getMaxTileWidth()) {
+ nxTiles = 1;
+ tileW[page - 1] = pageW[page - 1];
+ } else {
+ nxTiles = (pageW[page - 1] + state->getMaxTileWidth() - 1)
+ / state->getMaxTileWidth();
+ tileW[page - 1] = (pageW[page - 1] + nxTiles - 1) / nxTiles;
+ }
+ if (pageH[page - 1] <= state->getMaxTileHeight()) {
+ nyTiles = 1;
+ tileH[page - 1] = pageH[page - 1];
+ } else {
+ nyTiles = (pageH[page - 1] + state->getMaxTileHeight() - 1)
+ / state->getMaxTileHeight();
+ tileH[page - 1] = (pageH[page - 1] + nyTiles - 1) / nyTiles;
+ }
+
+ }
+}
+
+void TileMap::clearContinuousModeParams() {
+ gfree(pageX);
+ pageX = pageY = NULL;
+}
+
+void TileMap::updateContinuousModeParams() {
+ int page, pageW1, pageH1, pageW2, pageH2, x, y;
+
+ // check to see if the continuous mode params have already been updated
+ if (pageX) {
+ return;
+ }
+
+ updatePageParams();
+
+ switch (state->getDisplayMode()) {
+ case displayContinuous:
+ if (!pageX) {
+ pageX = pageY = (int *)gmallocn(state->getDoc()->getNumPages(),
+ sizeof(int));
+ }
+ y = 0;
+ maxW = 0;
+ for (page = 1; page <= state->getDoc()->getNumPages(); ++page) {
+ pageY[page - 1] = y;
+ y += pageH[page - 1] + continuousPageSpacing;
+ if (page == 1 || pageW[page - 1] > maxW) {
+ maxW = pageW[page - 1];
+ }
+ }
+ totalH = y - continuousPageSpacing;
+ break;
+ case displaySideBySideContinuous:
+ if (!pageX) {
+ pageX = pageY = (int *)gmallocn(state->getDoc()->getNumPages(),
+ sizeof(int));
+ }
+ y = 0;
+ maxW = maxW2 = 0;
+ for (page = 1; page <= state->getDoc()->getNumPages(); page += 2) {
+ pageW1 = pageW[page - 1];
+ pageH1 = pageH[page - 1];
+ if (page + 1 <= state->getDoc()->getNumPages()) {
+ pageW2 = pageW[page];
+ pageH2 = pageH[page];
+ } else {
+ pageW2 = pageW1;
+ pageH2 = pageH1;
+ }
+ pageY[page - 1] = y;
+ if (page == 1 || pageW1 > maxW) {
+ maxW = pageW1;
+ }
+ if (page + 1 <= state->getDoc()->getNumPages()) {
+ pageY[page] = y;
+ }
+ if (pageW2 > maxW2) {
+ maxW2 = pageW2;
+ }
+ y += (pageH1 > pageH2) ? pageH1 : pageH2;
+ y += continuousPageSpacing;
+ }
+ totalH = y - continuousPageSpacing;
+ break;
+ case displayHorizontalContinuous:
+ if (!pageX) {
+ pageX = pageY = (int *)gmallocn(state->getDoc()->getNumPages(),
+ sizeof(int));
+ }
+ x = 0;
+ maxH = 0;
+ for (page = 1; page <= state->getDoc()->getNumPages(); ++page) {
+ pageX[page - 1] = x;
+ x += pageW[page - 1] + horizContinuousPageSpacing;
+ if (page == 1 || pageH[page - 1] > maxH) {
+ maxH = pageH[page - 1];
+ }
+ }
+ totalW = x - horizContinuousPageSpacing;
+ break;
+ default:
+ break;
+ }
+}
+
+void TileMap::computePageMatrix(int page, double *m) {
+ PDFRectangle *cropBox;
+ double px1, py1, px2, py2, k;
+ int rotate;
+
+ updatePageParams();
+ cropBox = state->getDoc()->getCatalog()->getPage(page)->getCropBox();
+ px1 = cropBox->x1;
+ py1 = cropBox->y1;
+ px2 = cropBox->x2;
+ py2 = cropBox->y2;
+ k = pageDPI[page - 1] / 72.0;
+ rotate = state->getRotate() +
+ state->getDoc()->getCatalog()->getPage(page)->getRotate();
+ if (rotate > 360) {
+ rotate -= 360;
+ }
+ switch (rotate) {
+ case 0:
+ default:
+ m[0] = k;
+ m[1] = 0;
+ m[2] = 0;
+ m[3] = -k;
+ m[4] = -k * px1;
+ m[5] = k * py2;
+ break;
+ case 90:
+ m[0] = 0;
+ m[1] = k;
+ m[2] = k;
+ m[3] = 0;
+ m[4] = -k * py1;
+ m[5] = -k * px1;
+ break;
+ case 180:
+ m[0] = -k;
+ m[1] = 0;
+ m[2] = 0;
+ m[3] = k;
+ m[4] = k * px2;
+ m[5] = -k * py1;
+ break;
+ case 270:
+ m[0] = 0;
+ m[1] = -k;
+ m[2] = -k;
+ m[3] = 0;
+ m[4] = k * py2;
+ m[5] = k * px2;
+ break;
+ }
+}
+
+void TileMap::invertMatrix(double *m, double *im) {
+ double det;
+
+ det = 1 / (m[0] * m[3] - m[1] * m[2]);
+ im[0] = m[3] * det;
+ im[1] = -m[1] * det;
+ im[2] = -m[2] * det;
+ im[3] = m[0] * det;
+ im[4] = (m[2] * m[5] - m[3] * m[4]) * det;
+ im[5] = (m[1] * m[4] - m[0] * m[5]) * det;
+}
+
+int TileMap::findContinuousPage(int y) {
+ int a, b, m;
+
+ if (y < pageY[0]) {
+ return 0;
+ }
+ if (y >= totalH) {
+ return state->getDoc()->getNumPages() + 1;
+ }
+ a = -1;
+ b = state->getDoc()->getNumPages();
+ // invariant: pageY[a] < y < pageY[b]
+ while (b - a > 1) {
+ m = (a + b) / 2;
+ if (y > pageY[m] - continuousPageSpacing) {
+ a = m;
+ } else if (y < pageY[m] - continuousPageSpacing) {
+ b = m;
+ } else {
+ return m + 1;
+ }
+ }
+ return a + 1;
+}
+
+int TileMap::findSideBySideContinuousPage(int y) {
+ int a, b, m;
+
+ if (y < pageY[0]) {
+ return 0;
+ }
+ if (y >= totalH) {
+ return (state->getDoc()->getNumPages() + 2) & ~1;
+ }
+ a = -2;
+ b = (state->getDoc()->getNumPages() + 1) & ~1;
+ // invariant: pageY[a] < y < pageY[b]
+ while (b - a > 2) {
+ m = ((a + b) / 2) & ~1;
+ if (y > pageY[m] - continuousPageSpacing) {
+ a = m;
+ } else if (y < pageY[m] - continuousPageSpacing) {
+ b = m;
+ } else {
+ return m + 1;
+ }
+ }
+ return a + 1;
+}
+
+int TileMap::findHorizContinuousPage(int x) {
+ int a, b, m;
+
+ if (x < pageX[0]) {
+ return 0;
+ }
+ if (x >= totalW) {
+ return state->getDoc()->getNumPages() + 1;
+ }
+ a = -1;
+ b = state->getDoc()->getNumPages();
+ // invariant: pageX[a] < x < pageX[b]
+ while (b - a > 1) {
+ m = (a + b) / 2;
+ if (x > pageX[m] - horizContinuousPageSpacing) {
+ a = m;
+ } else if (x < pageX[m] - horizContinuousPageSpacing) {
+ b = m;
+ } else {
+ return m + 1;
+ }
+ }
+ return a + 1;
+}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h b/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h
new file mode 100644
index 00000000000..f8cb2525e9f
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/TileMap.h
@@ -0,0 +1,243 @@
+//========================================================================
+//
+// TileMap.h
+//
+// Copyright 2014 Glyph & Cog, LLC
+//
+//========================================================================
+
+#ifndef TILEMAP_H
+#define TILEMAP_H
+
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include "gtypes.h"
+
+class GList;
+class DisplayState;
+
+//------------------------------------------------------------------------
+
+// Tile descriptor: this is all of the information needed to specify a
+// tile.
+class TileDesc {
+public:
+
+ TileDesc(int pageA, int rotateA, double dpiA,
+ int txA, int tyA, int twA, int thA):
+ page(pageA), rotate(rotateA), dpi(dpiA),
+ tx(txA), ty(tyA), tw(twA), th(thA) {}
+
+ GBool matches(TileDesc *tile) {
+ return page == tile->page && rotate == tile->rotate &&
+ dpi == tile->dpi &&
+ tx == tile->tx && ty == tile->ty &&
+ tw == tile->tw && th == tile->th;
+ }
+
+ int page; // page number
+ int rotate; // rotation
+ double dpi; // tile resolution
+ int tx, ty; // origin of tile, relative to top left
+ // corner of page
+ int tw, th; // tile size
+};
+
+//------------------------------------------------------------------------
+
+// A TileDesc plus the tile's location in the display.
+class PlacedTileDesc: public TileDesc {
+public:
+
+ PlacedTileDesc(int pageA, int rotateA, double dpiA,
+ int txA, int tyA, int twA, int thA,
+ int pxA, int pyA):
+ TileDesc(pageA, rotateA, dpiA, txA, tyA, twA, thA), px(pxA), py(pyA) {}
+
+ int px, py; // position, in window coordinates, of
+ // tile origin
+};
+
+//------------------------------------------------------------------------
+
+// Tile map: this maps window position to tile, and vice versa; and
+// computes the list of tiles needed for the current display.
+class TileMap {
+public:
+
+ TileMap(DisplayState *stateA);
+ ~TileMap();
+
+ // Returns a list of PlacedTileDesc objects describing the tiles
+ // needed for the current display. The returned list is owned by
+ // the TileMap object (and may be reused) -- the caller should not
+ // modify or free it.
+ GList *getTileList();
+
+ // Return the max values for the horizontal and vertical scrollbars.
+ // Scroll thumbs should be winW and winH.
+ void getScrollLimits(int *horizMax, int *vertMax);
+
+ // Coordinate conversion functions.
+ // - user space: per-page, as defined by PDF file; unit = point
+ // - device space: (0,0) is upper-left corner of a page; unit = pixel
+ // - window space: (0,0) is upper-left corner of drawing area; unit = pixel
+ // Conversions to window space return false if the specified page
+ // isn't visible (in non-continuous modes). Conversions from window
+ // space return false if the point isn't on a page. Otherwise,
+ // these functions do not do bounds-checking or any clipping to
+ // window or page coordinates.
+ GBool cvtWindowToUser(int xw, int yw,
+ int *pg, double *xu, double *yu);
+ GBool cvtWindowToDev(int xw, int yw,
+ int *pg, int *xd, int *yd);
+ GBool cvtUserToWindow(int pg, double xu, double yu,
+ int *xw, int *yw);
+ GBool cvtDevToWindow(int pg, int xd, int yd,
+ int *xw, int *yw);
+ void cvtUserToDev(int pg, double xu, double yu, int *xd, int *yd);
+ void cvtDevToUser(int pg, int xd, int yd, double *xu, double *yu);
+
+ // Return the range of pages intersected by a rectangle in window
+ // coordinates. E.g., these are the pages that will need to be
+ // redrawn for a redraw event covering that rectangle.
+ void getWindowPageRange(int x, int y, int w, int h,
+ int *firstPage, int *lastPage);
+
+ // Return the scrollY setting that would place the top of <page> at
+ // the top of the window. (In non-continuous modes, this just
+ // returns zero.)
+ int getPageTopY(int page);
+
+ // Return the scrollY setting that would place the bottom of <page>
+ // at the bottom of the window.
+ int getPageBottomY(int page);
+
+ // Return the scrollX setting that would place the left side of
+ // <page> at the left side of the window. (In non-continuous modes,
+ // this just returns zero.)
+ int getPageLeftX(int page);
+
+ // In continuous modes: return the lowest page number visible
+ // anywhere in the window; in non-continuous modes: return the
+ // current page.
+ int getFirstPage();
+
+ // In continuous modes: return the lowest page number whose top (or
+ // left) edge is visible in the window (or if no top/left edge is
+ // visilble, the page after the single visible page); in
+ // non-continuous modes: return the current page.
+ int getFirstPageTop();
+
+ // In continuous modes: return the page number at the center of the
+ // window; in non-continuous modes: return the current page.
+ int getMidPage();
+
+ // In continuous modes: return the highest page number visible
+ // anywhere in the window; in non-continuous modes: return the
+ // current page.
+ int getLastPage();
+
+ // Get the resolution at which the specified will be rasterized.
+ double getDPI(int page);
+
+ // Get the width and height of a page, in points.
+ double getPageBoxWidth(int page);
+ double getPageBoxHeight(int page);
+
+ // Get the number of pixels (vertically) between adjacent pages in
+ // continuous / side-by-side continuous mode.
+ int getContinuousPageSpacing();
+
+ // Get the number of pixels (horizontally) between facing pages in
+ // the side-by-side modes.
+ int getSideBySidePageSpacing();
+
+ // Get the number of pixels (horizontally) between adjacent pages in
+ // horizontal continuous mode.
+ int getHorizContinuousPageSpacing();
+
+ void docChanged();
+ void windowSizeChanged();
+ void displayModeChanged();
+ void zoomChanged();
+ void rotateChanged();
+ void scrollPositionChanged();
+ void forceRedraw();
+
+private:
+
+ // Clear the pageDPI, pageW, pageH, tileW, and tileH arrays.
+ void clearPageParams();
+
+ // Update pageDPI, pageW, pageH, tileW, tileH (if needed).
+ void updatePageParams();
+
+ // Clear the pageX/pageY array.
+ void clearContinuousModeParams();
+
+ // Update pageX, pageY, maxW, maxW2, maxH, totalW, totalH.
+ void updateContinuousModeParams();
+
+ // Compute the user-to-device transform matrix for the specified
+ // page.
+ void computePageMatrix(int page, double *m);
+
+ // Invert a matrix.
+ void invertMatrix(double *m, double *im);
+
+ // Return the page number at y. If y falls in a gap between pages,
+ // return the next page. If y falls after the last page, return
+ // numPages + 1.
+ int findContinuousPage(int y);
+
+ // Return the left-side page number at y. If y falls in a gap between
+ // page pairs, return the next page. If y falls after the last page,
+ // return numPages + 1 (or numPages + 2 if numPages is odd).
+ int findSideBySideContinuousPage(int y);
+
+ // Return the page number at x. If x falls in a gap between pages,
+ // return the next page. If x falls after the last page, return
+ // numPages + 1.
+ int findHorizContinuousPage(int x);
+
+ DisplayState *state;
+
+ double *pageBoxW, *pageBoxH; // page sizes, in points
+
+ // Page parameters:
+ // pageDPI[pg-1] = rasterization resolution
+ // pageW[pg-1], pageH[pg-1] = size of rasterized page
+ // tileW[pg-1], tileH[pg-1] = size of tiles
+ double *pageDPI;
+ int *pageW, *pageH;
+ int *tileW, *tileH;
+
+ // In displayContinuous mode:
+ // pageY[pg-1] = top edge of page
+ // maxW = max page width
+ // totalH = total page height (including gaps)
+ // In displaySideBySideContinuous mode:
+ // pageY[pg-1] = top edge of page-pair
+ // pageY[pg] = top edge of page-pair (if pg+1 <= nPages)
+ // maxW = max left-side page width
+ // maxW2 = max right-side page width
+ // totalH = total page-pair height (including gaps)
+ // In displayHorizontalContinuous mode:
+ // pageX[pg-1] = left edge of page
+ // maxH = max page height
+ // totalW = total page width (including gaps)
+ // Only one of pageX or pageY is used at a time, so a single array
+ // is allocated, i.e., pageX = pageY.
+ int *pageX, *pageY;
+ int maxW, maxW2, maxH;
+ int totalW, totalH;
+
+ GList *tiles;
+};
+
+#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.cc
new file mode 100644
index 00000000000..b2dc329f2f6
--- /dev/null
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.cc
@@ -0,0 +1,182 @@
+//========================================================================
+//
+// UTF8.cc
+//
+// Copyright 2001-2017 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include "UTF8.h"
+
+int mapUTF8(Unicode u, char *buf, int bufSize) {
+ if (u <= 0x0000007f) {
+ if (bufSize < 1) {
+ return 0;
+ }
+ buf[0] = (char)u;
+ return 1;
+ } else if (u <= 0x000007ff) {
+ if (bufSize < 2) {
+ return 0;
+ }
+ buf[0] = (char)(0xc0 + (u >> 6));
+ buf[1] = (char)(0x80 + (u & 0x3f));
+ return 2;
+ } else if (u <= 0x0000ffff) {
+ if (bufSize < 3) {
+ return 0;
+ }
+ buf[0] = (char)(0xe0 + (u >> 12));
+ buf[1] = (char)(0x80 + ((u >> 6) & 0x3f));
+ buf[2] = (char)(0x80 + (u & 0x3f));
+ return 3;
+ } else if (u <= 0x0010ffff) {
+ if (bufSize < 4) {
+ return 0;
+ }
+ buf[0] = (char)(0xf0 + (u >> 18));
+ buf[1] = (char)(0x80 + ((u >> 12) & 0x3f));
+ buf[2] = (char)(0x80 + ((u >> 6) & 0x3f));
+ buf[3] = (char)(0x80 + (u & 0x3f));
+ return 4;
+ } else {
+ return 0;
+ }
+}
+
+int mapUCS2(Unicode u, char *buf, int bufSize) {
+ if (u <= 0xffff) {
+ if (bufSize < 2) {
+ return 0;
+ }
+ buf[0] = (char)((u >> 8) & 0xff);
+ buf[1] = (char)(u & 0xff);
+ return 2;
+ } else {
+ return 0;
+ }
+}
+
+GBool getUTF8(GString *s, int *i, Unicode *u) {
+ Guchar c0, c1, c2, c3, c4, c5;
+
+ if (*i >= s->getLength()) {
+ return gFalse;
+ }
+ c0 = (Guchar)s->getChar((*i)++);
+ if (c0 < 0x80) {
+ *u = (Unicode)c0;
+ } else if (c0 < 0xe0) {
+ if (*i < s->getLength() &&
+ ((c1 = (Guchar)s->getChar(*i)) & 0xc0) == 0x80) {
+ *i += 1;
+ *u = (Unicode)(((c0 & 0x1f) << 6) |
+ (c1 & 0x3f));
+ } else {
+ *u = (Unicode)c0;
+ }
+ } else if (c0 < 0xf0) {
+ if (*i < s->getLength() - 1 &&
+ ((c1 = (Guchar)s->getChar(*i)) & 0xc0) == 0x80 &&
+ ((c2 = (Guchar)s->getChar(*i + 1)) & 0xc0) == 0x80) {
+ *i += 2;
+ *u = (Unicode)(((c0 & 0x0f) << 12) |
+ ((c1 & 0x3f) << 6) |
+ (c2 & 0x3f));
+ } else {
+ *u = (Unicode)c0;
+ }
+ } else if (c0 < 0xf8) {
+ if (*i < s->getLength() - 2 &&
+ ((c1 = (Guchar)s->getChar(*i)) & 0xc0) == 0x80 &&
+ ((c2 = (Guchar)s->getChar(*i + 1)) & 0xc0) == 0x80 &&
+ ((c3 = (Guchar)s->getChar(*i + 2)) & 0xc0) == 0x80) {
+ *i += 3;
+ *u = (Unicode)(((c0 & 0x07) << 18) |
+ ((c1 & 0x3f) << 12) |
+ ((c2 & 0x3f) << 6) |
+ (c3 & 0x3f));
+ } else {
+ *u = (Unicode)c0;
+ }
+ } else if (c0 < 0xfc) {
+ if (*i < s->getLength() - 3 &&
+ ((c1 = (Guchar)s->getChar(*i)) & 0xc0) == 0x80 &&
+ ((c2 = (Guchar)s->getChar(*i + 1)) & 0xc0) == 0x80 &&
+ ((c3 = (Guchar)s->getChar(*i + 2)) & 0xc0) == 0x80 &&
+ ((c4 = (Guchar)s->getChar(*i + 3)) & 0xc0) == 0x80) {
+ *i += 4;
+ *u = (Unicode)(((c0 & 0x03) << 24) |
+ ((c1 & 0x3f) << 18) |
+ ((c2 & 0x3f) << 12) |
+ ((c3 & 0x3f) << 6) |
+ (c4 & 0x3f));
+ } else {
+ *u = (Unicode)c0;
+ }
+ } else if (c0 < 0xfe) {
+ if (*i < s->getLength() - 4 &&
+ ((c1 = (Guchar)s->getChar(*i)) & 0xc0) == 0x80 &&
+ ((c2 = (Guchar)s->getChar(*i + 1)) & 0xc0) == 0x80 &&
+ ((c3 = (Guchar)s->getChar(*i + 2)) & 0xc0) == 0x80 &&
+ ((c4 = (Guchar)s->getChar(*i + 3)) & 0xc0) == 0x80 &&
+ ((c5 = (Guchar)s->getChar(*i + 4)) & 0xc0) == 0x80) {
+ *i += 5;
+ *u = (Unicode)(((c0 & 0x01) << 30) |
+ ((c1 & 0x3f) << 24) |
+ ((c2 & 0x3f) << 18) |
+ ((c3 & 0x3f) << 12) |
+ ((c4 & 0x3f) << 6) |
+ (c5 & 0x3f));
+ } else {
+ *u = (Unicode)c0;
+ }
+ } else {
+ *u = (Unicode)c0;
+ }
+ return gTrue;
+}
+
+GBool getUTF16BE(GString *s, int *i, Unicode *u) {
+ int w0, w1;
+
+ if (*i >= s->getLength() - 1) {
+ return gFalse;
+ }
+ w0 = ((s->getChar(*i) & 0xff) << 8) | (s->getChar(*i + 1) & 0xff);
+ *i += 2;
+ if (w0 < 0xd800 || w0 >= 0xe000) {
+ *u = (Unicode)w0;
+ } else {
+ if (*i < s->getLength() - 1) {
+ w1 = ((s->getChar(*i) & 0xff) << 8) | (s->getChar(*i + 1) & 0xff);
+ *i += 2;
+ *u = 0x10000 + ((w0 - 0xd8000) << 10) + (w1 - 0xdc00);
+ } else {
+ *u = (Unicode)w0;
+ }
+ }
+ return gTrue;
+}
+
+GBool getUTF16LE(GString *s, int *i, Unicode *u) {
+ int w0, w1;
+
+ if (*i >= s->getLength() - 1) {
+ return gFalse;
+ }
+ w0 = (s->getChar(*i) & 0xff) | ((s->getChar(*i + 1) & 0xff) << 8);
+ *i += 2;
+ if (w0 < 0xd800 || w0 >= 0xe000) {
+ *u = (Unicode)w0;
+ } else {
+ if (*i < s->getLength() - 1) {
+ w1 = (s->getChar(*i) & 0xff) | ((s->getChar(*i + 1) & 0xff) << 8);
+ *i += 2;
+ *u = 0x10000 + ((w0 - 0xd8000) << 10) + (w1 - 0xdc00);
+ } else {
+ *u = (Unicode)w0;
+ }
+ }
+ return gTrue;
+}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.h b/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.h
index 8536dbf9436..1f29030096f 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UTF8.h
@@ -2,55 +2,41 @@
//
// UTF8.h
//
-// Copyright 2001-2003 Glyph & Cog, LLC
+// Copyright 2001-2017 Glyph & Cog, LLC
//
//========================================================================
-static int mapUTF8(Unicode u, char *buf, int bufSize) {
- if (u <= 0x0000007f) {
- if (bufSize < 1) {
- return 0;
- }
- buf[0] = (char)u;
- return 1;
- } else if (u <= 0x000007ff) {
- if (bufSize < 2) {
- return 0;
- }
- buf[0] = (char)(0xc0 + (u >> 6));
- buf[1] = (char)(0x80 + (u & 0x3f));
- return 2;
- } else if (u <= 0x0000ffff) {
- if (bufSize < 3) {
- return 0;
- }
- buf[0] = (char)(0xe0 + (u >> 12));
- buf[1] = (char)(0x80 + ((u >> 6) & 0x3f));
- buf[2] = (char)(0x80 + (u & 0x3f));
- return 3;
- } else if (u <= 0x0010ffff) {
- if (bufSize < 4) {
- return 0;
- }
- buf[0] = (char)(0xf0 + (u >> 18));
- buf[1] = (char)(0x80 + ((u >> 12) & 0x3f));
- buf[2] = (char)(0x80 + ((u >> 6) & 0x3f));
- buf[3] = (char)(0x80 + (u & 0x3f));
- return 4;
- } else {
- return 0;
- }
-}
-
-static int mapUCS2(Unicode u, char *buf, int bufSize) {
- if (u <= 0xffff) {
- if (bufSize < 2) {
- return 0;
- }
- buf[0] = (char)((u >> 8) & 0xff);
- buf[1] = (char)(u & 0xff);
- return 2;
- } else {
- return 0;
- }
-}
+#ifndef UTF8_H
+#define UTF8_H
+
+#include <aconf.h>
+
+#include "gtypes.h"
+#include "GString.h"
+#include "CharTypes.h"
+
+// Convert [u] to UTF-8 in [buf]. Returns the number of bytes written
+// to [buf]. If [u] requires more then [bufSize] bytes in UTF-8,
+// writes nothing and returns 0.
+extern int mapUTF8(Unicode u, char *buf, int bufSize);
+
+// Convert [u] to UCS-2BE in [buf]. Returns the number of bytes
+// written to [buf]. If [u] requires more then [bufSize] bytes in
+// UCS-2, writes nothing and returns 0.
+extern int mapUCS2(Unicode u, char *buf, int bufSize);
+
+// Parse one UTF-8 character from [s], starting at *[i]. Writes the
+// character to *[u], updates *[i] to point to the next available byte
+// in [s], and returns true. At end of string: writes nothing to *[u]
+// or *[i] and returns false. For an invalid UTF-8 character: sets
+// *[u] to the next byte, advances *[i] by one (to avoid infinite
+// loops), and returns true.
+extern GBool getUTF8(GString *s, int *i, Unicode *u);
+
+// Same as getUTF8, but for UTF-16BE.
+extern GBool getUTF16BE(GString *s, int *i, Unicode *u);
+
+// Same as getUTF8, but for UTF-16LE.
+extern GBool getUTF16LE(GString *s, int *i, Unicode *u);
+
+#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc
index 31f0c218eb9..833d6fc2f0c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.cc
@@ -15,6 +15,7 @@
#include <stdio.h>
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "gfile.h"
#include "GString.h"
#include "GList.h"
@@ -119,9 +120,6 @@ UnicodeMap::UnicodeMap(GString *encodingNameA) {
eMaps = NULL;
eMapsLen = 0;
refCnt = 1;
-#if MULTITHREADED
- gInitMutex(&mutex);
-#endif
}
UnicodeMap::UnicodeMap(const char *encodingNameA, GBool unicodeOutA,
@@ -134,9 +132,6 @@ UnicodeMap::UnicodeMap(const char *encodingNameA, GBool unicodeOutA,
eMaps = NULL;
eMapsLen = 0;
refCnt = 1;
-#if MULTITHREADED
- gInitMutex(&mutex);
-#endif
}
UnicodeMap::UnicodeMap(const char *encodingNameA, GBool unicodeOutA,
@@ -148,9 +143,6 @@ UnicodeMap::UnicodeMap(const char *encodingNameA, GBool unicodeOutA,
eMaps = NULL;
eMapsLen = 0;
refCnt = 1;
-#if MULTITHREADED
- gInitMutex(&mutex);
-#endif
}
UnicodeMap::~UnicodeMap() {
@@ -161,18 +153,13 @@ UnicodeMap::~UnicodeMap() {
if (eMaps) {
gfree(eMaps);
}
-#if MULTITHREADED
- gDestroyMutex(&mutex);
-#endif
}
void UnicodeMap::incRefCnt() {
#if MULTITHREADED
- gLockMutex(&mutex);
-#endif
+ gAtomicIncrement(&refCnt);
+#else
++refCnt;
-#if MULTITHREADED
- gUnlockMutex(&mutex);
#endif
}
@@ -180,11 +167,9 @@ void UnicodeMap::decRefCnt() {
GBool done;
#if MULTITHREADED
- gLockMutex(&mutex);
-#endif
+ done = gAtomicDecrement(&refCnt) == 0;
+#else
done = --refCnt == 0;
-#if MULTITHREADED
- gUnlockMutex(&mutex);
#endif
if (done) {
delete this;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h
index 66c482ca79f..a15d628b4cc 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMap.h
@@ -94,9 +94,10 @@ private:
int len; // (user, resident)
UnicodeMapExt *eMaps; // (user)
int eMapsLen; // (user)
- int refCnt;
#if MULTITHREADED
- GMutex mutex;
+ GAtomicCounter refCnt;
+#else
+ int refCnt;
#endif
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMapTables.h b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMapTables.h
index 073e474e6be..60ac55d124e 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMapTables.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeMapTables.h
@@ -2,7 +2,7 @@
//
// UnicodeMapTables.h
//
-// Copyright 2001-2009 Glyph & Cog, LLC
+// Copyright 2001-2014 Glyph & Cog, LLC
//
//========================================================================
@@ -28,6 +28,7 @@ static UnicodeMapRange latin1UnicodeMapRanges[] = {
{ 0x02c6, 0x02c6, 0x5e, 1 },
{ 0x02da, 0x02da, 0xb0, 1 },
{ 0x02dc, 0x02dc, 0x7e, 1 },
+ { 0x2010, 0x2010, 0x2d, 1 },
{ 0x2013, 0x2013, 0xad, 1 },
{ 0x2014, 0x2014, 0x2d2d, 2 },
{ 0x2018, 0x2018, 0x60, 1 },
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc
index 34e68dc774d..328d2478167 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/UnicodeTypeTable.cc
@@ -6,7 +6,9 @@
//
//========================================================================
+#include <aconf.h>
#include <stdlib.h>
+#include "gmempp.h"
#include "CharTypes.h"
#include "UnicodeTypeTable.h"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc
index fd420a9e424..1ee893b10a0 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.cc
@@ -13,6 +13,8 @@
#endif
#include <stdlib.h>
+#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "GList.h"
#include "GHash.h"
@@ -25,8 +27,10 @@
#include "XFAForm.h"
#ifdef _WIN32
-# define strcasecmp stricmp
-# define strncasecmp strnicmp
+# undef strcasecmp
+# undef strncasecmp
+# define strcasecmp _stricmp
+# define strncasecmp _strnicmp
#endif
//------------------------------------------------------------------------
@@ -165,18 +169,214 @@ static Guchar code3Of9Data[128][10] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
+// 3 bars + 3 spaces -- each can be 1, 2, 3, or 4 units wide
+static Guchar code128Data[107][6] = {
+ { 2, 1, 2, 2, 2, 2 },
+ { 2, 2, 2, 1, 2, 2 },
+ { 2, 2, 2, 2, 2, 1 },
+ { 1, 2, 1, 2, 2, 3 },
+ { 1, 2, 1, 3, 2, 2 },
+ { 1, 3, 1, 2, 2, 2 },
+ { 1, 2, 2, 2, 1, 3 },
+ { 1, 2, 2, 3, 1, 2 },
+ { 1, 3, 2, 2, 1, 2 },
+ { 2, 2, 1, 2, 1, 3 },
+ { 2, 2, 1, 3, 1, 2 },
+ { 2, 3, 1, 2, 1, 2 },
+ { 1, 1, 2, 2, 3, 2 },
+ { 1, 2, 2, 1, 3, 2 },
+ { 1, 2, 2, 2, 3, 1 },
+ { 1, 1, 3, 2, 2, 2 },
+ { 1, 2, 3, 1, 2, 2 },
+ { 1, 2, 3, 2, 2, 1 },
+ { 2, 2, 3, 2, 1, 1 },
+ { 2, 2, 1, 1, 3, 2 },
+ { 2, 2, 1, 2, 3, 1 },
+ { 2, 1, 3, 2, 1, 2 },
+ { 2, 2, 3, 1, 1, 2 },
+ { 3, 1, 2, 1, 3, 1 },
+ { 3, 1, 1, 2, 2, 2 },
+ { 3, 2, 1, 1, 2, 2 },
+ { 3, 2, 1, 2, 2, 1 },
+ { 3, 1, 2, 2, 1, 2 },
+ { 3, 2, 2, 1, 1, 2 },
+ { 3, 2, 2, 2, 1, 1 },
+ { 2, 1, 2, 1, 2, 3 },
+ { 2, 1, 2, 3, 2, 1 },
+ { 2, 3, 2, 1, 2, 1 },
+ { 1, 1, 1, 3, 2, 3 },
+ { 1, 3, 1, 1, 2, 3 },
+ { 1, 3, 1, 3, 2, 1 },
+ { 1, 1, 2, 3, 1, 3 },
+ { 1, 3, 2, 1, 1, 3 },
+ { 1, 3, 2, 3, 1, 1 },
+ { 2, 1, 1, 3, 1, 3 },
+ { 2, 3, 1, 1, 1, 3 },
+ { 2, 3, 1, 3, 1, 1 },
+ { 1, 1, 2, 1, 3, 3 },
+ { 1, 1, 2, 3, 3, 1 },
+ { 1, 3, 2, 1, 3, 1 },
+ { 1, 1, 3, 1, 2, 3 },
+ { 1, 1, 3, 3, 2, 1 },
+ { 1, 3, 3, 1, 2, 1 },
+ { 3, 1, 3, 1, 2, 1 },
+ { 2, 1, 1, 3, 3, 1 },
+ { 2, 3, 1, 1, 3, 1 },
+ { 2, 1, 3, 1, 1, 3 },
+ { 2, 1, 3, 3, 1, 1 },
+ { 2, 1, 3, 1, 3, 1 },
+ { 3, 1, 1, 1, 2, 3 },
+ { 3, 1, 1, 3, 2, 1 },
+ { 3, 3, 1, 1, 2, 1 },
+ { 3, 1, 2, 1, 1, 3 },
+ { 3, 1, 2, 3, 1, 1 },
+ { 3, 3, 2, 1, 1, 1 },
+ { 3, 1, 4, 1, 1, 1 },
+ { 2, 2, 1, 4, 1, 1 },
+ { 4, 3, 1, 1, 1, 1 },
+ { 1, 1, 1, 2, 2, 4 },
+ { 1, 1, 1, 4, 2, 2 },
+ { 1, 2, 1, 1, 2, 4 },
+ { 1, 2, 1, 4, 2, 1 },
+ { 1, 4, 1, 1, 2, 2 },
+ { 1, 4, 1, 2, 2, 1 },
+ { 1, 1, 2, 2, 1, 4 },
+ { 1, 1, 2, 4, 1, 2 },
+ { 1, 2, 2, 1, 1, 4 },
+ { 1, 2, 2, 4, 1, 1 },
+ { 1, 4, 2, 1, 1, 2 },
+ { 1, 4, 2, 2, 1, 1 },
+ { 2, 4, 1, 2, 1, 1 },
+ { 2, 2, 1, 1, 1, 4 },
+ { 4, 1, 3, 1, 1, 1 },
+ { 2, 4, 1, 1, 1, 2 },
+ { 1, 3, 4, 1, 1, 1 },
+ { 1, 1, 1, 2, 4, 2 },
+ { 1, 2, 1, 1, 4, 2 },
+ { 1, 2, 1, 2, 4, 1 },
+ { 1, 1, 4, 2, 1, 2 },
+ { 1, 2, 4, 1, 1, 2 },
+ { 1, 2, 4, 2, 1, 1 },
+ { 4, 1, 1, 2, 1, 2 },
+ { 4, 2, 1, 1, 1, 2 },
+ { 4, 2, 1, 2, 1, 1 },
+ { 2, 1, 2, 1, 4, 1 },
+ { 2, 1, 4, 1, 2, 1 },
+ { 4, 1, 2, 1, 2, 1 },
+ { 1, 1, 1, 1, 4, 3 },
+ { 1, 1, 1, 3, 4, 1 },
+ { 1, 3, 1, 1, 4, 1 },
+ { 1, 1, 4, 1, 1, 3 },
+ { 1, 1, 4, 3, 1, 1 },
+ { 4, 1, 1, 1, 1, 3 },
+ { 4, 1, 1, 3, 1, 1 },
+ { 1, 1, 3, 1, 4, 1 },
+ { 1, 1, 4, 1, 3, 1 },
+ { 3, 1, 1, 1, 4, 1 },
+ { 4, 1, 1, 1, 3, 1 },
+ { 2, 1, 1, 4, 1, 2 }, // start code A
+ { 2, 1, 1, 2, 1, 4 }, // start code B
+ { 2, 1, 1, 2, 3, 2 }, // start code C
+ { 2, 3, 3, 1, 1, 1 } // stop code (without final bar)
+};
+
+//------------------------------------------------------------------------
+
+class XFATableInfo {
+public:
+
+ XFATableInfo(ZxAttr *columnWidthsAttr);
+ ~XFATableInfo();
+ void computeRowHeight(ZxElement *rowSubform);
+
+ int nColumns; // number of columns
+ double *columnRight; // right edge (x coord) of each column
+ int rowIdx; // current row index
+ int columnIdx; // current column index
+ double rowTop; // top edge (y coord) of current row
+ double rowHeight; // height of current row (max cell height
+ // so far)
+};
+
+XFATableInfo::XFATableInfo(ZxAttr *columnWidthsAttr) {
+ GString *s;
+ double w;
+ int i, columnRightSize;
+
+ nColumns = 0;
+ columnRight = NULL;
+ columnRightSize = 0;
+ if (columnWidthsAttr) {
+ s = columnWidthsAttr->getValue();
+ i = 0;
+ while (1) {
+ for (;
+ i < s->getLength() &&
+ (s->getChar(i) == ' ' || s->getChar(i) == '\t' ||
+ s->getChar(i) == '\r' || s->getChar(i) == '\n');
+ ++i) ;
+ if (i == s->getLength()) {
+ break;
+ }
+ w = XFAFormField::getMeasurement(s, i);
+ if (nColumns == columnRightSize) {
+ columnRightSize = columnRightSize ? 2 * columnRightSize : 8;
+ columnRight = (double *)greallocn(columnRight, columnRightSize,
+ sizeof(double));
+ }
+ columnRight[nColumns] = (nColumns > 0 ? columnRight[nColumns - 1] : 0) + w;
+ ++nColumns;
+ for (++i;
+ i < s->getLength() &&
+ !(s->getChar(i) == ' ' || s->getChar(i) == '\t' ||
+ s->getChar(i) == '\r' || s->getChar(i) == '\n');
+ ++i) ;
+ }
+ }
+ rowIdx = -1;
+ columnIdx = 0;
+ rowTop = rowHeight = 0;
+}
+
+XFATableInfo::~XFATableInfo() {
+ gfree(columnRight);
+}
+
+void XFATableInfo::computeRowHeight(ZxElement *rowSubform) {
+ ZxNode *child;
+ ZxAttr *attr;
+ double h;
+
+ rowHeight = 0;
+ for (child = rowSubform->getFirstChild();
+ child;
+ child = child->getNextChild()) {
+ if (child->isElement("field") || child->isElement("draw")) {
+ if (!(attr = ((ZxElement *)child)->findAttr("h"))) {
+ attr = ((ZxElement *)child)->findAttr("minH");
+ }
+ h = XFAFormField::getMeasurement(attr, 0);
+ if (h > rowHeight) {
+ rowHeight = h;
+ }
+ }
+ }
+}
+
//------------------------------------------------------------------------
// XFAForm
//------------------------------------------------------------------------
-XFAForm *XFAForm::load(PDFDoc *docA, Object *acroFormObj, Object *xfaObj) {
+XFAForm *XFAForm::load(PDFDoc *docA, Catalog *catalog,
+ Object *acroFormObj, Object *xfaObj) {
XFAForm *xfaForm;
+ XFAFormField *field;
ZxDoc *xmlA;
ZxElement *tmpl;
Object catDict, resourceDictA, obj1;
GString *data;
GBool fullXFAA;
- GString *name;
+ GString *name, *fullName;
char buf[4096];
int n, i;
@@ -223,113 +423,328 @@ XFAForm *XFAForm::load(PDFDoc *docA, Object *acroFormObj, Object *xfaObj) {
acroFormObj->dictLookup("DR", &resourceDictA);
}
- xfaForm = new XFAForm(docA, xmlA, &resourceDictA, fullXFAA);
+ xfaForm = new XFAForm(docA, catalog->getNumPages(),
+ xmlA, &resourceDictA, fullXFAA);
resourceDictA.free();
if (xfaForm->xml->getRoot()) {
if ((tmpl = xfaForm->xml->getRoot()->findFirstChildElement("template"))) {
name = new GString("form");
- xfaForm->curPageNum = 1;
+ fullName = new GString("form");
+ xfaForm->curPageNum = 0;
xfaForm->curXOffset = xfaForm->curYOffset = 0;
- xfaForm->scanFields(tmpl, name, name);
+ xfaForm->scanNamedNode(tmpl, name, fullName, gFalse, NULL);
delete name;
+ delete fullName;
+
+ // apply pageOffsetX/Y (the pageSet/pageArea/contentArea offset)
+ // to all fields
+ if (xfaForm->pageSetNPages >= 1 &&
+ xfaForm->pageSetNPages < xfaForm->nPages) {
+ for (i = xfaForm->pageSetNPages + 1; i <= xfaForm->nPages; ++i) {
+ xfaForm->pageOffsetX[i - 1] =
+ xfaForm->pageOffsetX[xfaForm->pageSetNPages - 1];
+ xfaForm->pageOffsetY[i - 1] =
+ xfaForm->pageOffsetY[xfaForm->pageSetNPages - 1];
+ }
+ }
+ for (i = 0; i < xfaForm->fields->getLength(); ++i) {
+ field = (XFAFormField *)xfaForm->fields->get(i);
+ if (field->pageNum >= 1 && field->pageNum <= xfaForm->nPages) {
+ field->xOffset += xfaForm->pageOffsetX[field->pageNum - 1];
+ field->yOffset += xfaForm->pageOffsetY[field->pageNum - 1];
+ }
+ }
}
}
return xfaForm;
}
-XFAForm::XFAForm(PDFDoc *docA, ZxDoc *xmlA, Object *resourceDictA,
- GBool fullXFAA): Form(docA) {
+XFAForm::XFAForm(PDFDoc *docA, int nPagesA, ZxDoc *xmlA,
+ Object *resourceDictA, GBool fullXFAA):
+ Form(docA) {
+ int pg;
+
xml = xmlA;
fields = new GList();
resourceDictA->copy(&resourceDict);
fullXFA = fullXFAA;
+ nPages = nPagesA;
+ pageSetNPages = 0;
+ pageOffsetX = (double *)gmallocn(nPages, sizeof(double));
+ pageOffsetY = (double *)gmallocn(nPages, sizeof(double));
+ for (pg = 0; pg < nPages; ++pg) {
+ pageOffsetX[pg] = pageOffsetY[pg] = 0;
+ }
}
XFAForm::~XFAForm() {
delete xml;
deleteGList(fields, XFAFormField);
resourceDict.free();
+ gfree(pageOffsetX);
+ gfree(pageOffsetY);
}
-void XFAForm::scanFields(ZxElement *elem, GString *name, GString *dataName) {
- ZxAttr *attr;
+// Scan all children of <elem>, which is a named internal (non-field)
+// node, with the specified name.
+void XFAForm::scanNamedNode(ZxElement *elem, GString *name, GString *fullName,
+ GBool inPageSet, XFATableInfo *tableInfo) {
+ GHash *childNameCount, *childNameIdx;
ZxNode *child;
- ZxElement *bindElem;
- GHash *names1, *names2;
- GString *childName, *fullName, *fullDataName;
- int i;
- //~ need to handle subform
+ childNameCount = new GHash();
+ for (child = elem->getFirstChild(); child; child = child->getNextChild()) {
+ if (child->isElement()) {
+ scanNames((ZxElement *)child, childNameCount);
+ }
+ }
+ childNameIdx = new GHash();
+ for (child = elem->getFirstChild(); child; child = child->getNextChild()) {
+ if (child->isElement()) {
+ scanFields((ZxElement *)child, name, fullName, inPageSet,
+ tableInfo, childNameCount, childNameIdx);
+ }
+ }
+ delete childNameIdx;
+ delete childNameCount;
+}
+
+// Traverse all children of <elem>, incrementing nameCount[name] for
+// each named child. Traversal stops at each named child.
+void XFAForm::scanNames(ZxElement *elem, GHash *nameCount) {
+ ZxNode *child;
+ GString *childName;
+
+ if ((childName = getNodeName(elem))) {
+ if (nodeIsBindGlobal(elem)) {
+ nameCount->replace(childName, 1);
+ } else {
+ nameCount->replace(childName, nameCount->lookupInt(childName) + 1);
+ }
+ } else {
+ for (child = elem->getFirstChild(); child; child = child->getNextChild()) {
+ if (child->isElement()) {
+ scanNames((ZxElement *)child, nameCount);
+ }
+ }
+ }
+}
+
+// Create fields for <elem> and its children. <parentName> is the
+// name of <elem>'s parent. <siblingNameCount> contains the number of
+// occurrences of the siblings' (parent's childrens') names.
+// <siblingNameIdx> contains the number of occurrences of each name
+// used so far.
+void XFAForm::scanFields(ZxElement *elem, GString *parentName,
+ GString *parentFullName, GBool inPageSet,
+ XFATableInfo *tableInfo,
+ GHash *siblingNameCount, GHash *siblingNameIdx) {
+ XFATableInfo *newTableInfo;
+ ZxElement *brk, *contentArea;
+ ZxNode *child;
+ ZxAttr *attr;
+ GString *elemName, *elemFullName, *name, *fullName;
+ double xSubOffset, ySubOffset, columnWidth, rowHeight;
+ int savedPageNum;
+ int colSpan, i;
//~ 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
+ if ((elemName = getNodeName(elem))) {
+ name = GString::format("{0:t}.{1:t}", parentName, elemName);
+ } else {
+ name = parentName;
+ }
+
+ if ((elemFullName = getNodeFullName(elem))) {
+ fullName = GString::format("{0:t}.{1:t}", parentFullName, elemFullName);
+ } else {
+ fullName = parentFullName;
+ }
+
+ //~ do we need a separate siblingNameCount/siblingNameIndex for
+ //~ elemName and elemFullName?
+ if (elemFullName && siblingNameCount->lookupInt(elemFullName) > 1) {
+ i = siblingNameIdx->lookupInt(elemFullName);
+ fullName->appendf("[{0:d}]", i);
+ if (elemName) {
+ name->appendf("[{0:d}]", i);
+ }
+ siblingNameIdx->replace(elemFullName, i + 1);
+ }
+
+ if (tableInfo && (elem->isElement("field") || elem->isElement("draw"))) {
+ if ((attr = elem->findAttr("colSpan"))) {
+ colSpan = atoi(attr->getValue()->getCString());
+ } else {
+ colSpan = 1;
+ }
+ } else {
+ colSpan = 0;
+ }
+
if (elem->isElement("field")) {
- fields->append(new XFAFormField(this, elem, name->copy(),
- dataName->copy(), curPageNum,
- curXOffset, curYOffset));
- } else if (elem->isElement("breakBefore")) {
- if ((attr = elem->findAttr("targetType")) &&
- !attr->getValue()->cmp("pageArea") &&
- (attr = elem->findAttr("startNew")) &&
- !attr->getValue()->cmp("1")) {
- ++curPageNum;
+ if (curPageNum == 0) {
+ curPageNum = 1;
}
- } else if (elem->isElement("break")) {
- if ((attr = elem->findAttr("before")) &&
- !attr->getValue()->cmp("pageArea") &&
- (attr = elem->findAttr("startNew")) &&
- !attr->getValue()->cmp("1")) {
- ++curPageNum;
+ xSubOffset = ySubOffset = 0;
+ columnWidth = rowHeight = 0;
+ if (tableInfo) {
+ if (tableInfo->columnIdx > 0 &&
+ tableInfo->columnIdx <= tableInfo->nColumns) {
+ xSubOffset = tableInfo->columnRight[tableInfo->columnIdx - 1];
+ }
+ if (tableInfo->columnIdx + colSpan <= tableInfo->nColumns) {
+ columnWidth = tableInfo->columnRight[tableInfo->columnIdx + colSpan - 1]
+ - xSubOffset;
+ }
+ ySubOffset = tableInfo->rowTop;
+ rowHeight = tableInfo->rowHeight;
+ curXOffset += xSubOffset;
+ curYOffset += ySubOffset;
+ }
+ fields->append(new XFAFormField(this, elem, name->copy(), fullName->copy(),
+ curPageNum, curXOffset, curYOffset,
+ columnWidth, rowHeight));
+ if (tableInfo) {
+ curXOffset -= xSubOffset;
+ curYOffset -= ySubOffset;
}
- } else if (elem->isElement("contentArea")) {
- curXOffset = XFAFormField::getMeasurement(elem->findAttr("x"), 0);
- curYOffset = XFAFormField::getMeasurement(elem->findAttr("y"), 0);
} else {
- names1 = new GHash();
- for (child = elem->getFirstChild(); child; child = child->getNextChild()) {
- if (child->isElement() &&
- (attr = ((ZxElement *)child)->findAttr("name"))) {
- childName = attr->getValue();
- names1->replace(childName, names1->lookupInt(childName) + 1);
+ newTableInfo = tableInfo;
+ if (elem->isElement("subform")) {
+ if (((brk = elem->findFirstChildElement("breakBefore")) &&
+ (attr = brk->findAttr("targetType")) &&
+ !attr->getValue()->cmp("pageArea")) ||
+ ((brk = elem->findFirstChildElement("break")) &&
+ (attr = brk->findAttr("before")) &&
+ !attr->getValue()->cmp("pageArea"))) {
+ if (curPageNum < nPages) {
+ ++curPageNum;
+ }
+ }
+ if ((attr = elem->findAttr("layout"))) {
+ if (!attr->getValue()->cmp("table")) {
+ newTableInfo = new XFATableInfo(elem->findAttr("columnWidths"));
+ newTableInfo->rowIdx = -1;
+ newTableInfo->columnIdx = 0;
+ } else if (tableInfo && !attr->getValue()->cmp("row")) {
+ ++tableInfo->rowIdx;
+ tableInfo->columnIdx = 0;
+ tableInfo->rowTop += tableInfo->rowHeight;
+ tableInfo->computeRowHeight(elem);
+ }
+ }
+ xSubOffset = XFAFormField::getMeasurement(elem->findAttr("x"), 0);
+ ySubOffset = XFAFormField::getMeasurement(elem->findAttr("y"), 0);
+ curXOffset += xSubOffset;
+ curYOffset += ySubOffset;
+ } else if (elem->isElement("area")) {
+ xSubOffset = XFAFormField::getMeasurement(elem->findAttr("x"), 0);
+ ySubOffset = XFAFormField::getMeasurement(elem->findAttr("y"), 0);
+ curXOffset += xSubOffset;
+ curYOffset += ySubOffset;
+ } else {
+ xSubOffset = ySubOffset = 0;
+ }
+ savedPageNum = curPageNum;
+ if (elem->isElement("pageSet")) {
+ inPageSet = gTrue;
+ curPageNum = 0;
+ } else if (elem->isElement("pageArea")) {
+ if (inPageSet) {
+ if (curPageNum < nPages) {
+ ++curPageNum;
+ }
+ if ((contentArea = elem->findFirstChildElement("contentArea"))) {
+ pageOffsetX[curPageNum - 1] =
+ XFAFormField::getMeasurement(contentArea->findAttr("x"), 0);
+ pageOffsetY[curPageNum - 1] =
+ XFAFormField::getMeasurement(contentArea->findAttr("y"), 0);
+ // looks like the contentArea offset (pageOffsetX/Y) should
+ // not be added to fields defined inside the pageArea
+ // element (?)
+ xSubOffset -= pageOffsetX[curPageNum - 1];
+ ySubOffset -= pageOffsetY[curPageNum - 1];
+ curXOffset -= pageOffsetX[curPageNum - 1];
+ curYOffset -= pageOffsetY[curPageNum - 1];
+ }
}
}
- names2 = new GHash();
- for (child = elem->getFirstChild(); child; child = child->getNextChild()) {
- if (child->isElement()) {
- if (!((bindElem = child->findFirstChildElement("bind")) &&
- (attr = bindElem->findAttr("match")) &&
- !attr->getValue()->cmp("none")) &&
- (attr = ((ZxElement *)child)->findAttr("name"))) {
- childName = attr->getValue();
- if (names1->lookupInt(childName) > 1) {
- i = names2->lookupInt(childName);
- fullName = GString::format("{0:t}.{1:t}[{2:d}]",
- name, childName, i);
- fullDataName = GString::format("{0:t}.{1:t}[{2:d}]",
- dataName, childName, i);
- names2->replace(childName, i + 1);
- } else {
- fullName = GString::format("{0:t}.{1:t}", name, childName);
- fullDataName = GString::format("{0:t}.{1:t}", dataName, childName);
- }
- } else {
- fullName = name->copy();
- fullDataName = dataName->copy();
+ if (elemName) {
+ scanNamedNode(elem, name, fullName, inPageSet, newTableInfo);
+ } else {
+ for (child = elem->getFirstChild();
+ child;
+ child = child->getNextChild()) {
+ if (child->isElement()) {
+ scanFields((ZxElement *)child, name, fullName, inPageSet,
+ newTableInfo, siblingNameCount, siblingNameIdx);
}
- scanFields((ZxElement *)child, fullName, fullDataName);
- delete fullName;
- delete fullDataName;
}
}
- delete names1;
- delete names2;
+ curXOffset -= xSubOffset;
+ curYOffset -= ySubOffset;
+ if (newTableInfo != tableInfo) {
+ delete newTableInfo;
+ }
+ if (elem->isElement("pageSet")) {
+ pageSetNPages = curPageNum;
+ curPageNum = savedPageNum;
+ inPageSet = gFalse;
+ }
+ }
+
+ if (tableInfo) {
+ tableInfo->columnIdx += colSpan;
+ }
+
+ if (name != parentName) {
+ delete name;
+ }
+ if (fullName != parentFullName) {
+ delete fullName;
+ }
+}
+
+GString *XFAForm::getNodeName(ZxElement *elem) {
+ ZxElement *bindElem;
+ ZxAttr *attr;
+
+ if (!(elem->getType()->cmp("field") &&
+ (bindElem = elem->findFirstChildElement("bind")) &&
+ (attr = bindElem->findAttr("match")) &&
+ !attr->getValue()->cmp("none")) &&
+ !elem->isElement("area") &&
+ (attr = elem->findAttr("name"))) {
+ return attr->getValue();
+ }
+ return NULL;
+}
+
+GString *XFAForm::getNodeFullName(ZxElement *elem) {
+ ZxAttr *attr;
+
+ if (!elem->isElement("area") &&
+ (attr = elem->findAttr("name"))) {
+ return attr->getValue();
}
+ return NULL;
+}
+
+GBool XFAForm::nodeIsBindGlobal(ZxElement *elem) {
+ ZxElement *bindElem;
+ ZxAttr *attr;
+
+ return (bindElem = elem->findFirstChildElement("bind")) &&
+ (attr = bindElem->findAttr("match")) &&
+ !attr->getValue()->cmp("global");
}
void XFAForm::draw(int pageNum, Gfx *gfx, GBool printing) {
@@ -338,13 +753,13 @@ void XFAForm::draw(int pageNum, Gfx *gfx, GBool printing) {
int i;
// build the font dictionary
- if (resourceDict.isDict() &&
- resourceDict.dictLookup("Font", &obj1)->isDict()) {
- fontDict = new GfxFontDict(doc->getXRef(), NULL, obj1.getDict());
- } else {
- fontDict = NULL;
+ fontDict = NULL;
+ if (resourceDict.isDict()) {
+ if (resourceDict.dictLookup("Font", &obj1)->isDict()) {
+ fontDict = new GfxFontDict(doc->getXRef(), NULL, obj1.getDict());
+ }
+ obj1.free();
}
- obj1.free();
for (i = 0; i < fields->getLength(); ++i) {
((XFAFormField *)fields->get(i))->draw(pageNum, gfx, printing, fontDict);
@@ -365,21 +780,28 @@ FormField *XFAForm::getField(int idx) {
// XFAFormField
//------------------------------------------------------------------------
-XFAFormField::XFAFormField(XFAForm *xfaFormA, ZxElement *xmlA, GString *nameA,
- GString *dataNameA, int pageNumA,
- double xOffsetA, double yOffsetA) {
+XFAFormField::XFAFormField(XFAForm *xfaFormA, ZxElement *xmlA,
+ GString *nameA, GString *fullNameA,
+ int pageNumA, double xOffsetA, double yOffsetA,
+ double columnWidthA, double rowHeightA) {
xfaForm = xfaFormA;
xml = xmlA;
name = nameA;
- dataName = dataNameA;
+ fullName = fullNameA;
pageNum = pageNumA;
xOffset = xOffsetA;
yOffset = yOffsetA;
+ columnWidth = columnWidthA;
+ rowHeight = rowHeightA;
}
XFAFormField::~XFAFormField() {
delete name;
- delete dataName;
+ delete fullName;
+}
+
+int XFAFormField::getPageNum() {
+ return pageNum;
}
const char *XFAFormField::getType() {
@@ -390,6 +812,14 @@ const char *XFAFormField::getType() {
for (node = uiElem->getFirstChild(); node; node = node->getNextChild()) {
if (node->isElement("textEdit")) {
return "Text";
+ } else if (node->isElement("numericEdit")) {
+ return "Numeric";
+ } else if (node->isElement("dateTimeEdit")) {
+ return "DateTime";
+ } else if (node->isElement("choiceList")) {
+ return "ChoiceList";
+ } else if (node->isElement("checkButton")) {
+ return "CheckButton";
} else if (node->isElement("barcode")) {
return "BarCode";
}
@@ -415,8 +845,20 @@ Unicode *XFAFormField::getValue(int *length) {
for (node = uiElem->getFirstChild(); node; node = node->getNextChild()) {
if (node->isElement("textEdit")) {
s = getFieldValue("text");
+ break;
+ } else if (node->isElement("numericEdit")) {
+ //~ not sure if this is correct
+ s = getFieldValue("text");
+ break;
+ } else if (node->isElement("dateTimeEdit")) {
+ s = getFieldValue("text");
+ break;
+ } else if (node->isElement("checkButton")) {
+ s = getFieldValue("integer");
+ break;
} else if (node->isElement("barcode")) {
s = getFieldValue("text");
+ break;
}
//~ other field types go here
}
@@ -478,25 +920,217 @@ Unicode *XFAFormField::utf8ToUnicode(GString *s, int *length) {
return u;
}
+void XFAFormField::getBBox(double *llx, double *lly,
+ double *urx, double *ury) {
+ double xfaX, xfaY, xfaW, xfaH, pdfX, pdfY, pdfW, pdfH;
+ int pdfRot;
+
+ getRectangle(&xfaX, &xfaY, &xfaW, &xfaH,
+ &pdfX, &pdfY, &pdfW, &pdfH, &pdfRot);
+ *llx = pdfX;
+ *lly = pdfY;
+ *urx = pdfX + pdfW;
+ *ury = pdfY + pdfH;
+}
+
+void XFAFormField::getFont(Ref *fontID, double *fontSize) {
+ ZxElement *fontElem;
+ ZxAttr *attr;
+ GBool bold, italic;
+
+ fontID->num = fontID->gen = -1;
+ *fontSize = 0;
+ if ((fontElem = xml->findFirstChildElement("font"))) {
+ bold = italic = gFalse;
+ if ((attr = fontElem->findAttr("weight"))) {
+ if (!attr->getValue()->cmp("bold")) {
+ bold = gTrue;
+ }
+ }
+ if ((attr = fontElem->findAttr("posture"))) {
+ if (!attr->getValue()->cmp("italic")) {
+ italic = gTrue;
+ }
+ }
+ if ((attr = fontElem->findAttr("typeface"))) {
+ *fontID = findFontName(attr->getValue(), bold, italic);
+ }
+ if ((attr = fontElem->findAttr("size"))) {
+ *fontSize = getMeasurement(attr, 0);
+ }
+ }
+}
+
+void XFAFormField::getColor(double *red, double *green, double *blue) {
+ ZxElement *fontElem, *fillElem, *colorElem;
+ ZxAttr *attr;
+ int r, g, b;
+
+ *red = *green = *blue = 0;
+ if ((fontElem = xml->findFirstChildElement("font"))) {
+ if ((fillElem = fontElem->findFirstChildElement("fill"))) {
+ if ((colorElem = fillElem->findFirstChildElement("color"))) {
+ if ((attr = colorElem->findAttr("value"))) {
+ if (sscanf(attr->getValue()->getCString(), "%d,%d,%d",
+ &r, &g, &b) == 3) {
+ *red = r / 255.0;
+ *green = g / 255.0;
+ *blue = b / 255.0;
+ }
+ }
+ }
+ }
+ }
+}
+
void XFAFormField::draw(int pageNumA, Gfx *gfx, GBool printing,
GfxFontDict *fontDict) {
- Page *page;
- PDFRectangle *pageRect;
ZxElement *uiElem;
ZxNode *node;
- ZxAttr *attr;
GString *appearBuf;
MemStream *appearStream;
- Object appearDict, appearance, obj1, obj2;
+ Object appearDict, appearance, resourceDict, resourceSubdict;
+ Object fontResources, fontResource, defaultFont;
+ Object obj1, obj2;
+ char *resType, *fontName;
double mat[6];
- double x, y, w, h, x2, y2, w2, h2, x3, y3, w3, h3;
- double anchorX, anchorY;
- int pageRot, rot, rot3;
+ double xfaX, xfaY, xfaW, xfaH, pdfX, pdfY, pdfW, pdfH;
+ int rot3, i;
if (pageNumA != pageNum) {
return;
}
+ getRectangle(&xfaX, &xfaY, &xfaW, &xfaH, &pdfX, &pdfY, &pdfW, &pdfH, &rot3);
+
+ // generate transform matrix
+ switch (rot3) {
+ case 0:
+ default:
+ mat[0] = 1; mat[1] = 0;
+ mat[2] = 0; mat[3] = 1;
+ mat[4] = 0; mat[5] = 0;
+ break;
+ case 90:
+ mat[0] = 0; mat[1] = 1;
+ mat[2] = -1; mat[3] = 0;
+ mat[4] = xfaH; mat[5] = 0;
+ break;
+ case 180:
+ mat[0] = -1; mat[1] = 0;
+ mat[2] = 0; mat[3] = -1;
+ mat[4] = xfaW; mat[5] = xfaH;
+ break;
+ case 270:
+ mat[0] = 0; mat[1] = -1;
+ mat[2] = 1; mat[3] = 0;
+ mat[4] = 0; mat[5] = xfaW;
+ break;
+ }
+
+ // get the appearance stream data
+ appearBuf = new GString();
+#if 0 //~ for debugging
+ double debugPad = 0;
+ appearBuf->appendf("q 1 1 0 rg {0:.4f} {1:.4f} {2:.4f} {3:.4f} re f Q\n",
+ debugPad, debugPad, xfaW - 2*debugPad, xfaH - 2*debugPad);
+#endif
+ if ((uiElem = xml->findFirstChildElement("ui"))) {
+ for (node = uiElem->getFirstChild(); node; node = node->getNextChild()) {
+ if (node->isElement("textEdit") ||
+ node->isElement("numericEdit")) {
+ drawTextEdit(fontDict, xfaW, xfaH, rot3, appearBuf);
+ break;
+ } else if (node->isElement("dateTimeEdit")) {
+ drawTextEdit(fontDict, xfaW, xfaH, rot3, appearBuf);
+ break;
+ } else if (node->isElement("choiceList")) {
+ drawTextEdit(fontDict, xfaW, xfaH, rot3, appearBuf);
+ break;
+ } else if (node->isElement("checkButton")) {
+ drawCheckButton(fontDict, xfaW, xfaH, rot3, appearBuf);
+ break;
+ } else if (node->isElement("barcode")) {
+ drawBarCode(fontDict, xfaW, xfaH, rot3, appearBuf);
+ break;
+ }
+ //~ other field types go here
+ }
+ } else {
+ drawTextEdit(fontDict, xfaW, xfaH, rot3, appearBuf);
+ }
+
+ // create the appearance stream
+ appearDict.initDict(xfaForm->doc->getXRef());
+ appearDict.dictAdd(copyString("Length"),
+ obj1.initInt(appearBuf->getLength()));
+ appearDict.dictAdd(copyString("Subtype"), obj1.initName("Form"));
+ obj1.initArray(xfaForm->doc->getXRef());
+ obj1.arrayAdd(obj2.initReal(0));
+ obj1.arrayAdd(obj2.initReal(0));
+ obj1.arrayAdd(obj2.initReal(xfaW));
+ obj1.arrayAdd(obj2.initReal(xfaH));
+ appearDict.dictAdd(copyString("BBox"), &obj1);
+ obj1.initArray(xfaForm->doc->getXRef());
+ obj1.arrayAdd(obj2.initReal(mat[0]));
+ obj1.arrayAdd(obj2.initReal(mat[1]));
+ obj1.arrayAdd(obj2.initReal(mat[2]));
+ obj1.arrayAdd(obj2.initReal(mat[3]));
+ obj1.arrayAdd(obj2.initReal(mat[4]));
+ obj1.arrayAdd(obj2.initReal(mat[5]));
+ appearDict.dictAdd(copyString("Matrix"), &obj1);
+ // NB: we need to deep-copy the resource dict and font resource
+ // subdict, because the font subdict is modified, and multiple
+ // threads can be sharing these objects.
+ resourceDict.initDict(xfaForm->doc->getXRef());
+ if (xfaForm->resourceDict.isDict()) {
+ for (i = 0; i < xfaForm->resourceDict.dictGetLength(); ++i) {
+ resType = xfaForm->resourceDict.dictGetKey(i);
+ if (strcmp(resType, "Font")) {
+ xfaForm->resourceDict.dictGetVal(i, &resourceSubdict);
+ resourceDict.dictAdd(copyString(resType), &resourceSubdict);
+ }
+ }
+ }
+ fontResources.initDict(xfaForm->doc->getXRef());
+ if (xfaForm->resourceDict.isDict() &&
+ xfaForm->resourceDict.dictLookup("Font", &resourceSubdict)->isDict()) {
+ for (i = 0; i < resourceSubdict.dictGetLength(); ++i) {
+ fontName = resourceSubdict.dictGetKey(i);
+ resourceSubdict.dictGetVal(i, &fontResource);
+ fontResources.dictAdd(copyString(fontName), &fontResource);
+ }
+ resourceSubdict.free();
+ }
+ defaultFont.initDict(xfaForm->doc->getXRef());
+ defaultFont.dictAdd(copyString("Type"), obj1.initName("Font"));
+ defaultFont.dictAdd(copyString("Subtype"), obj1.initName("Type1"));
+ defaultFont.dictAdd(copyString("BaseFont"), obj1.initName("Helvetica"));
+ defaultFont.dictAdd(copyString("Encoding"), obj1.initName("WinAnsiEncoding"));
+ fontResources.dictAdd(copyString("xpdf_default_font"), &defaultFont);
+ resourceDict.dictAdd(copyString("Font"), &fontResources);
+ appearDict.dictAdd(copyString("Resources"), &resourceDict);
+ appearStream = new MemStream(appearBuf->getCString(), 0,
+ appearBuf->getLength(), &appearDict);
+ appearance.initStream(appearStream);
+ gfx->drawAnnot(&appearance, NULL, pdfX, pdfY, pdfX + pdfW, pdfY + pdfH);
+ appearance.free();
+ delete appearBuf;
+}
+
+void XFAFormField::getRectangle(double *xfaX, double *xfaY,
+ double *xfaW, double *xfaH,
+ double *pdfX, double *pdfY,
+ double *pdfW, double *pdfH,
+ int *pdfRot) {
+ Page *page;
+ PDFRectangle *pageRect;
+ ZxElement *captionElem, *paraElem, *marginElem;
+ ZxAttr *attr;
+ double x2, y2, w2, h2, t;
+ double anchorX, anchorY;
+ int pageRot, rot;
+
page = xfaForm->doc->getCatalog()->getPage(pageNum);
pageRect = page->getMediaBox();
pageRot = page->getRotate();
@@ -533,10 +1167,22 @@ void XFAFormField::draw(int pageNumA, Gfx *gfx, GBool printing,
anchorY = 1;
}
}
- x = getMeasurement(xml->findAttr("x"), 0) + xOffset;
- y = getMeasurement(xml->findAttr("y"), 0) + yOffset;
- w = getMeasurement(xml->findAttr("w"), 0);
- h = getMeasurement(xml->findAttr("h"), 0);
+ *xfaX = getMeasurement(xml->findAttr("x"), 0) + xOffset;
+ *xfaY = getMeasurement(xml->findAttr("y"), 0) + yOffset;
+ if (!(attr = xml->findAttr("w"))) {
+ attr = xml->findAttr("minW");
+ }
+ *xfaW = getMeasurement(attr, 0);
+ if (*xfaW < columnWidth) {
+ *xfaW = columnWidth;
+ }
+ if (!(attr = xml->findAttr("h"))) {
+ attr = xml->findAttr("minH");
+ }
+ *xfaH = getMeasurement(attr, 0);
+ if (*xfaH < rowHeight) {
+ *xfaH = rowHeight;
+ }
if ((attr = xml->findAttr("rotate"))) {
rot = atoi(attr->getValue()->getCString());
if ((rot %= 360) < 0) {
@@ -546,6 +1192,66 @@ void XFAFormField::draw(int pageNumA, Gfx *gfx, GBool printing,
rot = 0;
}
+ // look for <caption reserve="...."> -- add the caption width/height
+ // (plus a margin allowance)
+ if ((captionElem = xml->findFirstChildElement("caption"))) {
+ if ((attr = captionElem->findAttr("reserve"))) {
+ t = getMeasurement(attr, 0);
+ if ((attr = captionElem->findAttr("placement"))) {
+ if (!attr->getValue()->cmp("left")) {
+ *xfaX += t + 1.5;
+ *xfaW -= t + 1.5;
+ } else if (!attr->getValue()->cmp("right")) {
+ *xfaW -= t + 1.5;
+ } else if (!attr->getValue()->cmp("top")) {
+ *xfaY += t;
+ *xfaH -= t;
+ } else if (!attr->getValue()->cmp("bottom")) {
+ *xfaH -= t;
+ }
+ } else {
+ // default is placement="left"
+ *xfaX += t + 1.5;
+ *xfaW -= t + 1.5;
+ }
+ }
+ }
+
+ // look for <margin>
+ if ((marginElem = xml->findFirstChildElement("margin"))) {
+ if ((attr = marginElem->findAttr("leftInset"))) {
+ t = getMeasurement(attr, 0);
+ *xfaX += t;
+ *xfaW -= t;
+ }
+ if ((attr = marginElem->findAttr("rightInset"))) {
+ t = getMeasurement(attr, 0);
+ *xfaW -= t;
+ }
+ if ((attr = marginElem->findAttr("topInset"))) {
+ t = getMeasurement(attr, 0);
+ *xfaY += t;
+ *xfaH -= t;
+ }
+ if ((attr = marginElem->findAttr("bottomInset"))) {
+ t = getMeasurement(attr, 0);
+ *xfaH -= t;
+ }
+ }
+
+ // look for <para> -- add the margin
+ if ((paraElem = xml->findFirstChildElement("para"))) {
+ if ((attr = paraElem->findAttr("marginLeft"))) {
+ t = getMeasurement(attr, 0);
+ *xfaX += t;
+ *xfaW -= t;
+ }
+ if ((attr = paraElem->findAttr("marginRight"))) {
+ t = getMeasurement(attr, 0);
+ *xfaW -= t;
+ }
+ }
+
// get annot rect (UL corner, width, height) in XFA coords
// notes:
// - XFA coordinates are top-left origin, after page rotation
@@ -554,28 +1260,28 @@ void XFAFormField::draw(int pageNumA, Gfx *gfx, GBool printing,
switch (rot) {
case 0:
default:
- x2 = x - anchorX * w;
- y2 = y - anchorY * h;
- w2 = w;
- h2 = h;
+ x2 = *xfaX - anchorX * *xfaW;
+ y2 = *xfaY - anchorY * *xfaH;
+ w2 = *xfaW;
+ h2 = *xfaH;
break;
case 90:
- x2 = x - anchorY * h;
- y2 = y - (1 - anchorX) * w;
- w2 = h;
- h2 = w;
+ x2 = *xfaX - anchorY * *xfaH;
+ y2 = *xfaY - (1 - anchorX) * *xfaW;
+ w2 = *xfaH;
+ h2 = *xfaW;
break;
case 180:
- x2 = x - (1 - anchorX) * w;
- y2 = y - (1 - anchorY) * h;
- w2 = w;
- h2 = h;
+ x2 = *xfaX - (1 - anchorX) * *xfaW;
+ y2 = *xfaY - (1 - anchorY) * *xfaH;
+ w2 = *xfaW;
+ h2 = *xfaH;
break;
case 270:
- x2 = x - (1 - anchorY) * h;
- y2 = y - anchorX * w;
- w2 = h;
- h2 = w;
+ x2 = *xfaX - (1 - anchorY) * *xfaH;
+ y2 = *xfaY - anchorX * *xfaW;
+ w2 = *xfaH;
+ h2 = *xfaW;
break;
}
@@ -584,113 +1290,42 @@ void XFAFormField::draw(int pageNumA, Gfx *gfx, GBool printing,
switch (pageRot) {
case 0:
default:
- x3 = pageRect->x1 + x2;
- y3 = pageRect->y2 - (y2 + h2);
- w3 = w2;
- h3 = h2;
- break;
- case 90:
- x3 = pageRect->x1 + y2;
- y3 = pageRect->y1 + x2;
- w3 = h2;
- h3 = w2;
- break;
- case 180:
- x3 = pageRect->x2 - (x2 + w2);
- y3 = pageRect->y1 + y2;
- w3 = w2;
- h3 = h2;
- break;
- case 270:
- x3 = pageRect->x2 - (y2 + h2);
- y3 = pageRect->y1 + (x2 + w2);
- w3 = h2;
- h3 = w2;
- break;
- }
- rot3 = (rot + pageRot) % 360;
-
- // generate transform matrix
- switch (rot3) {
- case 0:
- default:
- mat[0] = 1; mat[1] = 0;
- mat[2] = 0; mat[3] = 1;
- mat[4] = 0; mat[5] = 0;
+ *pdfX = pageRect->x1 + x2;
+ *pdfY = pageRect->y2 - (y2 + h2);
+ *pdfW = w2;
+ *pdfH = h2;
break;
case 90:
- mat[0] = 0; mat[1] = 1;
- mat[2] = -1; mat[3] = 0;
- mat[4] = h; mat[5] = 0;
+ *pdfX = pageRect->x1 + y2;
+ *pdfY = pageRect->y1 + x2;
+ *pdfW = h2;
+ *pdfH = w2;
break;
case 180:
- mat[0] = -1; mat[1] = 0;
- mat[2] = 0; mat[3] = -1;
- mat[4] = w; mat[5] = h;
+ *pdfX = pageRect->x2 - (x2 + w2);
+ *pdfY = pageRect->y1 + y2;
+ *pdfW = w2;
+ *pdfH = h2;
break;
case 270:
- mat[0] = 0; mat[1] = -1;
- mat[2] = 1; mat[3] = 0;
- mat[4] = 0; mat[5] = w;
+ *pdfX = pageRect->x2 - (y2 + h2);
+ *pdfY = pageRect->y1 + (x2 + w2);
+ *pdfW = h2;
+ *pdfH = w2;
break;
}
-
- // get the appearance stream data
- appearBuf = new GString();
-#if 0 //~ for debugging
- appearBuf->appendf("q 1 1 0 rg 0 0 {0:.4f} {1:.4f} re f Q\n", w, h);
-#endif
- if ((uiElem = xml->findFirstChildElement("ui"))) {
- for (node = uiElem->getFirstChild(); node; node = node->getNextChild()) {
- if (node->isElement("textEdit")) {
- drawTextEdit(fontDict, w, h, rot3, appearBuf);
- break;
- } else if (node->isElement("barcode")) {
- drawBarCode(fontDict, w, h, rot3, appearBuf);
- break;
- }
- //~ other field types go here
- }
- }
-
- // create the appearance stream
- appearDict.initDict(xfaForm->doc->getXRef());
- appearDict.dictAdd(copyString("Length"),
- obj1.initInt(appearBuf->getLength()));
- appearDict.dictAdd(copyString("Subtype"), obj1.initName("Form"));
- obj1.initArray(xfaForm->doc->getXRef());
- obj1.arrayAdd(obj2.initReal(0));
- obj1.arrayAdd(obj2.initReal(0));
- obj1.arrayAdd(obj2.initReal(w));
- obj1.arrayAdd(obj2.initReal(h));
- appearDict.dictAdd(copyString("BBox"), &obj1);
- obj1.initArray(xfaForm->doc->getXRef());
- obj1.arrayAdd(obj2.initReal(mat[0]));
- obj1.arrayAdd(obj2.initReal(mat[1]));
- obj1.arrayAdd(obj2.initReal(mat[2]));
- obj1.arrayAdd(obj2.initReal(mat[3]));
- obj1.arrayAdd(obj2.initReal(mat[4]));
- obj1.arrayAdd(obj2.initReal(mat[5]));
- appearDict.dictAdd(copyString("Matrix"), &obj1);
- if (xfaForm->resourceDict.isDict()) {
- appearDict.dictAdd(copyString("Resources"),
- xfaForm->resourceDict.copy(&obj1));
- }
- appearStream = new MemStream(appearBuf->getCString(), 0,
- appearBuf->getLength(), &appearDict);
- appearance.initStream(appearStream);
- gfx->drawAnnot(&appearance, NULL, x3, y3, x3 + w3, y3 + h3);
- appearance.free();
- delete appearBuf;
+ *pdfRot = (rot + pageRot) % 360;
}
void XFAFormField::drawTextEdit(GfxFontDict *fontDict,
double w, double h, int rot,
GString *appearBuf) {
+ ZxElement *formatElem, *pictureElem;
+ ZxNode *pictureChildElem;
ZxElement *valueElem, *textElem, *uiElem, *textEditElem, *combElem;
ZxElement *fontElem, *paraElem;
ZxAttr *attr;
- GString *value, *fontName;
+ GString *picture, *value, *formattedValue, *fontName;
double fontSize;
int maxChars, combCells;
GBool multiLine, bold, italic;
@@ -701,6 +1336,28 @@ void XFAFormField::drawTextEdit(GfxFontDict *fontDict,
return;
}
+ uiElem = xml->findFirstChildElement("ui");
+
+ //--- picture formatting
+ if (uiElem &&
+ (formatElem = xml->findFirstChildElement("format")) &&
+ (pictureElem = formatElem->findFirstChildElement("picture")) &&
+ (pictureChildElem = pictureElem->getFirstChild()) &&
+ pictureChildElem->isCharData()) {
+ picture = ((ZxCharData *)pictureChildElem)->getData();
+ if (uiElem->findFirstChildElement("dateTimeEdit")) {
+ formattedValue = pictureFormatDateTime(value, picture);
+ } else if (uiElem->findFirstChildElement("numericEdit")) {
+ formattedValue = pictureFormatNumber(value, picture);
+ } else if (uiElem->findFirstChildElement("textEdit")) {
+ formattedValue = pictureFormatText(value, picture);
+ } else {
+ formattedValue = value->copy();
+ }
+ } else {
+ formattedValue = value->copy();
+ }
+
maxChars = 0;
if ((valueElem = xml->findFirstChildElement("value")) &&
(textElem = valueElem->findFirstChildElement("text")) &&
@@ -710,7 +1367,7 @@ void XFAFormField::drawTextEdit(GfxFontDict *fontDict,
multiLine = gFalse;
combCells = 0;
- if ((uiElem = xml->findFirstChildElement("ui")) &&
+ if (uiElem &&
(textEditElem = uiElem->findFirstChildElement("textEdit"))) {
if ((attr = textEditElem->findAttr("multiLine")) &&
!attr->getValue()->cmp("1")) {
@@ -776,10 +1433,71 @@ void XFAFormField::drawTextEdit(GfxFontDict *fontDict,
}
}
- drawText(value, multiLine, combCells,
+ drawText(formattedValue, multiLine, combCells,
fontName, bold, italic, fontSize,
hAlign, vAlign, 0, 0, w, h, gFalse, fontDict, appearBuf);
delete fontName;
+ delete formattedValue;
+}
+
+void XFAFormField::drawCheckButton(GfxFontDict *fontDict,
+ double w, double h, int rot,
+ GString *appearBuf) {
+ ZxElement *items;
+ ZxNode *firstItem, *firstItemVal;
+ const char *itemType;
+ const char *onValue;
+ GString *value;
+ double x, y;
+
+ // get the "on" value for this check button
+ itemType = "integer";
+ onValue = "1";
+ if ((items = xml->findFirstChildElement("items"))) {
+ if ((firstItem = items->getFirstChild())) {
+ if (firstItem->isElement("text") && firstItem->getFirstChild()) {
+ itemType = "text";
+ if ((firstItemVal = firstItem->getFirstChild())->isCharData()) {
+ onValue = ((ZxCharData *)firstItemVal)->getData()->getCString();
+ }
+ } else if (firstItem->isElement("integer") &&
+ firstItem->getFirstChild()) {
+ itemType = "integer";
+ if ((firstItemVal = firstItem->getFirstChild())->isCharData()) {
+ onValue = ((ZxCharData *)firstItemVal)->getData()->getCString();
+ }
+ }
+ }
+ }
+
+ // compare its value to the "on" value
+ if (!(value = getFieldValue(itemType))) {
+ return;
+ }
+ if (value->cmp(onValue)) {
+ return;
+ }
+
+ // adjust shape to be square
+ x = y = 0;
+ if (w > h) {
+ x += 0.5 * (w - h);
+ w = h;
+ } else {
+ y += 0.5 * (h - w);
+ h = w;
+ }
+
+ // margins
+ x += 1.5;
+ w -= 3;
+ y += 1.5;
+ h -= 3;
+
+ //~ this should look at the "shape" and "mark" attributes
+
+ appearBuf->appendf("0.5 w {0:.4f} {1:.4f} m {2:.4f} {3:.4f} l {0:.4f} {3:.4f} m {2:.4f} {1:.4f} l S\n",
+ x, y, x + w, y + h);
}
void XFAFormField::drawBarCode(GfxFontDict *fontDict,
@@ -792,7 +1510,7 @@ void XFAFormField::drawBarCode(GfxFontDict *fontDict,
double wideNarrowRatio, fontSize;
double yText, wText, yBarcode, hBarcode, wNarrow, xx;
GBool doText;
- int dataLength;
+ int dataLength, checksum;
GBool bold, italic;
char *p;
int i, j, c;
@@ -815,7 +1533,7 @@ void XFAFormField::drawBarCode(GfxFontDict *fontDict,
if ((attr = barcodeElem->findAttr("wideNarrowRatio"))) {
s1 = attr->getValue();
if ((p = strchr(s1->getCString(), ':'))) {
- s2 = new GString(s1, 0, p - s1->getCString());
+ s2 = new GString(s1, 0, (int)(p - s1->getCString()));
wideNarrowRatio = atof(p + 1);
if (wideNarrowRatio == 0) {
wideNarrowRatio = 1;
@@ -900,14 +1618,15 @@ void XFAFormField::drawBarCode(GfxFontDict *fontDict,
wText = w;
//--- remove extraneous start/stop chars
- //~ this may depend on barcode type
value2 = value->copy();
- if (value2->getLength() >= 1 && value2->getChar(0) == '*') {
- value2->del(0);
- }
- if (value2->getLength() >= 1 &&
- value2->getChar(value2->getLength() - 1) == '*') {
- value2->del(value2->getLength() - 1);
+ if (!barcodeType->cmp("code3Of9")) {
+ if (value2->getLength() >= 1 && value2->getChar(0) == '*') {
+ value2->del(0);
+ }
+ if (value2->getLength() >= 1 &&
+ value2->getChar(value2->getLength() - 1) == '*') {
+ value2->del(value2->getLength() - 1);
+ }
}
//--- draw the bar code
@@ -932,6 +1651,43 @@ void XFAFormField::drawBarCode(GfxFontDict *fontDict,
}
// center the text on the drawn barcode (not the max length barcode)
wText = (value2->getLength() + 2) * (7 + 3 * wideNarrowRatio) * wNarrow;
+ } else if (!barcodeType->cmp("code128B")) {
+ appearBuf->append("0 g\n");
+ wNarrow = w / (11 * (dataLength + 3) + 2);
+ xx = 0;
+ checksum = 0;
+ for (i = -1; i <= value2->getLength() + 1; ++i) {
+ if (i == -1) {
+ // start code B
+ c = 104;
+ checksum += c;
+ } else if (i == value2->getLength()) {
+ // checksum
+ c = checksum % 103;
+ } else if (i == value2->getLength() + 1) {
+ // stop code
+ c = 106;
+ } else {
+ c = value2->getChar(i) & 0xff;
+ if (c >= 32 && c <= 127) {
+ c -= 32;
+ } else {
+ c = 0;
+ }
+ checksum += (i + 1) * c;
+ }
+ for (j = 0; j < 6; j += 2) {
+ appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} re f\n",
+ xx, yBarcode,
+ code128Data[c][j] * wNarrow, hBarcode);
+ xx += (code128Data[c][j] + code128Data[c][j+1]) * wNarrow;
+ }
+ }
+ // final bar of the stop code
+ appearBuf->appendf("{0:.4f} {1:.4f} {2:.4f} {3:.4f} re f\n",
+ xx, yBarcode, 2 * wNarrow, hBarcode);
+ // center the text on the drawn barcode (not the max length barcode)
+ wText = (11 * (value2->getLength() + 3) + 2) * wNarrow;
} else {
error(errSyntaxError, -1,
"Unimplemented barcode type in XFA barcode field");
@@ -956,15 +1712,20 @@ Object *XFAFormField::getResources(Object *res) {
double XFAFormField::getMeasurement(ZxAttr *attr, double defaultVal) {
GString *s;
- double val, mul;
- GBool neg;
- int i;
if (!attr) {
return defaultVal;
}
s = attr->getValue();
- i = 0;
+ return getMeasurement(s, 0);
+}
+
+double XFAFormField::getMeasurement(GString *s, int begin) {
+ double val, mul;
+ GBool neg;
+ int i;
+
+ i = begin;
neg = gFalse;
if (i < s->getLength() && s->getChar(i) == '+') {
++i;
@@ -1010,9 +1771,43 @@ double XFAFormField::getMeasurement(ZxAttr *attr, double defaultVal) {
}
GString *XFAFormField::getFieldValue(const char *valueChildType) {
- ZxElement *valueElem, *datasets, *data, *elem;
+ ZxElement *valueElem, *datasets, *data, *formElem, *elem;
char *p;
+ // check the <datasets> packet
+ p = name->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();
+ if (xfaForm->xml->getRoot() && !strncmp(p, "form.", 5)) {
+ if ((formElem = xfaForm->xml->getRoot()->findFirstChildElement("form"))) {
+ elem = findFieldInFormElem(formElem, p + 5);
+ if (elem &&
+ (valueElem = elem->findFirstChildElement("value")) &&
+ (elem = valueElem->findFirstChildElement(valueChildType))) {
+ if (elem->getFirstChild() &&
+ elem->getFirstChild()->isCharData() &&
+ ((ZxCharData *)elem->getFirstChild())
+ ->getData()->getLength() > 0) {
+ return ((ZxCharData *)elem->getFirstChild())->getData();
+ }
+ }
+ }
+ }
+
// check the <value> element within the field
if ((valueElem = xml->findFirstChildElement("value")) &&
(elem = valueElem->findFirstChildElement(valueChildType))) {
@@ -1023,31 +1818,10 @@ GString *XFAFormField::getFieldValue(const char *valueChildType) {
}
}
- // check the <datasets> packet
- if (!xfaForm->xml->getRoot() ||
- !(datasets =
- xfaForm->xml->getRoot()->findFirstChildElement("xfa:datasets")) ||
- !(data = datasets->findFirstChildElement("xfa:data"))) {
- return NULL;
- }
- p = name->getCString();
- if (!strncmp(p, "form.", 5)) {
- p += 5;
- } else {
- return NULL;
- }
- elem = findFieldData(data, p);
- if (elem &&
- elem->getFirstChild() &&
- elem->getFirstChild()->isCharData() &&
- ((ZxCharData *)elem->getFirstChild())->getData()->getLength() > 0) {
- return ((ZxCharData *)elem->getFirstChild())->getData();
- }
-
return NULL;
}
-ZxElement *XFAFormField::findFieldData(ZxElement *elem, char *partName) {
+ZxElement *XFAFormField::findFieldInDatasets(ZxElement *elem, char *partName) {
ZxNode *node;
GString *nodeName;
int curIdx, idx, n;
@@ -1070,9 +1844,47 @@ ZxElement *XFAFormField::findFieldData(ZxElement *elem, char *partName) {
if (!partName[n]) {
return (ZxElement *)node;
} else if (partName[n] == '.') {
- return findFieldData((ZxElement *)node, partName + n + 1);
+ return findFieldInDatasets((ZxElement *)node, partName + n + 1);
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+ZxElement *XFAFormField::findFieldInFormElem(ZxElement *elem, char *partName) {
+ ZxElement *elem2;
+ ZxNode *node;
+ ZxAttr *attr;
+ GString *nodeName;
+ int curIdx, idx, n;
+
+ curIdx = 0;
+ for (node = elem->getFirstChild(); node; node = node->getNextChild()) {
+ if ((node->isElement("subform") || node->isElement("field")) &&
+ ((attr = ((ZxElement *)node)->findAttr("name")))) {
+ nodeName = attr->getValue();
+ n = nodeName->getLength();
+ if (!strncmp(partName, nodeName->getCString(), n)) {
+ if (partName[n] == '[') {
+ idx = atoi(partName + n + 1);
+ if (idx == curIdx) {
+ for (++n; partName[n] && partName[n-1] != ']'; ++n) ;
+ } else {
+ ++curIdx;
+ continue;
+ }
+ }
+ if (!partName[n]) {
+ return (ZxElement *)node;
+ } else if (partName[n] == '.') {
+ return findFieldInFormElem((ZxElement *)node, partName + n + 1);
}
}
+ } else if (node->isElement("subform")) {
+ if ((elem2 = findFieldInFormElem((ZxElement *)node, partName))) {
+ return elem2;
+ }
}
}
return NULL;
@@ -1111,33 +1923,62 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
GBool whiteBackground,
GfxFontDict *fontDict, GString *appearBuf) {
GfxFont *font;
+ const char *fontTag;
GString *s;
- double xx, yy, tw, charWidth, lineHeight;
- double rectX, rectY, rectW, rectH;
- int line, i, j, k, c, rectI;
+ 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?)
// find the font
- if (!(font = findFont(fontDict, fontName, bold, italic))) {
+ if ((font = findFont(fontDict, fontName, bold, italic))) {
+ fontTag = font->getTag()->getCString();
+ ascent = font->getAscent() * fontSize;
+ descent = font->getDescent() * fontSize;
+ } else {
error(errSyntaxError, -1, "Couldn't find a font for '{0:t}', {1:s}, {2:s} used in XFA field",
fontName, bold ? "bold" : "non-bold",
italic ? "italic" : "non-italic");
- return;
+ fontTag = "xpdf_default_font";
+ ascent = 0.718 * fontSize;
+ descent = -0.207 * fontSize;
}
// setup
rectW = rectH = 0;
rectI = appearBuf->getLength();
appearBuf->append("BT\n");
- appearBuf->appendf("/{0:t} {1:.2f} Tf\n", font->getTag(), fontSize);
+ appearBuf->appendf("/{0:s} {1:.2f} Tf\n", fontTag, fontSize);
// multi-line text
if (multiLine) {
- // figure out how many lines will fit
+ // compute line height
lineHeight = 1.2 * fontSize;
+ // handle bottom/middle alignment
+ if (vAlign == xfaVAlignBottom || vAlign == xfaVAlignMiddle) {
+ nLines = 0;
+ i = 0;
+ while (i < text->getLength()) {
+ getNextLine(text, i, font, fontSize, w, &j, &tw, &k);
+ ++nLines;
+ i = k;
+ }
+ blkH = nLines * lineHeight - (lineHeight - fontSize);
+ if (vAlign == xfaVAlignBottom) {
+ yTop = y + blkH;
+ } else {
+ yTop = y + 0.5 * (h + blkH);
+ }
+ if (yTop > y + h) {
+ yTop = y + h;
+ }
+ } else {
+ yTop = y + h;
+ }
+
// write a series of lines of text
line = 0;
i = 0;
@@ -1161,7 +2002,7 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
xx = x + w - tw;
break;
}
- yy = y + h - fontSize * font->getAscent() - line * lineHeight;
+ yy = yTop - line * lineHeight - ascent;
// draw the line
appearBuf->appendf("1 0 0 1 {0:.4f} {1:.4f} Tm\n", xx, yy);
@@ -1185,7 +2026,7 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
}
rectH = line * lineHeight;
rectY = y + h - rectH;
-
+
// comb formatting
} else if (combCells > 0) {
@@ -1209,23 +2050,22 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
switch (vAlign) {
case xfaVAlignTop:
default:
- yy = y + h - fontSize * font->getAscent();
+ yy = y + h - ascent;
break;
case xfaVAlignMiddle:
- yy = y + 0.5 * (h - fontSize * (font->getAscent() +
- font->getDescent()));
+ yy = y + 0.5 * (h - (ascent + descent));
break;
case xfaVAlignBottom:
- yy = y - fontSize * font->getDescent();
+ yy = y - descent;
break;
}
- rectY = yy + fontSize * font->getDescent();
- rectH = fontSize * (font->getAscent() - font->getDescent());
+ rectY = yy + descent;
+ rectH = ascent - descent;
// write the text string
for (i = 0; i < text->getLength(); ++i) {
c = text->getChar(i) & 0xff;
- if (!font->isCIDFont()) {
+ if (font && !font->isCIDFont()) {
charWidth = fontSize * ((Gfx8BitFont *)font)->getWidth(c);
appearBuf->appendf("1 0 0 1 {0:.4f} {1:.4f} Tm\n",
xx + i * tw + 0.5 * (tw - charWidth), yy);
@@ -1249,7 +2089,7 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
} else {
// compute string width
- if (!font->isCIDFont()) {
+ if (font && !font->isCIDFont()) {
tw = 0;
for (i = 0; i < text->getLength(); ++i) {
tw += ((Gfx8BitFont *)font)->getWidth(text->getChar(i));
@@ -1277,18 +2117,17 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
switch (vAlign) {
case xfaVAlignTop:
default:
- yy = y + h - fontSize * font->getAscent();
+ yy = y + h - ascent;
break;
case xfaVAlignMiddle:
- yy = y + 0.5 * (h - fontSize * (font->getAscent() +
- font->getDescent()));
+ yy = y + 0.5 * (h - (ascent + descent));
break;
case xfaVAlignBottom:
- yy = y - fontSize * font->getDescent();
+ yy = y - descent;
break;
}
- rectY = yy + fontSize * font->getDescent();
- rectH = fontSize * (font->getAscent() - font->getDescent());
+ rectY = yy + descent;
+ rectH = ascent - descent;
appearBuf->appendf("{0:.4f} {1:.4f} Td\n", xx, yy);
// write the text string
@@ -1326,6 +2165,8 @@ void XFAFormField::drawText(GString *text, GBool multiLine, int combCells,
}
rectX -= 0.25 * fontSize;
rectW += 0.5 * fontSize;
+ rectY -= 0.1 * fontSize;
+ rectH += 0.2 * fontSize;
s = GString::format("q 1 g {0:.4f} {1:.4f} {2:.4f} {3:.4f} re f Q\n",
rectX, rectY, rectW, rectH);
appearBuf->insert(rectI, s);
@@ -1391,6 +2232,77 @@ GfxFont *XFAFormField::findFont(GfxFontDict *fontDict, GString *fontName,
return NULL;
}
+// Searches the font resource dict for a font matching(<name>, <bold>,
+// <italic>), and returns the font object ID. This does not require a
+// GfxFontDict, and it does not do any parsing of font objects beyond
+// looking at BaseFont.
+Ref XFAFormField::findFontName(GString *name, GBool bold, GBool italic) {
+ Object fontDictObj, fontObj, baseFontObj, fontRef;
+ Ref fontID;
+ GString *reqName, *testName;
+ GBool foundName, foundBold, foundItalic;
+ char *p;
+ char c;
+ int i;
+
+ fontID.num = fontID.gen = -1;
+
+ // remove space chars from the requested name
+ reqName = new GString();
+ for (i = 0; i < name->getLength(); ++i) {
+ c = name->getChar(i);
+ if (c != ' ') {
+ reqName->append(c);
+ }
+ }
+
+ if (xfaForm->resourceDict.isDict()) {
+ if (xfaForm->resourceDict.dictLookup("Font", &fontDictObj)->isDict()) {
+ for (i = 0; i < fontDictObj.dictGetLength() && fontID.num < 0; ++i) {
+ fontDictObj.dictGetVal(i, &fontObj);
+ if (fontObj.dictLookup("BaseFont", &baseFontObj)->isName()) {
+
+ // remove space chars from the font name
+ testName = new GString();
+ for (p = baseFontObj.getName(); *p; ++p) {
+ if (*p != ' ') {
+ testName->append(p);
+ }
+ }
+
+ // compare the names
+ foundName = foundBold = foundItalic = gFalse;
+ for (p = testName->getCString(); *p; ++p) {
+ if (!strncasecmp(p, reqName->getCString(), reqName->getLength())) {
+ foundName = gTrue;
+ }
+ if (!strncasecmp(p, "bold", 4)) {
+ foundBold = gTrue;
+ }
+ if (!strncasecmp(p, "italic", 6) || !strncasecmp(p, "oblique", 7)) {
+ foundItalic = gTrue;
+ }
+ }
+ delete testName;
+ if (foundName && foundBold == bold && foundItalic == italic) {
+ if (fontObj.dictGetValNF(i, &fontRef)) {
+ fontID = fontRef.getRef();
+ }
+ fontRef.free();
+ }
+ }
+
+ baseFontObj.free();
+ fontObj.free();
+ }
+ }
+ fontDictObj.free();
+ }
+ delete reqName;
+
+ return fontID;
+}
+
// Figure out how much text will fit on the next line. Returns:
// *end = one past the last character to be included
// *width = width of the characters start .. end-1
@@ -1456,3 +2368,690 @@ void XFAFormField::getNextLine(GString *text, int start,
}
*next = j;
}
+
+//------------------------------------------------------------------------
+// 'picture' formatting
+//------------------------------------------------------------------------
+
+class XFAPictureNode {
+public:
+ virtual ~XFAPictureNode() {}
+ virtual GBool isLiteral() { return gFalse; }
+ virtual GBool isSign() { return gFalse; }
+ virtual GBool isDigit() { return gFalse; }
+ virtual GBool isDecPt() { return gFalse; }
+ virtual GBool isSeparator() { return gFalse; }
+ virtual GBool isYear() { return gFalse; }
+ virtual GBool isMonth() { return gFalse; }
+ virtual GBool isDay() { return gFalse; }
+ virtual GBool isHour() { return gFalse; }
+ virtual GBool isMinute() { return gFalse; }
+ virtual GBool isSecond() { return gFalse; }
+ virtual GBool isChar() { return gFalse; }
+};
+
+class XFAPictureLiteral: public XFAPictureNode {
+public:
+ XFAPictureLiteral(GString *sA) { s = sA; }
+ virtual ~XFAPictureLiteral() { delete s; }
+ virtual GBool isLiteral() { return gTrue; }
+ GString *s;
+};
+
+class XFAPictureSign: public XFAPictureNode {
+public:
+ XFAPictureSign(char cA) { c = cA; }
+ virtual GBool isSign() { return gTrue; }
+ char c;
+};
+
+class XFAPictureDigit: public XFAPictureNode {
+public:
+ XFAPictureDigit(char cA) { c = cA; pos = 0; }
+ virtual GBool isDigit() { return gTrue; }
+ char c;
+ int pos;
+};
+
+class XFAPictureDecPt: public XFAPictureNode {
+public:
+ XFAPictureDecPt() { }
+ virtual GBool isDecPt() { return gTrue; }
+};
+
+class XFAPictureSeparator: public XFAPictureNode {
+public:
+ XFAPictureSeparator() { }
+ virtual GBool isSeparator() { return gTrue; }
+};
+
+class XFAPictureYear: public XFAPictureNode {
+public:
+ XFAPictureYear(int nDigitsA) { nDigits = nDigitsA; }
+ virtual GBool isYear() { return gTrue; }
+ int nDigits;
+};
+
+class XFAPictureMonth: public XFAPictureNode {
+public:
+ XFAPictureMonth(int nDigitsA) { nDigits = nDigitsA; }
+ virtual GBool isMonth() { return gTrue; }
+ int nDigits;
+};
+
+class XFAPictureDay: public XFAPictureNode {
+public:
+ XFAPictureDay(int nDigitsA) { nDigits = nDigitsA; }
+ virtual GBool isDay() { return gTrue; }
+ int nDigits;
+};
+
+class XFAPictureHour: public XFAPictureNode {
+public:
+ XFAPictureHour(GBool is24HourA, int nDigitsA)
+ { is24Hour = is24HourA; nDigits = nDigitsA; }
+ virtual GBool isHour() { return gTrue; }
+ GBool is24Hour;
+ int nDigits;
+};
+
+class XFAPictureMinute: public XFAPictureNode {
+public:
+ XFAPictureMinute(int nDigitsA) { nDigits = nDigitsA; }
+ virtual GBool isMinute() { return gTrue; }
+ int nDigits;
+};
+
+class XFAPictureSecond: public XFAPictureNode {
+public:
+ XFAPictureSecond(int nDigitsA) { nDigits = nDigitsA; }
+ virtual GBool isSecond() { return gTrue; }
+ int nDigits;
+};
+
+class XFAPictureChar: public XFAPictureNode {
+public:
+ XFAPictureChar() {}
+ virtual GBool isChar() { return gTrue; }
+};
+
+GString *XFAFormField::pictureFormatDateTime(GString *value, GString *picture) {
+ GList *pic;
+ XFAPictureNode *node;
+ GString *ret, *s;
+ char c;
+ int year, month, day, hour, min, sec;
+ int len, picStart, picEnd, u, n, i, j;
+
+ len = value->getLength();
+ if (len == 0) {
+ return value->copy();
+ }
+
+ //--- parse the value
+
+ // expected format is yyyy(-mm(-dd)?)?Thh(:mm(:ss)?)?
+ // where:
+ // - the '-'s and ':'s are optional
+ // - the 'T' is literal
+ // - we're ignoring optional time zone info at the end
+ // (if the value is not in this canonical format, we just punt and
+ // return the value string)
+ //~ another option would be to parse the value following the
+ //~ <ui><picture> element
+ year = month = day = hour = min = sec = 0;
+ i = 0;
+ if (!(i + 4 <= len && isValidInt(value, i, 4))) {
+ return value->copy();
+ }
+ year = convertInt(value, i, 4);
+ i += 4;
+ if (i < len && value->getChar(i) == '-') {
+ ++i;
+ }
+ if (i + 2 <= len && isValidInt(value, i, 2)) {
+ month = convertInt(value, i, 2);
+ i += 2;
+ if (i < len && value->getChar(i) == '-') {
+ ++i;
+ }
+ if (i + 2 <= len && isValidInt(value, i, 2)) {
+ day = convertInt(value, i, 2);
+ i += 2;
+ }
+ }
+ if (i < len) {
+ if (value->getChar(i) != 'T') {
+ return value->copy();
+ }
+ ++i;
+ if (!(i + 2 <= len && isValidInt(value, i, 2))) {
+ return value->copy();
+ }
+ hour = convertInt(value, i, 2);
+ i += 2;
+ if (i < len && value->getChar(i) == ':') {
+ ++i;
+ }
+ if (i + 2 <= len && isValidInt(value, i, 2)) {
+ min = convertInt(value, i, 2);
+ i += 2;
+ if (i < len && value->getChar(i) == ':') {
+ ++i;
+ }
+ if (i + 2 <= len && isValidInt(value, i, 2)) {
+ sec = convertInt(value, i, 2);
+ i += 2;
+ }
+ }
+ }
+ if (i < len) {
+ return value->copy();
+ }
+
+ //--- skip the category and locale in the picture
+
+ picStart = 0;
+ picEnd = picture->getLength();
+ for (i = 0; i < picture->getLength(); ++i) {
+ c = picture->getChar(i);
+ if (c == '{') {
+ picStart = i + 1;
+ for (picEnd = picStart;
+ picEnd < picture->getLength() && picture->getChar(picEnd) != '}';
+ ++picEnd) ;
+ break;
+ } else if (!((c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ c == '(' ||
+ c == ')')) {
+ break;
+ }
+ }
+
+ //--- parse the picture
+
+ pic = new GList();
+ i = picStart;
+ while (i < picEnd) {
+ c = picture->getChar(i);
+ ++i;
+ if (c == '\'') {
+ s = new GString();
+ while (i < picEnd) {
+ c = picture->getChar(i);
+ if (c == '\'') {
+ ++i;
+ if (i < picEnd && picture->getChar(i) == '\'') {
+ s->append('\'');
+ ++i;
+ } else {
+ break;
+ }
+ } else if (c == '\\') {
+ ++i;
+ if (i == picEnd) {
+ break;
+ }
+ c = picture->getChar(i);
+ ++i;
+ if (c == 'u' && i+4 <= picEnd) {
+ u = 0;
+ for (j = 0; j < 4; ++j, ++i) {
+ c = picture->getChar(i);
+ u <<= 4;
+ if (c >= '0' && c <= '9') {
+ u += c - '0';
+ } else if (c >= 'a' && c <= 'F') {
+ u += c - 'a' + 10;
+ } else if (c >= 'A' && c <= 'F') {
+ u += c - 'A' + 10;
+ }
+ }
+ //~ this should convert to UTF-8 (?)
+ if (u <= 0xff) {
+ s->append((char)u);
+ }
+ } else {
+ s->append(c);
+ }
+ } else {
+ s->append(c);
+ }
+ }
+ pic->append(new XFAPictureLiteral(s));
+ } else if (c == ',' || c == '-' || c == ':' ||
+ c == '/' || c == '.' || c == ' ') {
+ s = new GString();
+ s->append(c);
+ pic->append(new XFAPictureLiteral(s));
+ } else if (c == 'Y') {
+ for (n = 1; n < 4 && i < picEnd && picture->getChar(i) == 'Y'; ++n, ++i) ;
+ pic->append(new XFAPictureYear(n));
+ } else if (c == 'M') {
+ for (n = 1; n < 2 && i < picEnd && picture->getChar(i) == 'M'; ++n, ++i) ;
+ pic->append(new XFAPictureMonth(n));
+ } else if (c == 'D') {
+ for (n = 1; n < 2 && i < picEnd && picture->getChar(i) == 'D'; ++n, ++i) ;
+ pic->append(new XFAPictureDay(n));
+ } else if (c == 'h') {
+ for (n = 1; n < 2 && i < picEnd && picture->getChar(i) == 'h'; ++n, ++i) ;
+ pic->append(new XFAPictureHour(gFalse, n));
+ } else if (c == 'H') {
+ for (n = 1; n < 2 && i < picEnd && picture->getChar(i) == 'H'; ++n, ++i) ;
+ pic->append(new XFAPictureHour(gTrue, n));
+ } else if (c == 'M') {
+ for (n = 1; n < 2 && i < picEnd && picture->getChar(i) == 'M'; ++n, ++i) ;
+ pic->append(new XFAPictureMinute(n));
+ } else if (c == 'S') {
+ for (n = 1; n < 2 && i < picEnd && picture->getChar(i) == 'S'; ++n, ++i) ;
+ pic->append(new XFAPictureSecond(n));
+ }
+ }
+
+ //--- generate formatted text
+
+ ret = new GString();
+ for (i = 0; i < pic->getLength(); ++i) {
+ node = (XFAPictureNode *)pic->get(i);
+ if (node->isLiteral()) {
+ ret->append(((XFAPictureLiteral *)node)->s);
+ } else if (node->isYear()) {
+ if (((XFAPictureYear *)node)->nDigits == 2) {
+ if (year >= 1930 && year < 2030) {
+ ret->appendf("{0:02d}", year % 100);
+ } else {
+ ret->append("??");
+ }
+ } else {
+ ret->appendf("{0:04d}", year);
+ }
+ } else if (node->isMonth()) {
+ if (((XFAPictureMonth *)node)->nDigits == 1) {
+ ret->appendf("{0:d}", month);
+ } else {
+ ret->appendf("{0:02d}", month);
+ }
+ } else if (node->isDay()) {
+ if (((XFAPictureDay *)node)->nDigits == 1) {
+ ret->appendf("{0:d}", day);
+ } else {
+ ret->appendf("{0:02d}", day);
+ }
+ } else if (node->isHour()) {
+ if (((XFAPictureHour *)node)->is24Hour) {
+ n = hour;
+ } else {
+ n = hour % 12;
+ if (n == 0) {
+ n = 12;
+ }
+ }
+ if (((XFAPictureHour *)node)->nDigits == 1) {
+ ret->appendf("{0:d}", n);
+ } else {
+ ret->appendf("{0:02d}", n);
+ }
+ } else if (node->isMinute()) {
+ if (((XFAPictureMinute *)node)->nDigits == 1) {
+ ret->appendf("{0:d}", min);
+ } else {
+ ret->appendf("{0:02d}", min);
+ }
+ } else if (node->isSecond()) {
+ if (((XFAPictureSecond *)node)->nDigits == 1) {
+ ret->appendf("{0:d}", sec);
+ } else {
+ ret->appendf("{0:02d}", sec);
+ }
+ }
+ }
+ deleteGList(pic, XFAPictureNode);
+
+ return ret;
+}
+
+GString *XFAFormField::pictureFormatNumber(GString *value, GString *picture) {
+ GList *pic;
+ XFAPictureNode *node;
+ GString *ret, *s;
+ GBool neg, haveDigits;
+ char c;
+ int start, decPt, trailingZero, len;
+ int picStart, picEnd, u, pos, i, j;
+
+ len = value->getLength();
+ if (len == 0) {
+ return value->copy();
+ }
+
+ //--- parse the value
+
+ // -nnnn.nnnn0000
+ // ^ ^ ^ ^
+ // | | | +-- len
+ // | | +------ trailingZero
+ // | +----------- decPt
+ // +--------------- start
+ start = 0;
+ neg = gFalse;
+ if (value->getChar(start) == '-') {
+ neg = gTrue;
+ ++start;
+ } else if (value->getChar(start) == '+') {
+ ++start;
+ }
+ for (decPt = start; decPt < len && value->getChar(decPt) != '.'; ++decPt) ;
+ for (trailingZero = len;
+ trailingZero > decPt && value->getChar(trailingZero - 1) == '0';
+ --trailingZero) ;
+
+ //--- skip the category and locale in the picture
+
+ picStart = 0;
+ picEnd = picture->getLength();
+ for (i = 0; i < picture->getLength(); ++i) {
+ c = picture->getChar(i);
+ if (c == '{') {
+ picStart = i + 1;
+ for (picEnd = picStart;
+ picEnd < picture->getLength() && picture->getChar(picEnd) != '}';
+ ++picEnd) ;
+ break;
+ } else if (!((c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ c == '(' ||
+ c == ')')) {
+ break;
+ }
+ }
+
+ //--- parse the picture
+
+ pic = new GList();
+ i = picStart;
+ while (i < picEnd) {
+ c = picture->getChar(i);
+ ++i;
+ if (c == '\'') {
+ s = new GString();
+ while (i < picEnd) {
+ c = picture->getChar(i);
+ if (c == '\'') {
+ ++i;
+ if (i < picEnd && picture->getChar(i) == '\'') {
+ s->append('\'');
+ ++i;
+ } else {
+ break;
+ }
+ } else if (c == '\\') {
+ ++i;
+ if (i == picEnd) {
+ break;
+ }
+ c = picture->getChar(i);
+ ++i;
+ if (c == 'u' && i+4 <= picEnd) {
+ u = 0;
+ for (j = 0; j < 4; ++j, ++i) {
+ c = picture->getChar(i);
+ u <<= 4;
+ if (c >= '0' && c <= '9') {
+ u += c - '0';
+ } else if (c >= 'a' && c <= 'F') {
+ u += c - 'a' + 10;
+ } else if (c >= 'A' && c <= 'F') {
+ u += c - 'A' + 10;
+ }
+ }
+ //~ this should convert to UTF-8 (?)
+ if (u <= 0xff) {
+ s->append((char)u);
+ }
+ } else {
+ s->append(c);
+ }
+ } else {
+ s->append(c);
+ ++i;
+ }
+ }
+ pic->append(new XFAPictureLiteral(s));
+ } else if (c == '-' || c == ':' || c == '/' || c == ' ') {
+ s = new GString();
+ s->append(c);
+ pic->append(new XFAPictureLiteral(s));
+ } else if (c == 's' || c == 'S') {
+ pic->append(new XFAPictureSign(c));
+ } else if (c == 'Z' || c == 'z' || c == '8' || c == '9') {
+ pic->append(new XFAPictureDigit(c));
+ } else if (c == '.') {
+ pic->append(new XFAPictureDecPt());
+ } else if (c == ',') {
+ pic->append(new XFAPictureSeparator());
+ }
+ }
+ for (i = 0; i < pic->getLength(); ++i) {
+ node = (XFAPictureNode *)pic->get(i);
+ if (node->isDecPt()) {
+ break;
+ }
+ }
+ pos = 0;
+ for (j = i - 1; j >= 0; --j) {
+ node = (XFAPictureNode *)pic->get(j);
+ if (node->isDigit()) {
+ ((XFAPictureDigit *)node)->pos = pos;
+ ++pos;
+ }
+ }
+ pos = -1;
+ for (j = i + 1; j < pic->getLength(); ++j) {
+ node = (XFAPictureNode *)pic->get(j);
+ if (node->isDigit()) {
+ ((XFAPictureDigit *)node)->pos = pos;
+ --pos;
+ }
+ }
+
+ //--- generate formatted text
+
+ ret = new GString();
+ haveDigits = gFalse;
+ for (i = 0; i < pic->getLength(); ++i) {
+ node = (XFAPictureNode *)pic->get(i);
+ if (node->isLiteral()) {
+ ret->append(((XFAPictureLiteral *)node)->s);
+ } else if (node->isSign()) {
+ if (((XFAPictureSign *)node)->c == 'S') {
+ ret->append(neg ? '-' : ' ');
+ } else {
+ if (neg) {
+ ret->append('-');
+ }
+ }
+ } else if (node->isDigit()) {
+ pos = ((XFAPictureDigit *)node)->pos;
+ c = ((XFAPictureDigit *)node)->c;
+ if (pos >= 0 && pos < decPt - start) {
+ ret->append(value->getChar(decPt - 1 - pos));
+ haveDigits = gTrue;
+ } else if (pos < 0 && -pos <= trailingZero - decPt - 1) {
+ ret->append(value->getChar(decPt - pos));
+ haveDigits = gTrue;
+ } else if (c == '8' &&
+ pos < 0 &&
+ -pos <= len - decPt - 1) {
+ ret->append('0');
+ haveDigits = gTrue;
+ } else if (c == '9') {
+ ret->append('0');
+ haveDigits = gTrue;
+ } else if (c == 'Z' && pos >= 0) {
+ ret->append(' ');
+ }
+ } else if (node->isDecPt()) {
+ if (!(i+1 < pic->getLength() &&
+ ((XFAPictureNode *)pic->get(i+1))->isDigit() &&
+ ((XFAPictureDigit *)pic->get(i+1))->c == 'z') ||
+ trailingZero > decPt + 1) {
+ ret->append('.');
+ }
+ } else if (node->isSeparator()) {
+ if (haveDigits) {
+ ret->append(',');
+ }
+ }
+ }
+ deleteGList(pic, XFAPictureNode);
+
+ return ret;
+}
+
+GString *XFAFormField::pictureFormatText(GString *value, GString *picture) {
+ GList *pic;
+ XFAPictureNode *node;
+ GString *ret, *s;
+ char c;
+ int len, picStart, picEnd, u, i, j;
+
+ len = value->getLength();
+ if (len == 0) {
+ return value->copy();
+ }
+
+ //--- skip the category and locale in the picture
+
+ picStart = 0;
+ picEnd = picture->getLength();
+ for (i = 0; i < picture->getLength(); ++i) {
+ c = picture->getChar(i);
+ if (c == '{') {
+ picStart = i + 1;
+ for (picEnd = picStart;
+ picEnd < picture->getLength() && picture->getChar(picEnd) != '}';
+ ++picEnd) ;
+ break;
+ } else if (!((c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ c == '(' ||
+ c == ')')) {
+ break;
+ }
+ }
+
+ //--- parse the picture
+
+ pic = new GList();
+ i = picStart;
+ while (i < picEnd) {
+ c = picture->getChar(i);
+ ++i;
+ if (c == '\'') {
+ s = new GString();
+ while (i < picEnd) {
+ c = picture->getChar(i);
+ if (c == '\'') {
+ ++i;
+ if (i < picEnd && picture->getChar(i) == '\'') {
+ s->append('\'');
+ ++i;
+ } else {
+ break;
+ }
+ } else if (c == '\\') {
+ ++i;
+ if (i == picEnd) {
+ break;
+ }
+ c = picture->getChar(i);
+ ++i;
+ if (c == 'u' && i+4 <= picEnd) {
+ u = 0;
+ for (j = 0; j < 4; ++j, ++i) {
+ c = picture->getChar(i);
+ u <<= 4;
+ if (c >= '0' && c <= '9') {
+ u += c - '0';
+ } else if (c >= 'a' && c <= 'F') {
+ u += c - 'a' + 10;
+ } else if (c >= 'A' && c <= 'F') {
+ u += c - 'A' + 10;
+ }
+ }
+ //~ this should convert to UTF-8 (?)
+ if (u <= 0xff) {
+ s->append((char)u);
+ }
+ } else {
+ s->append(c);
+ }
+ } else {
+ s->append(c);
+ ++i;
+ }
+ }
+ pic->append(new XFAPictureLiteral(s));
+ } else if (c == ',' || c == '-' || c == ':' ||
+ c == '/' || c == '.' || c == ' ') {
+ s = new GString();
+ s->append(c);
+ pic->append(new XFAPictureLiteral(s));
+ } else if (c == 'A' || c == 'X' || c == 'O' || c == '0' || c == '9') {
+ pic->append(new XFAPictureChar());
+ }
+ }
+
+ //--- generate formatted text
+
+ ret = new GString();
+ j = 0;
+ for (i = 0; i < pic->getLength(); ++i) {
+ node = (XFAPictureNode *)pic->get(i);
+ if (node->isLiteral()) {
+ ret->append(((XFAPictureLiteral *)node)->s);
+ } else if (node->isChar()) {
+ // if there are more chars in the picture than in the value,
+ // Adobe renders the value as-is, without picture formatting
+ if (j >= value->getLength()) {
+ delete ret;
+ ret = value->copy();
+ break;
+ }
+ ret->append(value->getChar(j));
+ ++j;
+ }
+ }
+ deleteGList(pic, XFAPictureNode);
+
+ return ret;
+}
+
+GBool XFAFormField::isValidInt(GString *s, int start, int len) {
+ int i;
+
+ for (i = 0; i < len; ++i) {
+ if (!(start + i < s->getLength() &&
+ s->getChar(start + i) >= '0' &&
+ s->getChar(start + i) <= '9')) {
+ return gFalse;
+ }
+ }
+ return gTrue;
+}
+
+int XFAFormField::convertInt(GString *s, int start, int len) {
+ char c;
+ int x, i;
+
+ x = 0;
+ for (i = 0; i < len && start + i < s->getLength(); ++i) {
+ c = s->getChar(start + i);
+ if (c < '0' || c > '9') {
+ break;
+ }
+ x = x * 10 + (c - '0');
+ }
+ return x;
+}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h
index 95bf14cd4c8..31794730d40 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XFAForm.h
@@ -17,6 +17,8 @@
#include "Form.h"
+class GHash;
+class XFATableInfo;
class ZxDoc;
class ZxElement;
class ZxAttr;
@@ -40,7 +42,8 @@ enum XFAVertAlign {
class XFAForm: public Form {
public:
- static XFAForm *load(PDFDoc *docA, Object *acroFormObj, Object *xfaObj);
+ static XFAForm *load(PDFDoc *docA, Catalog *catalog,
+ Object *acroFormObj, Object *xfaObj);
virtual ~XFAForm();
@@ -53,14 +56,28 @@ public:
private:
- XFAForm(PDFDoc *docA, ZxDoc *xmlA, Object *resourceDictA, GBool fullXFAA);
- void scanFields(ZxElement *elem, GString *name, GString *dataName);
+ XFAForm(PDFDoc *docA, int nPagesA, ZxDoc *xmlA,
+ Object *resourceDictA, GBool fullXFAA);
+ void scanNamedNode(ZxElement *elem, GString *name, GString *fullName,
+ GBool inPageSet, XFATableInfo *tableInfo);
+ void scanNames(ZxElement *elem, GHash *nameCount);
+ void scanFields(ZxElement *elem, GString *parentName,
+ GString *parentFullName, GBool inPageSet,
+ XFATableInfo *tableInfo,
+ GHash *siblingNameCount, GHash *siblingNameIdx);
+ GString *getNodeName(ZxElement *elem);
+ GString *getNodeFullName(ZxElement *elem);
+ GBool nodeIsBindGlobal(ZxElement *elem);
ZxDoc *xml;
GList *fields; // [XFAFormField]
Object resourceDict;
GBool fullXFA; // true for "Full XFA", false for
// "XFA Foreground"
+ int nPages; // number of pages in PDF file
+ double *pageOffsetX, // x,y offset for each page
+ *pageOffsetY;
+ int pageSetNPages; // number of pages in pageSet element
int curPageNum; // current page number - used by scanFields()
double curXOffset, // current x,y offset - used by scanFields()
curYOffset;
@@ -73,15 +90,20 @@ private:
class XFAFormField: public FormField {
public:
- XFAFormField(XFAForm *xfaFormA, ZxElement *xmlA, GString *nameA,
- GString *dataNameA, int pageNumA,
- double xOffsetA, double yOffsetA);
+ XFAFormField(XFAForm *xfaFormA, ZxElement *xmlA,
+ GString *nameA, GString *fullNameA,
+ int pageNumA, double xOffsetA, double yOffsetA,
+ double columnWidthA, double rowHeightA);
virtual ~XFAFormField();
+ virtual int getPageNum();
virtual const char *getType();
virtual Unicode *getName(int *length);
virtual Unicode *getValue(int *length);
+ virtual void getBBox(double *llx, double *lly, double *urx, double *ury);
+ virtual void getFont(Ref *fontID, double *fontSize);
+ virtual void getColor(double *red, double *green, double *blue);
virtual Object *getResources(Object *res);
@@ -89,15 +111,25 @@ private:
Unicode *utf8ToUnicode(GString *s, int *length);
void draw(int pageNumA, Gfx *gfx, GBool printing, GfxFontDict *fontDict);
+ void getRectangle(double *xfaX, double *xfaY,
+ double *xfaW, double *xfaH,
+ double *pdfX, double *pdfY,
+ double *pdfW, double *pdfH,
+ int *pdfRot);
void drawTextEdit(GfxFontDict *fontDict,
double w, double h, int rot,
GString *appearBuf);
+ void drawCheckButton(GfxFontDict *fontDict,
+ double w, double h, int rot,
+ GString *appearBuf);
void drawBarCode(GfxFontDict *fontDict,
double w, double h, int rot,
GString *appearBuf);
static double getMeasurement(ZxAttr *attr, double defaultVal);
+ static double getMeasurement(GString *s, int begin);
GString *getFieldValue(const char *valueChildType);
- ZxElement *findFieldData(ZxElement *elem, char *partName);
+ ZxElement *findFieldInDatasets(ZxElement *elem, char *partName);
+ ZxElement *findFieldInFormElem(ZxElement *elem, char *partName);
void transform(int rot, double w, double h,
double *wNew, double *hNew, GString *appearBuf);
void drawText(GString *text, GBool multiLine, int combCells,
@@ -109,18 +141,29 @@ private:
GfxFontDict *fontDict, GString *appearBuf);
GfxFont *findFont(GfxFontDict *fontDict, GString *fontName,
GBool bold, GBool italic);
+ Ref findFontName(GString *name, GBool bold, GBool italic);
void getNextLine(GString *text, int start,
GfxFont *font, double fontSize, double wMax,
int *end, double *width, int *next);
+ GString *pictureFormatDateTime(GString *value, GString *picture);
+ GString *pictureFormatNumber(GString *value, GString *picture);
+ GString *pictureFormatText(GString *value, GString *picture);
+ GBool isValidInt(GString *s, int start, int len);
+ int convertInt(GString *s, int start, int len);
XFAForm *xfaForm;
ZxElement *xml;
GString *name;
- GString *dataName;
+ GString *fullName;
int pageNum;
double xOffset, yOffset;
+ double columnWidth; // column width, if this field is in a
+ // table; otherwise zero
+ double rowHeight; // row height, if this field is in a
+ // table; otherwise zero
friend class XFAForm;
+ friend class XFATableInfo;
};
#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFApp.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFApp.cc
deleted file mode 100644
index 4f5af03a826..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFApp.cc
+++ /dev/null
@@ -1,447 +0,0 @@
-//========================================================================
-//
-// XPDFApp.cc
-//
-// Copyright 2002-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-#include <aconf.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
-#include "GString.h"
-#include "GList.h"
-#include "Error.h"
-#include "XPDFViewer.h"
-#include "XPDFApp.h"
-#include "config.h"
-
-// these macro defns conflict with xpdf's Object class
-#ifdef LESSTIF_VERSION
-#undef XtDisplay
-#undef XtScreen
-#undef XtWindow
-#undef XtParent
-#undef XtIsRealized
-#endif
-
-//------------------------------------------------------------------------
-
-#define remoteCmdSize 512
-
-//------------------------------------------------------------------------
-
-static String fallbackResources[] = {
- "*.zoomComboBox*fontList: -*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1",
- "*XmTextField.fontList: -*-courier-medium-r-normal--12-*-*-*-*-*-iso8859-1",
- "*.fontList: -*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1",
- "*XmTextField.translations: #override\\n"
- " Ctrl<Key>a:beginning-of-line()\\n"
- " Ctrl<Key>b:backward-character()\\n"
- " Ctrl<Key>d:delete-next-character()\\n"
- " Ctrl<Key>e:end-of-line()\\n"
- " Ctrl<Key>f:forward-character()\\n"
- " Ctrl<Key>u:beginning-of-line()delete-to-end-of-line()\\n"
- " Ctrl<Key>k:delete-to-end-of-line()\\n",
- "*.toolTipEnable: True",
- "*.toolTipPostDelay: 1500",
- "*.toolTipPostDuration: 0",
- "*.TipLabel.foreground: black",
- "*.TipLabel.background: LightYellow",
- "*.TipShell.borderWidth: 1",
- "*.TipShell.borderColor: black",
- NULL
-};
-
-static XrmOptionDescRec xOpts[] = {
- {"-display", ".display", XrmoptionSepArg, NULL},
- {"-foreground", "*Foreground", XrmoptionSepArg, NULL},
- {"-fg", "*Foreground", XrmoptionSepArg, NULL},
- {"-background", "*Background", XrmoptionSepArg, NULL},
- {"-bg", "*Background", XrmoptionSepArg, NULL},
- {"-geometry", ".geometry", XrmoptionSepArg, NULL},
- {"-g", ".geometry", XrmoptionSepArg, NULL},
- {"-font", "*.fontList", XrmoptionSepArg, NULL},
- {"-fn", "*.fontList", XrmoptionSepArg, NULL},
- {"-title", ".title", XrmoptionSepArg, NULL},
- {"-cmap", ".installCmap", XrmoptionNoArg, (XPointer)"on"},
- {"-rgb", ".rgbCubeSize", XrmoptionSepArg, NULL},
- {"-rv", ".reverseVideo", XrmoptionNoArg, (XPointer)"true"},
- {"-papercolor", ".paperColor", XrmoptionSepArg, NULL},
- {"-mattecolor", ".matteColor", XrmoptionSepArg, NULL},
- {"-z", ".initialZoom", XrmoptionSepArg, NULL}
-};
-
-#define nXOpts (sizeof(xOpts) / sizeof(XrmOptionDescRec))
-
-struct XPDFAppResources {
- String geometry;
- String title;
- Bool installCmap;
- int rgbCubeSize;
- Bool reverseVideo;
- String paperColor;
- String matteColor;
- String fullScreenMatteColor;
- String initialZoom;
-};
-
-static Bool defInstallCmap = False;
-static int defRGBCubeSize = defaultRGBCube;
-static Bool defReverseVideo = False;
-
-static XtResource xResources[] = {
- { "geometry", "Geometry", XtRString, sizeof(String), XtOffsetOf(XPDFAppResources, geometry), XtRString, (XtPointer)NULL },
- { "title", "Title", XtRString, sizeof(String), XtOffsetOf(XPDFAppResources, title), XtRString, (XtPointer)NULL },
- { "installCmap", "InstallCmap", XtRBool, sizeof(Bool), XtOffsetOf(XPDFAppResources, installCmap), XtRBool, (XtPointer)&defInstallCmap },
- { "rgbCubeSize", "RgbCubeSize", XtRInt, sizeof(int), XtOffsetOf(XPDFAppResources, rgbCubeSize), XtRInt, (XtPointer)&defRGBCubeSize },
- { "reverseVideo", "ReverseVideo", XtRBool, sizeof(Bool), XtOffsetOf(XPDFAppResources, reverseVideo), XtRBool, (XtPointer)&defReverseVideo },
- { "paperColor", "PaperColor", XtRString, sizeof(String), XtOffsetOf(XPDFAppResources, paperColor), XtRString, (XtPointer)NULL },
- { "matteColor", "MatteColor", XtRString, sizeof(String), XtOffsetOf(XPDFAppResources, matteColor), XtRString, (XtPointer)"gray50" },
- { "fullScreenMatteColor", "FullScreenMatteColor", XtRString, sizeof(String), XtOffsetOf(XPDFAppResources, fullScreenMatteColor), XtRString, (XtPointer)"black" },
- { "initialZoom", "InitialZoom", XtRString, sizeof(String), XtOffsetOf(XPDFAppResources, initialZoom), XtRString, (XtPointer)NULL }
-};
-
-#define nXResources (sizeof(xResources) / sizeof(XtResource))
-
-//------------------------------------------------------------------------
-// XPDFApp
-//------------------------------------------------------------------------
-
-#if 0 //~ for debugging
-static int xErrorHandler(Display *display, XErrorEvent *ev) {
- printf("X error:\n");
- printf(" resource ID = %08lx\n", ev->resourceid);
- printf(" serial = %lu\n", ev->serial);
- printf(" error_code = %d\n", ev->error_code);
- printf(" request_code = %d\n", ev->request_code);
- printf(" minor_code = %d\n", ev->minor_code);
- fflush(stdout);
- abort();
-}
-#endif
-
-XPDFApp::XPDFApp(int *argc, char *argv[]) {
- appShell = XtAppInitialize(&appContext, xpdfAppName, xOpts, nXOpts,
- argc, argv, fallbackResources, NULL, 0);
- display = XtDisplay(appShell);
- screenNum = XScreenNumberOfScreen(XtScreen(appShell));
-#if XmVERSION > 1
- XtVaSetValues(XmGetXmDisplay(XtDisplay(appShell)),
- XmNenableButtonTab, True, NULL);
-#endif
-#if XmVERSION > 1
- // Drag-and-drop appears to be buggy -- I'm seeing weird crashes
- // deep in the Motif code when I destroy widgets in the XpdfForms
- // code. Xpdf doesn't use it, so just turn it off.
- XtVaSetValues(XmGetXmDisplay(XtDisplay(appShell)),
- XmNdragInitiatorProtocolStyle, XmDRAG_NONE,
- XmNdragReceiverProtocolStyle, XmDRAG_NONE,
- NULL);
-#endif
-
-#if 0 //~ for debugging
- XSynchronize(display, True);
- XSetErrorHandler(&xErrorHandler);
-#endif
-
- fullScreen = gFalse;
- remoteAtom = None;
- remoteViewer = NULL;
- remoteWin = None;
-
- getResources();
-
- viewers = new GList();
-}
-
-void XPDFApp::getResources() {
- XPDFAppResources resources;
- XColor xcol, xcol2;
- Colormap colormap;
-
- XtGetApplicationResources(appShell, &resources, xResources, nXResources,
- NULL, 0);
- geometry = resources.geometry ? new GString(resources.geometry)
- : (GString *)NULL;
- title = resources.title ? new GString(resources.title) : (GString *)NULL;
- installCmap = (GBool)resources.installCmap;
- rgbCubeSize = resources.rgbCubeSize;
- reverseVideo = (GBool)resources.reverseVideo;
- if (reverseVideo) {
- paperRGB[0] = paperRGB[1] = paperRGB[2] = 0;
- paperPixel = BlackPixel(display, screenNum);
- } else {
- paperRGB[0] = paperRGB[1] = paperRGB[2] = 0xff;
- paperPixel = WhitePixel(display, screenNum);
- }
- XtVaGetValues(appShell, XmNcolormap, &colormap, NULL);
- if (resources.paperColor) {
- if (XAllocNamedColor(display, colormap, resources.paperColor,
- &xcol, &xcol2)) {
- paperRGB[0] = xcol.red >> 8;
- paperRGB[1] = xcol.green >> 8;
- paperRGB[2] = xcol.blue >> 8;
- paperPixel = xcol.pixel;
- } else {
- error(errIO, -1, "Couldn't allocate color '{0:s}'",
- resources.paperColor);
- }
- }
- if (XAllocNamedColor(display, colormap, resources.matteColor,
- &xcol, &xcol2)) {
- mattePixel = xcol.pixel;
- } else {
- mattePixel = paperPixel;
- }
- if (XAllocNamedColor(display, colormap, resources.fullScreenMatteColor,
- &xcol, &xcol2)) {
- fullScreenMattePixel = xcol.pixel;
- } else {
- fullScreenMattePixel = paperPixel;
- }
- initialZoom = resources.initialZoom ? new GString(resources.initialZoom)
- : (GString *)NULL;
-}
-
-XPDFApp::~XPDFApp() {
- deleteGList(viewers, XPDFViewer);
- if (geometry) {
- delete geometry;
- }
- if (title) {
- delete title;
- }
- if (initialZoom) {
- delete initialZoom;
- }
-}
-
-XPDFViewer *XPDFApp::open(GString *fileName, int page,
- GString *ownerPassword, GString *userPassword) {
- XPDFViewer *viewer;
-
- viewer = new XPDFViewer(this, fileName, page, NULL, fullScreen,
- ownerPassword, userPassword);
- if (!viewer->isOk()) {
- delete viewer;
- return NULL;
- }
- if (remoteAtom != None) {
- remoteViewer = viewer;
- remoteWin = viewer->getWindow();
- XtAddEventHandler(remoteWin, PropertyChangeMask, False,
- &remoteMsgCbk, this);
- XSetSelectionOwner(display, remoteAtom, XtWindow(remoteWin), CurrentTime);
- }
- viewers->append(viewer);
- return viewer;
-}
-
-XPDFViewer *XPDFApp::openAtDest(GString *fileName, GString *dest,
- GString *ownerPassword,
- GString *userPassword) {
- XPDFViewer *viewer;
-
- viewer = new XPDFViewer(this, fileName, 1, dest, fullScreen,
- ownerPassword, userPassword);
- if (!viewer->isOk()) {
- delete viewer;
- return NULL;
- }
- if (remoteAtom != None) {
- remoteViewer = viewer;
- remoteWin = viewer->getWindow();
- XtAddEventHandler(remoteWin, PropertyChangeMask, False,
- &remoteMsgCbk, this);
- XSetSelectionOwner(display, remoteAtom, XtWindow(remoteWin), CurrentTime);
- }
- viewers->append(viewer);
- return viewer;
-}
-
-XPDFViewer *XPDFApp::reopen(XPDFViewer *viewer, PDFDoc *doc, int page,
- GBool fullScreenA) {
- int i;
-
- for (i = 0; i < viewers->getLength(); ++i) {
- if (((XPDFViewer *)viewers->get(i)) == viewer) {
- viewers->del(i);
- delete viewer;
- }
- }
- viewer = new XPDFViewer(this, doc, page, NULL, fullScreenA);
- if (!viewer->isOk()) {
- delete viewer;
- return NULL;
- }
- if (remoteAtom != None) {
- remoteViewer = viewer;
- remoteWin = viewer->getWindow();
- XtAddEventHandler(remoteWin, PropertyChangeMask, False,
- &remoteMsgCbk, this);
- XSetSelectionOwner(display, remoteAtom, XtWindow(remoteWin), CurrentTime);
- }
- viewers->append(viewer);
- return viewer;
-}
-
-void XPDFApp::close(XPDFViewer *viewer, GBool closeLast) {
- int i;
-
- if (viewers->getLength() == 1) {
- if (viewer != (XPDFViewer *)viewers->get(0)) {
- return;
- }
- if (closeLast) {
- quit();
- } else {
- viewer->clear();
- }
- } else {
- for (i = 0; i < viewers->getLength(); ++i) {
- if (((XPDFViewer *)viewers->get(i)) == viewer) {
- viewers->del(i);
- if (remoteAtom != None && remoteViewer == viewer) {
- remoteViewer = (XPDFViewer *)viewers->get(viewers->getLength() - 1);
- remoteWin = remoteViewer->getWindow();
- XSetSelectionOwner(display, remoteAtom, XtWindow(remoteWin),
- CurrentTime);
- }
- delete viewer;
- return;
- }
- }
- }
-}
-
-void XPDFApp::quit() {
- if (remoteAtom != None) {
- XSetSelectionOwner(display, remoteAtom, None, CurrentTime);
- }
- while (viewers->getLength() > 0) {
- delete (XPDFViewer *)viewers->del(0);
- }
-#if HAVE_XTAPPSETEXITFLAG
- XtAppSetExitFlag(appContext);
-#else
- exit(0);
-#endif
-}
-
-void XPDFApp::run() {
- XtAppMainLoop(appContext);
-}
-
-void XPDFApp::setRemoteName(char *remoteName) {
- remoteAtom = XInternAtom(display, remoteName, False);
- remoteXWin = XGetSelectionOwner(display, remoteAtom);
-}
-
-GBool XPDFApp::remoteServerRunning() {
- return remoteXWin != None;
-}
-
-void XPDFApp::remoteExec(char *cmd) {
- char cmd2[remoteCmdSize];
- int n;
-
- n = strlen(cmd);
- if (n > remoteCmdSize - 2) {
- n = remoteCmdSize - 2;
- }
- memcpy(cmd2, cmd, n);
- cmd2[n] = '\n';
- cmd2[n+1] = '\0';
- XChangeProperty(display, remoteXWin, remoteAtom, remoteAtom, 8,
- PropModeReplace, (Guchar *)cmd2, n + 2);
- XFlush(display);
-}
-
-void XPDFApp::remoteOpen(GString *fileName, int page, GBool raise) {
- char cmd[remoteCmdSize];
-
- sprintf(cmd, "openFileAtPage(%.200s,%d)\n",
- fileName->getCString(), page);
- if (raise) {
- strcat(cmd, "raise\n");
- }
- XChangeProperty(display, remoteXWin, remoteAtom, remoteAtom, 8,
- PropModeReplace, (Guchar *)cmd, strlen(cmd) + 1);
- XFlush(display);
-}
-
-void XPDFApp::remoteOpenAtDest(GString *fileName, GString *dest, GBool raise) {
- char cmd[remoteCmdSize];
-
- sprintf(cmd, "openFileAtDest(%.200s,%.256s)\n",
- fileName->getCString(), dest->getCString());
- if (raise) {
- strcat(cmd, "raise\n");
- }
- XChangeProperty(display, remoteXWin, remoteAtom, remoteAtom, 8,
- PropModeReplace, (Guchar *)cmd, strlen(cmd) + 1);
- XFlush(display);
-}
-
-void XPDFApp::remoteReload(GBool raise) {
- char cmd[remoteCmdSize];
-
- strcpy(cmd, "reload\n");
- if (raise) {
- strcat(cmd, "raise\n");
- }
- XChangeProperty(display, remoteXWin, remoteAtom, remoteAtom, 8,
- PropModeReplace, (Guchar *)cmd, strlen(cmd) + 1);
- XFlush(display);
-}
-
-void XPDFApp::remoteRaise() {
- XChangeProperty(display, remoteXWin, remoteAtom, remoteAtom, 8,
- PropModeReplace, (Guchar *)"raise\n", 7);
- XFlush(display);
-}
-
-void XPDFApp::remoteQuit() {
- XChangeProperty(display, remoteXWin, remoteAtom, remoteAtom, 8,
- PropModeReplace, (Guchar *)"quit\n", 6);
- XFlush(display);
-}
-
-void XPDFApp::remoteMsgCbk(Widget widget, XtPointer ptr,
- XEvent *event, Boolean *cont) {
- XPDFApp *app = (XPDFApp *)ptr;
- char *cmd, *p0, *p1;
- Atom type;
- int format;
- Gulong size, remain;
- GString *cmdStr;
-
- if (event->xproperty.atom != app->remoteAtom) {
- *cont = True;
- return;
- }
- *cont = False;
-
- if (XGetWindowProperty(app->display, XtWindow(app->remoteWin),
- app->remoteAtom, 0, remoteCmdSize/4,
- True, app->remoteAtom,
- &type, &format, &size, &remain,
- (Guchar **)&cmd) != Success) {
- return;
- }
- if (!cmd) {
- return;
- }
- p0 = cmd;
- while (*p0 && (p1 = strchr(p0, '\n'))) {
- cmdStr = new GString(p0, p1 - p0);
- app->remoteViewer->execCmd(cmdStr, NULL);
- delete cmdStr;
- p0 = p1 + 1;
- }
- XFree((XPointer)cmd);
-}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFApp.h b/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFApp.h
deleted file mode 100644
index 9d4060ac97a..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFApp.h
+++ /dev/null
@@ -1,114 +0,0 @@
-//========================================================================
-//
-// XPDFApp.h
-//
-// Copyright 2002-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-#ifndef XPDFAPP_H
-#define XPDFAPP_H
-
-#include <aconf.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
-#define Object XtObject
-#include <Xm/XmAll.h>
-#undef Object
-#include "gtypes.h"
-#include "SplashTypes.h"
-
-class GString;
-class GList;
-class PDFDoc;
-class XPDFViewer;
-
-//------------------------------------------------------------------------
-
-#define xpdfAppName "Xpdf"
-
-//------------------------------------------------------------------------
-// XPDFApp
-//------------------------------------------------------------------------
-
-class XPDFApp {
-public:
-
- XPDFApp(int *argc, char *argv[]);
- ~XPDFApp();
-
- XPDFViewer *open(GString *fileName, int page = 1,
- GString *ownerPassword = NULL,
- GString *userPassword = NULL);
- XPDFViewer *openAtDest(GString *fileName, GString *dest,
- GString *ownerPassword = NULL,
- GString *userPassword = NULL);
- XPDFViewer *reopen(XPDFViewer *viewer, PDFDoc *doc, int page,
- GBool fullScreenA);
- void close(XPDFViewer *viewer, GBool closeLast);
- void quit();
-
- void run();
-
- //----- remote server
- void setRemoteName(char *remoteName);
- GBool remoteServerRunning();
- void remoteExec(char *cmd);
- void remoteOpen(GString *fileName, int page, GBool raise);
- void remoteOpenAtDest(GString *fileName, GString *dest, GBool raise);
- void remoteReload(GBool raise);
- void remoteRaise();
- void remoteQuit();
-
- //----- resource/option values
- GString *getGeometry() { return geometry; }
- GString *getTitle() { return title; }
- GBool getInstallCmap() { return installCmap; }
- int getRGBCubeSize() { return rgbCubeSize; }
- GBool getReverseVideo() { return reverseVideo; }
- SplashColorPtr getPaperRGB() { return paperRGB; }
- Gulong getPaperPixel() { return paperPixel; }
- Gulong getMattePixel(GBool fullScreenA)
- { return fullScreenA ? fullScreenMattePixel : mattePixel; }
- GString *getInitialZoom() { return initialZoom; }
- void setFullScreen(GBool fullScreenA) { fullScreen = fullScreenA; }
- GBool getFullScreen() { return fullScreen; }
-
- XtAppContext getAppContext() { return appContext; }
- Widget getAppShell() { return appShell; }
-
-private:
-
- void getResources();
- static void remoteMsgCbk(Widget widget, XtPointer ptr,
- XEvent *event, Boolean *cont);
-
- Display *display;
- int screenNum;
- XtAppContext appContext;
- Widget appShell;
- GList *viewers; // [XPDFViewer]
-
- Atom remoteAtom;
- Window remoteXWin;
- XPDFViewer *remoteViewer;
- Widget remoteWin;
-
- //----- resource/option values
- GString *geometry;
- GString *title;
- GBool installCmap;
- int rgbCubeSize;
- GBool reverseVideo;
- SplashColor paperRGB;
- Gulong paperPixel;
- Gulong mattePixel;
- Gulong fullScreenMattePixel;
- GString *initialZoom;
- GBool fullScreen;
-};
-
-#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.cc
deleted file mode 100644
index 9a3725f53fc..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.cc
+++ /dev/null
@@ -1,1680 +0,0 @@
-//========================================================================
-//
-// XPDFCore.cc
-//
-// Copyright 2002-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-#include <aconf.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
-#include <X11/keysym.h>
-#include <X11/cursorfont.h>
-#include <string.h>
-#include "gmem.h"
-#include "GString.h"
-#include "GList.h"
-#include "Error.h"
-#include "GlobalParams.h"
-#include "PDFDoc.h"
-#include "Link.h"
-#include "ErrorCodes.h"
-#include "GfxState.h"
-#include "CoreOutputDev.h"
-#include "PSOutputDev.h"
-#include "TextOutputDev.h"
-#include "SplashBitmap.h"
-#include "SplashPattern.h"
-#include "XPDFApp.h"
-#include "XPDFCore.h"
-
-// these macro defns conflict with xpdf's Object class
-#ifdef LESSTIF_VERSION
-#undef XtDisplay
-#undef XtScreen
-#undef XtWindow
-#undef XtParent
-#undef XtIsRealized
-#endif
-
-//------------------------------------------------------------------------
-
-// Divide a 16-bit value (in [0, 255*255]) by 255, returning an 8-bit result.
-static inline Guchar div255(int x) {
- return (Guchar)((x + (x >> 8) + 0x80) >> 8);
-}
-
-//------------------------------------------------------------------------
-
-GString *XPDFCore::currentSelection = NULL;
-XPDFCore *XPDFCore::currentSelectionOwner = NULL;
-Atom XPDFCore::targetsAtom;
-
-//------------------------------------------------------------------------
-// XPDFCoreTile
-//------------------------------------------------------------------------
-
-class XPDFCoreTile: public PDFCoreTile {
-public:
- XPDFCoreTile(int xDestA, int yDestA);
- virtual ~XPDFCoreTile();
- XImage *image;
-};
-
-XPDFCoreTile::XPDFCoreTile(int xDestA, int yDestA):
- PDFCoreTile(xDestA, yDestA)
-{
- image = NULL;
-}
-
-XPDFCoreTile::~XPDFCoreTile() {
- if (image) {
- gfree(image->data);
- image->data = NULL;
- XDestroyImage(image);
- }
-}
-
-//------------------------------------------------------------------------
-// XPDFCore
-//------------------------------------------------------------------------
-
-XPDFCore::XPDFCore(Widget shellA, Widget parentWidgetA,
- SplashColorPtr paperColorA, Gulong paperPixelA,
- Gulong mattePixelA, GBool fullScreenA, GBool reverseVideoA,
- GBool installCmap, int rgbCubeSizeA):
- PDFCore(splashModeRGB8, 4, reverseVideoA, paperColorA, !fullScreenA)
-{
- GString *initialZoom;
-
- shell = shellA;
- parentWidget = parentWidgetA;
- display = XtDisplay(parentWidget);
- screenNum = XScreenNumberOfScreen(XtScreen(parentWidget));
- targetsAtom = XInternAtom(display, "TARGETS", False);
-
- paperPixel = paperPixelA;
- mattePixel = mattePixelA;
- fullScreen = fullScreenA;
-
- setupX(installCmap, rgbCubeSizeA);
-
- scrolledWin = NULL;
- hScrollBar = NULL;
- vScrollBar = NULL;
- drawAreaFrame = NULL;
- drawArea = NULL;
-
- // get the initial zoom value
- if (fullScreen) {
- zoom = zoomPage;
- } else {
- initialZoom = globalParams->getInitialZoom();
- if (!initialZoom->cmp("page")) {
- zoom = zoomPage;
- } else if (!initialZoom->cmp("width")) {
- zoom = zoomWidth;
- } else {
- zoom = atoi(initialZoom->getCString());
- if (zoom <= 0) {
- zoom = defZoom;
- }
- }
- delete initialZoom;
- }
-
- linkAction = NULL;
-
- panning = gFalse;
-
- updateCbk = NULL;
- actionCbk = NULL;
- keyPressCbk = NULL;
- mouseCbk = NULL;
-
- // optional features default to on
- hyperlinksEnabled = gTrue;
- selectEnabled = gTrue;
-
- // do X-specific initialization and create the widgets
- initWindow();
- initPasswordDialog();
-}
-
-XPDFCore::~XPDFCore() {
- if (currentSelectionOwner == this && currentSelection) {
- delete currentSelection;
- currentSelection = NULL;
- currentSelectionOwner = NULL;
- }
- if (drawAreaGC) {
- XFreeGC(display, drawAreaGC);
- }
- if (scrolledWin) {
- XtDestroyWidget(scrolledWin);
- }
- if (busyCursor) {
- XFreeCursor(display, busyCursor);
- }
- if (linkCursor) {
- XFreeCursor(display, linkCursor);
- }
- if (selectCursor) {
- XFreeCursor(display, selectCursor);
- }
-}
-
-//------------------------------------------------------------------------
-// loadFile / displayPage / displayDest
-//------------------------------------------------------------------------
-
-int XPDFCore::loadFile(GString *fileName, GString *ownerPassword,
- GString *userPassword) {
- int err;
-
- err = PDFCore::loadFile(fileName, ownerPassword, userPassword);
- if (err == errNone) {
- // save the modification time
- modTime = getModTime(doc->getFileName()->getCString());
-
- // update the parent window
- if (updateCbk) {
- (*updateCbk)(updateCbkData, doc->getFileName(), -1,
- doc->getNumPages(), NULL);
- }
- }
- return err;
-}
-
-int XPDFCore::loadFile(BaseStream *stream, GString *ownerPassword,
- GString *userPassword) {
- int err;
-
- err = PDFCore::loadFile(stream, ownerPassword, userPassword);
- if (err == errNone) {
- // no file
- modTime = 0;
-
- // update the parent window
- if (updateCbk) {
- (*updateCbk)(updateCbkData, doc->getFileName(), -1,
- doc->getNumPages(), NULL);
- }
- }
- return err;
-}
-
-void XPDFCore::loadDoc(PDFDoc *docA) {
- PDFCore::loadDoc(docA);
-
- // save the modification time
- if (doc->getFileName()) {
- modTime = getModTime(doc->getFileName()->getCString());
- }
-
- // update the parent window
- if (updateCbk) {
- (*updateCbk)(updateCbkData, doc->getFileName(), -1,
- doc->getNumPages(), NULL);
- }
-}
-
-void XPDFCore::resizeToPage(int pg) {
- Dimension width, height;
- double width1, height1;
- Dimension topW, topH, topBorder, daW, daH;
- Dimension displayW, displayH;
-
- displayW = DisplayWidth(display, screenNum);
- displayH = DisplayHeight(display, screenNum);
- if (fullScreen) {
- width = displayW;
- height = displayH;
- } else {
- if (!doc || pg <= 0 || pg > doc->getNumPages()) {
- width1 = 612;
- height1 = 792;
- } else if (doc->getPageRotate(pg) == 90 ||
- doc->getPageRotate(pg) == 270) {
- width1 = doc->getPageCropHeight(pg);
- height1 = doc->getPageCropWidth(pg);
- } else {
- width1 = doc->getPageCropWidth(pg);
- height1 = doc->getPageCropHeight(pg);
- }
- if (zoom == zoomPage || zoom == zoomWidth) {
- width = (Dimension)(width1 * 0.01 * defZoom + 0.5);
- height = (Dimension)(height1 * 0.01 * defZoom + 0.5);
- } else {
- width = (Dimension)(width1 * 0.01 * zoom + 0.5);
- height = (Dimension)(height1 * 0.01 * zoom + 0.5);
- }
- if (continuousMode) {
- height += continuousModePageSpacing;
- }
- if (width > displayW - 100) {
- width = displayW - 100;
- }
- if (height > displayH - 100) {
- height = displayH - 100;
- }
- }
-
- if (XtIsRealized(shell)) {
- XtVaGetValues(shell, XmNwidth, &topW, XmNheight, &topH,
- XmNborderWidth, &topBorder, NULL);
- XtVaGetValues(drawArea, XmNwidth, &daW, XmNheight, &daH, NULL);
- XtVaSetValues(shell, XmNwidth, width + (topW - daW),
- XmNheight, height + (topH - daH), NULL);
- } else {
- XtVaSetValues(drawArea, XmNwidth, width, XmNheight, height, NULL);
- }
-}
-
-void XPDFCore::update(int topPageA, int scrollXA, int scrollYA,
- double zoomA, int rotateA, GBool force,
- GBool addToHist, GBool adjustScrollX) {
- int oldPage;
-
- oldPage = topPage;
- PDFCore::update(topPageA, scrollXA, scrollYA, zoomA, rotateA,
- force, addToHist, adjustScrollX);
- linkAction = NULL;
- if (doc && topPage != oldPage) {
- if (updateCbk) {
- (*updateCbk)(updateCbkData, NULL, topPage, -1, "");
- }
- }
-}
-
-GBool XPDFCore::checkForNewFile() {
- time_t newModTime;
-
- if (doc->getFileName()) {
- newModTime = getModTime(doc->getFileName()->getCString());
- if (newModTime != modTime) {
- modTime = newModTime;
- return gTrue;
- }
- }
- return gFalse;
-}
-
-//------------------------------------------------------------------------
-// page/position changes
-//------------------------------------------------------------------------
-
-GBool XPDFCore::gotoNextPage(int inc, GBool top) {
- if (!PDFCore::gotoNextPage(inc, top)) {
- XBell(display, 0);
- return gFalse;
- }
- return gTrue;
-}
-
-GBool XPDFCore::gotoPrevPage(int dec, GBool top, GBool bottom) {
- if (!PDFCore::gotoPrevPage(dec, top, bottom)) {
- XBell(display, 0);
- return gFalse;
- }
- return gTrue;
-}
-
-GBool XPDFCore::goForward() {
- if (!PDFCore::goForward()) {
- XBell(display, 0);
- return gFalse;
- }
- return gTrue;
-}
-
-GBool XPDFCore::goBackward() {
- if (!PDFCore::goBackward()) {
- XBell(display, 0);
- return gFalse;
- }
- return gTrue;
-}
-
-void XPDFCore::startPan(int wx, int wy) {
- panning = gTrue;
- panMX = wx;
- panMY = wy;
-}
-
-void XPDFCore::endPan(int wx, int wy) {
- panning = gFalse;
-}
-
-//------------------------------------------------------------------------
-// selection
-//------------------------------------------------------------------------
-
-void XPDFCore::startSelection(int wx, int wy) {
- int pg, x, y;
-
- takeFocus();
- if (doc && doc->getNumPages() > 0) {
- if (selectEnabled) {
- if (cvtWindowToDev(wx, wy, &pg, &x, &y)) {
- setSelection(pg, x, y, x, y);
- setCursor(selectCursor);
- dragging = gTrue;
- }
- }
- }
-}
-
-void XPDFCore::endSelection(int wx, int wy) {
- int pg, x, y;
- GBool ok;
-
- if (doc && doc->getNumPages() > 0) {
- ok = cvtWindowToDev(wx, wy, &pg, &x, &y);
- if (dragging) {
- dragging = gFalse;
- setCursor(None);
- if (ok) {
- moveSelection(pg, x, y);
- }
-#ifndef NO_TEXT_SELECT
- if (selectULX != selectLRX &&
- selectULY != selectLRY) {
- if (doc->okToCopy()) {
- copySelection();
- } else {
- error(errNotAllowed, -1,
- "Copying of text from this document is not allowed.");
- }
- }
-#endif
- }
- }
-}
-
-// X's copy-and-paste mechanism is brain damaged. Xt doesn't help
-// any, but doesn't make it too much worse, either. Motif, on the
-// other hand, adds significant complexity to the mess. So here we
-// blow off the Motif junk and stick to plain old Xt. The next two
-// functions (copySelection and convertSelectionCbk) implement the
-// magic needed to deal with Xt's mechanism. Note that this requires
-// global variables (currentSelection and currentSelectionOwner).
-
-void XPDFCore::copySelection() {
- int pg;
- double ulx, uly, lrx, lry;
-
- if (!doc->okToCopy()) {
- return;
- }
- if (getSelection(&pg, &ulx, &uly, &lrx, &lry)) {
- //~ for multithreading: need a mutex here
- if (currentSelection) {
- delete currentSelection;
- }
- currentSelection = extractText(pg, ulx, uly, lrx, lry);
- currentSelectionOwner = this;
- XtOwnSelection(drawArea, XA_PRIMARY, XtLastTimestampProcessed(display),
- &convertSelectionCbk, NULL, NULL);
- }
-}
-
-Boolean XPDFCore::convertSelectionCbk(Widget widget, Atom *selection,
- Atom *target, Atom *type,
- XtPointer *value, unsigned long *length,
- int *format) {
- Atom *array;
-
- // send back a list of supported conversion targets
- if (*target == targetsAtom) {
- if (!(array = (Atom *)XtMalloc(sizeof(Atom)))) {
- return False;
- }
- array[0] = XA_STRING;
- *value = (XtPointer)array;
- *type = XA_ATOM;
- *format = 32;
- *length = 1;
- return True;
-
- // send the selected text
- } else if (*target == XA_STRING) {
- //~ for multithreading: need a mutex here
- *value = XtNewString(currentSelection->getCString());
- *length = currentSelection->getLength();
- *type = XA_STRING;
- *format = 8; // 8-bit elements
- return True;
- }
-
- return False;
-}
-
-//------------------------------------------------------------------------
-// hyperlinks
-//------------------------------------------------------------------------
-
-void XPDFCore::doAction(LinkAction *action) {
- LinkActionKind kind;
- LinkDest *dest;
- GString *namedDest;
- char *s;
- GString *fileName, *fileName2;
- GString *cmd;
- GString *actionName;
- Object movieAnnot, obj1, obj2;
- GString *msg;
- int i;
-
- switch (kind = action->getKind()) {
-
- // GoTo / GoToR action
- case actionGoTo:
- case actionGoToR:
- if (kind == actionGoTo) {
- dest = NULL;
- namedDest = NULL;
- if ((dest = ((LinkGoTo *)action)->getDest())) {
- dest = dest->copy();
- } else if ((namedDest = ((LinkGoTo *)action)->getNamedDest())) {
- namedDest = namedDest->copy();
- }
- } else {
- dest = NULL;
- namedDest = NULL;
- if ((dest = ((LinkGoToR *)action)->getDest())) {
- dest = dest->copy();
- } else if ((namedDest = ((LinkGoToR *)action)->getNamedDest())) {
- namedDest = namedDest->copy();
- }
- s = ((LinkGoToR *)action)->getFileName()->getCString();
- //~ translate path name for VMS (deal with '/')
- if (isAbsolutePath(s) || !doc->getFileName()) {
- fileName = new GString(s);
- } else {
- fileName = appendToPath(grabPath(doc->getFileName()->getCString()), s);
- }
- if (loadFile(fileName) != errNone) {
- if (dest) {
- delete dest;
- }
- if (namedDest) {
- delete namedDest;
- }
- delete fileName;
- return;
- }
- delete fileName;
- }
- if (namedDest) {
- dest = doc->findDest(namedDest);
- delete namedDest;
- }
- if (dest) {
- displayDest(dest, zoom, rotate, gTrue);
- delete dest;
- } else {
- if (kind == actionGoToR) {
- displayPage(1, zoom, 0, gFalse, gTrue);
- }
- }
- break;
-
- // Launch action
- case actionLaunch:
- fileName = ((LinkLaunch *)action)->getFileName();
- s = fileName->getCString();
- if (!strcmp(s + fileName->getLength() - 4, ".pdf") ||
- !strcmp(s + fileName->getLength() - 4, ".PDF")) {
- //~ translate path name for VMS (deal with '/')
- if (isAbsolutePath(s) || !doc->getFileName()) {
- fileName = fileName->copy();
- } else {
- fileName = appendToPath(grabPath(doc->getFileName()->getCString()), s);
- }
- if (loadFile(fileName) != errNone) {
- delete fileName;
- return;
- }
- delete fileName;
- displayPage(1, zoom, rotate, gFalse, gTrue);
- } else {
- fileName = fileName->copy();
- if (((LinkLaunch *)action)->getParams()) {
- fileName->append(' ');
- fileName->append(((LinkLaunch *)action)->getParams());
- }
-#ifdef VMS
- fileName->insert(0, "spawn/nowait ");
-#elif defined(__EMX__)
- fileName->insert(0, "start /min /n ");
-#else
- fileName->append(" &");
-#endif
- if (globalParams->getLaunchCommand()) {
- fileName->insert(0, ' ');
- fileName->insert(0, globalParams->getLaunchCommand());
- system(fileName->getCString());
- } else {
- msg = new GString("About to execute the command:\n");
- msg->append(fileName);
- if (doQuestionDialog("Launching external application", msg)) {
- system(fileName->getCString());
- }
- delete msg;
- }
- delete fileName;
- }
- break;
-
- // URI action
- case actionURI:
- if (!(cmd = globalParams->getURLCommand())) {
- error(errConfig, -1, "No urlCommand defined in config file");
- break;
- }
- runCommand(cmd, ((LinkURI *)action)->getURI());
- break;
-
- // Named action
- case actionNamed:
- actionName = ((LinkNamed *)action)->getName();
- if (!actionName->cmp("NextPage")) {
- gotoNextPage(1, gTrue);
- } else if (!actionName->cmp("PrevPage")) {
- gotoPrevPage(1, gTrue, gFalse);
- } else if (!actionName->cmp("FirstPage")) {
- if (topPage != 1) {
- displayPage(1, zoom, rotate, gTrue, gTrue);
- }
- } else if (!actionName->cmp("LastPage")) {
- if (topPage != doc->getNumPages()) {
- displayPage(doc->getNumPages(), zoom, rotate, gTrue, gTrue);
- }
- } else if (!actionName->cmp("GoBack")) {
- goBackward();
- } else if (!actionName->cmp("GoForward")) {
- goForward();
- } else if (!actionName->cmp("Quit")) {
- if (actionCbk) {
- (*actionCbk)(actionCbkData, actionName->getCString());
- }
- } else {
- error(errSyntaxError, -1,
- "Unknown named action: '{0:t}'", actionName);
- }
- break;
-
- // Movie action
- case actionMovie:
- if (!(cmd = globalParams->getMovieCommand())) {
- error(errConfig, -1, "No movieCommand defined in config file");
- break;
- }
- if (((LinkMovie *)action)->hasAnnotRef()) {
- doc->getXRef()->fetch(((LinkMovie *)action)->getAnnotRef()->num,
- ((LinkMovie *)action)->getAnnotRef()->gen,
- &movieAnnot);
- } else {
- //~ need to use the correct page num here
- doc->getCatalog()->getPage(topPage)->getAnnots(&obj1);
- if (obj1.isArray()) {
- for (i = 0; i < obj1.arrayGetLength(); ++i) {
- if (obj1.arrayGet(i, &movieAnnot)->isDict()) {
- if (movieAnnot.dictLookup("Subtype", &obj2)->isName("Movie")) {
- obj2.free();
- break;
- }
- obj2.free();
- }
- movieAnnot.free();
- }
- obj1.free();
- }
- }
- if (movieAnnot.isDict()) {
- if (movieAnnot.dictLookup("Movie", &obj1)->isDict()) {
- if (obj1.dictLookup("F", &obj2)) {
- if ((fileName = LinkAction::getFileSpecName(&obj2))) {
- if (!isAbsolutePath(fileName->getCString()) &&
- doc->getFileName()) {
- fileName2 = appendToPath(
- grabPath(doc->getFileName()->getCString()),
- fileName->getCString());
- delete fileName;
- fileName = fileName2;
- }
- runCommand(cmd, fileName);
- delete fileName;
- }
- obj2.free();
- }
- obj1.free();
- }
- }
- movieAnnot.free();
- break;
-
- // unsupported action types
- case actionJavaScript:
- case actionSubmitForm:
- case actionHide:
- error(errSyntaxError, -1, "Unsupported link action type");
- break;
-
- // unknown action type
- case actionUnknown:
- error(errSyntaxError, -1, "Unknown link action type: '{0:t}'",
- ((LinkUnknown *)action)->getAction());
- break;
- }
-}
-
-// Run a command, given a <cmdFmt> string with one '%s' in it, and an
-// <arg> string to insert in place of the '%s'.
-void XPDFCore::runCommand(GString *cmdFmt, GString *arg) {
- GString *cmd;
- char *s;
-
- if ((s = strstr(cmdFmt->getCString(), "%s"))) {
- cmd = mungeURL(arg);
- cmd->insert(0, cmdFmt->getCString(),
- s - cmdFmt->getCString());
- cmd->append(s + 2);
- } else {
- cmd = cmdFmt->copy();
- }
-#ifdef VMS
- cmd->insert(0, "spawn/nowait ");
-#elif defined(__EMX__)
- cmd->insert(0, "start /min /n ");
-#else
- cmd->append(" &");
-#endif
- system(cmd->getCString());
- delete cmd;
-}
-
-// Escape any characters in a URL which might cause problems when
-// calling system().
-GString *XPDFCore::mungeURL(GString *url) {
- static const char *allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789"
- "-_.~/?:@&=+,#%";
- GString *newURL;
- char c;
- char buf[4];
- int i;
-
- newURL = new GString();
- for (i = 0; i < url->getLength(); ++i) {
- c = url->getChar(i);
- if (strchr(allowed, c)) {
- newURL->append(c);
- } else {
- sprintf(buf, "%%%02x", c & 0xff);
- newURL->append(buf);
- }
- }
- return newURL;
-}
-
-//------------------------------------------------------------------------
-// find
-//------------------------------------------------------------------------
-
-GBool XPDFCore::find(char *s, GBool caseSensitive, GBool next,
- GBool backward, GBool wholeWord, GBool onePageOnly) {
- if (!PDFCore::find(s, caseSensitive, next,
- backward, wholeWord, onePageOnly)) {
- XBell(display, 0);
- return gFalse;
- }
-#ifndef NO_TEXT_SELECT
- copySelection();
-#endif
- return gTrue;
-}
-
-GBool XPDFCore::findU(Unicode *u, int len, GBool caseSensitive,
- GBool next, GBool backward,
- GBool wholeWord, GBool onePageOnly) {
- if (!PDFCore::findU(u, len, caseSensitive, next,
- backward, wholeWord, onePageOnly)) {
- XBell(display, 0);
- return gFalse;
- }
-#ifndef NO_TEXT_SELECT
- copySelection();
-#endif
- return gTrue;
-}
-
-//------------------------------------------------------------------------
-// misc access
-//------------------------------------------------------------------------
-
-void XPDFCore::setBusyCursor(GBool busy) {
- setCursor(busy ? busyCursor : None);
-}
-
-void XPDFCore::takeFocus() {
- XmProcessTraversal(drawArea, XmTRAVERSE_CURRENT);
-}
-
-//------------------------------------------------------------------------
-// GUI code
-//------------------------------------------------------------------------
-
-void XPDFCore::setupX(GBool installCmap, int rgbCubeSizeA) {
- XVisualInfo visualTempl;
- XVisualInfo *visualList;
- Gulong mask;
- int nVisuals;
- XColor xcolor;
- XColor *xcolors;
- int r, g, b, n, m;
- GBool ok;
-
- // for some reason, querying XmNvisual doesn't work (even if done
- // after the window is mapped)
- visual = DefaultVisual(display, screenNum);
- XtVaGetValues(shell, XmNcolormap, &colormap, NULL);
-
- // check for TrueColor visual
- //~ this should scan the list, not just look at the first one
- visualTempl.visualid = XVisualIDFromVisual(visual);
- visualList = XGetVisualInfo(display, VisualIDMask,
- &visualTempl, &nVisuals);
- if (nVisuals < 1) {
- // this shouldn't happen
- XFree((XPointer)visualList);
- visualList = XGetVisualInfo(display, VisualNoMask, &visualTempl,
- &nVisuals);
- }
- depth = visualList->depth;
- if (visualList->c_class == TrueColor) {
- trueColor = gTrue;
- for (mask = visualList->red_mask, rShift = 0;
- mask && !(mask & 1);
- mask >>= 1, ++rShift) ;
- for (rDiv = 8; mask; mask >>= 1, --rDiv) ;
- for (mask = visualList->green_mask, gShift = 0;
- mask && !(mask & 1);
- mask >>= 1, ++gShift) ;
- for (gDiv = 8; mask; mask >>= 1, --gDiv) ;
- for (mask = visualList->blue_mask, bShift = 0;
- mask && !(mask & 1);
- mask >>= 1, ++bShift) ;
- for (bDiv = 8; mask; mask >>= 1, --bDiv) ;
- } else {
- trueColor = gFalse;
- }
- XFree((XPointer)visualList);
-
- // allocate a color cube
- if (!trueColor) {
-
- // set colors in private colormap
- if (installCmap) {
- for (rgbCubeSize = xMaxRGBCube; rgbCubeSize >= 2; --rgbCubeSize) {
- m = rgbCubeSize * rgbCubeSize * rgbCubeSize;
- if (XAllocColorCells(display, colormap, False, NULL, 0, colors, m)) {
- break;
- }
- }
- if (rgbCubeSize >= 2) {
- m = rgbCubeSize * rgbCubeSize * rgbCubeSize;
- xcolors = (XColor *)gmallocn(m, sizeof(XColor));
- n = 0;
- for (r = 0; r < rgbCubeSize; ++r) {
- for (g = 0; g < rgbCubeSize; ++g) {
- for (b = 0; b < rgbCubeSize; ++b) {
- xcolors[n].pixel = colors[n];
- xcolors[n].red = (r * 65535) / (rgbCubeSize - 1);
- xcolors[n].green = (g * 65535) / (rgbCubeSize - 1);
- xcolors[n].blue = (b * 65535) / (rgbCubeSize - 1);
- xcolors[n].flags = DoRed | DoGreen | DoBlue;
- ++n;
- }
- }
- }
- XStoreColors(display, colormap, xcolors, m);
- gfree(xcolors);
- } else {
- rgbCubeSize = 1;
- colors[0] = BlackPixel(display, screenNum);
- colors[1] = WhitePixel(display, screenNum);
- }
-
- // allocate colors in shared colormap
- } else {
- if (rgbCubeSize > xMaxRGBCube) {
- rgbCubeSize = xMaxRGBCube;
- }
- ok = gFalse;
- for (rgbCubeSize = rgbCubeSizeA; rgbCubeSize >= 2; --rgbCubeSize) {
- ok = gTrue;
- n = 0;
- for (r = 0; r < rgbCubeSize && ok; ++r) {
- for (g = 0; g < rgbCubeSize && ok; ++g) {
- for (b = 0; b < rgbCubeSize && ok; ++b) {
- if (n == 0) {
- colors[n] = BlackPixel(display, screenNum);
- ++n;
- } else {
- xcolor.red = (r * 65535) / (rgbCubeSize - 1);
- xcolor.green = (g * 65535) / (rgbCubeSize - 1);
- xcolor.blue = (b * 65535) / (rgbCubeSize - 1);
- if (XAllocColor(display, colormap, &xcolor)) {
- colors[n++] = xcolor.pixel;
- } else {
- ok = gFalse;
- }
- }
- }
- }
- }
- if (ok) {
- break;
- }
- XFreeColors(display, colormap, &colors[1], n-1, 0);
- }
- if (!ok) {
- rgbCubeSize = 1;
- colors[0] = BlackPixel(display, screenNum);
- colors[1] = WhitePixel(display, screenNum);
- }
- }
- }
-}
-
-void XPDFCore::initWindow() {
- Arg args[20];
- int n;
-
- // create the cursors
- busyCursor = XCreateFontCursor(display, XC_watch);
- linkCursor = XCreateFontCursor(display, XC_hand2);
- selectCursor = XCreateFontCursor(display, XC_cross);
- currentCursor = 0;
-
- // create the scrolled window and scrollbars
- n = 0;
- XtSetArg(args[n], XmNscrollingPolicy, XmAPPLICATION_DEFINED); ++n;
- XtSetArg(args[n], XmNvisualPolicy, XmVARIABLE); ++n;
- scrolledWin = XmCreateScrolledWindow(parentWidget, "scroll", args, n);
- XtManageChild(scrolledWin);
- n = 0;
- XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
- XtSetArg(args[n], XmNminimum, 0); ++n;
- XtSetArg(args[n], XmNmaximum, 1); ++n;
- XtSetArg(args[n], XmNsliderSize, 1); ++n;
- XtSetArg(args[n], XmNvalue, 0); ++n;
- XtSetArg(args[n], XmNincrement, 1); ++n;
- XtSetArg(args[n], XmNpageIncrement, 1); ++n;
- hScrollBar = XmCreateScrollBar(scrolledWin, "hScrollBar", args, n);
- if (!fullScreen) {
- XtManageChild(hScrollBar);
- }
- XtAddCallback(hScrollBar, XmNvalueChangedCallback,
- &hScrollChangeCbk, (XtPointer)this);
-#ifndef DISABLE_SMOOTH_SCROLL
- XtAddCallback(hScrollBar, XmNdragCallback,
- &hScrollDragCbk, (XtPointer)this);
-#endif
- n = 0;
- XtSetArg(args[n], XmNorientation, XmVERTICAL); ++n;
- XtSetArg(args[n], XmNminimum, 0); ++n;
- XtSetArg(args[n], XmNmaximum, 1); ++n;
- XtSetArg(args[n], XmNsliderSize, 1); ++n;
- XtSetArg(args[n], XmNvalue, 0); ++n;
- XtSetArg(args[n], XmNincrement, 1); ++n;
- XtSetArg(args[n], XmNpageIncrement, 1); ++n;
- vScrollBar = XmCreateScrollBar(scrolledWin, "vScrollBar", args, n);
- if (!fullScreen) {
- XtManageChild(vScrollBar);
- }
- XtAddCallback(vScrollBar, XmNvalueChangedCallback,
- &vScrollChangeCbk, (XtPointer)this);
-#ifndef DISABLE_SMOOTH_SCROLL
- XtAddCallback(vScrollBar, XmNdragCallback,
- &vScrollDragCbk, (XtPointer)this);
-#endif
-
- // create the drawing area
- n = 0;
- XtSetArg(args[n], XmNshadowType, XmSHADOW_IN); ++n;
- XtSetArg(args[n], XmNmarginWidth, 0); ++n;
- XtSetArg(args[n], XmNmarginHeight, 0); ++n;
- if (fullScreen) {
- XtSetArg(args[n], XmNshadowThickness, 0); ++n;
- }
- drawAreaFrame = XmCreateFrame(scrolledWin, "drawAreaFrame", args, n);
- XtManageChild(drawAreaFrame);
- n = 0;
- XtSetArg(args[n], XmNresizePolicy, XmRESIZE_ANY); ++n;
- XtSetArg(args[n], XmNwidth, 700); ++n;
- XtSetArg(args[n], XmNheight, 500); ++n;
- drawArea = XmCreateDrawingArea(drawAreaFrame, "drawArea", args, n);
- XtManageChild(drawArea);
- XtAddCallback(drawArea, XmNresizeCallback, &resizeCbk, (XtPointer)this);
- XtAddCallback(drawArea, XmNexposeCallback, &redrawCbk, (XtPointer)this);
- XtAddCallback(drawArea, XmNinputCallback, &inputCbk, (XtPointer)this);
- resizeCbk(drawArea, this, NULL);
-
- // set up mouse motion translations
- XtOverrideTranslations(drawArea, XtParseTranslationTable(
- "<Btn1Down>:DrawingAreaInput()\n"
- "<Btn1Up>:DrawingAreaInput()\n"
- "<Btn1Motion>:DrawingAreaInput()\n"
- "<Motion>:DrawingAreaInput()"));
-
- // can't create a GC until the window gets mapped
- drawAreaGC = NULL;
-}
-
-void XPDFCore::hScrollChangeCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmScrollBarCallbackStruct *data = (XmScrollBarCallbackStruct *)callData;
-
- core->scrollTo(data->value, core->scrollY);
-}
-
-void XPDFCore::hScrollDragCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmScrollBarCallbackStruct *data = (XmScrollBarCallbackStruct *)callData;
-
- core->scrollTo(data->value, core->scrollY);
-}
-
-void XPDFCore::vScrollChangeCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmScrollBarCallbackStruct *data = (XmScrollBarCallbackStruct *)callData;
-
- core->scrollTo(core->scrollX, data->value);
-}
-
-void XPDFCore::vScrollDragCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmScrollBarCallbackStruct *data = (XmScrollBarCallbackStruct *)callData;
-
- core->scrollTo(core->scrollX, data->value);
-}
-
-void XPDFCore::resizeCbk(Widget widget, XtPointer ptr, XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XEvent event;
- Widget top;
- Window rootWin;
- int x1, y1;
- Guint w1, h1, bw1, depth1;
- Arg args[2];
- int n;
- Dimension w, h;
- int sx, sy;
-
- // find the top-most widget which has an associated window, and look
- // for a pending ConfigureNotify in the event queue -- if there is
- // one, and it specifies a different width or height, that means
- // we're still resizing, and we want to skip the current event
- for (top = core->parentWidget;
- XtParent(top) && XtWindow(XtParent(top));
- top = XtParent(top)) ;
- if (XCheckTypedWindowEvent(core->display, XtWindow(top),
- ConfigureNotify, &event)) {
- XPutBackEvent(core->display, &event);
- XGetGeometry(core->display, event.xconfigure.window,
- &rootWin, &x1, &y1, &w1, &h1, &bw1, &depth1);
- if ((Guint)event.xconfigure.width != w1 ||
- (Guint)event.xconfigure.height != h1) {
- return;
- }
- }
-
- n = 0;
- XtSetArg(args[n], XmNwidth, &w); ++n;
- XtSetArg(args[n], XmNheight, &h); ++n;
- XtGetValues(core->drawArea, args, n);
- core->drawAreaWidth = (int)w;
- core->drawAreaHeight = (int)h;
- if (core->zoom == zoomPage || core->zoom == zoomWidth) {
- sx = sy = -1;
- } else {
- sx = core->scrollX;
- sy = core->scrollY;
- }
- core->update(core->topPage, sx, sy, core->zoom, core->rotate, gTrue, gFalse,
- gFalse);
-}
-
-void XPDFCore::redrawCbk(Widget widget, XtPointer ptr, XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmDrawingAreaCallbackStruct *data = (XmDrawingAreaCallbackStruct *)callData;
- int x, y, w, h;
-
- if (data->reason == XmCR_EXPOSE) {
- x = data->event->xexpose.x;
- y = data->event->xexpose.y;
- w = data->event->xexpose.width;
- h = data->event->xexpose.height;
- } else {
- x = 0;
- y = 0;
- w = core->drawAreaWidth;
- h = core->drawAreaHeight;
- }
- core->redrawWindow(x, y, w, h, gFalse);
-}
-
-void XPDFCore::inputCbk(Widget widget, XtPointer ptr, XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmDrawingAreaCallbackStruct *data = (XmDrawingAreaCallbackStruct *)callData;
- LinkAction *action;
- int pg, x, y;
- double xu, yu;
- const char *s;
- KeySym key;
- GBool ok;
-
- switch (data->event->type) {
- case ButtonPress:
- if (*core->mouseCbk) {
- (*core->mouseCbk)(core->mouseCbkData, data->event);
- }
- break;
- case ButtonRelease:
- if (*core->mouseCbk) {
- (*core->mouseCbk)(core->mouseCbkData, data->event);
- }
- break;
- case MotionNotify:
- if (core->doc && core->doc->getNumPages() > 0) {
- ok = core->cvtWindowToDev(data->event->xmotion.x, data->event->xmotion.y,
- &pg, &x, &y);
- if (core->dragging) {
- if (ok) {
- core->moveSelection(pg, x, y);
- }
- } else if (core->hyperlinksEnabled) {
- core->cvtDevToUser(pg, x, y, &xu, &yu);
- if (ok && (action = core->findLink(pg, xu, yu))) {
- core->setCursor(core->linkCursor);
- if (action != core->linkAction) {
- core->linkAction = action;
- if (core->updateCbk) {
- s = "";
- switch (action->getKind()) {
- case actionGoTo:
- s = "[internal link]";
- break;
- case actionGoToR:
- s = ((LinkGoToR *)action)->getFileName()->getCString();
- break;
- case actionLaunch:
- s = ((LinkLaunch *)action)->getFileName()->getCString();
- break;
- case actionURI:
- s = ((LinkURI *)action)->getURI()->getCString();
- break;
- case actionNamed:
- s = ((LinkNamed *)action)->getName()->getCString();
- break;
- case actionMovie:
- s = "[movie]";
- break;
- case actionJavaScript:
- case actionSubmitForm:
- case actionHide:
- case actionUnknown:
- s = "[unknown link]";
- break;
- }
- (*core->updateCbk)(core->updateCbkData, NULL, -1, -1, s);
- }
- }
- } else {
- core->setCursor(None);
- if (core->linkAction) {
- core->linkAction = NULL;
- if (core->updateCbk) {
- (*core->updateCbk)(core->updateCbkData, NULL, -1, -1, "");
- }
- }
- }
- }
- }
- if (core->panning) {
- core->scrollTo(core->scrollX - (data->event->xmotion.x - core->panMX),
- core->scrollY - (data->event->xmotion.y - core->panMY));
- core->panMX = data->event->xmotion.x;
- core->panMY = data->event->xmotion.y;
- }
- break;
- case KeyPress:
- if (core->keyPressCbk) {
- key = XLookupKeysym(&data->event->xkey,
- (data->event->xkey.state & ShiftMask) ? 1 : 0);
- (*core->keyPressCbk)(core->keyPressCbkData,
- key, data->event->xkey.state, data->event);
- }
- break;
- }
-}
-
-PDFCoreTile *XPDFCore::newTile(int xDestA, int yDestA) {
- return new XPDFCoreTile(xDestA, yDestA);
-}
-
-void XPDFCore::updateTileData(PDFCoreTile *tileA, int xSrc, int ySrc,
- int width, int height, GBool composited) {
- XPDFCoreTile *tile = (XPDFCoreTile *)tileA;
- XImage *image;
- SplashColorPtr dataPtr, p;
- Gulong pixel;
- Guchar *ap;
- Guchar alpha, alpha1;
- int w, h, bw, x, y, r, g, b, gray;
- int *errDownR, *errDownG, *errDownB;
- int errRightR, errRightG, errRightB;
- int errDownRightR, errDownRightG, errDownRightB;
- int r0, g0, b0, re, ge, be;
-
- if (!tile->image) {
- w = tile->xMax - tile->xMin;
- h = tile->yMax - tile->yMin;
- image = XCreateImage(display, visual, depth, ZPixmap, 0, NULL, w, h, 8, 0);
- image->data = (char *)gmallocn(h, image->bytes_per_line);
- tile->image = image;
- } else {
- image = (XImage *)tile->image;
- }
-
- //~ optimize for known XImage formats
- bw = tile->bitmap->getRowSize();
- dataPtr = tile->bitmap->getDataPtr();
-
- if (trueColor) {
- for (y = 0; y < height; ++y) {
- p = dataPtr + (ySrc + y) * bw + xSrc * 3;
- if (!composited && tile->bitmap->getAlphaPtr()) {
- ap = tile->bitmap->getAlphaPtr() +
- (ySrc + y) * tile->bitmap->getWidth() + xSrc;
- } else {
- ap = NULL;
- }
- for (x = 0; x < width; ++x) {
- r = splashRGB8R(p);
- g = splashRGB8G(p);
- b = splashRGB8B(p);
- if (ap) {
- alpha = *ap++;
- alpha1 = 255 - alpha;
- r = div255(alpha1 * paperColor[0] + alpha * r);
- g = div255(alpha1 * paperColor[1] + alpha * g);
- b = div255(alpha1 * paperColor[2] + alpha * b);
- }
- r >>= rDiv;
- g >>= gDiv;
- b >>= bDiv;
- pixel = ((Gulong)r << rShift) +
- ((Gulong)g << gShift) +
- ((Gulong)b << bShift);
- XPutPixel(image, xSrc + x, ySrc + y, pixel);
- p += 3;
- }
- }
- } else if (rgbCubeSize == 1) {
- //~ this should really use splashModeMono, with non-clustered dithering
- for (y = 0; y < height; ++y) {
- p = dataPtr + (ySrc + y) * bw + xSrc * 3;
- if (!composited && tile->bitmap->getAlphaPtr()) {
- ap = tile->bitmap->getAlphaPtr() +
- (ySrc + y) * tile->bitmap->getWidth() + xSrc;
- } else {
- ap = NULL;
- }
- for (x = 0; x < width; ++x) {
- r = splashRGB8R(p);
- g = splashRGB8G(p);
- b = splashRGB8B(p);
- if (ap) {
- alpha = *ap++;
- alpha1 = 255 - alpha;
- r = div255(alpha1 * paperColor[0] + alpha * r);
- g = div255(alpha1 * paperColor[1] + alpha * g);
- b = div255(alpha1 * paperColor[2] + alpha * b);
- }
- gray = (int)(0.299 * r + 0.587 * g + 0.114 * b + 0.5);
- if (gray < 128) {
- pixel = colors[0];
- } else {
- pixel = colors[1];
- }
- XPutPixel(image, xSrc + x, ySrc + y, pixel);
- p += 3;
- }
- }
- } else {
- // do Floyd-Steinberg dithering on the whole bitmap
- errDownR = (int *)gmallocn(width + 2, sizeof(int));
- errDownG = (int *)gmallocn(width + 2, sizeof(int));
- errDownB = (int *)gmallocn(width + 2, sizeof(int));
- errRightR = errRightG = errRightB = 0;
- errDownRightR = errDownRightG = errDownRightB = 0;
- memset(errDownR, 0, (width + 2) * sizeof(int));
- memset(errDownG, 0, (width + 2) * sizeof(int));
- memset(errDownB, 0, (width + 2) * sizeof(int));
- for (y = 0; y < height; ++y) {
- p = dataPtr + (ySrc + y) * bw + xSrc * 3;
- if (!composited && tile->bitmap->getAlphaPtr()) {
- ap = tile->bitmap->getAlphaPtr() +
- (ySrc + y) * tile->bitmap->getWidth() + xSrc;
- } else {
- ap = NULL;
- }
- for (x = 0; x < width; ++x) {
- r = splashRGB8R(p);
- g = splashRGB8G(p);
- b = splashRGB8B(p);
- if (ap) {
- alpha = *ap++;
- alpha1 = 255 - alpha;
- r = div255(alpha1 * paperColor[0] + alpha * r);
- g = div255(alpha1 * paperColor[1] + alpha * g);
- b = div255(alpha1 * paperColor[2] + alpha * b);
- }
- r0 = r + errRightR + errDownR[x+1];
- g0 = g + errRightG + errDownG[x+1];
- b0 = b + errRightB + errDownB[x+1];
- if (r0 < 0) {
- r = 0;
- } else if (r0 >= 255) {
- r = rgbCubeSize - 1;
- } else {
- r = div255(r0 * (rgbCubeSize - 1));
- }
- if (g0 < 0) {
- g = 0;
- } else if (g0 >= 255) {
- g = rgbCubeSize - 1;
- } else {
- g = div255(g0 * (rgbCubeSize - 1));
- }
- if (b0 < 0) {
- b = 0;
- } else if (b0 >= 255) {
- b = rgbCubeSize - 1;
- } else {
- b = div255(b0 * (rgbCubeSize - 1));
- }
- re = r0 - ((r << 8) - r) / (rgbCubeSize - 1);
- ge = g0 - ((g << 8) - g) / (rgbCubeSize - 1);
- be = b0 - ((b << 8) - b) / (rgbCubeSize - 1);
- errRightR = (re * 7) >> 4;
- errRightG = (ge * 7) >> 4;
- errRightB = (be * 7) >> 4;
- errDownR[x] += (re * 3) >> 4;
- errDownG[x] += (ge * 3) >> 4;
- errDownB[x] += (be * 3) >> 4;
- errDownR[x+1] = ((re * 5) >> 4) + errDownRightR;
- errDownG[x+1] = ((ge * 5) >> 4) + errDownRightG;
- errDownB[x+1] = ((be * 5) >> 4) + errDownRightB;
- errDownRightR = re >> 4;
- errDownRightG = ge >> 4;
- errDownRightB = be >> 4;
- pixel = colors[(r * rgbCubeSize + g) * rgbCubeSize + b];
- XPutPixel(image, xSrc + x, ySrc + y, pixel);
- p += 3;
- }
- }
- gfree(errDownR);
- gfree(errDownG);
- gfree(errDownB);
- }
-}
-
-void XPDFCore::redrawRect(PDFCoreTile *tileA, int xSrc, int ySrc,
- int xDest, int yDest, int width, int height,
- GBool composited) {
- XPDFCoreTile *tile = (XPDFCoreTile *)tileA;
- Window drawAreaWin;
- XGCValues gcValues;
-
- // create a GC for the drawing area
- drawAreaWin = XtWindow(drawArea);
- if (!drawAreaGC) {
- gcValues.foreground = mattePixel;
- drawAreaGC = XCreateGC(display, drawAreaWin, GCForeground, &gcValues);
- }
-
- // draw the document
- if (tile) {
- XPutImage(display, drawAreaWin, drawAreaGC, tile->image,
- xSrc, ySrc, xDest, yDest, width, height);
-
- // draw the background
- } else {
- XFillRectangle(display, drawAreaWin, drawAreaGC,
- xDest, yDest, width, height);
- }
-
- XFlush(display);
-}
-
-void XPDFCore::updateScrollbars() {
- Arg args[20];
- int n;
- int maxPos;
-
- if (pages->getLength() > 0) {
- if (continuousMode) {
- maxPos = maxPageW;
- } else {
- maxPos = ((PDFCorePage *)pages->get(0))->w;
- }
- } else {
- maxPos = 1;
- }
- if (maxPos < drawAreaWidth) {
- maxPos = drawAreaWidth;
- }
- n = 0;
- XtSetArg(args[n], XmNvalue, scrollX); ++n;
- XtSetArg(args[n], XmNmaximum, maxPos); ++n;
- XtSetArg(args[n], XmNsliderSize, drawAreaWidth); ++n;
- XtSetArg(args[n], XmNincrement, 16); ++n;
- XtSetArg(args[n], XmNpageIncrement, drawAreaWidth); ++n;
- XtSetValues(hScrollBar, args, n);
-
- if (pages->getLength() > 0) {
- if (continuousMode) {
- maxPos = totalDocH;
- } else {
- maxPos = ((PDFCorePage *)pages->get(0))->h;
- }
- } else {
- maxPos = 1;
- }
- if (maxPos < drawAreaHeight) {
- maxPos = drawAreaHeight;
- }
- n = 0;
- XtSetArg(args[n], XmNvalue, scrollY); ++n;
- XtSetArg(args[n], XmNmaximum, maxPos); ++n;
- XtSetArg(args[n], XmNsliderSize, drawAreaHeight); ++n;
- XtSetArg(args[n], XmNincrement, 16); ++n;
- XtSetArg(args[n], XmNpageIncrement, drawAreaHeight); ++n;
- XtSetValues(vScrollBar, args, n);
-}
-
-void XPDFCore::setCursor(Cursor cursor) {
- Window topWin;
-
- if (cursor == currentCursor) {
- return;
- }
- if (!(topWin = XtWindow(shell))) {
- return;
- }
- if (cursor == None) {
- XUndefineCursor(display, topWin);
- } else {
- XDefineCursor(display, topWin, cursor);
- }
- XFlush(display);
- currentCursor = cursor;
-}
-
-GBool XPDFCore::doQuestionDialog(const char *title, GString *msg) {
- return doDialog(XmDIALOG_QUESTION, gTrue, title, msg);
-}
-
-void XPDFCore::doInfoDialog(const char *title, GString *msg) {
- doDialog(XmDIALOG_INFORMATION, gFalse, title, msg);
-}
-
-void XPDFCore::doErrorDialog(const char *title, GString *msg) {
- doDialog(XmDIALOG_ERROR, gFalse, title, msg);
-}
-
-GBool XPDFCore::doDialog(int type, GBool hasCancel,
- const char *title, GString *msg) {
- Widget dialog, scroll, text;
- XtAppContext appContext;
- Arg args[20];
- int n;
- XmString s1, s2;
- XEvent event;
-
- n = 0;
- XtSetArg(args[n], XmNdialogType, type); ++n;
- XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
- s1 = XmStringCreateLocalized((char *)title);
- XtSetArg(args[n], XmNdialogTitle, s1); ++n;
- s2 = NULL; // make gcc happy
- if (msg->getLength() <= 80) {
- s2 = XmStringCreateLocalized(msg->getCString());
- XtSetArg(args[n], XmNmessageString, s2); ++n;
- }
- dialog = XmCreateMessageDialog(drawArea, "questionDialog", args, n);
- XmStringFree(s1);
- if (msg->getLength() <= 80) {
- XmStringFree(s2);
- } else {
- n = 0;
- XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n;
- if (drawAreaWidth > 300) {
- XtSetArg(args[n], XmNwidth, drawAreaWidth - 100); ++n;
- }
- scroll = XmCreateScrolledWindow(dialog, "scroll", args, n);
- XtManageChild(scroll);
- n = 0;
- XtSetArg(args[n], XmNeditable, False); ++n;
- XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); ++n;
- XtSetArg(args[n], XmNvalue, msg->getCString()); ++n;
- XtSetArg(args[n], XmNshadowThickness, 0); ++n;
- text = XmCreateText(scroll, "text", args, n);
- XtManageChild(text);
- }
- XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
- XtAddCallback(dialog, XmNokCallback,
- &dialogOkCbk, (XtPointer)this);
- if (hasCancel) {
- XtAddCallback(dialog, XmNcancelCallback,
- &dialogCancelCbk, (XtPointer)this);
- } else {
- XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
- }
-
- XtManageChild(dialog);
-
- appContext = XtWidgetToApplicationContext(dialog);
- dialogDone = 0;
- do {
- XtAppNextEvent(appContext, &event);
- XtDispatchEvent(&event);
- } while (!dialogDone);
-
- XtUnmanageChild(dialog);
- XtDestroyWidget(dialog);
-
- return dialogDone > 0;
-}
-
-void XPDFCore::dialogOkCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
-
- core->dialogDone = 1;
-}
-
-void XPDFCore::dialogCancelCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
-
- core->dialogDone = -1;
-}
-
-//------------------------------------------------------------------------
-// password dialog
-//------------------------------------------------------------------------
-
-void XPDFCore::initPasswordDialog() {
- Widget row, label, okBtn, cancelBtn;
- Arg args[20];
- int n;
- XmString s;
-
- //----- dialog
- n = 0;
- s = XmStringCreateLocalized(xpdfAppName ": Password");
- XtSetArg(args[n], XmNdialogTitle, s); ++n;
- XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
- passwordDialog = XmCreateFormDialog(drawArea, "passwordDialog", args, n);
- XmStringFree(s);
-
- //----- message
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNtopOffset, 4); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 4); ++n;
- s = XmStringCreateLocalized("This document requires a password.");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- label = XmCreateLabel(passwordDialog, "msg", args, n);
- XmStringFree(s);
- XtManageChild(label);
-
- //----- label and password entry
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, label); ++n;
- XtSetArg(args[n], XmNtopOffset, 4); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 4); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 4); ++n;
- XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
- XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
- row = XmCreateRowColumn(passwordDialog, "row", args, n);
- XtManageChild(row);
- n = 0;
- s = XmStringCreateLocalized("Password: ");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- label = XmCreateLabel(row, "label", args, n);
- XmStringFree(s);
- XtManageChild(label);
- n = 0;
- XtSetArg(args[n], XmNcolumns, 16); ++n;
- passwordText = XmCreateTextField(row, "text", args, n);
- XtManageChild(passwordText);
- XtAddCallback(passwordText, XmNmodifyVerifyCallback,
- &passwordTextVerifyCbk, this);
-
- //----- "Ok" and "Cancel" buttons
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, row); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 4); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomOffset, 4); ++n;
- XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
- okBtn = XmCreatePushButton(passwordDialog, "Ok", args, n);
- XtManageChild(okBtn);
- XtAddCallback(okBtn, XmNactivateCallback,
- &passwordOkCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, row); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightOffset, 4); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomOffset, 4); ++n;
- XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
- cancelBtn = XmCreatePushButton(passwordDialog, "Cancel", args, n);
- XtManageChild(cancelBtn);
- XtAddCallback(cancelBtn, XmNactivateCallback,
- &passwordCancelCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
- XtSetArg(args[n], XmNcancelButton, cancelBtn); ++n;
-#if XmVersion > 1001
- XtSetArg(args[n], XmNinitialFocus, passwordText); ++n;
-#endif
- XtSetValues(passwordDialog, args, n);
-}
-
-void XPDFCore::passwordTextVerifyCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
- XmTextVerifyCallbackStruct *data =
- (XmTextVerifyCallbackStruct *)callData;
- int i, n;
-
- i = (int)data->startPos;
- n = (int)data->endPos - i;
- if (i > core->password->getLength()) {
- i = core->password->getLength();
- }
- if (i + n > core->password->getLength()) {
- n = core->password->getLength() - i;
- }
- core->password->del(i, n);
- core->password->insert(i, data->text->ptr, data->text->length);
-
- for (i = 0; i < data->text->length; ++i) {
- data->text->ptr[i] = '*';
- }
- data->doit = True;
-}
-
-void XPDFCore::passwordOkCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
-
- core->dialogDone = 1;
-}
-
-void XPDFCore::passwordCancelCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFCore *core = (XPDFCore *)ptr;
-
- core->dialogDone = -1;
-}
-
-GString *XPDFCore::getPassword() {
- XtAppContext appContext;
- XEvent event;
-
- // NB: set <password> before calling XmTextFieldSetString, because
- // SetString will trigger a call to passwordTextVerifyCbk, which
- // expects <password> to be valid
- password = new GString();
- XmTextFieldSetString(passwordText, "");
- XtManageChild(passwordDialog);
-
- appContext = XtWidgetToApplicationContext(passwordDialog);
- dialogDone = 0;
- do {
- XtAppNextEvent(appContext, &event);
- XtDispatchEvent(&event);
- } while (!dialogDone);
- XtUnmanageChild(passwordDialog);
-
- if (dialogDone < 0) {
- delete password;
- return NULL;
- }
- return password;
-}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.h b/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.h
deleted file mode 100644
index be1dcfab288..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFCore.h
+++ /dev/null
@@ -1,253 +0,0 @@
-//========================================================================
-//
-// XPDFCore.h
-//
-// Copyright 2002-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-#ifndef XPDFCORE_H
-#define XPDFCORE_H
-
-#include <aconf.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
-#define Object XtObject
-#include <Xm/XmAll.h>
-#undef Object
-#include "gtypes.h"
-#include "gfile.h" // for time_t
-#include "SplashTypes.h"
-#include "PDFCore.h"
-
-class GString;
-class BaseStream;
-class PDFDoc;
-class LinkAction;
-
-//------------------------------------------------------------------------
-
-#define xMaxRGBCube 6 // max size of RGB color cube
-
-//------------------------------------------------------------------------
-// callbacks
-//------------------------------------------------------------------------
-
-typedef void (*XPDFUpdateCbk)(void *data, GString *fileName,
- int pageNum, int numPages,
- const char *linkLabel);
-
-typedef void (*XPDFActionCbk)(void *data, char *action);
-
-typedef void (*XPDFKeyPressCbk)(void *data, KeySym key, Guint modifiers,
- XEvent *event);
-
-typedef void (*XPDFMouseCbk)(void *data, XEvent *event);
-
-//------------------------------------------------------------------------
-// XPDFCore
-//------------------------------------------------------------------------
-
-class XPDFCore: public PDFCore {
-public:
-
- // Create viewer core inside <parentWidgetA>.
- XPDFCore(Widget shellA, Widget parentWidgetA,
- SplashColorPtr paperColorA, Gulong paperPixelA,
- Gulong mattePixelA, GBool fullScreenA, GBool reverseVideoA,
- GBool installCmap, int rgbCubeSizeA);
-
- ~XPDFCore();
-
- //----- loadFile / displayPage / displayDest
-
- // Load a new file. Returns pdfOk or error code.
- virtual int loadFile(GString *fileName, GString *ownerPassword = NULL,
- GString *userPassword = NULL);
-
- // Load a new file, via a Stream instead of a file name. Returns
- // pdfOk or error code.
- virtual int loadFile(BaseStream *stream, GString *ownerPassword = NULL,
- GString *userPassword = NULL);
-
- // Load an already-created PDFDoc object.
- virtual void loadDoc(PDFDoc *docA);
-
- // Resize the window to fit page <pg> of the current document.
- void resizeToPage(int pg);
-
- // Update the display, given the specified parameters.
- virtual void update(int topPageA, int scrollXA, int scrollYA,
- double zoomA, int rotateA, GBool force,
- GBool addToHist, GBool adjustScrollX);
-
- //----- page/position changes
-
- virtual GBool gotoNextPage(int inc, GBool top);
- virtual GBool gotoPrevPage(int dec, GBool top, GBool bottom);
- virtual GBool goForward();
- virtual GBool goBackward();
- void startPan(int wx, int wy);
- void endPan(int wx, int wy);
-
- //----- selection
-
- void startSelection(int wx, int wy);
- void endSelection(int wx, int wy);
- void copySelection();
-
- //----- hyperlinks
-
- void doAction(LinkAction *action);
- LinkAction *getLinkAction() { return linkAction; }
- GString *mungeURL(GString *url);
-
- //----- find
-
- virtual GBool find(char *s, GBool caseSensitive, GBool next,
- GBool backward, GBool wholeWord, GBool onePageOnly);
- virtual GBool findU(Unicode *u, int len, GBool caseSensitive,
- GBool next, GBool backward,
- GBool wholeWord, GBool onePageOnly);
-
- //----- simple modal dialogs
-
- GBool doQuestionDialog(const char *title, GString *msg);
- void doInfoDialog(const char *title, GString *msg);
- void doErrorDialog(const char *title, GString *msg);
-
- //----- password dialog
-
- virtual GString *getPassword();
-
- //----- misc access
-
- Widget getWidget() { return scrolledWin; }
- Widget getDrawAreaWidget() { return drawArea; }
- virtual void setBusyCursor(GBool busy);
- Cursor getBusyCursor() { return busyCursor; }
- void takeFocus();
- void enableHyperlinks(GBool on) { hyperlinksEnabled = on; }
- GBool getHyperlinksEnabled() { return hyperlinksEnabled; }
- void enableSelect(GBool on) { selectEnabled = on; }
- void setUpdateCbk(XPDFUpdateCbk cbk, void *data)
- { updateCbk = cbk; updateCbkData = data; }
- void setActionCbk(XPDFActionCbk cbk, void *data)
- { actionCbk = cbk; actionCbkData = data; }
- void setKeyPressCbk(XPDFKeyPressCbk cbk, void *data)
- { keyPressCbk = cbk; keyPressCbkData = data; }
- void setMouseCbk(XPDFMouseCbk cbk, void *data)
- { mouseCbk = cbk; mouseCbkData = data; }
- GBool getFullScreen() { return fullScreen; }
-
-private:
-
- virtual GBool checkForNewFile();
-
- //----- hyperlinks
- void runCommand(GString *cmdFmt, GString *arg);
-
- //----- selection
- static Boolean convertSelectionCbk(Widget widget, Atom *selection,
- Atom *target, Atom *type,
- XtPointer *value, unsigned long *length,
- int *format);
-
- //----- GUI code
- void setupX(GBool installCmap, int rgbCubeSizeA);
- void initWindow();
- static void hScrollChangeCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void hScrollDragCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void vScrollChangeCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void vScrollDragCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void resizeCbk(Widget widget, XtPointer ptr, XtPointer callData);
- static void redrawCbk(Widget widget, XtPointer ptr, XtPointer callData);
- static void inputCbk(Widget widget, XtPointer ptr, XtPointer callData);
- virtual PDFCoreTile *newTile(int xDestA, int yDestA);
- virtual void updateTileData(PDFCoreTile *tileA, int xSrc, int ySrc,
- int width, int height, GBool composited);
- virtual void redrawRect(PDFCoreTile *tileA, int xSrc, int ySrc,
- int xDest, int yDest, int width, int height,
- GBool composited);
- virtual void updateScrollbars();
- void setCursor(Cursor cursor);
- GBool doDialog(int type, GBool hasCancel,
- const char *title, GString *msg);
- static void dialogOkCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void dialogCancelCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- void initPasswordDialog();
- static void passwordTextVerifyCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void passwordOkCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void passwordCancelCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
-
- Gulong paperPixel;
- Gulong mattePixel;
- //~unimp: move fullScreen into PDFCore?
- GBool fullScreen;
-
- Display *display;
- int screenNum;
- Visual *visual;
- Colormap colormap;
- Guint depth; // visual depth
- GBool trueColor; // set if using a TrueColor visual
- int rDiv, gDiv, bDiv; // RGB right shifts (for TrueColor)
- int rShift, gShift, bShift; // RGB left shifts (for TrueColor)
- int rgbCubeSize; // size of color cube (for non-TrueColor)
- Gulong // color cube (for non-TrueColor)
- colors[xMaxRGBCube * xMaxRGBCube * xMaxRGBCube];
-
- Widget shell; // top-level shell containing the widget
- Widget parentWidget; // parent widget (not created by XPDFCore)
- Widget scrolledWin;
- Widget hScrollBar;
- Widget vScrollBar;
- Widget drawAreaFrame;
- Widget drawArea;
- Cursor busyCursor, linkCursor, selectCursor;
- Cursor currentCursor;
- GC drawAreaGC; // GC for blitting into drawArea
-
- static GString *currentSelection; // selected text
- static XPDFCore *currentSelectionOwner;
- static Atom targetsAtom;
-
- GBool panning;
- int panMX, panMY;
-
- time_t modTime; // last modification time of PDF file
-
- LinkAction *linkAction; // mouse cursor is over this link
-
- XPDFUpdateCbk updateCbk;
- void *updateCbkData;
- XPDFActionCbk actionCbk;
- void *actionCbkData;
- XPDFKeyPressCbk keyPressCbk;
- void *keyPressCbkData;
- XPDFMouseCbk mouseCbk;
- void *mouseCbkData;
-
- GBool hyperlinksEnabled;
- GBool selectEnabled;
-
- int dialogDone;
-
- Widget passwordDialog;
- Widget passwordText;
- GString *password;
-};
-
-#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFTree.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFTree.cc
deleted file mode 100644
index bae9cb000a9..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFTree.cc
+++ /dev/null
@@ -1,951 +0,0 @@
-//========================================================================
-//
-// XPDFTree.cc
-//
-// Copyright 2002-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-#include <aconf.h>
-#include <stdlib.h>
-#include "gmem.h"
-#include "XPDFTreeP.h"
-
-//------------------------------------------------------------------------
-
-#define xpdfTreeIndent 16
-
-//------------------------------------------------------------------------
-
-struct _XPDFTreeEntry {
- Widget widget;
- XPDFTreeEntry *children;
- XPDFTreeEntry *next;
-};
-
-//------------------------------------------------------------------------
-
-static void classPartInitialize(WidgetClass widgetClass);
-static void initialize(Widget requestWidget, Widget newWidget,
- ArgList args, Cardinal *numArgs);
-static void destroy(Widget widget);
-static void destroySubtree(XPDFTreeEntry *e);
-static void resize(Widget widget);
-static void redisplay(Widget widget, XEvent *event, Region region);
-static void redisplaySubtree(XPDFTreeWidget w, XPDFTreeEntry *e,
- XEvent *event, Region region);
-static void drawExpandedIcon(XPDFTreeWidget w, Position x, Position y);
-static void drawCollapsedIcon(XPDFTreeWidget w, Position x, Position y);
-static Boolean setValues(Widget oldWidget, Widget requestWidget,
- Widget newWidget, ArgList args, Cardinal *numArgs);
-static void setValuesAlmost(Widget oldWidget, Widget newWidget,
- XtWidgetGeometry *request,
- XtWidgetGeometry *reply);
-static XtGeometryResult queryGeometry(Widget widget,
- XtWidgetGeometry *request,
- XtWidgetGeometry *reply);
-static XtGeometryResult geometryManager(Widget widget,
- XtWidgetGeometry *request,
- XtWidgetGeometry *reply);
-static void changeManaged(Widget widget);
-static void initConstraint(Widget requestWidget, Widget newWidget,
- ArgList args, Cardinal *numArgs);
-static void destroyConstraint(Widget widget);
-static void deleteSubtree(Widget widget);
-static Boolean constraintSetValues(Widget oldWidget, Widget requestWidget,
- Widget newWidget,
- ArgList args, Cardinal *numArgs);
-static void insertChildOnList(XPDFTreeEntry *e, XPDFTreeEntry **listHead);
-static void deleteChildFromList(XPDFTreeEntry *e, XPDFTreeEntry **listHead);
-static void createGC(Widget widget);
-static void destroyGC(Widget widget);
-static void layout(Widget widget, Widget instigator);
-static int layoutSubtree(XPDFTreeWidget w, Widget instigator,
- XPDFTreeEntry *e, Position x, Position y,
- Boolean visible);
-static void calcSize(Widget widget, Widget instigator,
- Dimension *totalWidth,
- Dimension *totalHeight);
-static void calcSubtreeSize(XPDFTreeWidget w, Widget instigator,
- XPDFTreeEntry *e,
- Dimension *width, Dimension *height);
-static Boolean needRelayout(Widget oldWidget, Widget newWidget);
-static void click(Widget widget, XEvent *event,
- String *params, Cardinal *numParams);
-static Boolean findPosition(XPDFTreeWidget w, int x, int y,
- XPDFTreeEntry **e, Boolean *onExpandIcon);
-static Boolean findPositionInSubtree(XPDFTreeWidget w, int x, int y,
- XPDFTreeEntry **e,
- Boolean *onExpandIcon);
-
-//------------------------------------------------------------------------
-
-static XtResource resources[] = {
- { XmNmarginWidth, XmCMarginWidth, XmRHorizontalDimension,
- sizeof(Dimension), XtOffsetOf(XPDFTreeRec, tree.marginWidth),
- XmRImmediate, (XtPointer)0 },
- { XmNmarginHeight, XmCMarginHeight, XmRVerticalDimension,
- sizeof(Dimension), XtOffsetOf(XPDFTreeRec, tree.marginHeight),
- XmRImmediate, (XtPointer)0 },
- { XPDFNselectionCallback, XmCCallback, XmRCallback,
- sizeof(XtCallbackList), XtOffsetOf(XPDFTreeRec, tree.selectCallback),
- XmRImmediate, (XtPointer)NULL }
-};
-
-static XmSyntheticResource synResources[] = {
- { XmNmarginWidth, sizeof(Dimension),
- XtOffsetOf(XPDFTreeRec, tree.marginWidth),
-#if XmVERSION > 1
- XmeFromHorizontalPixels, XmeToHorizontalPixels
-#else
- _XmFromHorizontalPixels, _XmToHorizontalPixels
-#endif
- },
- { XmNmarginHeight, sizeof(Dimension),
- XtOffsetOf(XPDFTreeRec, tree.marginHeight),
-#if XmVERSION > 1
- XmeFromVerticalPixels, XmeToVerticalPixels
-#else
- _XmFromVerticalPixels, _XmToVerticalPixels
-#endif
- }
-};
-
-static XtResource constraints[] = {
- { XPDFNentryParent, XPDFCentryParent, XmRWidget,
- sizeof(Widget), XtOffsetOf(XPDFTreeConstraintRec, tree.entryParent),
- XmRImmediate, (XtPointer)NULL },
- { XPDFNentryExpanded, XPDFCentryExpanded, XmRBoolean,
- sizeof(Boolean), XtOffsetOf(XPDFTreeConstraintRec, tree.entryExpanded),
- XmRImmediate, (XtPointer)False },
- { XPDFNentryPosition, XPDFCentryPosition, XmRInt,
- sizeof(int), XtOffsetOf(XPDFTreeConstraintRec, tree.entryPosition),
- XmRImmediate, (XtPointer)0 }
-};
-
-static char defaultTranslations[] =
- "<Btn1Down>: XPDFTreeClick()";
-
-static XtActionsRec actions[] = {
- { "XPDFTreeClick", click }
-};
-
-externaldef(xpdftreeclassrec) XPDFTreeClassRec xpdfTreeClassRec = {
- { // Core
- (WidgetClass)&xmManagerClassRec, // superclass
- "XPDFTree", // class_name
- sizeof(XPDFTreeRec), // widget_size
- NULL, // class_initialize
- &classPartInitialize, // class_part_initialize
- FALSE, // class_inited
- &initialize, // initialize
- NULL, // initialize_hook
- XtInheritRealize, // realize
- actions, // actions
- XtNumber(actions), // num_actions
- resources, // resources
- XtNumber(resources), // num_resources
- NULLQUARK, // xrm_class
- TRUE, // compress_motion
- XtExposeCompressMaximal, // compress_exposure
- TRUE, // compress_enterleave
- FALSE, // visible_interest
- &destroy, // destroy
- &resize, // resize
- &redisplay, // expose
- &setValues, // set_values
- NULL, // set_values_hook
- &setValuesAlmost, // set_values_almost
- NULL, // get_values_hook
- NULL, // accept_focus
- XtVersion, // version
- NULL, // callback_private
- defaultTranslations, // tm_table
- &queryGeometry, // query_geometry
- NULL, // display_accelerator
- NULL // extension
- },
- { // Composite
- &geometryManager, // geometry_manager
- &changeManaged, // change_managed
- XtInheritInsertChild, // insert_child
- XtInheritDeleteChild, // delete_child
- NULL // extension
- },
- { // Constraint
- constraints, // constraint_resources
- XtNumber(constraints), // constraint_num_resources
- sizeof(XPDFTreeConstraintRec), // constraint_size
- &initConstraint, // constraint_initialize
- &destroyConstraint, // constraint_destroy
- &constraintSetValues, // constraint_set_values
- NULL // extension
- },
- { // XmManager
- XtInheritTranslations, // translations
-#if XmVERSION > 1
- synResources, // syn_resources
- XtNumber(synResources), // num_syn_resources
-#else
- NULL, // syn_resources
- 0, // num_syn_resources
-#endif
- NULL, // syn_constraint_resources
- 0, // num_syn_constraint_res's
- XmInheritParentProcess, // parent_process
- NULL // extension
- },
- { // XPDFTree
- &createGC, // createGC
- &destroyGC, // destroyGC
- &layout, // layout
- &calcSize, // calcSize
- &needRelayout, // needRelayout
- NULL // extension
- }
-};
-
-externaldef(xpdftreewidgetclass) WidgetClass xpdfTreeWidgetClass =
- (WidgetClass)&xpdfTreeClassRec;
-
-//------------------------------------------------------------------------
-
-static void classPartInitialize(WidgetClass widgetCls) {
- XPDFTreeWidgetClass wc = (XPDFTreeWidgetClass)widgetCls;
- XPDFTreeWidgetClass sc = (XPDFTreeWidgetClass)wc->coreClass.superclass;
-
- // method inheritance
- if (wc->treeClass.createGC == XPDFInheritCreateGC) {
- wc->treeClass.createGC = sc->treeClass.createGC;
- }
- if (wc->treeClass.destroyGC == XPDFInheritDestroyGC) {
- wc->treeClass.destroyGC = sc->treeClass.destroyGC;
- }
- if (wc->treeClass.layout == XPDFInheritLayout) {
- wc->treeClass.layout = sc->treeClass.layout;
- }
- if (wc->treeClass.calcSize == XPDFInheritCalcSize) {
- wc->treeClass.calcSize = sc->treeClass.calcSize;
- }
- if (wc->treeClass.needRelayout == XPDFInheritNeedRelayout) {
- wc->treeClass.needRelayout = sc->treeClass.needRelayout;
- }
-}
-
-static void initialize(Widget requestWidget, Widget newWidget,
- ArgList args, Cardinal *numArgs) {
- XPDFTreeWidget nw = (XPDFTreeWidget)newWidget;
- XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(newWidget);
-
- nw->tree.root = NULL;
- nw->tree.redrawY = -1;
- if (cls->treeClass.createGC) {
- (*cls->treeClass.createGC)(newWidget);
- } else {
- createGC(newWidget);
- }
-}
-
-static void destroy(Widget widget) {
- XPDFTreeWidget w = (XPDFTreeWidget)widget;
- XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(widget);
-
- if (w->tree.root) {
- destroySubtree(w->tree.root);
- w->tree.root = NULL;
- }
- if (cls->treeClass.destroyGC) {
- (*cls->treeClass.destroyGC)(widget);
- } else {
- destroyGC(widget);
- }
-}
-
-static void destroySubtree(XPDFTreeEntry *e) {
- if (e->children) {
- destroySubtree(e->children);
- }
- if (e->next) {
- destroySubtree(e->next);
- }
-}
-
-static void resize(Widget widget) {
- XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(widget);
-
- if (cls->treeClass.layout) {
- (*cls->treeClass.layout)(widget, NULL);
- } else {
- layout(widget, NULL);
- }
-}
-
-static void redisplay(Widget widget, XEvent *event, Region region) {
- XPDFTreeWidget w = (XPDFTreeWidget)widget;
- XPDFTreeEntry *e;
-
- if (w->tree.redrawY >= 0) {
- XClearArea(XtDisplay((Widget)w), XtWindow((Widget)w),
- 0, w->tree.redrawY, w->core.width, w->core.height, False);
- w->tree.redrawY = -1;
- }
- for (e = w->tree.root; e; e = e->next) {
- redisplaySubtree(w, e, event, region);
- }
-}
-
-static void redisplaySubtree(XPDFTreeWidget w, XPDFTreeEntry *e,
- XEvent *event, Region region) {
- XPDFTreeConstraint c;
- Position x, y, y2;
- XPDFTreeEntry *child;
-
- (*XtClass(e->widget)->core_class.expose)(e->widget, event, region);
- c = XPDFTreeCPart(e->widget);
- x = e->widget->core.x;
- y = e->widget->core.y + e->widget->core.height / 2;
- if (e->children) {
- if (c->entryExpanded) {
- drawExpandedIcon(w, x - 8, y);
- y2 = y; // make gcc happy
- for (child = e->children; child; child = child->next) {
- y2 = child->widget->core.y + child->widget->core.height / 2;
- XDrawLine(XtDisplay((Widget)w), XtWindow((Widget)w), w->tree.dottedGC,
- x - 8, y2, x + 6, y2);
- redisplaySubtree(w, child, event, region);
- }
- XDrawLine(XtDisplay((Widget)w), XtWindow((Widget)w), w->tree.dottedGC,
- x - 8, y + 2, x - 8, y2);
- } else {
- drawCollapsedIcon(w, x - 8, y);
- }
- }
-}
-
-static void drawExpandedIcon(XPDFTreeWidget w, Position x, Position y) {
- XPoint pts[4];
-
- pts[0].x = x - 4; pts[0].y = y - 2;
- pts[1].x = x + 4; pts[1].y = y - 2;
- pts[2].x = x; pts[2].y = y + 2;
- pts[3].x = x - 4; pts[3].y = y - 2;
- XDrawLines(XtDisplay((Widget)w), XtWindow((Widget)w), w->tree.plainGC,
- pts, 4, CoordModeOrigin);
-}
-
-static void drawCollapsedIcon(XPDFTreeWidget w, Position x, Position y) {
- XPoint pts[4];
-
- pts[0].x = x - 2; pts[0].y = y - 4;
- pts[1].x = x - 2; pts[1].y = y + 4;
- pts[2].x = x + 2; pts[2].y = y;
- pts[3].x = x - 2; pts[3].y = y - 4;
- XDrawLines(XtDisplay((Widget)w), XtWindow((Widget)w), w->tree.plainGC,
- pts, 4, CoordModeOrigin);
-}
-
-static Boolean setValues(Widget oldWidget, Widget requestWidget,
- Widget newWidget, ArgList args, Cardinal *numArgs) {
- XPDFTreeWidget ow = (XPDFTreeWidget)oldWidget;
- XPDFTreeWidget nw = (XPDFTreeWidget)newWidget;
- XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(nw);
- Boolean relayout, redisp;
-
- // check to see if layout-affecting resources have changed
- if (cls->treeClass.needRelayout) {
- relayout = (*cls->treeClass.needRelayout)((Widget)ow, (Widget)nw);
- } else {
- relayout = needRelayout((Widget)ow, (Widget)nw);
- }
- redisp = False;
- if (relayout) {
-
- // calculate a new ideal size (reset the widget size first so
- // calcSize will compute a new one)
- if (nw->core.width == ow->core.width) {
- nw->core.width = 0;
- }
- if (nw->core.height == ow->core.height) {
- nw->core.height = 0;
- }
- if (cls->treeClass.calcSize) {
- (*cls->treeClass.calcSize)((Widget)nw, NULL,
- &nw->core.width, &nw->core.height);
- } else {
- calcSize((Widget)nw, NULL, &nw->core.width, &nw->core.height);
- }
-
- // if resources have changed but size hasn't, layout manually
- // (because Xt just looks at the size)
- if (nw->core.width == ow->core.width &&
- nw->core.height == ow->core.height) {
- if (cls->treeClass.layout) {
- (*cls->treeClass.layout)((Widget)nw, NULL);
- } else {
- layout((Widget)nw, NULL);
- }
- redisp = True;
- }
- }
-
- return redisp;
-}
-
-static void setValuesAlmost(Widget oldWidget, Widget newWidget,
- XtWidgetGeometry *request,
- XtWidgetGeometry *reply) {
- XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(newWidget);
-
- // our parent rejected a geometry request, so accept the compromise
- // and relayout
- if (!reply->request_mode) {
- if (cls->treeClass.layout) {
- (*cls->treeClass.layout)(newWidget, NULL);
- } else {
- layout(newWidget, NULL);
- }
- }
- *request = *reply;
-}
-
-static XtGeometryResult queryGeometry(Widget widget,
- XtWidgetGeometry *request,
- XtWidgetGeometry *reply) {
- XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(widget);
-
- if (!XtIsRealized(widget)) {
- reply->width = XtWidth(widget);
- reply->height = XtHeight(widget);
- } else {
- reply->width = 0;
- reply->height = 0;
- }
- if (cls->treeClass.calcSize) {
- (*cls->treeClass.calcSize)(widget, NULL, &reply->width, &reply->height);
- } else {
- calcSize(widget, NULL, &reply->width, &reply->height);
- }
-#if XmVERSION > 1
- return XmeReplyToQueryGeometry(widget, request, reply);
-#else
- if ((request->request_mode & CWWidth) &&
- (request->request_mode & CWHeight) &&
- request->width == reply->width &&
- request->height == reply->height) {
- return XtGeometryYes;
- }
- if (reply->width == XtWidth(widget) &&
- reply->height == XtHeight(widget)) {
- return XtGeometryNo;
- }
- reply->request_mode = CWWidth | CWHeight;
- return XtGeometryAlmost;
-#endif
-}
-
-static XtGeometryResult geometryManager(Widget widget,
- XtWidgetGeometry *request,
- XtWidgetGeometry *reply) {
- XPDFTreeWidget w = (XPDFTreeWidget)XtParent(widget);
- XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(w);
- Dimension curWidth, curHeight, curBW;
- XtWidgetGeometry parentReq;
- XtGeometryResult result;
-
- // deny any requests for a new position
- if ((request->request_mode & CWX) || (request->request_mode & CWY)) {
- return XtGeometryNo;
- }
-
- // save the current geometry
- curWidth = w->core.width;
- curHeight = w->core.height;
- curBW = w->core.border_width;
-
- // make the requested changes
- if (request->request_mode & CWWidth) {
- w->core.width = request->width;
- }
- if (request->request_mode & CWHeight) {
- w->core.height = request->height;
- }
- if (request->request_mode & CWBorderWidth) {
- w->core.border_width = request->border_width;
- }
-
- // calculate the new ideal size
- parentReq.width = 0;
- parentReq.height = 0;
- if (cls->treeClass.calcSize) {
- (*cls->treeClass.calcSize)((Widget)w, widget,
- &parentReq.width, &reply->height);
- } else {
- calcSize((Widget)w, widget, &parentReq.width, &reply->height);
- }
-
- // send geometry request to our parent
- parentReq.request_mode = CWWidth | CWHeight;
- if (request->request_mode & XtCWQueryOnly) {
- parentReq.request_mode |= XtCWQueryOnly;
- }
- result = XtMakeGeometryRequest((Widget)w, &parentReq, NULL);
- if (result == XtGeometryAlmost) {
- result = XtGeometryNo;
- }
-
- if (result == XtGeometryNo || (request->request_mode & XtCWQueryOnly)) {
- // restore the original geometry
- w->core.width = curWidth;
- w->core.height = curHeight;
- w->core.border_width = curBW;
- } else {
- if (cls->treeClass.layout) {
- (*cls->treeClass.layout)((Widget)w, widget);
- } else {
- layout((Widget)w, widget);
- }
- }
-
- return result;
-}
-
-static void changeManaged(Widget widget) {
- Dimension width, height;
- XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass(widget);
-
- // compute the ideal size
- if (!XtIsRealized(widget)) {
- width = XtWidth(widget);
- height = XtHeight(widget);
- } else {
- width = 0;
- height = 0;
- }
- if (cls->treeClass.calcSize) {
- (*cls->treeClass.calcSize)(widget, NULL, &width, &height);
- } else {
- calcSize(widget, NULL, &width, &height);
- }
-
- // make resize request to parent -- keep asking until we get a yes
- // or no
- while (XtMakeResizeRequest(widget, width, height, &width, &height)
- == XtGeometryAlmost) ;
-
- // relayout
- if (cls->treeClass.layout) {
- (*cls->treeClass.layout)(widget, NULL);
- } else {
- layout(widget, NULL);
- }
-
-#if XmVERSION > 1
- // update keyboard traversal
- XmeNavigChangeManaged(widget);
-#else
- _XmNavigChangeManaged(widget);
-#endif
-}
-
-static void initConstraint(Widget requestWidget, Widget newWidget,
- ArgList args, Cardinal *numArgs) {
- XPDFTreeWidget w = (XPDFTreeWidget)XtParent(newWidget);
- XPDFTreeConstraint c;
-
- c = XPDFTreeCPart(newWidget);
- c->e = (XPDFTreeEntry *)gmalloc(sizeof(XPDFTreeEntry));
- c->e->widget = newWidget;
- c->e->children = NULL;
- c->e->next = NULL;
- if (c->entryParent) {
- insertChildOnList(c->e, &XPDFTreeCPart(c->entryParent)->e->children);
- } else {
- insertChildOnList(c->e, &w->tree.root);
- }
-}
-
-static void destroyConstraint(Widget widget) {
- deleteSubtree(widget);
-}
-
-static void deleteSubtree(Widget widget) {
- XPDFTreeWidget w = (XPDFTreeWidget)XtParent(widget);
- XPDFTreeConstraint c;
-
- c = XPDFTreeCPart(widget);
- if (!c->e) {
- return;
- }
- while (c->e->children) {
- deleteSubtree(c->e->children->widget);
- }
- if (c->entryParent) {
- deleteChildFromList(c->e, &XPDFTreeCPart(c->entryParent)->e->children);
- } else {
- deleteChildFromList(c->e, &w->tree.root);
- }
- gfree(c->e);
- c->e = NULL;
-}
-
-static Boolean constraintSetValues(Widget oldWidget, Widget requestWidget,
- Widget newWidget,
- ArgList args, Cardinal *numArgs) {
- XPDFTreeWidget w = (XPDFTreeWidget)XtParent(newWidget);
- XPDFTreeWidgetClass cls = (XPDFTreeWidgetClass)XtClass((Widget)w);
- XPDFTreeConstraint oc, nc;
- Boolean relayout;
- Dimension width, height;
-
- if (!XtIsManaged(newWidget)) {
- return False;
- }
- oc = XPDFTreeCPart(oldWidget);
- nc = XPDFTreeCPart(newWidget);
- relayout = False;
- if (nc->entryParent != oc->entryParent ||
- nc->entryPosition != oc->entryPosition) {
- if (oc->entryParent) {
- deleteChildFromList(oc->e, &XPDFTreeCPart(oc->entryParent)->e->children);
- } else {
- deleteChildFromList(oc->e, &w->tree.root);
- }
- if (nc->entryParent) {
- insertChildOnList(nc->e, &XPDFTreeCPart(nc->entryParent)->e->children);
- } else {
- insertChildOnList(nc->e, &w->tree.root);
- }
- relayout = True;
- } else if (nc->entryExpanded != oc->entryExpanded) {
- relayout = True;
- }
-
- if (relayout) {
-
- // calculate a new ideal size (reset the widget size first so
- // calcSize will compute a new one)
- width = 0;
- height = 0;
- if (cls->treeClass.calcSize) {
- (*cls->treeClass.calcSize)((Widget)w, NULL, &width, &height);
- } else {
- calcSize((Widget)w, NULL, &width, &height);
- }
-
- // make resize request to parent -- keep asking until we get a yes
- // or no
- while (XtMakeResizeRequest((Widget)w, width, height, &width, &height)
- == XtGeometryAlmost) ;
-
- // relayout the widget
- if (cls->treeClass.layout) {
- (*cls->treeClass.layout)((Widget)w, NULL);
- } else {
- layout((Widget)w, NULL);
- }
- }
-
- return relayout;
-}
-
-static void insertChildOnList(XPDFTreeEntry *e, XPDFTreeEntry **listHead) {
- int pos;
- XPDFTreeEntry *e2;
-
- pos = XPDFTreeCPart(e->widget)->entryPosition;
- if (!*listHead || pos < XPDFTreeCPart((*listHead)->widget)->entryPosition) {
- e->next = *listHead;
- *listHead = e;
- } else {
- for (e2 = *listHead;
- e2->next && pos >= XPDFTreeCPart(e2->next->widget)->entryPosition;
- e2 = e2->next) ;
- e->next = e2->next;
- e2->next = e;
- }
-}
-
-static void deleteChildFromList(XPDFTreeEntry *e, XPDFTreeEntry **listHead) {
- XPDFTreeEntry **p;
-
- for (p = listHead; *p; p = &(*p)->next) {
- if (*p == e) {
- *p = e->next;
- e->next = NULL;
- return;
- }
- }
-}
-
-static void createGC(Widget widget) {
- XPDFTreeWidget w = (XPDFTreeWidget)widget;
- XGCValues gcValues;
-
- gcValues.foreground = w->manager.foreground;
- gcValues.line_width = 0;
- gcValues.line_style = LineSolid;
- w->tree.plainGC = XtGetGC(widget,
- GCForeground | GCLineWidth | GCLineStyle,
- &gcValues);
-
- gcValues.line_style = LineOnOffDash;
- gcValues.dashes = 1;
- gcValues.dash_offset = 0;
- w->tree.dottedGC = XtGetGC(widget,
- GCForeground | GCLineWidth | GCLineStyle |
- GCDashList | GCDashOffset,
- &gcValues);
-}
-
-static void destroyGC(Widget widget) {
- XPDFTreeWidget w = (XPDFTreeWidget)widget;
-
- XtReleaseGC(widget, w->tree.plainGC);
- XtReleaseGC(widget, w->tree.dottedGC);
-}
-
-static void layout(Widget widget, Widget instigator) {
- XPDFTreeWidget w = (XPDFTreeWidget)widget;
- XPDFTreeEntry *e;
- Position x, y;
-
- x = w->tree.marginWidth + xpdfTreeIndent;
- y = w->tree.marginHeight;
- for (e = w->tree.root; e; e = e->next) {
- y = layoutSubtree(w, instigator, e, x, y, True);
- }
-}
-
-static int layoutSubtree(XPDFTreeWidget w, Widget instigator,
- XPDFTreeEntry *e, Position x, Position y,
- Boolean visible) {
- Widget ew;
- XPDFTreeEntry *child;
- XPDFTreeConstraint c;
- int dy;
-
- ew = e->widget;
- if (!XtIsManaged(ew)) {
- return y;
- }
- c = XPDFTreeCPart(ew);
-
- // place this entry
- if (ew) {
- if (visible) {
- if (ew == instigator) {
- ew->core.x = x;
- ew->core.y = y;
- } else {
-#if XmVERSION > 1
- XmeConfigureObject(ew, x, y, ew->core.width, ew->core.height,
- ew->core.border_width);
-#else
- _XmConfigureObject(ew, x, y, ew->core.width, ew->core.height,
- ew->core.border_width);
-#endif
- }
- dy = ew->core.height + 2 * ew->core.border_width;
- // this is a kludge to avoid crashes if the widget becomes too
- // tall
- if ((int)y + dy > 32767) {
- y = 32767;
- } else {
- y += dy;
- }
- }
- }
-
- // place this entry's children
- x += xpdfTreeIndent;
- for (child = e->children; child; child = child->next) {
- y = layoutSubtree(w, instigator, child, x, y,
- visible && (!c || c->entryExpanded));
- }
-
- return y;
-}
-
-static void calcSize(Widget widget, Widget instigator,
- Dimension *totalWidth,
- Dimension *totalHeight) {
- XPDFTreeWidget w = (XPDFTreeWidget)widget;
- XPDFTreeEntry *e;
- int h1;
- Dimension w1, w2, h2;
-
- w1 = h1 = 0;
- for (e = w->tree.root; e; e = e->next) {
- calcSubtreeSize(w, instigator, e, &w2, &h2);
- if (w2 > w1) {
- w1 = w2;
- }
- h1 += (int)h2;
- }
- w1 += xpdfTreeIndent + 2 * w->tree.marginWidth;
- h1 += 2 * (int)w->tree.marginHeight;
- if (h1 == 0) {
- h1 = 1;
- } else if (h1 > 32767) {
- // this is a kludge to avoid crashes if the widget becomes too
- // tall
- h1 = 32767;
- }
- if (!*totalWidth) {
- *totalWidth = w1;
- }
- if (!*totalHeight) {
- *totalHeight = (Dimension)h1;
- }
-}
-
-static void calcSubtreeSize(XPDFTreeWidget w, Widget instigator,
- XPDFTreeEntry *e,
- Dimension *width, Dimension *height) {
- Widget ew;
- XPDFTreeEntry *child;
- XPDFTreeConstraint c;
- XtWidgetGeometry geom;
- int h1;
- Dimension w1, w2, h2;
-
- ew = e->widget;
- if (!XtIsManaged(ew)) {
- *width = *height = 0;
- return;
- }
- c = XPDFTreeCPart(ew);
-
- // get size of this entry
- if (ew) {
- if (!XtIsManaged(ew)) {
- *width = *height = 0;
- return;
- }
- if (ew == instigator) {
- w1 = ew->core.width;
- h1 = (int)ew->core.height;
- } else {
- XtQueryGeometry(ew, NULL, &geom);
- w1 = (geom.request_mode & CWWidth) ? geom.width : ew->core.width;
- h1 = (int)((geom.request_mode & CWHeight) ? geom.height
- : ew->core.height);
- }
- h1 += 2 * (int)ew->core.border_width;
- } else {
- // root of tree
- w1 = 0;
- h1 = 0;
- }
-
- // if this entry is expanded, get size of all of its children
- if (c->entryExpanded) {
- for (child = e->children; child; child = child->next) {
- calcSubtreeSize(w, instigator, child, &w2, &h2);
- w2 += xpdfTreeIndent;
- if (w2 > w1) {
- w1 = w2;
- }
- h1 += (int)h2;
- }
- }
-
- // this is a kludge to avoid crashes if the widget becomes too tall
- if (h1 > 32767) {
- h1 = 32767;
- }
- *width = w1;
- *height = h1;
-}
-
-static Boolean needRelayout(Widget oldWidget, Widget newWidget) {
- XPDFTreeWidget ow = (XPDFTreeWidget)oldWidget;
- XPDFTreeWidget nw = (XPDFTreeWidget)newWidget;
-
- if (nw->tree.marginWidth != ow->tree.marginWidth ||
- nw->tree.marginHeight != ow->tree.marginHeight) {
- return True;
- }
- return False;
-}
-
-static void click(Widget widget, XEvent *event,
- String *params, Cardinal *numParams) {
- XPDFTreeWidget w = (XPDFTreeWidget)widget;
- XButtonPressedEvent *bpe;
- XPDFTreeEntry *e;
- Boolean onExpandIcon;
- XPDFTreeConstraint c;
- XPDFTreeSelectCallbackStruct cbs;
-
- if (event->type != ButtonPress) {
- return;
- }
- bpe = (XButtonPressedEvent *)event;
- if (findPosition(w, bpe->x, bpe->y, &e, &onExpandIcon)) {
- if (onExpandIcon) {
- c = XPDFTreeCPart(e->widget);
- w->tree.redrawY = e->widget->core.y;
- XtVaSetValues(e->widget, XPDFNentryExpanded, !c->entryExpanded, NULL);
- } else {
- XmProcessTraversal(e->widget, XmTRAVERSE_CURRENT);
- XtCallActionProc(widget, "ManagerGadgetActivate", event, NULL, 0);
- cbs.reason = XmCR_ACTIVATE;
- cbs.event = event;
- cbs.selectedItem = e->widget;
- XtCallCallbackList(widget, w->tree.selectCallback, &cbs);
- }
- }
-}
-
-static Boolean findPosition(XPDFTreeWidget w, int x, int y,
- XPDFTreeEntry **e, Boolean *onExpandIcon) {
- XPDFTreeEntry *e2;
-
- for (e2 = w->tree.root; e2; e2 = e2->next) {
- *e = e2;
- if (findPositionInSubtree(w, x, y, e, onExpandIcon)) {
- return True;
- }
- }
- return False;
-}
-
-// If (x,y) falls on either an expand/collapse icon or a label gadget,
-// set *<e> and *<onExpandIcon> and return true.
-static Boolean findPositionInSubtree(XPDFTreeWidget w, int x, int y,
- XPDFTreeEntry **e,
- Boolean *onExpandIcon) {
- Widget child;
- XPDFTreeConstraint c;
- XPDFTreeEntry *e2;
- int y1;
-
- child = (*e)->widget;
- y1 = child->core.y + child->core.height / 2;
- if (x >= child->core.x && x < child->core.x + child->core.width &&
- y >= child->core.y && y < child->core.y + child->core.height) {
- *onExpandIcon = False;
- return True;
- } else if (x >= child->core.x - 16 && x < child->core.x - 4 &&
- y >= y1 - 6 && y < y1 + 6 &&
- (*e)->children) {
- *onExpandIcon = True;
- return True;
- }
- c = XPDFTreeCPart(child);
- if (!c || c->entryExpanded) {
- for (e2 = (*e)->children; e2; e2 = e2->next) {
- *e = e2;
- if (findPositionInSubtree(w, x, y, e, onExpandIcon)) {
- return True;
- }
- }
- }
- return False;
-}
-
-Widget XPDFCreateTree(Widget parent, char *name,
- ArgList argList, Cardinal numArgs) {
- return XtCreateWidget(name, xpdfTreeWidgetClass, parent, argList, numArgs);
-}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFTree.h b/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFTree.h
deleted file mode 100644
index be7293a3c2e..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFTree.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//========================================================================
-//
-// XPDFTree.h
-//
-// Copyright 2002-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-#ifndef XPDFTREE_H
-#define XPDFTREE_H
-
-#include <aconf.h>
-#include <Xm/Xm.h>
-
-extern "C" {
-
-externalref WidgetClass xpdfTreeWidgetClass;
-
-typedef struct _XPDFTreeClassRec *XPDFTreeWidgetClass;
-typedef struct _XPDFTreeRec *XPDFTreeWidget;
-
-#ifndef XPDFIsTree
-#define XPDFIsTree(w) XtIsSubclass(w, xpdfTreeWidgetClass)
-#endif
-
-#define XPDFNentryParent "entryParent"
-#define XPDFNentryExpanded "entryExpanded"
-#define XPDFNentryPosition "entryPosition"
-#define XPDFNselectionCallback "selectionCallback"
-
-#define XPDFCentryParent "EntryParent"
-#define XPDFCentryExpanded "EntryExpanded"
-#define XPDFCentryPosition "EntryPosition"
-
-typedef struct {
- int reason;
- XEvent *event;
- Widget selectedItem;
-} XPDFTreeSelectCallbackStruct;
-
-extern Widget XPDFCreateTree(Widget parent, char *name,
- ArgList argList, Cardinal argCount);
-
-} // extern "C"
-
-#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFTreeP.h b/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFTreeP.h
deleted file mode 100644
index 85cb12e5118..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFTreeP.h
+++ /dev/null
@@ -1,88 +0,0 @@
-//========================================================================
-//
-// XPDFTreeP.h
-//
-// Copyright 2002-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-#ifndef XPDFTREEP_H
-#define XPDFTREEP_H
-
-#include <aconf.h>
-#include <Xm/ManagerP.h>
-#include "XPDFTree.h"
-
-extern "C" {
-
-typedef void (*XPDFLayoutProc)(Widget widget, Widget instigator);
-typedef void (*XPDFCalcSizeProc)(Widget widget, Widget instigator,
- Dimension *totalWidth,
- Dimension *totalHeight);
-typedef Boolean (*XPDFNeedRelayoutProc)(Widget oldWidget, Widget newWidget);
-
-#define XPDFInheritCreateGC ((XtWidgetProc)_XtInherit)
-#define XPDFInheritDestroyGC ((XtWidgetProc)_XtInherit)
-#define XPDFInheritLayout ((XPDFLayoutProc)_XtInherit)
-#define XPDFInheritCalcSize ((XPDFCalcSizeProc)_XtInherit)
-#define XPDFInheritNeedRelayout ((XPDFNeedRelayoutProc)_XtInherit)
-
-typedef struct {
- XtWidgetProc createGC;
- XtWidgetProc destroyGC;
- XPDFLayoutProc layout;
- XPDFCalcSizeProc calcSize;
- XPDFNeedRelayoutProc needRelayout;
- XtPointer extension;
-} XPDFTreeClassPart;
-
-typedef struct _XPDFTreeClassRec {
- CoreClassPart coreClass;
- CompositeClassPart compositeClass;
- ConstraintClassPart constraintClass;
- XmManagerClassPart managerClass;
- XPDFTreeClassPart treeClass;
-} XPDFTreeClassRec;
-
-externalref XPDFTreeClassRec xpdfTreeClassRec;
-
-typedef struct _XPDFTreeEntry XPDFTreeEntry;
-
-typedef struct {
- Dimension marginWidth;
- Dimension marginHeight;
- XtCallbackList selectCallback;
- GC plainGC;
- GC dottedGC;
- XPDFTreeEntry *root;
- int redrawY;
-} XPDFTreePart;
-
-typedef struct _XPDFTreeRec {
- CorePart core;
- CompositePart composite;
- ConstraintPart constraint;
- XmManagerPart manager;
- XPDFTreePart tree;
-} XPDFTreeRec;
-
-#define XPDFTreeIndex (XmManagerIndex + 1)
-
-typedef struct _XPDFTreeConstraintPart {
- Widget entryParent;
- Boolean entryExpanded;
- int entryPosition;
- XPDFTreeEntry *e;
-} XPDFTreeConstraintPart, *XPDFTreeConstraint;
-
-typedef struct _XPDFTreeConstraintRec {
- XmManagerConstraintPart manager;
- XPDFTreeConstraintPart tree;
-} XPDFTreeConstraintRec, *XPDFTreeConstraintPtr;
-
-#define XPDFTreeCPart(w) \
- (&((XPDFTreeConstraintPtr)(w)->core.constraints)->tree)
-
-} // extern "C"
-
-#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFViewer.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFViewer.cc
deleted file mode 100644
index 4292a0e4a7f..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFViewer.cc
+++ /dev/null
@@ -1,3582 +0,0 @@
-//========================================================================
-//
-// XPDFViewer.cc
-//
-// Copyright 2002-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-#include <aconf.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <X11/keysym.h>
-#include <X11/cursorfont.h>
-#ifdef HAVE_X11_XPM_H
-#include <X11/xpm.h>
-#endif
-#if defined(__sgi) && (XmVERSION <= 1)
-#define Object XtObject
-#include <Sgm/HPanedW.h>
-#undef Object
-#endif
-#include "gmem.h"
-#include "gfile.h"
-#include "GString.h"
-#include "GList.h"
-#include "Error.h"
-#include "GlobalParams.h"
-#include "PDFDoc.h"
-#include "Link.h"
-#include "ErrorCodes.h"
-#include "Outline.h"
-#include "UnicodeMap.h"
-#ifndef DISABLE_OUTLINE
-#define Object XtObject
-#include "XPDFTree.h"
-#undef Object
-#endif
-#include "XPDFApp.h"
-#include "XPDFViewer.h"
-#include "PSOutputDev.h"
-#include "config.h"
-
-// these macro defns conflict with xpdf's Object class
-#ifdef LESSTIF_VERSION
-#undef XtDisplay
-#undef XtScreen
-#undef XtWindow
-#undef XtParent
-#undef XtIsRealized
-#endif
-
-#if XmVERSION <= 1
-#define XmSET True
-#define XmUNSET False
-#endif
-
-// hack around old X includes which are missing these symbols
-#ifndef XK_Page_Up
-#define XK_Page_Up 0xFF55
-#endif
-#ifndef XK_Page_Down
-#define XK_Page_Down 0xFF56
-#endif
-#ifndef XK_KP_Home
-#define XK_KP_Home 0xFF95
-#endif
-#ifndef XK_KP_Left
-#define XK_KP_Left 0xFF96
-#endif
-#ifndef XK_KP_Up
-#define XK_KP_Up 0xFF97
-#endif
-#ifndef XK_KP_Right
-#define XK_KP_Right 0xFF98
-#endif
-#ifndef XK_KP_Down
-#define XK_KP_Down 0xFF99
-#endif
-#ifndef XK_KP_Prior
-#define XK_KP_Prior 0xFF9A
-#endif
-#ifndef XK_KP_Page_Up
-#define XK_KP_Page_Up 0xFF9A
-#endif
-#ifndef XK_KP_Next
-#define XK_KP_Next 0xFF9B
-#endif
-#ifndef XK_KP_Page_Down
-#define XK_KP_Page_Down 0xFF9B
-#endif
-#ifndef XK_KP_End
-#define XK_KP_End 0xFF9C
-#endif
-#ifndef XK_KP_Begin
-#define XK_KP_Begin 0xFF9D
-#endif
-#ifndef XK_KP_Insert
-#define XK_KP_Insert 0xFF9E
-#endif
-#ifndef XK_KP_Delete
-#define XK_KP_Delete 0xFF9F
-#endif
-
-//------------------------------------------------------------------------
-// GUI includes
-//------------------------------------------------------------------------
-
-#include "xpdfIcon.xpm"
-#include "leftArrow.xbm"
-#include "leftArrowDis.xbm"
-#include "dblLeftArrow.xbm"
-#include "dblLeftArrowDis.xbm"
-#include "rightArrow.xbm"
-#include "rightArrowDis.xbm"
-#include "dblRightArrow.xbm"
-#include "dblRightArrowDis.xbm"
-#include "backArrow.xbm"
-#include "backArrowDis.xbm"
-#include "forwardArrow.xbm"
-#include "forwardArrowDis.xbm"
-#include "find.xbm"
-#include "findDis.xbm"
-#include "print.xbm"
-#include "printDis.xbm"
-#include "about.xbm"
-#include "about-text.h"
-
-//------------------------------------------------------------------------
-
-struct ZoomMenuInfo {
- const char *label;
- double zoom;
-};
-
-static ZoomMenuInfo zoomMenuInfo[nZoomMenuItems] = {
- { "400%", 400 },
- { "200%", 200 },
- { "150%", 150 },
- { "125%", 125 },
- { "100%", 100 },
- { "50%", 50 },
- { "25%", 25 },
- { "12.5%", 12.5 },
- { "fit page", zoomPage },
- { "fit width", zoomWidth }
-};
-
-#define maxZoomIdx 0
-#define defZoomIdx 3
-#define minZoomIdx 7
-#define zoomPageIdx 8
-#define zoomWidthIdx 9
-
-//------------------------------------------------------------------------
-
-#define cmdMaxArgs 8
-
-XPDFViewerCmd XPDFViewer::cmdTab[] = {
- { "about", 0, gFalse, gFalse, &XPDFViewer::cmdAbout },
- { "closeOutline", 0, gFalse, gFalse, &XPDFViewer::cmdCloseOutline },
- { "closeWindow", 0, gFalse, gFalse, &XPDFViewer::cmdCloseWindow },
- { "closeWindowOrQuit", 0, gFalse, gFalse, &XPDFViewer::cmdCloseWindowOrQuit },
- { "continuousMode", 0, gFalse, gFalse, &XPDFViewer::cmdContinuousMode },
- { "endPan", 0, gTrue, gTrue, &XPDFViewer::cmdEndPan },
- { "endSelection", 0, gTrue, gTrue, &XPDFViewer::cmdEndSelection },
- { "find", 0, gTrue, gFalse, &XPDFViewer::cmdFind },
- { "findNext", 0, gTrue, gFalse, &XPDFViewer::cmdFindNext },
- { "focusToDocWin", 0, gFalse, gFalse, &XPDFViewer::cmdFocusToDocWin },
- { "focusToPageNum", 0, gFalse, gFalse, &XPDFViewer::cmdFocusToPageNum },
- { "followLink", 0, gTrue, gTrue, &XPDFViewer::cmdFollowLink },
- { "followLinkInNewWin", 0, gTrue, gTrue, &XPDFViewer::cmdFollowLinkInNewWin },
- { "followLinkInNewWinNoSel", 0, gTrue, gTrue, &XPDFViewer::cmdFollowLinkInNewWinNoSel },
- { "followLinkNoSel", 0, gTrue, gTrue, &XPDFViewer::cmdFollowLinkNoSel },
- { "fullScreenMode", 0, gFalse, gFalse, &XPDFViewer::cmdFullScreenMode },
- { "goBackward", 0, gFalse, gFalse, &XPDFViewer::cmdGoBackward },
- { "goForward", 0, gFalse, gFalse, &XPDFViewer::cmdGoForward },
- { "gotoDest", 1, gTrue, gFalse, &XPDFViewer::cmdGotoDest },
- { "gotoLastPage", 0, gTrue, gFalse, &XPDFViewer::cmdGotoLastPage },
- { "gotoLastPageNoScroll", 0, gTrue, gFalse, &XPDFViewer::cmdGotoLastPageNoScroll },
- { "gotoPage", 1, gTrue, gFalse, &XPDFViewer::cmdGotoPage },
- { "gotoPageNoScroll", 1, gTrue, gFalse, &XPDFViewer::cmdGotoPageNoScroll },
- { "nextPage", 0, gTrue, gFalse, &XPDFViewer::cmdNextPage },
- { "nextPageNoScroll", 0, gTrue, gFalse, &XPDFViewer::cmdNextPageNoScroll },
- { "open", 0, gFalse, gFalse, &XPDFViewer::cmdOpen },
- { "openFile", 1, gFalse, gFalse, &XPDFViewer::cmdOpenFile },
- { "openFileAtDest", 2, gFalse, gFalse, &XPDFViewer::cmdOpenFileAtDest },
- { "openFileAtDestInNewWin", 2, gFalse, gFalse, &XPDFViewer::cmdOpenFileAtDestInNewWin },
- { "openFileAtPage", 2, gFalse, gFalse, &XPDFViewer::cmdOpenFileAtPage },
- { "openFileAtPageInNewWin", 2, gFalse, gFalse, &XPDFViewer::cmdOpenFileAtPageInNewWin },
- { "openFileInNewWin", 1, gFalse, gFalse, &XPDFViewer::cmdOpenFileInNewWin },
- { "openInNewWin", 0, gFalse, gFalse, &XPDFViewer::cmdOpenInNewWin },
- { "openOutline", 0, gFalse, gFalse, &XPDFViewer::cmdOpenOutline },
- { "pageDown", 0, gTrue, gFalse, &XPDFViewer::cmdPageDown },
- { "pageUp", 0, gTrue, gFalse, &XPDFViewer::cmdPageUp },
- { "postPopupMenu", 0, gFalse, gTrue, &XPDFViewer::cmdPostPopupMenu },
- { "prevPage", 0, gTrue, gFalse, &XPDFViewer::cmdPrevPage },
- { "prevPageNoScroll", 0, gTrue, gFalse, &XPDFViewer::cmdPrevPageNoScroll },
- { "print", 0, gTrue, gFalse, &XPDFViewer::cmdPrint },
- { "quit", 0, gFalse, gFalse, &XPDFViewer::cmdQuit },
- { "raise", 0, gFalse, gFalse, &XPDFViewer::cmdRaise },
- { "redraw", 0, gTrue, gFalse, &XPDFViewer::cmdRedraw },
- { "reload", 0, gTrue, gFalse, &XPDFViewer::cmdReload },
- { "rotateCCW", 0, gTrue, gFalse, &XPDFViewer::cmdRotateCCW },
- { "rotateCW", 0, gTrue, gFalse, &XPDFViewer::cmdRotateCW },
- { "run", 1, gFalse, gFalse, &XPDFViewer::cmdRun },
- { "scrollDown", 1, gTrue, gFalse, &XPDFViewer::cmdScrollDown },
- { "scrollDownNextPage", 1, gTrue, gFalse, &XPDFViewer::cmdScrollDownNextPage },
- { "scrollLeft", 1, gTrue, gFalse, &XPDFViewer::cmdScrollLeft },
- { "scrollOutlineDown", 1, gTrue, gFalse, &XPDFViewer::cmdScrollOutlineDown },
- { "scrollOutlineUp", 1, gTrue, gFalse, &XPDFViewer::cmdScrollOutlineUp },
- { "scrollRight", 1, gTrue, gFalse, &XPDFViewer::cmdScrollRight },
- { "scrollToBottomEdge", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToBottomEdge },
- { "scrollToBottomRight", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToBottomRight },
- { "scrollToLeftEdge", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToLeftEdge },
- { "scrollToRightEdge", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToRightEdge },
- { "scrollToTopEdge", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToTopEdge },
- { "scrollToTopLeft", 0, gTrue, gFalse, &XPDFViewer::cmdScrollToTopLeft },
- { "scrollUp", 1, gTrue, gFalse, &XPDFViewer::cmdScrollUp },
- { "scrollUpPrevPage", 1, gTrue, gFalse, &XPDFViewer::cmdScrollUpPrevPage },
- { "setSelection", 5, gTrue, gFalse, &XPDFViewer::cmdSetSelection },
- { "singlePageMode", 0, gFalse, gFalse, &XPDFViewer::cmdSinglePageMode },
- { "startPan", 0, gTrue, gTrue, &XPDFViewer::cmdStartPan },
- { "startSelection", 0, gTrue, gTrue, &XPDFViewer::cmdStartSelection },
- { "toggleContinuousMode", 0, gFalse, gFalse, &XPDFViewer::cmdToggleContinuousMode },
- { "toggleFullScreenMode", 0, gFalse, gFalse, &XPDFViewer::cmdToggleFullScreenMode },
- { "toggleOutline", 0, gFalse, gFalse, &XPDFViewer::cmdToggleOutline },
- { "windowMode", 0, gFalse, gFalse, &XPDFViewer::cmdWindowMode },
- { "zoomFitPage", 0, gFalse, gFalse, &XPDFViewer::cmdZoomFitPage },
- { "zoomFitWidth", 0, gFalse, gFalse, &XPDFViewer::cmdZoomFitWidth },
- { "zoomIn", 0, gFalse, gFalse, &XPDFViewer::cmdZoomIn },
- { "zoomOut", 0, gFalse, gFalse, &XPDFViewer::cmdZoomOut },
- { "zoomPercent", 1, gFalse, gFalse, &XPDFViewer::cmdZoomPercent },
- { "zoomToSelection", 0, gTrue, gFalse, &XPDFViewer::cmdZoomToSelection }
-};
-
-#define nCmds (sizeof(cmdTab) / sizeof(XPDFViewerCmd))
-
-//------------------------------------------------------------------------
-
-XPDFViewer::XPDFViewer(XPDFApp *appA, GString *fileName,
- int pageA, GString *destName, GBool fullScreen,
- GString *ownerPassword, GString *userPassword) {
- LinkDest *dest;
- int pg;
- double z;
-
- app = appA;
- win = NULL;
- core = NULL;
- ok = gFalse;
-#ifndef DISABLE_OUTLINE
- outlineLabels = NULL;
- outlineLabelsLength = outlineLabelsSize = 0;
- outlinePaneWidth = 175;
-#endif
-
- // do Motif-specific initialization and create the window;
- // this also creates the core object
- initWindow(fullScreen);
- initAboutDialog();
- initFindDialog();
- initPrintDialog();
- openDialog = NULL;
- saveAsDialog = NULL;
-
- dest = NULL; // make gcc happy
- pg = pageA; // make gcc happy
-
- if (fileName) {
- if (loadFile(fileName, ownerPassword, userPassword)) {
- getPageAndDest(pageA, destName, &pg, &dest);
-#ifndef DISABLE_OUTLINE
- if (outlineScroll != None &&
- core->getDoc()->getOutline()->getItems() &&
- core->getDoc()->getOutline()->getItems()->getLength() > 0) {
- XtVaSetValues(outlineScroll, XmNwidth, outlinePaneWidth, NULL);
- }
-#endif
- } else {
- return;
- }
- }
- core->resizeToPage(pg);
-
- // map the window -- we do this after calling resizeToPage to avoid
- // an annoying on-screen resize
- mapWindow();
-
- // display the first page
- z = core->getZoom();
- if (dest) {
- displayDest(dest, z, core->getRotate(), gTrue);
- delete dest;
- } else {
- displayPage(pg, z, core->getRotate(), gTrue, gTrue);
- }
-
- ok = gTrue;
-}
-
-XPDFViewer::XPDFViewer(XPDFApp *appA, PDFDoc *doc, int pageA,
- GString *destName, GBool fullScreen) {
- LinkDest *dest;
- int pg;
- double z;
-
- app = appA;
- win = NULL;
- core = NULL;
- ok = gFalse;
-#ifndef DISABLE_OUTLINE
- outlineLabels = NULL;
- outlineLabelsLength = outlineLabelsSize = 0;
- outlinePaneWidth = 175;
-#endif
-
- // do Motif-specific initialization and create the window;
- // this also creates the core object
- initWindow(fullScreen);
- initAboutDialog();
- initFindDialog();
- initPrintDialog();
- openDialog = NULL;
- saveAsDialog = NULL;
-
- dest = NULL; // make gcc happy
- pg = pageA; // make gcc happy
-
- if (doc) {
- core->loadDoc(doc);
- getPageAndDest(pageA, destName, &pg, &dest);
-#ifndef DISABLE_OUTLINE
- if (outlineScroll != None &&
- core->getDoc()->getOutline()->getItems() &&
- core->getDoc()->getOutline()->getItems()->getLength() > 0) {
- XtVaSetValues(outlineScroll, XmNwidth, outlinePaneWidth, NULL);
- }
-#endif
- }
- core->resizeToPage(pg);
-
- // map the window -- we do this after calling resizeToPage to avoid
- // an annoying on-screen resize
- mapWindow();
-
- // display the first page
- z = core->getZoom();
- if (dest) {
- displayDest(dest, z, core->getRotate(), gTrue);
- delete dest;
- } else {
- displayPage(pg, z, core->getRotate(), gTrue, gTrue);
- }
-
- ok = gTrue;
-}
-
-XPDFViewer::~XPDFViewer() {
- delete core;
- if (aboutBigFont) {
- XmFontListFree(aboutBigFont);
- }
- if (aboutVersionFont) {
- XmFontListFree(aboutVersionFont);
- }
- if (aboutFixedFont) {
- XmFontListFree(aboutFixedFont);
- }
- closeWindow();
-#ifndef DISABLE_OUTLINE
- if (outlineLabels) {
- gfree(outlineLabels);
- }
-#endif
-}
-
-void XPDFViewer::open(GString *fileName, int pageA, GString *destName) {
- LinkDest *dest;
- int pg;
- double z;
-
- if (!core->getDoc() ||
- !core->getDoc()->getFileName() ||
- fileName->cmp(core->getDoc()->getFileName())) {
- if (!loadFile(fileName, NULL, NULL)) {
- return;
- }
- }
- getPageAndDest(pageA, destName, &pg, &dest);
- z = core->getZoom();
- if (dest) {
- displayDest(dest, z, core->getRotate(), gTrue);
- delete dest;
- } else {
- displayPage(pg, z, core->getRotate(), gTrue, gTrue);
- }
-}
-
-void XPDFViewer::clear() {
- char *title;
- XmString s;
-
- core->clear();
-
- // set up title
- title = app->getTitle() ? app->getTitle()->getCString()
- : (char *)xpdfAppName;
- XtVaSetValues(win, XmNtitle, title, XmNiconName, title, NULL);
-
- if (toolBar != None) {
-
- // set up number-of-pages display
- s = XmStringCreateLocalized("");
- XtVaSetValues(pageNumText, XmNlabelString, s, NULL);
- XmStringFree(s);
- s = XmStringCreateLocalized(" of 0");
- XtVaSetValues(pageCountLabel, XmNlabelString, s, NULL);
- XmStringFree(s);
-
- // disable buttons
- XtVaSetValues(prevTenPageBtn, XmNsensitive, False, NULL);
- XtVaSetValues(prevPageBtn, XmNsensitive, False, NULL);
- XtVaSetValues(nextTenPageBtn, XmNsensitive, False, NULL);
- XtVaSetValues(nextPageBtn, XmNsensitive, False, NULL);
- }
-
- // remove the old outline
-#ifndef DISABLE_OUTLINE
- setupOutline();
-#endif
-}
-
-//------------------------------------------------------------------------
-// load / display
-//------------------------------------------------------------------------
-
-GBool XPDFViewer::loadFile(GString *fileName, GString *ownerPassword,
- GString *userPassword) {
- return core->loadFile(fileName, ownerPassword, userPassword) == errNone;
-}
-
-void XPDFViewer::reloadFile() {
- int pg;
-
- if (!core->getDoc() || !core->getDoc()->getFileName()) {
- return;
- }
- pg = core->getPageNum();
- loadFile(core->getDoc()->getFileName());
- if (pg > core->getDoc()->getNumPages()) {
- pg = core->getDoc()->getNumPages();
- }
- displayPage(pg, core->getZoom(), core->getRotate(), gFalse, gFalse);
-}
-
-void XPDFViewer::displayPage(int pageA, double zoomA, int rotateA,
- GBool scrollToTop, GBool addToHist) {
- core->displayPage(pageA, zoomA, rotateA, scrollToTop, addToHist);
-}
-
-void XPDFViewer::displayDest(LinkDest *dest, double zoomA, int rotateA,
- GBool addToHist) {
- core->displayDest(dest, zoomA, rotateA, addToHist);
-}
-
-void XPDFViewer::getPageAndDest(int pageA, GString *destName,
- int *pageOut, LinkDest **destOut) {
- Ref pageRef;
-
- // find the page number for a named destination
- *pageOut = pageA;
- *destOut = NULL;
- if (destName && (*destOut = core->getDoc()->findDest(destName))) {
- if ((*destOut)->isPageRef()) {
- pageRef = (*destOut)->getPageRef();
- *pageOut = core->getDoc()->findPage(pageRef.num, pageRef.gen);
- } else {
- *pageOut = (*destOut)->getPageNum();
- }
- }
-
- if (*pageOut <= 0) {
- *pageOut = 1;
- }
- if (*pageOut > core->getDoc()->getNumPages()) {
- *pageOut = core->getDoc()->getNumPages();
- }
-}
-
-//------------------------------------------------------------------------
-// hyperlinks / actions
-//------------------------------------------------------------------------
-
-void XPDFViewer::doLink(int wx, int wy, GBool onlyIfNoSelection,
- GBool newWin) {
- XPDFViewer *newViewer;
- LinkAction *action;
- int pg, selPg;
- double xu, yu, selULX, selULY, selLRX, selLRY;
-
- if (core->getHyperlinksEnabled() &&
- core->cvtWindowToUser(wx, wy, &pg, &xu, &yu) &&
- !(onlyIfNoSelection &&
- core->getSelection(&selPg, &selULX, &selULY, &selLRX, &selLRY))) {
- if ((action = core->findLink(pg, xu, yu))) {
- if (newWin &&
- core->getDoc()->getFileName() &&
- (action->getKind() == actionGoTo ||
- action->getKind() == actionGoToR ||
- (action->getKind() == actionNamed &&
- ((LinkNamed *)action)->getName()->cmp("Quit")))) {
- newViewer = app->open(core->getDoc()->getFileName());
- newViewer->core->doAction(action);
- } else {
- core->doAction(action);
- }
- }
- }
-}
-
-void XPDFViewer::actionCbk(void *data, char *action) {
- XPDFViewer *viewer = (XPDFViewer *)data;
-
- if (!strcmp(action, "Quit")) {
- viewer->app->quit();
- }
-}
-
-//------------------------------------------------------------------------
-// keyboard/mouse input
-//------------------------------------------------------------------------
-
-void XPDFViewer::keyPressCbk(void *data, KeySym key, Guint modifiers,
- XEvent *event) {
- XPDFViewer *viewer = (XPDFViewer *)data;
- int keyCode;
- GList *cmds;
- int i;
-
- if (key >= 0x20 && key <= 0xfe) {
- keyCode = (int)key;
- } else if (key == XK_Tab ||
- key == XK_KP_Tab) {
- keyCode = xpdfKeyCodeTab;
- } else if (key == XK_Return) {
- keyCode = xpdfKeyCodeReturn;
- } else if (key == XK_KP_Enter) {
- keyCode = xpdfKeyCodeEnter;
- } else if (key == XK_BackSpace) {
- keyCode = xpdfKeyCodeBackspace;
- } else if (key == XK_Insert ||
- key == XK_KP_Insert) {
- keyCode = xpdfKeyCodeInsert;
- } else if (key == XK_Delete ||
- key == XK_KP_Delete) {
- keyCode = xpdfKeyCodeDelete;
- } else if (key == XK_Home ||
- key == XK_KP_Home) {
- keyCode = xpdfKeyCodeHome;
- } else if (key == XK_End ||
- key == XK_KP_End) {
- keyCode = xpdfKeyCodeEnd;
- } else if (key == XK_Page_Up ||
- key == XK_KP_Page_Up) {
- keyCode = xpdfKeyCodePgUp;
- } else if (key == XK_Page_Down ||
- key == XK_KP_Page_Down) {
- keyCode = xpdfKeyCodePgDn;
- } else if (key == XK_Left ||
- key == XK_KP_Left) {
- keyCode = xpdfKeyCodeLeft;
- } else if (key == XK_Right ||
- key == XK_KP_Right) {
- keyCode = xpdfKeyCodeRight;
- } else if (key == XK_Up ||
- key == XK_KP_Up) {
- keyCode = xpdfKeyCodeUp;
- } else if (key == XK_Down ||
- key == XK_KP_Down) {
- keyCode = xpdfKeyCodeDown;
- } else if (key >= XK_F1 && key <= XK_F35) {
- keyCode = xpdfKeyCodeF1 + (key - XK_F1);
- } else {
- return;
- }
-
- if ((cmds = globalParams->getKeyBinding(keyCode,
- viewer->getModifiers(modifiers),
- viewer->getContext(modifiers)))) {
- for (i = 0; i < cmds->getLength(); ++i) {
- viewer->execCmd((GString *)cmds->get(i), event);
- }
- deleteGList(cmds, GString);
- }
-}
-
-void XPDFViewer::mouseCbk(void *data, XEvent *event) {
- XPDFViewer *viewer = (XPDFViewer *)data;
- int keyCode;
- GList *cmds;
- int i;
-
- if (event->type == ButtonPress) {
- if (event->xbutton.button >= 1 && event->xbutton.button <= 32) {
- keyCode = xpdfKeyCodeMousePress1 + event->xbutton.button - 1;
- } else {
- return;
- }
- } else if (event->type == ButtonRelease) {
- if (event->xbutton.button >= 1 && event->xbutton.button <= 32) {
- keyCode = xpdfKeyCodeMouseRelease1 + event->xbutton.button - 1;
- } else {
- return;
- }
- } else {
- return;
- }
-
- if ((cmds = globalParams->getKeyBinding(keyCode,
- viewer->getModifiers(
- event->xkey.state),
- viewer->getContext(
- event->xkey.state)))) {
- for (i = 0; i < cmds->getLength(); ++i) {
- viewer->execCmd((GString *)cmds->get(i), event);
- }
- deleteGList(cmds, GString);
- }
-}
-
-int XPDFViewer::getModifiers(Guint modifiers) {
- int mods;
-
- mods = 0;
- if (modifiers & ShiftMask) {
- mods |= xpdfKeyModShift;
- }
- if (modifiers & ControlMask) {
- mods |= xpdfKeyModCtrl;
- }
- if (modifiers & Mod1Mask) {
- mods |= xpdfKeyModAlt;
- }
- return mods;
-}
-
-int XPDFViewer::getContext(Guint modifiers) {
- int context;
-
- context = (core->getFullScreen() ? xpdfKeyContextFullScreen
- : xpdfKeyContextWindow) |
- (core->getContinuousMode() ? xpdfKeyContextContinuous
- : xpdfKeyContextSinglePage) |
- (core->getLinkAction() ? xpdfKeyContextOverLink
- : xpdfKeyContextOffLink) |
- ((modifiers & Mod5Mask) ? xpdfKeyContextScrLockOn
- : xpdfKeyContextScrLockOff);
- return context;
-}
-
-void XPDFViewer::execCmd(GString *cmd, XEvent *event) {
- GString *name;
- GString *args[cmdMaxArgs];
- char *p0, *p1;
- int nArgs, i;
- int a, b, m, cmp;
-
- //----- parse the command
- name = NULL;
- nArgs = 0;
- for (i = 0; i < cmdMaxArgs; ++i) {
- args[i] = NULL;
- }
- p0 = cmd->getCString();
- for (p1 = p0; *p1 && isalnum(*p1); ++p1) ;
- if (p1 == p0) {
- goto err1;
- }
- name = new GString(p0, p1 - p0);
- if (*p1 == '(') {
- while (nArgs < cmdMaxArgs) {
- p0 = p1 + 1;
- for (p1 = p0; *p1 && *p1 != ',' && *p1 != ')'; ++p1) ;
- args[nArgs++] = new GString(p0, p1 - p0);
- if (*p1 != ',') {
- break;
- }
- }
- if (*p1 != ')') {
- goto err1;
- }
- ++p1;
- }
- if (*p1) {
- goto err1;
- }
-
- //----- find the command
- a = -1;
- b = nCmds;
- // invariant: cmdTab[a].name < name < cmdTab[b].name
- while (b - a > 1) {
- m = (a + b) / 2;
- cmp = strcmp(cmdTab[m].name, name->getCString());
- if (cmp < 0) {
- a = m;
- } else if (cmp > 0) {
- b = m;
- } else {
- a = b = m;
- }
- }
- if (cmp != 0) {
- goto err1;
- }
-
- //----- execute the command
- if (nArgs != cmdTab[a].nArgs ||
- (cmdTab[a].requiresEvent && !event)) {
- goto err1;
- }
- if (cmdTab[a].requiresDoc && !core->getDoc()) {
- // don't issue an error message for this -- it happens, e.g., when
- // clicking in a window with no open PDF file
- goto err2;
- }
- (this->*cmdTab[a].func)(args, nArgs, event);
-
- //----- clean up
- delete name;
- for (i = 0; i < nArgs; ++i) {
- if (args[i]) {
- delete args[i];
- }
- }
- return;
-
- err1:
- error(errConfig, -1, "Invalid command syntax: '{0:t}'", cmd);
- err2:
- if (name) {
- delete name;
- }
- for (i = 0; i < nArgs; ++i) {
- if (args[i]) {
- delete args[i];
- }
- }
-}
-
-//------------------------------------------------------------------------
-// command functions
-//------------------------------------------------------------------------
-
-static int mouseX(XEvent *event) {
- switch (event->type) {
- case ButtonPress:
- case ButtonRelease:
- return event->xbutton.x;
- case KeyPress:
- return event->xkey.x;
- }
- return 0;
-}
-
-static int mouseY(XEvent *event) {
- switch (event->type) {
- case ButtonPress:
- case ButtonRelease:
- return event->xbutton.y;
- case KeyPress:
- return event->xkey.y;
- }
- return 0;
-}
-
-void XPDFViewer::cmdAbout(GString *args[], int nArgs,
- XEvent *event) {
- XtManageChild(aboutDialog);
-}
-
-void XPDFViewer::cmdCloseOutline(GString *args[], int nArgs,
- XEvent *event) {
-#ifndef DISABLE_OUTLINE
- Dimension w;
-
- if (outlineScroll == None) {
- return;
- }
- XtVaGetValues(outlineScroll, XmNwidth, &w, NULL);
- if (w > 1) {
- outlinePaneWidth = w;
- // this ugly kludge is apparently the only way to resize the panes
- // within an XmPanedWindow
- XtVaSetValues(outlineScroll, XmNpaneMinimum, 1,
- XmNpaneMaximum, 1, NULL);
- XtVaSetValues(outlineScroll, XmNpaneMinimum, 1,
- XmNpaneMaximum, 10000, NULL);
- }
-#endif
-}
-
-void XPDFViewer::cmdCloseWindow(GString *args[], int nArgs,
- XEvent *event) {
- app->close(this, gFalse);
-}
-
-void XPDFViewer::cmdCloseWindowOrQuit(GString *args[], int nArgs,
- XEvent *event) {
- app->close(this, gTrue);
-}
-
-void XPDFViewer::cmdContinuousMode(GString *args[], int nArgs,
- XEvent *event) {
- Widget btn;
-
- if (core->getContinuousMode()) {
- return;
- }
- core->setContinuousMode(gTrue);
-
- btn = XtNameToWidget(popupMenu, "continuousMode");
- XtVaSetValues(btn, XmNset, XmSET, NULL);
-}
-
-void XPDFViewer::cmdEndPan(GString *args[], int nArgs,
- XEvent *event) {
- core->endPan(mouseX(event), mouseY(event));
-}
-
-void XPDFViewer::cmdEndSelection(GString *args[], int nArgs,
- XEvent *event) {
- core->endSelection(mouseX(event), mouseY(event));
-}
-
-void XPDFViewer::cmdFind(GString *args[], int nArgs,
- XEvent *event) {
- mapFindDialog();
-}
-
-void XPDFViewer::cmdFindNext(GString *args[], int nArgs,
- XEvent *event) {
- doFind(gTrue);
-}
-
-void XPDFViewer::cmdFocusToDocWin(GString *args[], int nArgs,
- XEvent *event) {
- core->takeFocus();
-}
-
-void XPDFViewer::cmdFocusToPageNum(GString *args[], int nArgs,
- XEvent *event) {
- if (toolBar != None) {
- XmTextFieldSetSelection(pageNumText, 0,
- strlen(XmTextFieldGetString(pageNumText)),
- XtLastTimestampProcessed(display));
- XmProcessTraversal(pageNumText, XmTRAVERSE_CURRENT);
- }
-}
-
-void XPDFViewer::cmdFollowLink(GString *args[], int nArgs,
- XEvent *event) {
- doLink(mouseX(event), mouseY(event), gFalse, gFalse);
-}
-
-void XPDFViewer::cmdFollowLinkInNewWin(GString *args[], int nArgs,
- XEvent *event) {
- doLink(mouseX(event), mouseY(event), gFalse, gTrue);
-}
-
-void XPDFViewer::cmdFollowLinkInNewWinNoSel(GString *args[], int nArgs,
- XEvent *event) {
- doLink(mouseX(event), mouseY(event), gTrue, gTrue);
-}
-
-void XPDFViewer::cmdFollowLinkNoSel(GString *args[], int nArgs,
- XEvent *event) {
- doLink(mouseX(event), mouseY(event), gTrue, gFalse);
-}
-
-void XPDFViewer::cmdFullScreenMode(GString *args[], int nArgs,
- XEvent *event) {
- PDFDoc *doc;
- XPDFViewer *viewer;
- int pg;
- Widget btn;
-
- if (core->getFullScreen()) {
- return;
- }
- pg = core->getPageNum();
- XtPopdown(win);
- doc = core->takeDoc(gFalse);
- viewer = app->reopen(this, doc, pg, gTrue);
-
- btn = XtNameToWidget(viewer->popupMenu, "fullScreen");
- XtVaSetValues(btn, XmNset, XmSET, NULL);
-}
-
-void XPDFViewer::cmdGoBackward(GString *args[], int nArgs,
- XEvent *event) {
- core->goBackward();
-}
-
-void XPDFViewer::cmdGoForward(GString *args[], int nArgs,
- XEvent *event) {
- core->goForward();
-}
-
-void XPDFViewer::cmdGotoDest(GString *args[], int nArgs,
- XEvent *event) {
- int pg;
- LinkDest *dest;
-
- getPageAndDest(1, args[0], &pg, &dest);
- if (dest) {
- displayDest(dest, core->getZoom(), core->getRotate(), gTrue);
- delete dest;
- }
-}
-
-void XPDFViewer::cmdGotoLastPage(GString *args[], int nArgs,
- XEvent *event) {
- displayPage(core->getDoc()->getNumPages(),
- core->getZoom(), core->getRotate(),
- gTrue, gTrue);
-}
-
-void XPDFViewer::cmdGotoLastPageNoScroll(GString *args[], int nArgs,
- XEvent *event) {
- displayPage(core->getDoc()->getNumPages(),
- core->getZoom(), core->getRotate(),
- gFalse, gTrue);
-}
-
-void XPDFViewer::cmdGotoPage(GString *args[], int nArgs,
- XEvent *event) {
- int pg;
-
- pg = atoi(args[0]->getCString());
- if (pg < 1 || pg > core->getDoc()->getNumPages()) {
- return;
- }
- displayPage(pg, core->getZoom(), core->getRotate(), gTrue, gTrue);
-}
-
-void XPDFViewer::cmdGotoPageNoScroll(GString *args[], int nArgs,
- XEvent *event) {
- int pg;
-
- pg = atoi(args[0]->getCString());
- if (pg < 1 || pg > core->getDoc()->getNumPages()) {
- return;
- }
- displayPage(pg, core->getZoom(), core->getRotate(), gFalse, gTrue);
-}
-
-void XPDFViewer::cmdNextPage(GString *args[], int nArgs,
- XEvent *event) {
- core->gotoNextPage(1, gTrue);
-}
-
-void XPDFViewer::cmdNextPageNoScroll(GString *args[], int nArgs,
- XEvent *event) {
- core->gotoNextPage(1, gFalse);
-}
-
-void XPDFViewer::cmdOpen(GString *args[], int nArgs,
- XEvent *event) {
- mapOpenDialog(gFalse);
-}
-
-void XPDFViewer::cmdOpenFile(GString *args[], int nArgs,
- XEvent *event) {
- open(args[0], 1, NULL);
-}
-
-void XPDFViewer::cmdOpenFileAtDest(GString *args[], int nArgs,
- XEvent *event) {
- open(args[0], 1, args[1]);
-}
-
-void XPDFViewer::cmdOpenFileAtDestInNewWin(GString *args[], int nArgs,
- XEvent *event) {
- app->openAtDest(args[0], args[1]);
-}
-
-void XPDFViewer::cmdOpenFileAtPage(GString *args[], int nArgs,
- XEvent *event) {
- open(args[0], atoi(args[1]->getCString()), NULL);
-}
-
-void XPDFViewer::cmdOpenFileAtPageInNewWin(GString *args[], int nArgs,
- XEvent *event) {
- app->open(args[0], atoi(args[1]->getCString()));
-}
-
-void XPDFViewer::cmdOpenFileInNewWin(GString *args[], int nArgs,
- XEvent *event) {
- app->open(args[0]);
-}
-
-void XPDFViewer::cmdOpenInNewWin(GString *args[], int nArgs,
- XEvent *event) {
- mapOpenDialog(gTrue);
-}
-
-void XPDFViewer::cmdOpenOutline(GString *args[], int nArgs,
- XEvent *event) {
-#ifndef DISABLE_OUTLINE
- Dimension w;
-
- if (outlineScroll == None) {
- return;
- }
- XtVaGetValues(outlineScroll, XmNwidth, &w, NULL);
- if (w == 1) {
- // this ugly kludge is apparently the only way to resize the panes
- // within an XmPanedWindow
- XtVaSetValues(outlineScroll, XmNpaneMinimum, outlinePaneWidth,
- XmNpaneMaximum, outlinePaneWidth, NULL);
- XtVaSetValues(outlineScroll, XmNpaneMinimum, 1,
- XmNpaneMaximum, 10000, NULL);
- }
-#endif
-}
-
-void XPDFViewer::cmdPageDown(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollPageDown();
-}
-
-void XPDFViewer::cmdPageUp(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollPageUp();
-}
-
-void XPDFViewer::cmdPostPopupMenu(GString *args[], int nArgs,
- XEvent *event) {
- XmMenuPosition(popupMenu, event->type == ButtonPress ? &event->xbutton
- : (XButtonEvent *)NULL);
- XtManageChild(popupMenu);
-
- // this is magic (taken from DDD) - weird things happen if this
- // call isn't made (this is done in two different places, in hopes
- // of squashing this stupid bug)
- XtUngrabButton(core->getDrawAreaWidget(), AnyButton, AnyModifier);
-}
-
-void XPDFViewer::cmdPrevPage(GString *args[], int nArgs,
- XEvent *event) {
- core->gotoPrevPage(1, gTrue, gFalse);
-}
-
-void XPDFViewer::cmdPrevPageNoScroll(GString *args[], int nArgs,
- XEvent *event) {
- core->gotoPrevPage(1, gFalse, gFalse);
-}
-
-void XPDFViewer::cmdPrint(GString *args[], int nArgs,
- XEvent *event) {
- XtManageChild(printDialog);
-}
-
-void XPDFViewer::cmdQuit(GString *args[], int nArgs,
- XEvent *event) {
- app->quit();
-}
-
-void XPDFViewer::cmdRaise(GString *args[], int nArgs,
- XEvent *event) {
- XMapRaised(display, XtWindow(win));
- XFlush(display);
-}
-
-void XPDFViewer::cmdRedraw(GString *args[], int nArgs,
- XEvent *event) {
- displayPage(core->getPageNum(), core->getZoom(), core->getRotate(),
- gFalse, gFalse);
-}
-
-void XPDFViewer::cmdReload(GString *args[], int nArgs,
- XEvent *event) {
- reloadFile();
-}
-
-void XPDFViewer::cmdRotateCCW(GString *args[], int nArgs,
- XEvent *event) {
- int r;
-
- r = core->getRotate();
- r = (r == 0) ? 270 : r - 90;
- displayPage(core->getPageNum(), core->getZoom(), r, gTrue, gFalse);
-}
-
-void XPDFViewer::cmdRotateCW(GString *args[], int nArgs,
- XEvent *event) {
- int r;
-
- r = core->getRotate();
- r = (r == 270) ? 0 : r + 90;
- displayPage(core->getPageNum(), core->getZoom(), r, gTrue, gFalse);
-}
-
-void XPDFViewer::cmdRun(GString *args[], int nArgs,
- XEvent *event) {
- GString *fmt, *cmd, *s;
- LinkAction *action;
- double selLRX, selLRY, selURX, selURY, mouseX, mouseY;
- int selPage, mousePage;
- GBool gotSel, gotMouse;
- char buf[64];
- char *p;
- char c0, c1;
- int i;
-
- cmd = new GString();
- fmt = args[0];
- i = 0;
- gotSel = gotMouse = gFalse;
- while (i < fmt->getLength()) {
- c0 = fmt->getChar(i);
- if (c0 == '%' && i+1 < fmt->getLength()) {
- c1 = fmt->getChar(i+1);
- switch (c1) {
- case 'f':
- if (core->getDoc() && (s = core->getDoc()->getFileName())) {
- cmd->append(s);
- }
- break;
- case 'b':
- if (core->getDoc() && (s = core->getDoc()->getFileName())) {
- if ((p = strrchr(s->getCString(), '.'))) {
- cmd->append(s->getCString(), p - s->getCString());
- } else {
- cmd->append(s);
- }
- }
- break;
- case 'u':
- if ((action = core->getLinkAction()) &&
- action->getKind() == actionURI) {
- s = core->mungeURL(((LinkURI *)action)->getURI());
- cmd->append(s);
- delete s;
- }
- break;
- case 'p':
- if (core->getDoc()) {
- sprintf(buf, "%d", core->getPageNum());
- cmd->append(buf);
- }
- break;
- case 'x':
- case 'y':
- case 'X':
- case 'Y':
- if (!gotSel) {
- if (!core->getSelection(&selPage, &selURX, &selURY,
- &selLRX, &selLRY)) {
- selPage = 0;
- selURX = selURY = selLRX = selLRY = 0;
- }
- gotSel = gTrue;
- }
- sprintf(buf, "%g",
- (c1 == 'x') ? selURX :
- (c1 == 'y') ? selURY :
- (c1 == 'X') ? selLRX : selLRY);
- cmd->append(buf);
- break;
- case 'i':
- case 'j':
- case 'k':
- if (!gotMouse) {
- if (event->type == ButtonPress || event->type == ButtonRelease) {
- core->cvtWindowToUser(event->xbutton.x, event->xbutton.y,
- &mousePage, &mouseX, &mouseY);
- } else if (event->type == KeyPress) {
- core->cvtWindowToUser(event->xkey.x, event->xkey.y,
- &mousePage, &mouseX, &mouseY);
- } else {
- mousePage = 0;
- mouseX = mouseY = 0;
- }
- gotMouse = gTrue;
- }
- if (c1 == 'i') {
- sprintf(buf, "%d", mousePage);
- } else {
- sprintf(buf, "%g", (c1 == 'j') ? mouseX : mouseY);
- }
- cmd->append(buf);
- break;
- default:
- cmd->append(c1);
- break;
- }
- i += 2;
- } else {
- cmd->append(c0);
- ++i;
- }
- }
-#ifdef VMS
- cmd->insert(0, "spawn/nowait ");
-#elif defined(__EMX__)
- cmd->insert(0, "start /min /n ");
-#else
- cmd->append(" &");
-#endif
- system(cmd->getCString());
- delete cmd;
-}
-
-void XPDFViewer::cmdScrollDown(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollDown(atoi(args[0]->getCString()));
-}
-
-void XPDFViewer::cmdScrollDownNextPage(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollDownNextPage(atoi(args[0]->getCString()));
-}
-
-void XPDFViewer::cmdScrollLeft(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollLeft(atoi(args[0]->getCString()));
-}
-
-void XPDFViewer::cmdScrollOutlineDown(GString *args[], int nArgs,
- XEvent *event) {
-#ifndef DISABLE_OUTLINE
- Widget sb;
- int val, inc, pageInc, m, slider;
-
- if (outlineScroll == None) {
- return;
- }
- if ((sb = XtNameToWidget(outlineScroll, "VertScrollBar"))) {
- XtVaGetValues(sb, XmNvalue, &val, XmNincrement, &inc,
- XmNpageIncrement, &pageInc, XmNmaximum, &m,
- XmNsliderSize, &slider, NULL);
- if ((val += inc * atoi(args[0]->getCString())) > m - slider) {
- val = m - slider;
- }
- XmScrollBarSetValues(sb, val, slider, inc, pageInc, True);
- }
-#endif
-}
-
-void XPDFViewer::cmdScrollOutlineUp(GString *args[], int nArgs,
- XEvent *event) {
-#ifndef DISABLE_OUTLINE
- Widget sb;
- int val, inc, pageInc, m, slider;
-
- if (outlineScroll == None) {
- return;
- }
- if ((sb = XtNameToWidget(outlineScroll, "VertScrollBar"))) {
- XtVaGetValues(sb, XmNvalue, &val, XmNincrement, &inc,
- XmNpageIncrement, &pageInc, XmNminimum, &m,
- XmNsliderSize, &slider, NULL);
- if ((val -= inc * atoi(args[0]->getCString())) < m) {
- val = m;
- }
- XmScrollBarSetValues(sb, val, slider, inc, pageInc, True);
- }
-#endif
-}
-
-void XPDFViewer::cmdScrollRight(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollRight(atoi(args[0]->getCString()));
-}
-
-void XPDFViewer::cmdScrollToBottomEdge(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollToBottomEdge();
-}
-
-void XPDFViewer::cmdScrollToBottomRight(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollToBottomRight();
-}
-
-void XPDFViewer::cmdScrollToLeftEdge(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollToLeftEdge();
-}
-
-void XPDFViewer::cmdScrollToRightEdge(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollToRightEdge();
-}
-
-void XPDFViewer::cmdScrollToTopEdge(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollToTopEdge();
-}
-
-void XPDFViewer::cmdScrollToTopLeft(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollToTopLeft();
-}
-
-void XPDFViewer::cmdScrollUp(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollUp(atoi(args[0]->getCString()));
-}
-
-void XPDFViewer::cmdScrollUpPrevPage(GString *args[], int nArgs,
- XEvent *event) {
- core->scrollUpPrevPage(atoi(args[0]->getCString()));
-}
-
-void XPDFViewer::cmdSetSelection(GString *args[], int nArgs, XEvent *event) {
- int pg, ulx, uly, lrx, lry;
-
- pg = atoi(args[0]->getCString());
- core->cvtUserToDev(core->getPageNum(),
- atof(args[1]->getCString()), atof(args[2]->getCString()),
- &ulx, &uly);
- core->cvtUserToDev(core->getPageNum(),
- atof(args[3]->getCString()), atof(args[4]->getCString()),
- &lrx, &lry);
- core->setSelection(pg, ulx, uly, lrx, lry);
-}
-
-void XPDFViewer::cmdSinglePageMode(GString *args[], int nArgs,
- XEvent *event) {
- Widget btn;
-
- if (!core->getContinuousMode()) {
- return;
- }
- core->setContinuousMode(gFalse);
-
- btn = XtNameToWidget(popupMenu, "continuousMode");
- XtVaSetValues(btn, XmNset, XmUNSET, NULL);
-}
-
-void XPDFViewer::cmdStartPan(GString *args[], int nArgs,
- XEvent *event) {
- core->startPan(mouseX(event), mouseY(event));
-}
-
-void XPDFViewer::cmdStartSelection(GString *args[], int nArgs,
- XEvent *event) {
- core->startSelection(mouseX(event), mouseY(event));
-}
-
-void XPDFViewer::cmdToggleContinuousMode(GString *args[], int nArgs,
- XEvent *event) {
- if (core->getContinuousMode()) {
- cmdSinglePageMode(NULL, 0, event);
- } else {
- cmdContinuousMode(NULL, 0, event);
- }
-}
-
-void XPDFViewer::cmdToggleFullScreenMode(GString *args[], int nArgs,
- XEvent *event) {
- if (core->getFullScreen()) {
- cmdWindowMode(NULL, 0, event);
- } else {
- cmdFullScreenMode(NULL, 0, event);
- }
-}
-
-void XPDFViewer::cmdToggleOutline(GString *args[], int nArgs,
- XEvent *event) {
-#ifndef DISABLE_OUTLINE
- Dimension w;
-
- if (outlineScroll == None) {
- return;
- }
- XtVaGetValues(outlineScroll, XmNwidth, &w, NULL);
- if (w > 1) {
- cmdCloseOutline(NULL, 0, event);
- } else {
- cmdOpenOutline(NULL, 0, event);
- }
-#endif
-}
-
-void XPDFViewer::cmdWindowMode(GString *args[], int nArgs,
- XEvent *event) {
- PDFDoc *doc;
- XPDFViewer *viewer;
- int pg;
- Widget btn;
-
- if (!core->getFullScreen()) {
- return;
- }
- pg = core->getPageNum();
- XtPopdown(win);
- doc = core->takeDoc(gFalse);
- viewer = app->reopen(this, doc, pg, gFalse);
-
- btn = XtNameToWidget(viewer->popupMenu, "fullScreen");
- XtVaSetValues(btn, XmNset, XmUNSET, NULL);
-}
-
-void XPDFViewer::cmdZoomFitPage(GString *args[], int nArgs,
- XEvent *event) {
- if (core->getZoom() != zoomPage) {
- setZoomIdx(zoomPageIdx);
- displayPage(core->getPageNum(), zoomPage,
- core->getRotate(), gTrue, gFalse);
- }
-}
-
-void XPDFViewer::cmdZoomFitWidth(GString *args[], int nArgs,
- XEvent *event) {
- if (core->getZoom() != zoomWidth) {
- setZoomIdx(zoomWidthIdx);
- displayPage(core->getPageNum(), zoomWidth,
- core->getRotate(), gTrue, gFalse);
- }
-}
-
-void XPDFViewer::cmdZoomIn(GString *args[], int nArgs,
- XEvent *event) {
- int z;
-
- z = getZoomIdx();
- if (z <= minZoomIdx && z > maxZoomIdx) {
- --z;
- setZoomIdx(z);
- displayPage(core->getPageNum(), zoomMenuInfo[z].zoom,
- core->getRotate(), gTrue, gFalse);
- }
-}
-
-void XPDFViewer::cmdZoomOut(GString *args[], int nArgs,
- XEvent *event) {
- int z;
-
- z = getZoomIdx();
- if (z < minZoomIdx && z >= maxZoomIdx) {
- ++z;
- setZoomIdx(z);
- displayPage(core->getPageNum(), zoomMenuInfo[z].zoom,
- core->getRotate(), gTrue, gFalse);
- }
-}
-
-void XPDFViewer::cmdZoomPercent(GString *args[], int nArgs,
- XEvent *event) {
- double z;
-
- z = atof(args[0]->getCString());
- setZoomVal(z);
- displayPage(core->getPageNum(), z, core->getRotate(), gTrue, gFalse);
-}
-
-void XPDFViewer::cmdZoomToSelection(GString *args[], int nArgs,
- XEvent *event) {
- int pg;
- double ulx, uly, lrx, lry;
-
- if (core->getSelection(&pg, &ulx, &uly, &lrx, &lry)) {
- core->zoomToRect(pg, ulx, uly, lrx, lry);
- }
-}
-
-//------------------------------------------------------------------------
-// GUI code: main window
-//------------------------------------------------------------------------
-
-void XPDFViewer::initWindow(GBool fullScreen) {
- Colormap colormap;
- XColor xcol;
- Atom state, val;
- Arg args[20];
- int n;
- char *title;
-
- display = XtDisplay(app->getAppShell());
- screenNum = XScreenNumberOfScreen(XtScreen(app->getAppShell()));
-
- toolBar = None;
-#ifndef DISABLE_OUTLINE
- outlineScroll = None;
-#endif
-
- // private colormap
- if (app->getInstallCmap()) {
- XtVaGetValues(app->getAppShell(), XmNcolormap, &colormap, NULL);
- // ensure that BlackPixel and WhitePixel are reserved in the
- // new colormap
- xcol.red = xcol.green = xcol.blue = 0;
- XAllocColor(display, colormap, &xcol);
- xcol.red = xcol.green = xcol.blue = 65535;
- XAllocColor(display, colormap, &xcol);
- colormap = XCopyColormapAndFree(display, colormap);
- }
-
- // top-level window
- n = 0;
- title = app->getTitle() ? app->getTitle()->getCString()
- : (char *)xpdfAppName;
- XtSetArg(args[n], XmNtitle, title); ++n;
- XtSetArg(args[n], XmNiconName, title); ++n;
- XtSetArg(args[n], XmNminWidth, 100); ++n;
- XtSetArg(args[n], XmNminHeight, 100); ++n;
- XtSetArg(args[n], XmNbaseWidth, 0); ++n;
- XtSetArg(args[n], XmNbaseHeight, 0); ++n;
- XtSetArg(args[n], XmNdeleteResponse, XmDO_NOTHING); ++n;
- win = XtCreatePopupShell("win", topLevelShellWidgetClass,
- app->getAppShell(), args, n);
- if (app->getInstallCmap()) {
- XtVaSetValues(win, XmNcolormap, colormap, NULL);
- }
- XmAddWMProtocolCallback(win, XInternAtom(display, "WM_DELETE_WINDOW", False),
- &closeMsgCbk, this);
-
- // create the full-screen window
- if (fullScreen) {
- initCore(win, gTrue);
-
- // create the normal (non-full-screen) window
- } else {
- if (app->getGeometry()) {
- n = 0;
- XtSetArg(args[n], XmNgeometry, app->getGeometry()->getCString()); ++n;
- XtSetValues(win, args, n);
- }
-
- n = 0;
- form = XmCreateForm(win, "form", args, n);
- XtManageChild(form);
-
-#ifdef DISABLE_OUTLINE
- initToolbar(form);
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetValues(toolBar, args, n);
-
- initCore(form, gFalse);
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNbottomWidget, toolBar); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetValues(core->getWidget(), args, n);
-#else
- initToolbar(form);
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetValues(toolBar, args, n);
-
- initPanedWin(form);
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNbottomWidget, toolBar); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetValues(panedWin, args, n);
-
- initCore(panedWin, fullScreen);
- n = 0;
- XtSetArg(args[n], XmNpositionIndex, 1); ++n;
- XtSetArg(args[n], XmNallowResize, True); ++n;
- XtSetArg(args[n], XmNpaneMinimum, 1); ++n;
- XtSetArg(args[n], XmNpaneMaximum, 10000); ++n;
- XtSetValues(core->getWidget(), args, n);
-#endif
- }
-
- // set the zoom menu to match the initial zoom setting
- setZoomVal(core->getZoom());
-
- // set traversal order
- XtVaSetValues(core->getDrawAreaWidget(),
- XmNnavigationType, XmEXCLUSIVE_TAB_GROUP, NULL);
- if (toolBar != None) {
- XtVaSetValues(backBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
- NULL);
- XtVaSetValues(prevTenPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
- NULL);
- XtVaSetValues(prevPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
- NULL);
- XtVaSetValues(nextPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
- NULL);
- XtVaSetValues(nextTenPageBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
- NULL);
- XtVaSetValues(forwardBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
- NULL);
- XtVaSetValues(pageNumText, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
- NULL);
- XtVaSetValues(zoomWidget, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
- NULL);
- XtVaSetValues(findBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
- NULL);
- XtVaSetValues(printBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
- NULL);
- XtVaSetValues(aboutBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
- NULL);
- XtVaSetValues(quitBtn, XmNnavigationType, XmEXCLUSIVE_TAB_GROUP,
- NULL);
- }
-
- initPopupMenu();
-
- if (fullScreen) {
- // Set both the old-style Motif decorations hint and the new-style
- // _NET_WM_STATE property. This is redundant, but might be useful
- // for older window managers. We also set the geometry to +0+0 to
- // avoid interactive placement. (Note: we need to realize the
- // shell, so it has a Window on which to set the _NET_WM_STATE
- // property, but we don't want to map it until later, so we set
- // mappedWhenManaged to false.)
- n = 0;
- XtSetArg(args[n], XmNmappedWhenManaged, False); ++n;
- XtSetArg(args[n], XmNmwmDecorations, 0); ++n;
- XtSetArg(args[n], XmNgeometry, "+0+0"); ++n;
- XtSetValues(win, args, n);
- XtRealizeWidget(win);
- state = XInternAtom(display, "_NET_WM_STATE", False);
- val = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", False);
- XChangeProperty(display, XtWindow(win), state, XA_ATOM, 32,
- PropModeReplace, (Guchar *)&val, 1);
- }
-}
-
-void XPDFViewer::initToolbar(Widget parent) {
- Widget label, lastBtn;
-#ifndef USE_COMBO_BOX
- Widget btn;
-#endif
- Arg args[20];
- int n;
- XmString s, emptyString;
- int i;
-
- // toolbar
- n = 0;
- toolBar = XmCreateForm(parent, "toolBar", args, n);
- XtManageChild(toolBar);
-
- // create an empty string -- this is used for buttons that will get
- // pixmaps later
- emptyString = XmStringCreateLocalized("");
-
- // page movement buttons
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNmarginWidth, 6); ++n;
- XtSetArg(args[n], XmNsensitive, False); ++n;
- XtSetArg(args[n], XmNlabelString, emptyString); ++n;
- backBtn = XmCreatePushButton(toolBar, "back", args, n);
- addToolTip(backBtn, "Back");
- XtManageChild(backBtn);
- XtAddCallback(backBtn, XmNactivateCallback,
- &backCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, backBtn); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNmarginWidth, 6); ++n;
- XtSetArg(args[n], XmNsensitive, False); ++n;
- XtSetArg(args[n], XmNlabelString, emptyString); ++n;
- prevTenPageBtn = XmCreatePushButton(toolBar, "prevTenPage", args, n);
- addToolTip(prevTenPageBtn, "-10 pages");
- XtManageChild(prevTenPageBtn);
- XtAddCallback(prevTenPageBtn, XmNactivateCallback,
- &prevTenPageCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, prevTenPageBtn); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNmarginWidth, 6); ++n;
- XtSetArg(args[n], XmNsensitive, False); ++n;
- XtSetArg(args[n], XmNlabelString, emptyString); ++n;
- prevPageBtn = XmCreatePushButton(toolBar, "prevPage", args, n);
- addToolTip(prevPageBtn, "Previous page");
- XtManageChild(prevPageBtn);
- XtAddCallback(prevPageBtn, XmNactivateCallback,
- &prevPageCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, prevPageBtn); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNmarginWidth, 6); ++n;
- XtSetArg(args[n], XmNsensitive, False); ++n;
- XtSetArg(args[n], XmNlabelString, emptyString); ++n;
- nextPageBtn = XmCreatePushButton(toolBar, "nextPage", args, n);
- addToolTip(nextPageBtn, "Next page");
- XtManageChild(nextPageBtn);
- XtAddCallback(nextPageBtn, XmNactivateCallback,
- &nextPageCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, nextPageBtn); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNmarginWidth, 6); ++n;
- XtSetArg(args[n], XmNsensitive, False); ++n;
- XtSetArg(args[n], XmNlabelString, emptyString); ++n;
- nextTenPageBtn = XmCreatePushButton(toolBar, "nextTenPage", args, n);
- addToolTip(nextTenPageBtn, "+10 pages");
- XtManageChild(nextTenPageBtn);
- XtAddCallback(nextTenPageBtn, XmNactivateCallback,
- &nextTenPageCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, nextTenPageBtn); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNmarginWidth, 6); ++n;
- XtSetArg(args[n], XmNsensitive, False); ++n;
- XtSetArg(args[n], XmNlabelString, emptyString); ++n;
- forwardBtn = XmCreatePushButton(toolBar, "forward", args, n);
- addToolTip(forwardBtn, "Forward");
- XtManageChild(forwardBtn);
- XtAddCallback(forwardBtn, XmNactivateCallback,
- &forwardCbk, (XtPointer)this);
-
- // page number display
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, forwardBtn); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- s = XmStringCreateLocalized("Page ");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- label = XmCreateLabel(toolBar, "pageLabel", args, n);
- XmStringFree(s);
- XtManageChild(label);
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, label); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNmarginWidth, 3); ++n;
- XtSetArg(args[n], XmNmarginHeight, 3); ++n;
- XtSetArg(args[n], XmNcolumns, 5); ++n;
- pageNumText = XmCreateTextField(toolBar, "pageNum", args, n);
- XtManageChild(pageNumText);
- XtAddCallback(pageNumText, XmNactivateCallback,
- &pageNumCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, pageNumText); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- s = XmStringCreateLocalized(" of 00000");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); ++n;
- XtSetArg(args[n], XmNrecomputeSize, False); ++n;
- pageCountLabel = XmCreateLabel(toolBar, "pageCountLabel", args, n);
- XmStringFree(s);
- XtManageChild(pageCountLabel);
- s = XmStringCreateLocalized(" of 0");
- XtVaSetValues(pageCountLabel, XmNlabelString, s, NULL);
- XmStringFree(s);
-
- // zoom menu
-#if USE_COMBO_BOX
- XmString st[nZoomMenuItems];
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, pageCountLabel); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNmarginWidth, 0); ++n;
- XtSetArg(args[n], XmNmarginHeight, 0); ++n;
- XtSetArg(args[n], XmNcomboBoxType, XmDROP_DOWN_COMBO_BOX); ++n;
- XtSetArg(args[n], XmNpositionMode, XmONE_BASED); ++n;
- XtSetArg(args[n], XmNcolumns, 7); ++n;
- for (i = 0; i < nZoomMenuItems; ++i) {
- st[i] = XmStringCreateLocalized((char *)zoomMenuInfo[i].label);
- }
- XtSetArg(args[n], XmNitems, st); ++n;
- XtSetArg(args[n], XmNitemCount, nZoomMenuItems); ++n;
- zoomComboBox = XmCreateComboBox(toolBar, "zoomComboBox", args, n);
- for (i = 0; i < nZoomMenuItems; ++i) {
- XmStringFree(st[i]);
- }
- addToolTip(zoomComboBox, "Zoom");
- XtAddCallback(zoomComboBox, XmNselectionCallback,
- &zoomComboBoxCbk, (XtPointer)this);
- XtManageChild(zoomComboBox);
- zoomWidget = zoomComboBox;
-#else
- Widget menuPane;
- char buf[16];
- n = 0;
- menuPane = XmCreatePulldownMenu(toolBar, "zoomMenuPane", args, n);
- for (i = 0; i < nZoomMenuItems; ++i) {
- n = 0;
- s = XmStringCreateLocalized((char *)zoomMenuInfo[i].label);
- XtSetArg(args[n], XmNlabelString, s); ++n;
- XtSetArg(args[n], XmNuserData, (XtPointer)i); ++n;
- sprintf(buf, "zoom%d", i);
- btn = XmCreatePushButton(menuPane, buf, args, n);
- XmStringFree(s);
- XtManageChild(btn);
- XtAddCallback(btn, XmNactivateCallback,
- &zoomMenuCbk, (XtPointer)this);
- zoomMenuBtns[i] = btn;
- }
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, pageCountLabel); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNmarginWidth, 0); ++n;
- XtSetArg(args[n], XmNmarginHeight, 0); ++n;
- XtSetArg(args[n], XmNsubMenuId, menuPane); ++n;
- zoomMenu = XmCreateOptionMenu(toolBar, "zoomMenu", args, n);
- addToolTip(zoomMenu, "Zoom");
- XtManageChild(zoomMenu);
- zoomWidget = zoomMenu;
-#endif
-
- // find/print/about buttons
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, zoomWidget); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNmarginWidth, 6); ++n;
- XtSetArg(args[n], XmNlabelString, emptyString); ++n;
- findBtn = XmCreatePushButton(toolBar, "find", args, n);
- addToolTip(findBtn, "Find");
- XtManageChild(findBtn);
- XtAddCallback(findBtn, XmNactivateCallback,
- &findCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, findBtn); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNmarginWidth, 6); ++n;
- XtSetArg(args[n], XmNlabelString, emptyString); ++n;
- printBtn = XmCreatePushButton(toolBar, "print", args, n);
- addToolTip(printBtn, "Print");
- XtManageChild(printBtn);
- XtAddCallback(printBtn, XmNactivateCallback,
- &printCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, printBtn); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNmarginWidth, 6); ++n;
- XtSetArg(args[n], XmNlabelString, emptyString); ++n;
- aboutBtn = XmCreatePushButton(toolBar, "about", args, n);
- addToolTip(aboutBtn, "About / help");
- XtManageChild(aboutBtn);
- XtAddCallback(aboutBtn, XmNactivateCallback,
- &aboutCbk, (XtPointer)this);
- lastBtn = aboutBtn;
-
- // quit button
- n = 0;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNmarginWidth, 6); ++n;
- s = XmStringCreateLocalized("Quit");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- quitBtn = XmCreatePushButton(toolBar, "quit", args, n);
- XmStringFree(s);
- XtManageChild(quitBtn);
- XtAddCallback(quitBtn, XmNactivateCallback,
- &quitCbk, (XtPointer)this);
-
- // link label
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, lastBtn); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNrightWidget, quitBtn); ++n;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- s = XmStringCreateLocalized("");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- XtSetArg(args[n], XmNrecomputeSize, True); ++n;
- XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); ++n;
- linkLabel = XmCreateLabel(toolBar, "linkLabel", args, n);
- XmStringFree(s);
- XtManageChild(linkLabel);
-
- XmStringFree(emptyString);
-}
-
-#ifndef DISABLE_OUTLINE
-void XPDFViewer::initPanedWin(Widget parent) {
- Widget clipWin;
- Arg args[20];
- int n;
-
- // paned window
- n = 0;
- XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
-#if defined(__sgi) && (XmVERSION <= 1)
- panedWin = SgCreateHorzPanedWindow(parent, "panedWin", args, n);
-#else
- panedWin = XmCreatePanedWindow(parent, "panedWin", args, n);
-#endif
- XtManageChild(panedWin);
-
- // scrolled window for outline container
- n = 0;
- XtSetArg(args[n], XmNpositionIndex, 0); ++n;
- XtSetArg(args[n], XmNallowResize, True); ++n;
- XtSetArg(args[n], XmNpaneMinimum, 1); ++n;
- XtSetArg(args[n], XmNpaneMaximum, 10000); ++n;
-#if !(defined(__sgi) && (XmVERSION <= 1))
- XtSetArg(args[n], XmNwidth, 1); ++n;
-#endif
- XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n;
- outlineScroll = XmCreateScrolledWindow(panedWin, "outlineScroll", args, n);
- XtManageChild(outlineScroll);
- XtVaGetValues(outlineScroll, XmNclipWindow, &clipWin, NULL);
- XtVaSetValues(clipWin, XmNbackground, app->getPaperPixel(), NULL);
-
- // outline tree
- n = 0;
- XtSetArg(args[n], XmNbackground, app->getPaperPixel()); ++n;
- outlineTree = XPDFCreateTree(outlineScroll, "outlineTree", args, n);
- XtManageChild(outlineTree);
- XtAddCallback(outlineTree, XPDFNselectionCallback, &outlineSelectCbk,
- (XtPointer)this);
-}
-#endif
-
-void XPDFViewer::initCore(Widget parent, GBool fullScreen) {
- core = new XPDFCore(win, parent,
- app->getPaperRGB(), app->getPaperPixel(),
- app->getMattePixel(fullScreen),
- fullScreen, app->getReverseVideo(),
- app->getInstallCmap(), app->getRGBCubeSize());
- core->setUpdateCbk(&updateCbk, this);
- core->setActionCbk(&actionCbk, this);
- core->setKeyPressCbk(&keyPressCbk, this);
- core->setMouseCbk(&mouseCbk, this);
-}
-
-void XPDFViewer::initPopupMenu() {
- Widget btn;
- Arg args[20];
- int n;
- XmString s, s2;
-
- n = 0;
-#if XmVersion < 1002
- // older versions of Motif need this, newer ones choke on it,
- // sometimes not displaying the menu at all, maybe depending on the
- // state of the NumLock key (taken from DDD)
- XtSetArg(args[n], XmNmenuPost, "<Btn3Down>"); ++n;
-#endif
- popupMenu = XmCreatePopupMenu(core->getDrawAreaWidget(), "popupMenu",
- args, n);
- n = 0;
- s = XmStringCreateLocalized("Open...");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- s2 = XmStringCreateLocalized("O");
- XtSetArg(args[n], XmNacceleratorText, s2); ++n;
- btn = XmCreatePushButton(popupMenu, "open", args, n);
- XmStringFree(s);
- XmStringFree(s2);
- XtManageChild(btn);
- XtAddCallback(btn, XmNactivateCallback,
- &openCbk, (XtPointer)this);
- n = 0;
- s = XmStringCreateLocalized("Open in new window...");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- btn = XmCreatePushButton(popupMenu, "openInNewWindow", args, n);
- XmStringFree(s);
- XtManageChild(btn);
- XtAddCallback(btn, XmNactivateCallback,
- &openInNewWindowCbk, (XtPointer)this);
- n = 0;
- s = XmStringCreateLocalized("Reload");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- s2 = XmStringCreateLocalized("R");
- XtSetArg(args[n], XmNacceleratorText, s2); ++n;
- btn = XmCreatePushButton(popupMenu, "reload", args, n);
- XmStringFree(s);
- XmStringFree(s2);
- XtManageChild(btn);
- XtAddCallback(btn, XmNactivateCallback,
- &reloadCbk, (XtPointer)this);
- n = 0;
- s = XmStringCreateLocalized("Save as...");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- btn = XmCreatePushButton(popupMenu, "saveAs", args, n);
- XmStringFree(s);
- XtManageChild(btn);
- XtAddCallback(btn, XmNactivateCallback,
- &saveAsCbk, (XtPointer)this);
- n = 0;
- btn = XmCreateSeparator(popupMenu, "sep1", args, n);
- XtManageChild(btn);
- n = 0;
- s = XmStringCreateLocalized("Continuous view");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
- XtSetArg(args[n], XmNvisibleWhenOff, True); ++n;
- XtSetArg(args[n], XmNset, core->getContinuousMode() ? XmSET : XmUNSET); ++n;
- btn = XmCreateToggleButton(popupMenu, "continuousMode", args, n);
- XmStringFree(s);
- XtManageChild(btn);
- XtAddCallback(btn, XmNvalueChangedCallback,
- &continuousModeToggleCbk, (XtPointer)this);
- n = 0;
- s = XmStringCreateLocalized("Full screen");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
- XtSetArg(args[n], XmNvisibleWhenOff, True); ++n;
- XtSetArg(args[n], XmNset, core->getFullScreen() ? XmSET : XmUNSET); ++n;
- btn = XmCreateToggleButton(popupMenu, "fullScreen", args, n);
- XmStringFree(s);
- XtManageChild(btn);
- XtAddCallback(btn, XmNvalueChangedCallback,
- &fullScreenToggleCbk, (XtPointer)this);
- n = 0;
- s = XmStringCreateLocalized("Rotate counterclockwise");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- btn = XmCreatePushButton(popupMenu, "rotateCCW", args, n);
- XmStringFree(s);
- XtManageChild(btn);
- XtAddCallback(btn, XmNactivateCallback,
- &rotateCCWCbk, (XtPointer)this);
- n = 0;
- s = XmStringCreateLocalized("Rotate clockwise");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- btn = XmCreatePushButton(popupMenu, "rotateCW", args, n);
- XmStringFree(s);
- XtManageChild(btn);
- XtAddCallback(btn, XmNactivateCallback,
- &rotateCWCbk, (XtPointer)this);
- n = 0;
- s = XmStringCreateLocalized("Zoom to selection");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- btn = XmCreatePushButton(popupMenu, "zoomToSelection", args, n);
- XmStringFree(s);
- XtManageChild(btn);
- XtAddCallback(btn, XmNactivateCallback,
- &zoomToSelectionCbk, (XtPointer)this);
- n = 0;
- btn = XmCreateSeparator(popupMenu, "sep2", args, n);
- XtManageChild(btn);
- n = 0;
- s = XmStringCreateLocalized("Close");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- s2 = XmStringCreateLocalized("Ctrl+W");
- XtSetArg(args[n], XmNacceleratorText, s2); ++n;
- btn = XmCreatePushButton(popupMenu, "close", args, n);
- XmStringFree(s);
- XmStringFree(s2);
- XtManageChild(btn);
- XtAddCallback(btn, XmNactivateCallback,
- &closeCbk, (XtPointer)this);
- n = 0;
- s = XmStringCreateLocalized("Quit");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- s2 = XmStringCreateLocalized("Q");
- XtSetArg(args[n], XmNacceleratorText, s2); ++n;
- btn = XmCreatePushButton(popupMenu, "quit", args, n);
- XmStringFree(s);
- XmStringFree(s2);
- XtManageChild(btn);
- XtAddCallback(btn, XmNactivateCallback,
- &quitCbk, (XtPointer)this);
-
- // this is magic (taken from DDD) - weird things happen if this
- // call isn't made
- XtUngrabButton(core->getDrawAreaWidget(), AnyButton, AnyModifier);
-}
-
-void XPDFViewer::addToolTip(Widget widget, char *text) {
-#ifdef XmNtoolTipString
- XmString s;
- Cardinal n, i;
- WidgetList children;
-
- if (XtIsComposite(widget)) {
- XtVaGetValues(widget, XmNnumChildren, &n, XmNchildren, &children, NULL);
- for (i = 0; i < n; ++i) {
- addToolTip(children[i], text);
- }
- } else {
- s = XmStringCreateLocalized(text);
- XtVaSetValues(widget, XmNtoolTipString, s, NULL);
- XmStringFree(s);
- }
-#endif
-}
-
-void XPDFViewer::mapWindow() {
-#ifdef HAVE_X11_XPM_H
- Pixmap iconPixmap;
-#endif
- int depth;
- Pixel fg, bg, arm;
-
- // show the window
- XtPopup(win, XtGrabNone);
- core->takeFocus();
-
- // create the icon
-#ifdef HAVE_X11_XPM_H
- if (XpmCreatePixmapFromData(display, XtWindow(win), xpdfIcon,
- &iconPixmap, NULL, NULL) == XpmSuccess) {
- XtVaSetValues(win, XmNiconPixmap, iconPixmap, NULL);
- }
-#endif
-
- // set button bitmaps (must be done after the window is mapped)
- if (toolBar != None) {
- XtVaGetValues(backBtn, XmNdepth, &depth,
- XmNforeground, &fg, XmNbackground, &bg,
- XmNarmColor, &arm, NULL);
- XtVaSetValues(backBtn, XmNlabelType, XmPIXMAP,
- XmNlabelPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)backArrow_bits,
- backArrow_width,
- backArrow_height,
- fg, bg, depth),
- XmNarmPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)backArrow_bits,
- backArrow_width,
- backArrow_height,
- fg, arm, depth),
- XmNlabelInsensitivePixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)backArrowDis_bits,
- backArrowDis_width,
- backArrowDis_height,
- fg, bg, depth),
- NULL);
- XtVaSetValues(prevTenPageBtn, XmNlabelType, XmPIXMAP,
- XmNlabelPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)dblLeftArrow_bits,
- dblLeftArrow_width,
- dblLeftArrow_height,
- fg, bg, depth),
- XmNarmPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)dblLeftArrow_bits,
- dblLeftArrow_width,
- dblLeftArrow_height,
- fg, arm, depth),
- XmNlabelInsensitivePixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)dblLeftArrowDis_bits,
- dblLeftArrowDis_width,
- dblLeftArrowDis_height,
- fg, bg, depth),
- NULL);
- XtVaSetValues(prevPageBtn, XmNlabelType, XmPIXMAP,
- XmNlabelPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)leftArrow_bits,
- leftArrow_width,
- leftArrow_height,
- fg, bg, depth),
- XmNarmPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)leftArrow_bits,
- leftArrow_width,
- leftArrow_height,
- fg, arm, depth),
- XmNlabelInsensitivePixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)leftArrowDis_bits,
- leftArrowDis_width,
- leftArrowDis_height,
- fg, bg, depth),
- NULL);
- XtVaSetValues(nextPageBtn, XmNlabelType, XmPIXMAP,
- XmNlabelPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)rightArrow_bits,
- rightArrow_width,
- rightArrow_height,
- fg, bg, depth),
- XmNarmPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)rightArrow_bits,
- rightArrow_width,
- rightArrow_height,
- fg, arm, depth),
- XmNlabelInsensitivePixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)rightArrowDis_bits,
- rightArrowDis_width,
- rightArrowDis_height,
- fg, bg, depth),
- NULL);
- XtVaSetValues(nextTenPageBtn, XmNlabelType, XmPIXMAP,
- XmNlabelPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)dblRightArrow_bits,
- dblRightArrow_width,
- dblRightArrow_height,
- fg, bg, depth),
- XmNarmPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)dblRightArrow_bits,
- dblRightArrow_width,
- dblRightArrow_height,
- fg, arm, depth),
- XmNlabelInsensitivePixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)dblRightArrowDis_bits,
- dblRightArrowDis_width,
- dblRightArrowDis_height,
- fg, bg, depth),
- NULL);
- XtVaSetValues(forwardBtn, XmNlabelType, XmPIXMAP,
- XmNlabelPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)forwardArrow_bits,
- forwardArrow_width,
- forwardArrow_height,
- fg, bg, depth),
- XmNarmPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)forwardArrow_bits,
- forwardArrow_width,
- forwardArrow_height,
- fg, arm, depth),
- XmNlabelInsensitivePixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)forwardArrowDis_bits,
- forwardArrowDis_width,
- forwardArrowDis_height,
- fg, bg, depth),
- NULL);
- XtVaSetValues(findBtn, XmNlabelType, XmPIXMAP,
- XmNlabelPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)find_bits,
- find_width,
- find_height,
- fg, bg, depth),
- XmNarmPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)find_bits,
- find_width,
- find_height,
- fg, arm, depth),
- XmNlabelInsensitivePixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)findDis_bits,
- findDis_width,
- findDis_height,
- fg, bg, depth),
- NULL);
- XtVaSetValues(printBtn, XmNlabelType, XmPIXMAP,
- XmNlabelPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)print_bits,
- print_width,
- print_height,
- fg, bg, depth),
- XmNarmPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)print_bits,
- print_width,
- print_height,
- fg, arm, depth),
- XmNlabelInsensitivePixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)printDis_bits,
- printDis_width,
- printDis_height,
- fg, bg, depth),
- NULL);
- XtVaSetValues(aboutBtn, XmNlabelType, XmPIXMAP,
- XmNlabelPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)about_bits,
- about_width,
- about_height,
- fg, bg, depth),
- XmNarmPixmap,
- XCreatePixmapFromBitmapData(display, XtWindow(toolBar),
- (char *)about_bits,
- about_width,
- about_height,
- fg, arm, depth),
- NULL);
- }
-}
-
-void XPDFViewer::closeWindow() {
- XtPopdown(win);
- XtDestroyWidget(win);
-}
-
-int XPDFViewer::getZoomIdx() {
- int i;
-
- for (i = 0; i < nZoomMenuItems; ++i) {
- if (core->getZoom() == zoomMenuInfo[i].zoom) {
- return i;
- }
- }
- return -1;
-}
-
-void XPDFViewer::setZoomIdx(int idx) {
- if (toolBar == None) {
- return;
- }
-#if USE_COMBO_BOX
- XtVaSetValues(zoomComboBox, XmNselectedPosition, idx + 1, NULL);
-#else
- XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[idx], NULL);
-#endif
-}
-
-void XPDFViewer::setZoomVal(double z) {
- if (toolBar == None) {
- return;
- }
-
-#if USE_COMBO_BOX
- char buf[32];
- XmString s;
- int i;
-
- for (i = 0; i < nZoomMenuItems; ++i) {
- if (z == zoomMenuInfo[i].zoom) {
- XtVaSetValues(zoomComboBox, XmNselectedPosition, i + 1, NULL);
- return;
- }
- }
- sprintf(buf, "%d%%", (int)z);
- s = XmStringCreateLocalized(buf);
- XtVaSetValues(zoomComboBox, XmNselectedItem, s, NULL);
- XmStringFree(s);
-#else
- int i;
-
- for (i = 0; i < nZoomMenuItems; ++i) {
- if (z == zoomMenuInfo[i].zoom) {
- XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[i], NULL);
- return;
- }
- }
- for (i = maxZoomIdx; i < minZoomIdx; ++i) {
- if (z > zoomMenuInfo[i].zoom) {
- break;
- }
- }
- XtVaSetValues(zoomMenu, XmNmenuHistory, zoomMenuBtns[i], NULL);
-#endif
-}
-
-void XPDFViewer::prevPageCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->core->gotoPrevPage(1, gTrue, gFalse);
- viewer->core->takeFocus();
-}
-
-void XPDFViewer::prevTenPageCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->core->gotoPrevPage(10, gTrue, gFalse);
- viewer->core->takeFocus();
-}
-
-void XPDFViewer::nextPageCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->core->gotoNextPage(1, gTrue);
- viewer->core->takeFocus();
-}
-
-void XPDFViewer::nextTenPageCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->core->gotoNextPage(10, gTrue);
- viewer->core->takeFocus();
-}
-
-void XPDFViewer::backCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->core->goBackward();
- viewer->core->takeFocus();
-}
-
-void XPDFViewer::forwardCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->core->goForward();
- viewer->core->takeFocus();
-}
-
-#if USE_COMBO_BOX
-
-void XPDFViewer::zoomComboBoxCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
- XmComboBoxCallbackStruct *data = (XmComboBoxCallbackStruct *)callData;
- double z;
- char *s;
- XmStringContext context;
- XmStringCharSet charSet;
- XmStringDirection dir;
- Boolean sep;
-
- z = viewer->core->getZoom();
- if (data->item_position == 0) {
- XmStringInitContext(&context, data->item_or_text);
- if (XmStringGetNextSegment(context, &s, &charSet, &dir, &sep)) {
- z = atof(s);
- if (z <= 1) {
- z = defZoom;
- }
- XtFree(charSet);
- XtFree(s);
- }
- XmStringFreeContext(context);
- } else {
- z = zoomMenuInfo[data->item_position - 1].zoom;
- }
- // only redraw if this was triggered by an event; otherwise
- // the caller is responsible for doing the redraw
- if (z != viewer->core->getZoom() && data->event) {
- viewer->displayPage(viewer->core->getPageNum(), z,
- viewer->core->getRotate(), gTrue, gFalse);
- }
- viewer->core->takeFocus();
-}
-
-#else // USE_COMBO_BOX
-
-void XPDFViewer::zoomMenuCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
- XmPushButtonCallbackStruct *data = (XmPushButtonCallbackStruct *)callData;
- XtPointer userData;
- double z;
-
- XtVaGetValues(widget, XmNuserData, &userData, NULL);
- z = zoomMenuInfo[(long)userData].zoom;
- // only redraw if this was triggered by an event; otherwise
- // the caller is responsible for doing the redraw
- if (z != viewer->core->getZoom() && data->event) {
- viewer->displayPage(viewer->core->getPageNum(), z,
- viewer->core->getRotate(), gTrue, gFalse);
- }
- viewer->core->takeFocus();
-}
-
-#endif // USE_COMBO_BOX
-
-void XPDFViewer::findCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- if (!viewer->core->getDoc()) {
- return;
- }
- viewer->mapFindDialog();
-}
-
-void XPDFViewer::printCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- if (!viewer->core->getDoc()) {
- return;
- }
- XtManageChild(viewer->printDialog);
-}
-
-void XPDFViewer::aboutCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- XtManageChild(viewer->aboutDialog);
-}
-
-void XPDFViewer::quitCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->app->quit();
-}
-
-void XPDFViewer::openCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->mapOpenDialog(gFalse);
-}
-
-void XPDFViewer::openInNewWindowCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->mapOpenDialog(gTrue);
-}
-
-void XPDFViewer::reloadCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->reloadFile();
-}
-
-void XPDFViewer::saveAsCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- if (!viewer->core->getDoc()) {
- return;
- }
- viewer->mapSaveAsDialog();
-}
-
-void XPDFViewer::continuousModeToggleCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
- XmToggleButtonCallbackStruct *data =
- (XmToggleButtonCallbackStruct *)callData;
-
- viewer->core->setContinuousMode(data->set == XmSET);
-}
-
-void XPDFViewer::fullScreenToggleCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
- XmToggleButtonCallbackStruct *data =
- (XmToggleButtonCallbackStruct *)callData;
-
- if (data->set == XmSET) {
- viewer->cmdFullScreenMode(NULL, 0, NULL);
- } else {
- viewer->cmdWindowMode(NULL, 0, NULL);
- }
-}
-
-void XPDFViewer::rotateCCWCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->cmdRotateCCW(NULL, 0, NULL);
-}
-
-void XPDFViewer::rotateCWCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->cmdRotateCW(NULL, 0, NULL);
-}
-
-void XPDFViewer::zoomToSelectionCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
- int pg;
- double ulx, uly, lrx, lry;
-
- if (viewer->core->getSelection(&pg, &ulx, &uly, &lrx, &lry)) {
- viewer->core->zoomToRect(pg, ulx, uly, lrx, lry);
- }
-}
-
-void XPDFViewer::closeCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->app->close(viewer, gFalse);
-}
-
-void XPDFViewer::closeMsgCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->app->close(viewer, gTrue);
-}
-
-void XPDFViewer::pageNumCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
- char *s, *p;
- int pg;
- char buf[20];
-
- if (!viewer->core->getDoc()) {
- goto err;
- }
- s = XmTextFieldGetString(viewer->pageNumText);
- for (p = s; *p; ++p) {
- if (!isdigit(*p)) {
- goto err;
- }
- }
- pg = atoi(s);
- if (pg < 1 || pg > viewer->core->getDoc()->getNumPages()) {
- goto err;
- }
- viewer->displayPage(pg, viewer->core->getZoom(),
- viewer->core->getRotate(), gFalse, gTrue);
- viewer->core->takeFocus();
- return;
-
- err:
- XBell(viewer->display, 0);
- sprintf(buf, "%d", viewer->core->getPageNum());
- XmTextFieldSetString(viewer->pageNumText, buf);
-}
-
-void XPDFViewer::updateCbk(void *data, GString *fileName,
- int pageNum, int numPages, const char *linkString) {
- XPDFViewer *viewer = (XPDFViewer *)data;
- GString *title;
- char buf[20];
- XmString s;
-
- if (fileName) {
- if (!(title = viewer->app->getTitle())) {
- title = (new GString(xpdfAppName))->append(": ")->append(fileName);
- }
- XtVaSetValues(viewer->win, XmNtitle, title->getCString(),
- XmNiconName, title->getCString(), NULL);
- if (!viewer->app->getTitle()) {
- delete title;
- }
-#ifndef DISABLE_OUTLINE
- viewer->setupOutline();
-#endif
- viewer->setupPrintDialog();
- }
-
- if (viewer->toolBar != None) {
- if (pageNum >= 0) {
- s = XmStringCreateLocalized("");
- XtVaSetValues(viewer->linkLabel, XmNlabelString, s, NULL);
- XmStringFree(s);
- sprintf(buf, "%d", pageNum);
- XmTextFieldSetString(viewer->pageNumText, buf);
- XtVaSetValues(viewer->prevTenPageBtn, XmNsensitive,
- pageNum > 1, NULL);
- XtVaSetValues(viewer->prevPageBtn, XmNsensitive,
- pageNum > 1, NULL);
- XtVaSetValues(viewer->nextTenPageBtn, XmNsensitive,
- pageNum < viewer->core->getDoc()->getNumPages(), NULL);
- XtVaSetValues(viewer->nextPageBtn, XmNsensitive,
- pageNum < viewer->core->getDoc()->getNumPages(), NULL);
- XtVaSetValues(viewer->backBtn, XmNsensitive,
- viewer->core->canGoBack(), NULL);
- XtVaSetValues(viewer->forwardBtn, XmNsensitive,
- viewer->core->canGoForward(), NULL);
- }
-
- if (numPages >= 0) {
- sprintf(buf, " of %d", numPages);
- s = XmStringCreateLocalized(buf);
- XtVaSetValues(viewer->pageCountLabel, XmNlabelString, s, NULL);
- XmStringFree(s);
- }
-
- if (linkString) {
- s = XmStringCreateLocalized((char *)linkString);
- XtVaSetValues(viewer->linkLabel, XmNlabelString, s, NULL);
- XmStringFree(s);
- }
- }
-}
-
-//------------------------------------------------------------------------
-// GUI code: outline
-//------------------------------------------------------------------------
-
-#ifndef DISABLE_OUTLINE
-
-void XPDFViewer::setupOutline() {
- GList *items;
- UnicodeMap *uMap;
- GString *enc;
- int i;
-
- if (outlineScroll == None) {
- return;
- }
-
- // unmanage and destroy the old labels
- if (outlineLabels) {
- XtUnmanageChildren(outlineLabels, outlineLabelsLength);
- for (i = 0; i < outlineLabelsLength; ++i) {
- XtDestroyWidget(outlineLabels[i]);
- }
- gfree(outlineLabels);
- outlineLabels = NULL;
- outlineLabelsLength = outlineLabelsSize = 0;
- }
-
- if (core->getDoc()) {
-
- // create the new labels
- items = core->getDoc()->getOutline()->getItems();
- if (items && items->getLength() > 0) {
- enc = new GString("Latin1");
- uMap = globalParams->getUnicodeMap(enc);
- delete enc;
- setupOutlineItems(items, NULL, uMap);
- uMap->decRefCnt();
- }
-
- // manage the new labels
- XtManageChildren(outlineLabels, outlineLabelsLength);
- }
-}
-
-void XPDFViewer::setupOutlineItems(GList *items, Widget parent,
- UnicodeMap *uMap) {
- OutlineItem *item;
- GList *kids;
- Widget label;
- Arg args[20];
- GString *title;
- char buf[8];
- XmString s;
- int i, j, n;
-
- for (i = 0; i < items->getLength(); ++i) {
- item = (OutlineItem *)items->get(i);
- title = new GString();
- for (j = 0; j < item->getTitleLength(); ++j) {
- n = uMap->mapUnicode(item->getTitle()[j], buf, sizeof(buf));
- title->append(buf, n);
- }
- n = 0;
- XtSetArg(args[n], XPDFNentryPosition, i); ++n;
- if (parent) {
- XtSetArg(args[n], XPDFNentryParent, parent); ++n;
- }
- XtSetArg(args[n], XPDFNentryExpanded, item->isOpen()); ++n;
- s = XmStringCreateLocalized(title->getCString());
- delete title;
- XtSetArg(args[n], XmNlabelString, s); ++n;
- XtSetArg(args[n], XmNuserData, item); ++n;
- XtSetArg(args[n], XmNmarginWidth, 0); ++n;
- XtSetArg(args[n], XmNmarginHeight, 2); ++n;
- XtSetArg(args[n], XmNshadowThickness, 0); ++n;
- XtSetArg(args[n], XmNforeground,
- app->getReverseVideo() ? WhitePixel(display, screenNum)
- : BlackPixel(display, screenNum)); ++n;
- XtSetArg(args[n], XmNbackground, app->getPaperPixel()); ++n;
- label = XmCreateLabelGadget(outlineTree, "label", args, n);
- XmStringFree(s);
- if (outlineLabelsLength == outlineLabelsSize) {
- outlineLabelsSize += 64;
- outlineLabels = (Widget *)greallocn(outlineLabels,
- outlineLabelsSize, sizeof(Widget *));
- }
- outlineLabels[outlineLabelsLength++] = label;
- item->open();
- if ((kids = item->getKids())) {
- setupOutlineItems(kids, label, uMap);
- }
- }
-}
-
-void XPDFViewer::outlineSelectCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
- XPDFTreeSelectCallbackStruct *data =
- (XPDFTreeSelectCallbackStruct *)callData;
- OutlineItem *item;
-
- XtVaGetValues(data->selectedItem, XmNuserData, &item, NULL);
- if (item) {
- if (item->getAction()) {
- viewer->core->doAction(item->getAction());
- }
- }
- viewer->core->takeFocus();
-}
-
-#endif // !DISABLE_OUTLINE
-
-//------------------------------------------------------------------------
-// GUI code: "about" dialog
-//------------------------------------------------------------------------
-
-void XPDFViewer::initAboutDialog() {
- Widget scrolledWin, col, label, sep, closeBtn;
- Arg args[20];
- int n, i;
- XmString s;
- char buf[20];
-
- //----- dialog
- n = 0;
- s = XmStringCreateLocalized(xpdfAppName ": About");
- XtSetArg(args[n], XmNdialogTitle, s); ++n;
- XtSetArg(args[n], XmNwidth, 450); ++n;
- XtSetArg(args[n], XmNheight, 300); ++n;
- aboutDialog = XmCreateFormDialog(win, "aboutDialog", args, n);
- XmStringFree(s);
-
- //----- "close" button
- n = 0;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightOffset, 4); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomOffset, 4); ++n;
- closeBtn = XmCreatePushButton(aboutDialog, "Close", args, n);
- XtManageChild(closeBtn);
- n = 0;
- XtSetArg(args[n], XmNdefaultButton, closeBtn); ++n;
- XtSetArg(args[n], XmNcancelButton, closeBtn); ++n;
- XtSetValues(aboutDialog, args, n);
-
- //----- scrolled window and RowColumn
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNbottomWidget, closeBtn); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); ++n;
- scrolledWin = XmCreateScrolledWindow(aboutDialog, "scrolledWin", args, n);
- XtManageChild(scrolledWin);
- n = 0;
- XtSetArg(args[n], XmNorientation, XmVERTICAL); ++n;
- XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
- col = XmCreateRowColumn(scrolledWin, "col", args, n);
- XtManageChild(col);
-
- //----- fonts
- aboutBigFont =
- createFontList("-*-times-bold-i-normal--20-*-*-*-*-*-iso8859-1");
- aboutVersionFont =
- createFontList("-*-times-medium-r-normal--16-*-*-*-*-*-iso8859-1");
- aboutFixedFont =
- createFontList("-*-courier-medium-r-normal--12-*-*-*-*-*-iso8859-1");
-
- //----- heading
- n = 0;
- s = XmStringCreateLocalized("Xpdf");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- XtSetArg(args[n], XmNfontList, aboutBigFont); ++n;
- label = XmCreateLabel(col, "h0", args, n);
- XmStringFree(s);
- XtManageChild(label);
- n = 0;
- s = XmStringCreateLocalized("Version " xpdfVersion);
- XtSetArg(args[n], XmNlabelString, s); ++n;
- XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
- label = XmCreateLabel(col, "h1", args, n);
- XmStringFree(s);
- XtManageChild(label);
- n = 0;
- s = XmStringCreateLocalized(xpdfCopyright);
- XtSetArg(args[n], XmNlabelString, s); ++n;
- XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
- label = XmCreateLabel(col, "h2", args, n);
- XmStringFree(s);
- XtManageChild(label);
- n = 0;
- s = XmStringCreateLocalized(" ");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
- label = XmCreateLabel(col, "h3", args, n);
- XmStringFree(s);
- XtManageChild(label);
- n = 0;
- XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
- sep = XmCreateSeparator(col, "sep", args, n);
- XtManageChild(sep);
- n = 0;
- s = XmStringCreateLocalized(" ");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- XtSetArg(args[n], XmNfontList, aboutVersionFont); ++n;
- label = XmCreateLabel(col, "h4", args, n);
- XmStringFree(s);
- XtManageChild(label);
- n = 0;
-
- //----- text
- for (i = 0; aboutWinText[i]; ++i) {
- n = 0;
- s = XmStringCreateLocalized((char *)aboutWinText[i]);
- XtSetArg(args[n], XmNlabelString, s); ++n;
- XtSetArg(args[n], XmNfontList, aboutFixedFont); ++n;
- sprintf(buf, "t%d", i);
- label = XmCreateLabel(col, buf, args, n);
- XtManageChild(label);
- XmStringFree(s);
- }
-}
-
-//------------------------------------------------------------------------
-// GUI code: "open" dialog
-//------------------------------------------------------------------------
-
-void XPDFViewer::initOpenDialog() {
- Arg args[20];
- int n;
- XmString s1, s2, s3;
- GString *dir;
-
- n = 0;
- s1 = XmStringCreateLocalized("Open");
- XtSetArg(args[n], XmNokLabelString, s1); ++n;
- s2 = XmStringCreateLocalized("*.[Pp][Dd][Ff]");
- XtSetArg(args[n], XmNpattern, s2); ++n;
- s3 = XmStringCreateLocalized(xpdfAppName ": Open");
- XtSetArg(args[n], XmNdialogTitle, s3); ++n;
- XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
- XtSetArg(args[n], XmNautoUnmanage, True); ++n;
- openDialog = XmCreateFileSelectionDialog(win, "openDialog", args, n);
- XmStringFree(s1);
- XmStringFree(s2);
- XmStringFree(s3);
- XtUnmanageChild(XmFileSelectionBoxGetChild(openDialog,
- XmDIALOG_HELP_BUTTON));
- XtAddCallback(openDialog, XmNokCallback,
- &openOkCbk, (XtPointer)this);
-
- if (core->getDoc() && core->getDoc()->getFileName()) {
- dir = makePathAbsolute(grabPath(
- core->getDoc()->getFileName()->getCString()));
- s1 = XmStringCreateLocalized(dir->getCString());
- XtVaSetValues(openDialog, XmNdirectory, s1, NULL);
- XmStringFree(s1);
- delete dir;
- }
-}
-
-void XPDFViewer::mapOpenDialog(GBool openInNewWindowA) {
- if (!openDialog) {
- initOpenDialog();
- }
- openInNewWindow = openInNewWindowA;
- XmFileSelectionDoSearch(openDialog, NULL);
- XtManageChild(openDialog);
-}
-
-void XPDFViewer::openOkCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
- XmFileSelectionBoxCallbackStruct *data =
- (XmFileSelectionBoxCallbackStruct *)callData;
- char *fileName;
- XmStringContext context;
- XmStringCharSet charSet;
- XmStringDirection dir;
- Boolean sep;
- GString *fileNameStr;
-
- XmStringInitContext(&context, data->value);
- if (XmStringGetNextSegment(context, &fileName, &charSet, &dir, &sep)) {
- fileNameStr = new GString(fileName);
- if (viewer->openInNewWindow) {
- viewer->app->open(fileNameStr);
- } else {
- if (viewer->loadFile(fileNameStr)) {
- viewer->displayPage(1, viewer->core->getZoom(),
- viewer->core->getRotate(), gTrue, gTrue);
- }
- }
- delete fileNameStr;
- XtFree(charSet);
- XtFree(fileName);
- }
- XmStringFreeContext(context);
-}
-
-//------------------------------------------------------------------------
-// GUI code: "find" dialog
-//------------------------------------------------------------------------
-
-void XPDFViewer::initFindDialog() {
- Widget form1, label, okBtn, closeBtn;
- Arg args[20];
- int n;
- XmString s;
-
- //----- dialog
- n = 0;
- s = XmStringCreateLocalized(xpdfAppName ": Find");
- XtSetArg(args[n], XmNdialogTitle, s); ++n;
- XtSetArg(args[n], XmNnavigationType, XmNONE); ++n;
- XtSetArg(args[n], XmNautoUnmanage, False); ++n;
- findDialog = XmCreateFormDialog(win, "findDialog", args, n);
- XmStringFree(s);
-
- //----- "find" and "close" buttons
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 4); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomOffset, 4); ++n;
- XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
- okBtn = XmCreatePushButton(findDialog, "Find", args, n);
- XtManageChild(okBtn);
- XtAddCallback(okBtn, XmNactivateCallback,
- &findFindCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightOffset, 4); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomOffset, 4); ++n;
- XtSetArg(args[n], XmNnavigationType, XmEXCLUSIVE_TAB_GROUP); ++n;
- closeBtn = XmCreatePushButton(findDialog, "Close", args, n);
- XtManageChild(closeBtn);
- XtAddCallback(closeBtn, XmNactivateCallback,
- &findCloseCbk, (XtPointer)this);
-
- //----- checkboxes
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 4); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNbottomWidget, okBtn); ++n;
- XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
-#if XmVERSION <= 1
- XtSetArg(args[n], XmNindicatorOn, True); ++n;
-#else
- XtSetArg(args[n], XmNindicatorOn, XmINDICATOR_FILL); ++n;
-#endif
- XtSetArg(args[n], XmNset, XmUNSET); ++n;
- s = XmStringCreateLocalized("Search backward");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- findBackwardToggle = XmCreateToggleButton(findDialog, "backward", args, n);
- XmStringFree(s);
- XtManageChild(findBackwardToggle);
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, findBackwardToggle); ++n;
- XtSetArg(args[n], XmNleftOffset, 16); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNbottomWidget, okBtn); ++n;
- XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
-#if XmVERSION <= 1
- XtSetArg(args[n], XmNindicatorOn, True); ++n;
-#else
- XtSetArg(args[n], XmNindicatorOn, XmINDICATOR_FILL); ++n;
-#endif
- XtSetArg(args[n], XmNset, XmUNSET); ++n;
- s = XmStringCreateLocalized("Match case");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- findCaseSensitiveToggle =
- XmCreateToggleButton(findDialog, "matchCase", args, n);
- XmStringFree(s);
- XtManageChild(findCaseSensitiveToggle);
- n = 0;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, findCaseSensitiveToggle); ++n;
- XtSetArg(args[n], XmNleftOffset, 16); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightOffset, 4); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNbottomWidget, okBtn); ++n;
- XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); ++n;
-#if XmVERSION <= 1
- XtSetArg(args[n], XmNindicatorOn, True); ++n;
-#else
- XtSetArg(args[n], XmNindicatorOn, XmINDICATOR_FILL); ++n;
-#endif
- XtSetArg(args[n], XmNset, XmUNSET); ++n;
- s = XmStringCreateLocalized("Whole words only");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- findWholeWordToggle = XmCreateToggleButton(findDialog, "wholeWord", args, n);
- XmStringFree(s);
- XtManageChild(findWholeWordToggle);
-
- //----- search string entry
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNtopOffset, 4); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNbottomWidget, findBackwardToggle); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 2); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightOffset, 2); ++n;
- form1 = XmCreateForm(findDialog, "form", args, n);
- XtManageChild(form1);
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- s = XmStringCreateLocalized("Find text: ");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- label = XmCreateLabel(form1, "label", args, n);
- XmStringFree(s);
- XtManageChild(label);
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNleftWidget, label); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- findText = XmCreateTextField(form1, "text", args, n);
- XtManageChild(findText);
-#ifdef LESSTIF_VERSION
- XtAddCallback(findText, XmNactivateCallback,
- &findFindCbk, (XtPointer)this);
-#endif
-
- //----- dialog parameters
- n = 0;
- XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
- XtSetArg(args[n], XmNcancelButton, closeBtn); ++n;
-#if XmVersion > 1001
- XtSetArg(args[n], XmNinitialFocus, findText); ++n;
-#endif
- XtSetValues(findDialog, args, n);
-}
-
-void XPDFViewer::findFindCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- viewer->doFind(gFalse);
-}
-
-void XPDFViewer::mapFindDialog() {
- XmTextFieldSetSelection(findText, 0, XmTextFieldGetLastPosition(findText),
- XtLastTimestampProcessed(display));
- XmTextFieldSetInsertionPosition(findText, 0);
- XtManageChild(findDialog);
-}
-
-void XPDFViewer::doFind(GBool next) {
- if (XtWindow(findDialog)) {
- XDefineCursor(display, XtWindow(findDialog), core->getBusyCursor());
- }
- core->find(XmTextFieldGetString(findText),
- XmToggleButtonGetState(findCaseSensitiveToggle),
- next,
- XmToggleButtonGetState(findBackwardToggle),
- XmToggleButtonGetState(findWholeWordToggle),
- gFalse);
- if (XtWindow(findDialog)) {
- XUndefineCursor(display, XtWindow(findDialog));
- }
-}
-
-void XPDFViewer::findCloseCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
-
- XtUnmanageChild(viewer->findDialog);
-}
-
-//------------------------------------------------------------------------
-// GUI code: "save as" dialog
-//------------------------------------------------------------------------
-
-void XPDFViewer::initSaveAsDialog() {
- Arg args[20];
- int n;
- XmString s1, s2, s3;
- GString *dir;
-
- n = 0;
- s1 = XmStringCreateLocalized("Save");
- XtSetArg(args[n], XmNokLabelString, s1); ++n;
- s2 = XmStringCreateLocalized("*.[Pp][Dd][Ff]");
- XtSetArg(args[n], XmNpattern, s2); ++n;
- s3 = XmStringCreateLocalized(xpdfAppName ": Save as");
- XtSetArg(args[n], XmNdialogTitle, s3); ++n;
- XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
- XtSetArg(args[n], XmNautoUnmanage, True); ++n;
- saveAsDialog = XmCreateFileSelectionDialog(win, "saveAsDialog", args, n);
- XmStringFree(s1);
- XmStringFree(s2);
- XmStringFree(s3);
- XtUnmanageChild(XmFileSelectionBoxGetChild(saveAsDialog,
- XmDIALOG_HELP_BUTTON));
- XtAddCallback(saveAsDialog, XmNokCallback,
- &saveAsOkCbk, (XtPointer)this);
-
- if (core->getDoc() && core->getDoc()->getFileName()) {
- dir = makePathAbsolute(grabPath(
- core->getDoc()->getFileName()->getCString()));
- s1 = XmStringCreateLocalized(dir->getCString());
- XtVaSetValues(saveAsDialog, XmNdirectory, s1, NULL);
- XmStringFree(s1);
- delete dir;
- }
-}
-
-void XPDFViewer::mapSaveAsDialog() {
- if (!saveAsDialog) {
- initSaveAsDialog();
- }
- XmFileSelectionDoSearch(saveAsDialog, NULL);
- XtManageChild(saveAsDialog);
-}
-
-void XPDFViewer::saveAsOkCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
- XmFileSelectionBoxCallbackStruct *data =
- (XmFileSelectionBoxCallbackStruct *)callData;
- char *fileName;
- GString *fileNameStr;
- XmStringContext context;
- XmStringCharSet charSet;
- XmStringDirection dir;
- Boolean sep;
-
- XmStringInitContext(&context, data->value);
- if (XmStringGetNextSegment(context, &fileName, &charSet, &dir, &sep)) {
- fileNameStr = new GString(fileName);
- viewer->core->getDoc()->saveAs(fileNameStr);
- delete fileNameStr;
- XtFree(charSet);
- XtFree(fileName);
- }
- XmStringFreeContext(context);
-}
-
-//------------------------------------------------------------------------
-// GUI code: "print" dialog
-//------------------------------------------------------------------------
-
-void XPDFViewer::initPrintDialog() {
- Widget sep1, sep2, row, label1, label2, okBtn, cancelBtn;
- Arg args[20];
- int n;
- XmString s;
- GString *psFileName;
-
- //----- dialog
- n = 0;
- s = XmStringCreateLocalized(xpdfAppName ": Print");
- XtSetArg(args[n], XmNdialogTitle, s); ++n;
- XtSetArg(args[n], XmNdialogStyle, XmDIALOG_PRIMARY_APPLICATION_MODAL); ++n;
- printDialog = XmCreateFormDialog(win, "printDialog", args, n);
- XmStringFree(s);
-
- //----- "print with command"
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNtopOffset, 4); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
- XtSetArg(args[n], XmNset, XmSET); ++n;
- s = XmStringCreateLocalized("Print with command:");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- printWithCmdBtn = XmCreateToggleButton(printDialog, "printWithCmd", args, n);
- XmStringFree(s);
- XtManageChild(printWithCmdBtn);
- XtAddCallback(printWithCmdBtn, XmNvalueChangedCallback,
- &printWithCmdBtnCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, printWithCmdBtn); ++n;
- XtSetArg(args[n], XmNtopOffset, 2); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 16); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightOffset, 4); ++n;
- XtSetArg(args[n], XmNcolumns, 40); ++n;
- printCmdText = XmCreateTextField(printDialog, "printCmd", args, n);
- XtManageChild(printCmdText);
-
- //----- "print to file"
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, printCmdText); ++n;
- XtSetArg(args[n], XmNtopOffset, 4); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); ++n;
- XtSetArg(args[n], XmNset, XmUNSET); ++n;
- s = XmStringCreateLocalized("Print to file:");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- printToFileBtn = XmCreateToggleButton(printDialog, "printToFile", args, n);
- XmStringFree(s);
- XtManageChild(printToFileBtn);
- XtAddCallback(printToFileBtn, XmNvalueChangedCallback,
- &printToFileBtnCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, printToFileBtn); ++n;
- XtSetArg(args[n], XmNtopOffset, 2); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 16); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightOffset, 4); ++n;
- XtSetArg(args[n], XmNcolumns, 40); ++n;
- XtSetArg(args[n], XmNsensitive, False); ++n;
- printFileText = XmCreateTextField(printDialog, "printFile", args, n);
- XtManageChild(printFileText);
-
- //----- separator
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, printFileText); ++n;
- XtSetArg(args[n], XmNtopOffset, 8); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 8); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightOffset, 8); ++n;
- XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
- sep1 = XmCreateSeparator(printDialog, "sep1", args, n);
- XtManageChild(sep1);
-
- //----- page range
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, sep1); ++n;
- XtSetArg(args[n], XmNtopOffset, 8); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 4); ++n;
- XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
- XtSetArg(args[n], XmNpacking, XmPACK_TIGHT); ++n;
- row = XmCreateRowColumn(printDialog, "row", args, n);
- XtManageChild(row);
- n = 0;
- s = XmStringCreateLocalized("Pages:");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- label1 = XmCreateLabel(row, "label1", args, n);
- XmStringFree(s);
- XtManageChild(label1);
- n = 0;
- XtSetArg(args[n], XmNcolumns, 5); ++n;
- printFirstPage = XmCreateTextField(row, "printFirstPage", args, n);
- XtManageChild(printFirstPage);
- n = 0;
- s = XmStringCreateLocalized("to");
- XtSetArg(args[n], XmNlabelString, s); ++n;
- label2 = XmCreateLabel(row, "label2", args, n);
- XmStringFree(s);
- XtManageChild(label2);
- n = 0;
- XtSetArg(args[n], XmNcolumns, 5); ++n;
- printLastPage = XmCreateTextField(row, "printLastPage", args, n);
- XtManageChild(printLastPage);
-
- //----- separator
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, row); ++n;
- XtSetArg(args[n], XmNtopOffset, 8); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 8); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightOffset, 8); ++n;
- XtSetArg(args[n], XmNorientation, XmHORIZONTAL); ++n;
- sep2 = XmCreateSeparator(printDialog, "sep2", args, n);
- XtManageChild(sep2);
-
- //----- "print" and "cancel" buttons
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, sep2); ++n;
- XtSetArg(args[n], XmNtopOffset, 8); ++n;
- XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNleftOffset, 4); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomOffset, 4); ++n;
- okBtn = XmCreatePushButton(printDialog, "Print", args, n);
- XtManageChild(okBtn);
- XtAddCallback(okBtn, XmNactivateCallback,
- &printPrintCbk, (XtPointer)this);
- n = 0;
- XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); ++n;
- XtSetArg(args[n], XmNtopWidget, sep2); ++n;
- XtSetArg(args[n], XmNtopOffset, 8); ++n;
- XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNrightOffset, 4); ++n;
- XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); ++n;
- XtSetArg(args[n], XmNbottomOffset, 4); ++n;
- cancelBtn = XmCreatePushButton(printDialog, "Cancel", args, n);
- XtManageChild(cancelBtn);
- n = 0;
- XtSetArg(args[n], XmNdefaultButton, okBtn); ++n;
- XtSetArg(args[n], XmNcancelButton, cancelBtn); ++n;
- XtSetValues(printDialog, args, n);
-
- //----- initial values
- if ((psFileName = globalParams->getPSFile())) {
- if (psFileName->getChar(0) == '|') {
- XmTextFieldSetString(printCmdText,
- psFileName->getCString() + 1);
- } else {
- XmTextFieldSetString(printFileText, psFileName->getCString());
- }
- delete psFileName;
- }
-}
-
-void XPDFViewer::setupPrintDialog() {
- PDFDoc *doc;
- char buf[20];
- GString *pdfFileName, *psFileName, *psFileName2;
- char *p;
-
- doc = core->getDoc();
- psFileName = globalParams->getPSFile();
- if (!psFileName || psFileName->getChar(0) == '|') {
- if ((pdfFileName = doc->getFileName())) {
- p = pdfFileName->getCString() + pdfFileName->getLength() - 4;
- if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) {
- psFileName2 = new GString(pdfFileName->getCString(),
- pdfFileName->getLength() - 4);
- } else {
- psFileName2 = pdfFileName->copy();
- }
- psFileName2->append(".ps");
- XmTextFieldSetString(printFileText, psFileName2->getCString());
- delete psFileName2;
- }
- }
- if (psFileName && psFileName->getChar(0) == '|') {
- XmToggleButtonSetState(printWithCmdBtn, True, False);
- XmToggleButtonSetState(printToFileBtn, False, False);
- XtVaSetValues(printCmdText, XmNsensitive, True, NULL);
- XtVaSetValues(printFileText, XmNsensitive, False, NULL);
- } else {
- XmToggleButtonSetState(printWithCmdBtn, False, False);
- XmToggleButtonSetState(printToFileBtn, True, False);
- XtVaSetValues(printCmdText, XmNsensitive, False, NULL);
- XtVaSetValues(printFileText, XmNsensitive, True, NULL);
- }
- if (psFileName) {
- delete psFileName;
- }
-
- sprintf(buf, "%d", doc->getNumPages());
- XmTextFieldSetString(printFirstPage, "1");
- XmTextFieldSetString(printLastPage, buf);
-}
-
-void XPDFViewer::printWithCmdBtnCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
- XmToggleButtonCallbackStruct *data =
- (XmToggleButtonCallbackStruct *)callData;
-
- if (data->set != XmSET) {
- XmToggleButtonSetState(viewer->printWithCmdBtn, True, False);
- }
- XmToggleButtonSetState(viewer->printToFileBtn, False, False);
- XtVaSetValues(viewer->printCmdText, XmNsensitive, True, NULL);
- XtVaSetValues(viewer->printFileText, XmNsensitive, False, NULL);
-}
-
-void XPDFViewer::printToFileBtnCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
- XmToggleButtonCallbackStruct *data =
- (XmToggleButtonCallbackStruct *)callData;
-
- if (data->set != XmSET) {
- XmToggleButtonSetState(viewer->printToFileBtn, True, False);
- }
- XmToggleButtonSetState(viewer->printWithCmdBtn, False, False);
- XtVaSetValues(viewer->printFileText, XmNsensitive, True, NULL);
- XtVaSetValues(viewer->printCmdText, XmNsensitive, False, NULL);
-}
-
-void XPDFViewer::printPrintCbk(Widget widget, XtPointer ptr,
- XtPointer callData) {
- XPDFViewer *viewer = (XPDFViewer *)ptr;
- unsigned char withCmd;
- GString *psFileName;
- int firstPage, lastPage;
- PDFDoc *doc;
- PSOutputDev *psOut;
-
- doc = viewer->core->getDoc();
- if (!doc->okToPrint()) {
- error(errNotAllowed, -1, "Printing this document is not allowed.");
- return;
- }
-
- viewer->core->setBusyCursor(gTrue);
-
- XtVaGetValues(viewer->printWithCmdBtn, XmNset, &withCmd, NULL);
- if (withCmd) {
- psFileName = new GString(XmTextFieldGetString(viewer->printCmdText));
- psFileName->insert(0, '|');
- } else {
- psFileName = new GString(XmTextFieldGetString(viewer->printFileText));
- }
-
- firstPage = atoi(XmTextFieldGetString(viewer->printFirstPage));
- lastPage = atoi(XmTextFieldGetString(viewer->printLastPage));
- if (firstPage < 1) {
- firstPage = 1;
- } else if (firstPage > doc->getNumPages()) {
- firstPage = doc->getNumPages();
- }
- if (lastPage < firstPage) {
- lastPage = firstPage;
- } else if (lastPage > doc->getNumPages()) {
- lastPage = doc->getNumPages();
- }
-
- psOut = new PSOutputDev(psFileName->getCString(), doc,
- firstPage, lastPage, psModePS);
- if (psOut->isOk()) {
- doc->displayPages(psOut, firstPage, lastPage, 72, 72,
- 0, gTrue, globalParams->getPSCrop(), gTrue);
- }
- delete psOut;
- delete psFileName;
-
- viewer->core->setBusyCursor(gFalse);
-}
-
-//------------------------------------------------------------------------
-// Motif support
-//------------------------------------------------------------------------
-
-XmFontList XPDFViewer::createFontList(char *xlfd) {
- XmFontList fontList;
-
-#if XmVersion <= 1001
-
- XFontStruct *font;
- String params;
- Cardinal nParams;
-
- font = XLoadQueryFont(display, xlfd);
- if (font) {
- fontList = XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
- } else {
- params = (String)xlfd;
- nParams = 1;
- XtAppWarningMsg(app->getAppContext(),
- "noSuchFont", "CvtStringToXmFontList",
- "XtToolkitError", "No such font: %s",
- &params, &nParams);
- fontList = NULL;
- }
-
-#else
-
- XmFontListEntry entry;
-
- entry = XmFontListEntryLoad(display, xlfd,
- XmFONT_IS_FONT, XmFONTLIST_DEFAULT_TAG);
- fontList = XmFontListAppendEntry(NULL, entry);
- XmFontListEntryFree(&entry);
-
-#endif
-
- return fontList;
-}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFViewer.h b/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFViewer.h
deleted file mode 100644
index 8b03e7fc4fe..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XPDFViewer.h
+++ /dev/null
@@ -1,357 +0,0 @@
-//========================================================================
-//
-// XPDFViewer.h
-//
-// Copyright 2002-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-#ifndef XPDFVIEWER_H
-#define XPDFVIEWER_H
-
-#include <aconf.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
-#define Object XtObject
-#include <Xm/XmAll.h>
-#undef Object
-#include "gtypes.h"
-#include "XPDFCore.h"
-
-#if (XmVERSION <= 1) && !defined(__sgi)
-#define DISABLE_OUTLINE
-#endif
-
-#if (XmVERSION >= 2 && !defined(LESSTIF_VERSION))
-# define USE_COMBO_BOX 1
-#else
-# undef USE_COMBO_BOX
-#endif
-
-class GString;
-class GList;
-class UnicodeMap;
-class LinkDest;
-class XPDFApp;
-class XPDFViewer;
-
-//------------------------------------------------------------------------
-
-// NB: this must match the defn of zoomMenuBtnInfo in XPDFViewer.cc
-#define nZoomMenuItems 10
-
-//------------------------------------------------------------------------
-
-struct XPDFViewerCmd {
- const char *name;
- int nArgs;
- GBool requiresDoc;
- GBool requiresEvent;
- void (XPDFViewer::*func)(GString *args[], int nArgs, XEvent *event);
-};
-
-//------------------------------------------------------------------------
-// XPDFViewer
-//------------------------------------------------------------------------
-
-class XPDFViewer {
-public:
-
- XPDFViewer(XPDFApp *appA, GString *fileName,
- int pageA, GString *destName, GBool fullScreen,
- GString *ownerPassword, GString *userPassword);
- XPDFViewer(XPDFApp *appA, PDFDoc *doc, int pageA,
- GString *destName, GBool fullScreen);
- GBool isOk() { return ok; }
- ~XPDFViewer();
-
- void open(GString *fileName, int pageA, GString *destName);
- void clear();
- void reloadFile();
-
- void execCmd(GString *cmd, XEvent *event);
-
- Widget getWindow() { return win; }
-
-private:
-
- //----- load / display
- GBool loadFile(GString *fileName, GString *ownerPassword = NULL,
- GString *userPassword = NULL);
- void displayPage(int pageA, double zoomA, int rotateA,
- GBool scrollToTop, GBool addToHist);
- void displayDest(LinkDest *dest, double zoomA, int rotateA,
- GBool addToHist);
- void getPageAndDest(int pageA, GString *destName,
- int *pageOut, LinkDest **destOut);
-
- //----- hyperlinks / actions
- void doLink(int wx, int wy, GBool onlyIfNoSelection, GBool newWin);
- static void actionCbk(void *data, char *action);
-
- //----- keyboard/mouse input
- static void keyPressCbk(void *data, KeySym key, Guint modifiers,
- XEvent *event);
- static void mouseCbk(void *data, XEvent *event);
- int getModifiers(Guint modifiers);
- int getContext(Guint modifiers);
-
- //----- command functions
- void cmdAbout(GString *args[], int nArgs, XEvent *event);
- void cmdCloseOutline(GString *args[], int nArgs, XEvent *event);
- void cmdCloseWindow(GString *args[], int nArgs, XEvent *event);
- void cmdCloseWindowOrQuit(GString *args[], int nArgs, XEvent *event);
- void cmdContinuousMode(GString *args[], int nArgs, XEvent *event);
- void cmdEndPan(GString *args[], int nArgs, XEvent *event);
- void cmdEndSelection(GString *args[], int nArgs, XEvent *event);
- void cmdFind(GString *args[], int nArgs, XEvent *event);
- void cmdFindNext(GString *args[], int nArgs, XEvent *event);
- void cmdFocusToDocWin(GString *args[], int nArgs, XEvent *event);
- void cmdFocusToPageNum(GString *args[], int nArgs, XEvent *event);
- void cmdFollowLink(GString *args[], int nArgs, XEvent *event);
- void cmdFollowLinkInNewWin(GString *args[], int nArgs, XEvent *event);
- void cmdFollowLinkInNewWinNoSel(GString *args[], int nArgs, XEvent *event);
- void cmdFollowLinkNoSel(GString *args[], int nArgs, XEvent *event);
- void cmdFullScreenMode(GString *args[], int nArgs, XEvent *event);
- void cmdGoBackward(GString *args[], int nArgs, XEvent *event);
- void cmdGoForward(GString *args[], int nArgs, XEvent *event);
- void cmdGotoDest(GString *args[], int nArgs, XEvent *event);
- void cmdGotoLastPage(GString *args[], int nArgs, XEvent *event);
- void cmdGotoLastPageNoScroll(GString *args[], int nArgs, XEvent *event);
- void cmdGotoPage(GString *args[], int nArgs, XEvent *event);
- void cmdGotoPageNoScroll(GString *args[], int nArgs, XEvent *event);
- void cmdNextPage(GString *args[], int nArgs, XEvent *event);
- void cmdNextPageNoScroll(GString *args[], int nArgs, XEvent *event);
- void cmdOpen(GString *args[], int nArgs, XEvent *event);
- void cmdOpenFile(GString *args[], int nArgs, XEvent *event);
- void cmdOpenFileAtDest(GString *args[], int nArgs, XEvent *event);
- void cmdOpenFileAtDestInNewWin(GString *args[], int nArgs, XEvent *event);
- void cmdOpenFileAtPage(GString *args[], int nArgs, XEvent *event);
- void cmdOpenFileAtPageInNewWin(GString *args[], int nArgs, XEvent *event);
- void cmdOpenFileInNewWin(GString *args[], int nArgs, XEvent *event);
- void cmdOpenInNewWin(GString *args[], int nArgs, XEvent *event);
- void cmdOpenOutline(GString *args[], int nArgs, XEvent *event);
- void cmdPageDown(GString *args[], int nArgs, XEvent *event);
- void cmdPageUp(GString *args[], int nArgs, XEvent *event);
- void cmdPostPopupMenu(GString *args[], int nArgs, XEvent *event);
- void cmdPrevPage(GString *args[], int nArgs, XEvent *event);
- void cmdPrevPageNoScroll(GString *args[], int nArgs, XEvent *event);
- void cmdPrint(GString *args[], int nArgs, XEvent *event);
- void cmdQuit(GString *args[], int nArgs, XEvent *event);
- void cmdRaise(GString *args[], int nArgs, XEvent *event);
- void cmdRedraw(GString *args[], int nArgs, XEvent *event);
- void cmdReload(GString *args[], int nArgs, XEvent *event);
- void cmdRotateCCW(GString *args[], int nArgs, XEvent *event);
- void cmdRotateCW(GString *args[], int nArgs, XEvent *event);
- void cmdRun(GString *args[], int nArgs, XEvent *event);
- void cmdScrollDown(GString *args[], int nArgs, XEvent *event);
- void cmdScrollDownNextPage(GString *args[], int nArgs, XEvent *event);
- void cmdScrollLeft(GString *args[], int nArgs, XEvent *event);
- void cmdScrollOutlineDown(GString *args[], int nArgs, XEvent *event);
- void cmdScrollOutlineUp(GString *args[], int nArgs, XEvent *event);
- void cmdScrollRight(GString *args[], int nArgs, XEvent *event);
- void cmdScrollToBottomEdge(GString *args[], int nArgs, XEvent *event);
- void cmdScrollToBottomRight(GString *args[], int nArgs, XEvent *event);
- void cmdScrollToLeftEdge(GString *args[], int nArgs, XEvent *event);
- void cmdScrollToRightEdge(GString *args[], int nArgs, XEvent *event);
- void cmdScrollToTopEdge(GString *args[], int nArgs, XEvent *event);
- void cmdScrollToTopLeft(GString *args[], int nArgs, XEvent *event);
- void cmdScrollUp(GString *args[], int nArgs, XEvent *event);
- void cmdScrollUpPrevPage(GString *args[], int nArgs, XEvent *event);
- void cmdSetSelection(GString *args[], int nArgs, XEvent *event);
- void cmdSinglePageMode(GString *args[], int nArgs, XEvent *event);
- void cmdStartPan(GString *args[], int nArgs, XEvent *event);
- void cmdStartSelection(GString *args[], int nArgs, XEvent *event);
- void cmdToggleContinuousMode(GString *args[], int nArgs, XEvent *event);
- void cmdToggleFullScreenMode(GString *args[], int nArgs, XEvent *event);
- void cmdToggleOutline(GString *args[], int nArgs, XEvent *event);
- void cmdWindowMode(GString *args[], int nArgs, XEvent *event);
- void cmdZoomFitPage(GString *args[], int nArgs, XEvent *event);
- void cmdZoomFitWidth(GString *args[], int nArgs, XEvent *event);
- void cmdZoomIn(GString *args[], int nArgs, XEvent *event);
- void cmdZoomOut(GString *args[], int nArgs, XEvent *event);
- void cmdZoomPercent(GString *args[], int nArgs, XEvent *event);
- void cmdZoomToSelection(GString *args[], int nArgs, XEvent *event);
-
- //----- GUI code: main window
- void initWindow(GBool fullScreen);
- void initToolbar(Widget parent);
-#ifndef DISABLE_OUTLINE
- void initPanedWin(Widget parent);
-#endif
- void initCore(Widget parent, GBool fullScreen);
- void initPopupMenu();
- void addToolTip(Widget widget, char *text);
- void mapWindow();
- void closeWindow();
- int getZoomIdx();
- void setZoomIdx(int idx);
- void setZoomVal(double z);
- static void prevPageCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void prevTenPageCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void nextPageCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void nextTenPageCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void backCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void forwardCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
-#if USE_COMBO_BOX
- static void zoomComboBoxCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
-#else
- static void zoomMenuCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
-#endif
- static void findCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void printCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void aboutCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void quitCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void openCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void openInNewWindowCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void reloadCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void saveAsCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void continuousModeToggleCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void fullScreenToggleCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void rotateCCWCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void rotateCWCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void zoomToSelectionCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void closeCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void closeMsgCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void pageNumCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void updateCbk(void *data, GString *fileName,
- int pageNum, int numPages, const char *linkString);
-
- //----- GUI code: outline
-#ifndef DISABLE_OUTLINE
- void setupOutline();
- void setupOutlineItems(GList *items, Widget parent, UnicodeMap *uMap);
- static void outlineSelectCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
-#endif
-
- //----- GUI code: "about" dialog
- void initAboutDialog();
-
- //----- GUI code: "open" dialog
- void initOpenDialog();
- void mapOpenDialog(GBool openInNewWindowA);
- static void openOkCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
-
- //----- GUI code: "find" dialog
- void initFindDialog();
- static void findFindCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- void mapFindDialog();
- void doFind(GBool next);
- static void findCloseCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
-
- //----- GUI code: "save as" dialog
- void initSaveAsDialog();
- void mapSaveAsDialog();
- static void saveAsOkCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
-
- //----- GUI code: "print" dialog
- void initPrintDialog();
- void setupPrintDialog();
- static void printWithCmdBtnCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void printToFileBtnCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
- static void printPrintCbk(Widget widget, XtPointer ptr,
- XtPointer callData);
-
- //----- Motif support
- XmFontList createFontList(char *xlfd);
-
- static XPDFViewerCmd cmdTab[];
-
- XPDFApp *app;
- GBool ok;
-
- Display *display;
- int screenNum;
- Widget win; // top-level window
- Widget form;
- Widget panedWin;
-#ifndef DISABLE_OUTLINE
- Widget outlineScroll;
- Widget outlineTree;
- Widget *outlineLabels;
- int outlineLabelsLength;
- int outlineLabelsSize;
- Dimension outlinePaneWidth;
-#endif
- XPDFCore *core;
- Widget toolBar;
- Widget backBtn;
- Widget prevTenPageBtn;
- Widget prevPageBtn;
- Widget nextPageBtn;
- Widget nextTenPageBtn;
- Widget forwardBtn;
- Widget pageNumText;
- Widget pageCountLabel;
-#if USE_COMBO_BOX
- Widget zoomComboBox;
-#else
- Widget zoomMenu;
- Widget zoomMenuBtns[nZoomMenuItems];
-#endif
- Widget zoomWidget;
- Widget findBtn;
- Widget printBtn;
- Widget aboutBtn;
- Widget linkLabel;
- Widget quitBtn;
- Widget popupMenu;
-
- Widget aboutDialog;
- XmFontList aboutBigFont, aboutVersionFont, aboutFixedFont;
-
- Widget openDialog;
- GBool openInNewWindow;
-
- Widget findDialog;
- Widget findText;
- Widget findBackwardToggle;
- Widget findCaseSensitiveToggle;
- Widget findWholeWordToggle;
-
- Widget saveAsDialog;
-
- Widget printDialog;
- Widget printWithCmdBtn;
- Widget printToFileBtn;
- Widget printCmdText;
- Widget printFileText;
- Widget printFirstPage;
- Widget printLastPage;
-};
-
-#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc
index 71540a9717a..10ea26568b8 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.cc
@@ -18,6 +18,7 @@
#include <ctype.h>
#include <limits.h>
#include "gmem.h"
+#include "gmempp.h"
#include "gfile.h"
#include "Object.h"
#include "Stream.h"
@@ -54,6 +55,8 @@ public:
~XRefPosSet();
void add(GFileOffset pos);
GBool check(GFileOffset pos);
+ int getLength() { return len; }
+ GFileOffset get(int idx) { return tab[idx]; }
private:
@@ -154,6 +157,7 @@ private:
ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
Stream *str;
+ Lexer *lexer;
Parser *parser;
int *offsets;
Object objStr, obj1, obj2;
@@ -204,7 +208,8 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
objStr.streamReset();
obj1.initNull();
str = new EmbedStream(objStr.getStream(), &obj1, gTrue, first);
- parser = new Parser(xref, new Lexer(xref, str), gFalse);
+ lexer = new Lexer(xref, str);
+ parser = new Parser(xref, lexer, gFalse);
for (i = 0; i < nObjects; ++i) {
parser->getObj(&obj1, gTrue);
parser->getObj(&obj2, gTrue);
@@ -226,7 +231,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
goto err2;
}
}
- while (str->getChar() != EOF) ;
+ lexer->skipToEOF();
delete parser;
// skip to the first object - this shouldn't be necessary because
@@ -245,9 +250,10 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
str = new EmbedStream(objStr.getStream(), &obj1, gTrue,
offsets[i+1] - offsets[i]);
}
- parser = new Parser(xref, new Lexer(xref, str), gFalse);
+ lexer = new Lexer(xref, str);
+ parser = new Parser(xref, lexer, gFalse);
parser->getObj(&objs[i]);
- while (str->getChar() != EOF) ;
+ lexer->skipToEOF();
delete parser;
}
@@ -274,9 +280,11 @@ ObjectStream::~ObjectStream() {
Object *ObjectStream::getObject(int objIdx, int objNum, Object *obj) {
if (objIdx < 0 || objIdx >= nObjects || objNum != objNums[objIdx]) {
- return obj->initNull();
+ obj->initNull();
+ } else {
+ objs[objIdx].copy(obj);
}
- return objs[objIdx].copy(obj);
+ return obj;
}
//------------------------------------------------------------------------
@@ -294,6 +302,9 @@ XRef::XRef(BaseStream *strA, GBool repair) {
size = 0;
last = -1;
entries = NULL;
+ lastStartxrefPos = 0;
+ xrefTablePos = NULL;
+ xrefTablePosLen = 0;
streamEnds = NULL;
streamEndsLen = 0;
for (i = 0; i < objStrCacheSize; ++i) {
@@ -308,6 +319,11 @@ XRef::XRef(BaseStream *strA, GBool repair) {
cache[i].num = -1;
}
+#if MULTITHREADED
+ gInitMutex(&objStrsMutex);
+ gInitMutex(&cacheMutex);
+#endif
+
str = strA;
start = str->getStart();
@@ -332,6 +348,12 @@ XRef::XRef(BaseStream *strA, GBool repair) {
// read the xref table
posSet = new XRefPosSet();
while (readXRef(&pos, posSet)) ;
+ xrefTablePosLen = posSet->getLength();
+ xrefTablePos = (GFileOffset *)gmallocn(xrefTablePosLen,
+ sizeof(GFileOffset));
+ for (i = 0; i < xrefTablePosLen; ++i) {
+ xrefTablePos[i] = posSet->get(i);
+ }
delete posSet;
if (!ok) {
errCode = errDamaged;
@@ -368,6 +390,9 @@ XRef::~XRef() {
}
gfree(entries);
trailerDict.free();
+ if (xrefTablePos) {
+ gfree(xrefTablePos);
+ }
if (streamEnds) {
gfree(streamEnds);
}
@@ -376,6 +401,10 @@ XRef::~XRef() {
delete objStrs[i];
}
}
+#if MULTITHREADED
+ gDestroyMutex(&objStrsMutex);
+ gDestroyMutex(&cacheMutex);
+#endif
}
// Read the 'startxref' position.
@@ -400,6 +429,7 @@ GFileOffset XRef::getStartXref() {
}
for (p = &buf[i+9]; isspace(*p & 0xff); ++p) ;
lastXRefPos = strToFileOffset(p);
+ lastStartxrefPos = str->getPos() - n + i;
return lastXRefPos;
}
@@ -631,6 +661,7 @@ GBool XRef::readXRefTable(GFileOffset *pos, int offset, XRefPosSet *posSet) {
readXRef(&pos2, posSet);
if (!ok) {
obj2.free();
+ obj.free();
goto err1;
}
}
@@ -957,6 +988,20 @@ void XRef::setEncryption(int permFlagsA, GBool ownerPasswordOkA,
encAlgorithm = encAlgorithmA;
}
+GBool XRef::getEncryption(int *permFlagsA, GBool *ownerPasswordOkA,
+ int *keyLengthA, int *encVersionA,
+ CryptAlgorithm *encAlgorithmA) {
+ if (!encrypted) {
+ return gFalse;
+ }
+ *permFlagsA = permFlags;
+ *ownerPasswordOkA = ownerPasswordOk;
+ *keyLengthA = keyLength;
+ *encVersionA = encVersion;
+ *encAlgorithmA = encAlgorithm;
+ return gTrue;
+}
+
GBool XRef::okToPrint(GBool ignoreOwnerPW) {
return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permPrint);
}
@@ -976,7 +1021,6 @@ GBool XRef::okToAddNotes(GBool ignoreOwnerPW) {
Object *XRef::fetch(int num, int gen, Object *obj, int recursion) {
XRefEntry *e;
Parser *parser;
- ObjectStream *objStr;
Object obj1, obj2, obj3;
XRefCacheEntry tmp;
int i, j;
@@ -987,8 +1031,15 @@ Object *XRef::fetch(int num, int gen, Object *obj, int recursion) {
}
// check the cache
+#if MULTITHREADED
+ gLockMutex(&cacheMutex);
+#endif
if (cache[0].num == num && cache[0].gen == gen) {
- return cache[0].obj.copy(obj);
+ cache[0].obj.copy(obj);
+#if MULTITHREADED
+ gUnlockMutex(&cacheMutex);
+#endif
+ return obj;
}
for (i = 1; i < xrefCacheSize; ++i) {
if (cache[i].num == num && cache[i].gen == gen) {
@@ -997,9 +1048,16 @@ Object *XRef::fetch(int num, int gen, Object *obj, int recursion) {
cache[j] = cache[j - 1];
}
cache[0] = tmp;
- return cache[0].obj.copy(obj);
+ cache[0].obj.copy(obj);
+#if MULTITHREADED
+ gUnlockMutex(&cacheMutex);
+#endif
+ return obj;
}
}
+#if MULTITHREADED
+ gUnlockMutex(&cacheMutex);
+#endif
e = &entries[num];
switch (e->type) {
@@ -1044,10 +1102,9 @@ Object *XRef::fetch(int num, int gen, Object *obj, int recursion) {
error(errSyntaxError, -1, "Invalid object stream");
goto err;
}
- if (!(objStr = getObjectStream((int)e->offset))) {
+ if (!getObjectStreamObject((int)e->offset, e->gen, num, obj)) {
goto err;
}
- objStr->getObject(e->gen, num, obj);
break;
default:
@@ -1056,6 +1113,9 @@ Object *XRef::fetch(int num, int gen, Object *obj, int recursion) {
// put the new object in the cache, throwing away the oldest object
// currently in the cache
+#if MULTITHREADED
+ gLockMutex(&cacheMutex);
+#endif
if (cache[xrefCacheSize - 1].num >= 0) {
cache[xrefCacheSize - 1].obj.free();
}
@@ -1065,6 +1125,9 @@ Object *XRef::fetch(int num, int gen, Object *obj, int recursion) {
cache[0].num = num;
cache[0].gen = gen;
obj->copy(&cache[0].obj);
+#if MULTITHREADED
+ gUnlockMutex(&cacheMutex);
+#endif
return obj;
@@ -1072,13 +1135,32 @@ Object *XRef::fetch(int num, int gen, Object *obj, int recursion) {
return obj->initNull();
}
+GBool XRef::getObjectStreamObject(int objStrNum, int objIdx,
+ int objNum, Object *obj) {
+ ObjectStream *objStr;
+
+#if MULTITHREADED
+ gLockMutex(&objStrsMutex);
+#endif
+ if (!(objStr = getObjectStream(objStrNum))) {
+ return gFalse;
+ }
+ objStr->getObject(objIdx, objNum, obj);
+#if MULTITHREADED
+ gUnlockMutex(&objStrsMutex);
+#endif
+ return gTrue;
+}
+
+// NB: objStrsMutex must be locked when calling this function.
ObjectStream *XRef::getObjectStream(int objStrNum) {
ObjectStream *objStr;
int i, j;
// check the MRU entry in the cache
if (objStrs[0] && objStrs[0]->getObjStrNum() == objStrNum) {
- return objStrs[0];
+ objStr = objStrs[0];
+ return objStr;
}
// check the rest of the cache
@@ -1099,6 +1181,8 @@ ObjectStream *XRef::getObjectStream(int objStrNum) {
delete objStr;
return NULL;
}
+
+ // add to the cache
if (objStrs[objStrCacheSize - 1]) {
delete objStrs[objStrCacheSize - 1];
}
@@ -1106,6 +1190,7 @@ ObjectStream *XRef::getObjectStream(int objStrNum) {
objStrs[j] = objStrs[j - 1];
}
objStrs[0] = objStr;
+
return objStr;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h b/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h
index 0b74dcb8806..ed44eac6e2b 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/XRef.h
@@ -18,6 +18,9 @@
#include "gtypes.h"
#include "gfile.h"
#include "Object.h"
+#if MULTITHREADED
+#include "GMutex.h"
+#endif
class Dict;
class Stream;
@@ -73,6 +76,9 @@ public:
// Is the file encrypted?
GBool isEncrypted() { return encrypted; }
+ GBool getEncryption(int *permFlagsA, GBool *ownerPasswordOkA,
+ int *keyLengthA, int *encVersionA,
+ CryptAlgorithm *encAlgorithmA);
// Check various permissions.
GBool okToPrint(GBool ignoreOwnerPW = gFalse);
@@ -97,10 +103,17 @@ public:
// Return the offset of the last xref table.
GFileOffset getLastXRefPos() { return lastXRefPos; }
+ // Return the offset of the 'startxref' at the end of the file.
+ GFileOffset getLastStartxrefPos() { return lastStartxrefPos; }
+
// Return the catalog object reference.
int getRootNum() { return rootNum; }
int getRootGen() { return rootGen; }
+ // Get the xref table positions.
+ int getNumXRefTables() { return xrefTablePosLen; }
+ GFileOffset getXRefTablePos(int idx) { return xrefTablePos[idx]; }
+
// Get end position for a stream in a damaged file.
// Returns false if unknown or file is not damaged.
GBool getStreamEnd(GFileOffset streamStart, GFileOffset *streamEnd);
@@ -123,11 +136,17 @@ private:
int errCode; // error code (if <ok> is false)
Object trailerDict; // trailer dictionary
GFileOffset lastXRefPos; // offset of last xref table
+ GFileOffset lastStartxrefPos; // offset of 'startxref' at end of file
+ GFileOffset *xrefTablePos; // positions of all xref tables
+ int xrefTablePosLen; // number of xref table positions
GFileOffset *streamEnds; // 'endstream' positions - only used in
// damaged files
int streamEndsLen; // number of valid entries in streamEnds
ObjectStream * // cached object streams
objStrs[objStrCacheSize];
+#if MULTITHREADED
+ GMutex objStrsMutex;
+#endif
GBool encrypted; // true if file is encrypted
int permFlags; // permission bits
GBool ownerPasswordOk; // true if owner password is correct
@@ -137,6 +156,9 @@ private:
CryptAlgorithm encAlgorithm; // encryption algorithm
XRefCacheEntry // cache of recently accessed objects
cache[xrefCacheSize];
+#if MULTITHREADED
+ GMutex cacheMutex;
+#endif
GFileOffset getStartXref();
GBool readXRef(GFileOffset *pos, XRefPosSet *posSet);
@@ -144,6 +166,8 @@ private:
GBool readXRefStreamSection(Stream *xrefStr, int *w, int first, int n);
GBool readXRefStream(Stream *xrefStr, GFileOffset *pos);
GBool constructXRef();
+ GBool getObjectStreamObject(int objStrNum, int objIdx,
+ int objNum, Object *obj);
ObjectStream *getObjectStream(int objStrNum);
GFileOffset strToFileOffset(char *s);
};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XpdfPluginAPI.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/XpdfPluginAPI.cc
deleted file mode 100644
index d513bec9154..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XpdfPluginAPI.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-//========================================================================
-//
-// XpdfPluginAPI.cc
-//
-// Copyright 2004 Glyph & Cog, LLC
-//
-//========================================================================
-
-#include "aconf.h"
-
-#ifdef ENABLE_PLUGINS
-
-#include "gmem.h"
-#include "GlobalParams.h"
-#include "Object.h"
-#include "PDFDoc.h"
-#ifdef _WIN32
-#include "WinPDFCore.h"
-#else
-#include "XPDFCore.h"
-#endif
-#include "XpdfPluginAPI.h"
-
-//------------------------------------------------------------------------
-
-//~ This should use a pool of Objects; change xpdfFreeObj to match.
-static Object *allocObj() {
- return (Object *)gmalloc(sizeof(Object));
-}
-
-//------------------------------------------------------------------------
-// Document access functions
-//------------------------------------------------------------------------
-
-XpdfObject _xpdfGetInfoDict(XpdfDoc doc) {
- Object *obj;
-
- obj = allocObj();
- return (XpdfObject)((PDFDoc *)doc)->getDocInfo(obj);
-}
-
-XpdfObject _xpdfGetCatalog(XpdfDoc doc) {
- Object *obj;
-
- obj = allocObj();
- return (XpdfObject)((PDFDoc *)doc)->getXRef()->getCatalog(obj);
-}
-
-#ifdef _WIN32
-
-HWND _xpdfWin32GetWindow(XpdfDoc doc) {
- WinPDFCore *core;
-
- if (!(core = (WinPDFCore *)((PDFDoc *)doc)->getCore())) {
- return NULL;
- }
- return core->getDrawFrame();
-}
-
-#else
-
-Widget _xpdfXGetWindow(XpdfDoc doc) {
- XPDFCore *core;
-
- if (!(core = (XPDFCore *)((PDFDoc *)doc)->getCore())) {
- return NULL;
- }
- return core->getWidget();
-}
-
-#endif
-
-//------------------------------------------------------------------------
-// Object access functions.
-//------------------------------------------------------------------------
-
-XpdfBool _xpdfObjIsBool(XpdfObject obj) {
- return (XpdfBool)((Object *)obj)->isBool();
-}
-
-XpdfBool _xpdfObjIsInt(XpdfObject obj) {
- return (XpdfBool)((Object *)obj)->isInt();
-}
-
-XpdfBool _xpdfObjIsReal(XpdfObject obj) {
- return (XpdfBool)((Object *)obj)->isReal();
-}
-
-XpdfBool _xpdfObjIsNumber(XpdfObject obj) {
- return (XpdfBool)((Object *)obj)->isNum();
-}
-
-XpdfBool _xpdfObjIsString(XpdfObject obj) {
- return (XpdfBool)((Object *)obj)->isString();
-}
-
-XpdfBool _xpdfObjIsName(XpdfObject obj) {
- return (XpdfBool)((Object *)obj)->isName();
-}
-
-XpdfBool _xpdfObjIsNull(XpdfObject obj) {
- return (XpdfBool)((Object *)obj)->isNull();
-}
-
-XpdfBool _xpdfObjIsArray(XpdfObject obj) {
- return (XpdfBool)((Object *)obj)->isArray();
-}
-
-XpdfBool _xpdfObjIsDict(XpdfObject obj) {
- return (XpdfBool)((Object *)obj)->isDict();
-}
-
-XpdfBool _xpdfObjIsStream(XpdfObject obj) {
- return (XpdfBool)((Object *)obj)->isStream();
-}
-
-XpdfBool _xpdfObjIsRef(XpdfObject obj) {
- return (XpdfBool)((Object *)obj)->isRef();
-}
-
-XpdfBool _xpdfBoolValue(XpdfObject obj) {
- return (XpdfBool)((Object *)obj)->getBool();
-}
-
-int _xpdfIntValue(XpdfObject obj) {
- if (!((Object *)obj)->isInt()) {
- return 0;
- }
- return ((Object *)obj)->getInt();
-}
-
-double _xpdfRealValue(XpdfObject obj) {
- if (!((Object *)obj)->isReal()) {
- return 0;
- }
- return ((Object *)obj)->getReal();
-}
-
-double _xpdfNumberValue(XpdfObject obj) {
- if (!((Object *)obj)->isNum()) {
- return 0;
- }
- return ((Object *)obj)->getNum();
-}
-
-int _xpdfStringLength(XpdfObject obj) {
- if (!((Object *)obj)->isString()) {
- return 0;
- }
- return ((Object *)obj)->getString()->getLength();
-}
-
-char *_xpdfStringValue(XpdfObject obj) {
- if (!((Object *)obj)->isString()) {
- return 0;
- }
- return ((Object *)obj)->getString()->getCString();
-}
-
-char *_xpdfNameValue(XpdfObject obj) {
- if (!((Object *)obj)->isName()) {
- return NULL;
- }
- return ((Object *)obj)->getName();
-}
-
-int _xpdfArrayLength(XpdfObject obj) {
- if (!((Object *)obj)->isArray()) {
- return 0;
- }
- return ((Object *)obj)->arrayGetLength();
-}
-
-XpdfObject _xpdfArrayGet(XpdfObject obj, int idx) {
- Object *elem;
-
- elem = allocObj();
- if (!((Object *)obj)->isArray()) {
- return (XpdfObject)elem->initNull();
- }
- return (XpdfObject)((Object *)obj)->arrayGet(idx, elem);
-}
-
-XpdfObject _xpdfDictGet(XpdfObject obj, char *key) {
- Object *elem;
-
- elem = allocObj();
- if (!((Object *)obj)->isDict()) {
- return (XpdfObject)elem->initNull();
- }
- return (XpdfObject)((Object *)obj)->dictLookup(key, elem);
-}
-
-void _xpdfFreeObj(XpdfObject obj) {
- ((Object *)obj)->free();
- gfree(obj);
-}
-
-//------------------------------------------------------------------------
-// Memory allocation functions
-//------------------------------------------------------------------------
-
-void *_xpdfMalloc(int size) {
- return gmalloc(size);
-}
-
-void *_xpdfRealloc(void *p, int size) {
- return grealloc(p, size);
-}
-
-void _xpdfFree(void *p) {
- gfree(p);
-}
-
-//------------------------------------------------------------------------
-// Security handlers
-//------------------------------------------------------------------------
-
-void _xpdfRegisterSecurityHandler(XpdfSecurityHandler *handler) {
- if (handler->version <= xpdfPluginAPIVersion) {
- globalParams->addSecurityHandler(handler);
- }
-}
-
-//------------------------------------------------------------------------
-
-XpdfPluginVecTable xpdfPluginVecTable = {
- xpdfPluginAPIVersion,
- &_xpdfGetInfoDict,
- &_xpdfGetCatalog,
-#ifdef _WIN32
- &_xpdfWin32GetWindow,
-#else
- &_xpdfXGetWindow,
-#endif
- &_xpdfObjIsBool,
- &_xpdfObjIsInt,
- &_xpdfObjIsReal,
- &_xpdfObjIsString,
- &_xpdfObjIsName,
- &_xpdfObjIsNull,
- &_xpdfObjIsArray,
- &_xpdfObjIsDict,
- &_xpdfObjIsStream,
- &_xpdfObjIsRef,
- &_xpdfBoolValue,
- &_xpdfIntValue,
- &_xpdfRealValue,
- &_xpdfStringLength,
- &_xpdfStringValue,
- &_xpdfNameValue,
- &_xpdfArrayLength,
- &_xpdfArrayGet,
- &_xpdfDictGet,
- &_xpdfFreeObj,
- &_xpdfMalloc,
- &_xpdfRealloc,
- &_xpdfFree,
- &_xpdfRegisterSecurityHandler,
-};
-
-#endif // ENABLE_PLUGINS
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/XpdfPluginAPI.h b/Build/source/libs/xpdf/xpdf-src/xpdf/XpdfPluginAPI.h
deleted file mode 100644
index 22540f728bd..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/XpdfPluginAPI.h
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * XpdfPluginAPI.h
- *
- * Copyright 2004 Glyph & Cog, LLC
- */
-
-#ifndef XPDFPLUGINAPI_H
-#define XPDFPLUGINAPI_H
-
-#ifdef _WIN32
-#include <windows.h>
-#else
-#define Object XtObject
-#include <X11/Intrinsic.h>
-#undef Object
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*------------------------------------------------------------------------
- * Macros
- *------------------------------------------------------------------------*/
-
-/*
- * The current API version.
- */
-#define xpdfPluginAPIVersion 1
-
-#ifdef _WIN32
-# ifdef __cplusplus
-# define PLUGINFUNC(retType) extern "C" __declspec(dllexport) retType
-# else
-# define PLUGINFUNC(retType) extern __declspec(dllexport) retType
-# endif
-#else
-# ifdef __cplusplus
-# define PLUGINFUNC(retType) extern "C" retType
-# else
-# define PLUGINFUNC(retType) extern retType
-# endif
-#endif
-
-/*------------------------------------------------------------------------
- * Plugin setup/cleanup
- *------------------------------------------------------------------------*/
-
-/*
- * All plugins are required to implement two functions:
- *
- * -- Initialize the plugin. Returns non-zero if successful.
- * PLUGINFUNC(XpdfBool) xpdfInitPlugin(void);
- *
- * -- Free the plugin.
- * PLUGINFUNC(void) xpdfFreePlugin(void);
- */
-
-/*------------------------------------------------------------------------
- * Types
- *------------------------------------------------------------------------*/
-
-/*
- * Standard C boolean -- zero = false, non-zero = true.
- */
-typedef int XpdfBool;
-#define xpdfTrue 1
-#define xpdfFalse 0
-
-/*
- * PDF document handle.
- */
-typedef struct _XpdfDoc *XpdfDoc;
-
-/*
- * PDF object handle.
- */
-typedef struct _XpdfObject *XpdfObject;
-
-/*
- * Document access permissions. Any of these can be bitwise 'or'ed
- * together. If xpdfPermissionOpen is not included, the document
- * cannot be opened at all, and the other bits are ignored.
- */
-typedef unsigned int XpdfPermission;
-#define xpdfPermissionOpen (1 << 0)
-#define xpdfPermissionPrint (1 << 2)
-#define xpdfPermissionChange (1 << 3)
-#define xpdfPermissionCopy (1 << 4)
-#define xpdfPermissionNotes (1 << 5)
-
-/*------------------------------------------------------------------------
- * Security handler
- *------------------------------------------------------------------------*/
-
-/*
- * XpdfSecurityHandler - a security handler plugin should create one
- * of these and pass it to xpdfRegisterSecurityHandler.
- */
-#ifdef __cplusplus
-struct XpdfSecurityHandler {
-#else
-typedef struct {
-#endif
-
- /*
- * Version of the security handler spec (this document) -- use
- * xpdfPluginAPIVersion.
- */
- int version;
-
- /*
- * Security handler name.
- */
- char *name;
-
- /*
- * Any global data the security handler needs. XpdfViewer will pass
- * this pointer to all handler functions as the <handlerData>
- * argument.
- */
- void *handlerData;
-
- /*
- * Allocate and initialize data for a new document. XpdfViewer will
- * pass the returned pointer to all other handler functions as the
- * <docData> argument. Returns non-zero if successful.
- */
- XpdfBool (*newDoc)(void *handlerData, XpdfDoc doc,
- XpdfObject encryptDict, void **docData);
-
- /*
- * Free the data allocated by newDoc.
- */
- void (*freeDoc)(void *handlerData, void *docData);
-
- /*
- * Construct authorization data based on the supplied owner and user
- * passwords (either or both of which may be NULL). This function
- * is called in "batch" mode, i.e., if the password was supplied on
- * the command line or via an Xpdf library API. It should not
- * generate any user interaction (e.g., a password dialog). It is
- * not required to support this function: the makeAuthData function
- * pointer can be set to NULL. Returns non-zero if successful.
- */
- XpdfBool (*makeAuthData)(void *handlerData, void *docData,
- char *ownerPassword, char *userPassword,
- void **authData);
-
- /*
- * Request any needed information (e.g., a password) from the user,
- * and construct an authorization data object. Returns non-zero if
- * successful.
- */
- XpdfBool (*getAuthData)(void *handlerData, void *docData,
- void **authData);
-
- /*
- * Free the data allocated by getAuthData.
- */
- void (*freeAuthData)(void *handlerData, void *docData,
- void *authData);
-
- /*
- * Request permission to access the document. This returns all
- * permissions granted by authData.
- */
- XpdfPermission (*authorize)(void *handlerData, void *docData,
- void *authData);
-
- /*
- * Get the decryption key and algorithm version associated with the
- * document. Returns non-zero if successful.
- */
- XpdfBool (*getKey)(void *handlerData, void *docData,
- char **key, int *keyLen, int *cryptVersion);
-
- /*
- * Free the data allocated by getKey.
- */
- void (*freeKey)(void *handlerData, void *docData,
- char *key, int keyLen);
-
-#ifdef __cplusplus
-};
-#else
-} XpdfSecurityHandler;
-#endif
-
-/*------------------------------------------------------------------------*/
-
-typedef struct {
- int version;
-
-/*------------------------------------------------------------------------
- * Document access functions
- *------------------------------------------------------------------------*/
-
-/*
- * Get a document's info dictionary. (The returned object must be
- * freed with xpdfFreeObj.)
- */
-XpdfObject (*_xpdfGetInfoDict)(XpdfDoc doc);
-
-/*
- * Get a document's catalog ("root") dictionary. (The returned object
- * must be freed with xpdfFreeObj.)
- */
-XpdfObject (*_xpdfGetCatalog)(XpdfDoc doc);
-
-#ifdef _WIN32
-
-/*
- * Get the handle for the viewer window associated with the specified
- * document. [Win32 only]
- */
-HWND (*_xpdfWin32GetWindow)(XpdfDoc doc);
-
-#else
-
-/*
- * Get the Motif widget for the viewer window associated with the
- * specified document. [X only]
- */
-Widget (*_xpdfXGetWindow)(XpdfDoc doc);
-
-#endif
-
-/*------------------------------------------------------------------------
- * Object access functions
- *------------------------------------------------------------------------*/
-
-/*
- * Check an object's type.
- */
-XpdfBool (*_xpdfObjIsBool)(XpdfObject obj);
-XpdfBool (*_xpdfObjIsInt)(XpdfObject obj);
-XpdfBool (*_xpdfObjIsReal)(XpdfObject obj);
-XpdfBool (*_xpdfObjIsString)(XpdfObject obj);
-XpdfBool (*_xpdfObjIsName)(XpdfObject obj);
-XpdfBool (*_xpdfObjIsNull)(XpdfObject obj);
-XpdfBool (*_xpdfObjIsArray)(XpdfObject obj);
-XpdfBool (*_xpdfObjIsDict)(XpdfObject obj);
-XpdfBool (*_xpdfObjIsStream)(XpdfObject obj);
-XpdfBool (*_xpdfObjIsRef)(XpdfObject obj);
-
-/*
- * Value access.
- * (Objects returned by xpdfArrayGet and xpdfDictGet must be freed
- * with xpdfFreeObj.)
- */
-XpdfBool (*_xpdfBoolValue)(XpdfObject obj);
-int (*_xpdfIntValue)(XpdfObject obj);
-double (*_xpdfRealValue)(XpdfObject obj);
-int (*_xpdfStringLength)(XpdfObject obj);
-char *(*_xpdfStringValue)(XpdfObject obj);
-char *(*_xpdfNameValue)(XpdfObject obj);
-int (*_xpdfArrayLength)(XpdfObject obj);
-XpdfObject (*_xpdfArrayGet)(XpdfObject obj, int idx);
-XpdfObject (*_xpdfDictGet)(XpdfObject obj, char *key);
-
-/*
- * Object destruction. NB: *all* objects must be freed after use.
- */
-void (*_xpdfFreeObj)(XpdfObject obj);
-
-/*------------------------------------------------------------------------
- * Memory allocation functions
- *------------------------------------------------------------------------*/
-
-void *(*_xpdfMalloc)(int size);
-void *(*_xpdfRealloc)(void *p, int size);
-void (*_xpdfFree)(void *p);
-
-/*------------------------------------------------------------------------
- * Security handler functions
- *------------------------------------------------------------------------*/
-
-/*
- * Register a new security handler.
- */
-void (*_xpdfRegisterSecurityHandler)(XpdfSecurityHandler *handler);
-
-/*------------------------------------------------------------------------*/
-
-} XpdfPluginVecTable;
-
-#ifdef _WIN32
-
-extern __declspec(dllexport) XpdfPluginVecTable xpdfPluginVecTable;
-
-#define xpdfPluginSetup \
- extern __declspec(dllexport) \
- XpdfPluginVecTable xpdfPluginVecTable = {xpdfPluginAPIVersion};
-
-#else
-
-extern XpdfPluginVecTable xpdfPluginVecTable;
-
-#define xpdfPluginSetup \
- XpdfPluginVecTable xpdfPluginVecTable = {xpdfPluginAPIVersion};
-
-#endif
-
-#define xpdfGetInfoDict (*xpdfPluginVecTable._xpdfGetInfoDict)
-#define xpdfGetCatalog (*xpdfPluginVecTable._xpdfGetCatalog)
-#ifdef _WIN32
-#define xpdfWin32GetWindow (*xpdfPluginVecTable._xpdfWin32GetWindow)
-#else
-#define xpdfXGetWindow (*xpdfPluginVecTable._xpdfXGetWindow)
-#endif
-#define xpdfObjIsBool (*xpdfPluginVecTable._xpdfObjIsBool)
-#define xpdfObjIsInt (*xpdfPluginVecTable._xpdfObjIsInt)
-#define xpdfObjIsReal (*xpdfPluginVecTable._xpdfObjIsReal)
-#define xpdfObjIsString (*xpdfPluginVecTable._xpdfObjIsString)
-#define xpdfObjIsName (*xpdfPluginVecTable._xpdfObjIsName)
-#define xpdfObjIsNull (*xpdfPluginVecTable._xpdfObjIsNull)
-#define xpdfObjIsArray (*xpdfPluginVecTable._xpdfObjIsArray)
-#define xpdfObjIsDict (*xpdfPluginVecTable._xpdfObjIsDict)
-#define xpdfObjIsStream (*xpdfPluginVecTable._xpdfObjIsStream)
-#define xpdfObjIsRef (*xpdfPluginVecTable._xpdfObjIsRef)
-#define xpdfBoolValue (*xpdfPluginVecTable._xpdfBoolValue)
-#define xpdfIntValue (*xpdfPluginVecTable._xpdfIntValue)
-#define xpdfRealValue (*xpdfPluginVecTable._xpdfRealValue)
-#define xpdfStringLength (*xpdfPluginVecTable._xpdfStringLength)
-#define xpdfStringValue (*xpdfPluginVecTable._xpdfStringValue)
-#define xpdfNameValue (*xpdfPluginVecTable._xpdfNameValue)
-#define xpdfArrayLength (*xpdfPluginVecTable._xpdfArrayLength)
-#define xpdfArrayGet (*xpdfPluginVecTable._xpdfArrayGet)
-#define xpdfDictGet (*xpdfPluginVecTable._xpdfDictGet)
-#define xpdfFreeObj (*xpdfPluginVecTable._xpdfFreeObj)
-#define xpdfMalloc (*xpdfPluginVecTable._xpdfMalloc)
-#define xpdfRealloc (*xpdfPluginVecTable._xpdfRealloc)
-#define xpdfFree (*xpdfPluginVecTable._xpdfFree)
-#define xpdfRegisterSecurityHandler (*xpdfPluginVecTable._xpdfRegisterSecurityHandler)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc
index 95242674eb3..ba6e11496ae 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.cc
@@ -14,6 +14,7 @@
#include <stdio.h>
#include <string.h>
#include "gmem.h"
+#include "gmempp.h"
#include "GString.h"
#include "GList.h"
#include "GHash.h"
@@ -80,6 +81,54 @@ ZxNode::~ZxNode() {
}
}
+ZxNode *ZxNode::deleteChild(ZxNode *child) {
+ ZxNode *p1, *p2;
+
+ for (p1 = NULL, p2 = firstChild;
+ p2 && p2 != child;
+ p1 = p2, p2 = p2->next) ;
+ if (!p2) {
+ return NULL;
+ }
+ if (p1) {
+ p1->next = child->next;
+ } else {
+ firstChild = child->next;
+ }
+ child->parent = NULL;
+ child->next = NULL;
+ return child;
+}
+
+void ZxNode::appendChild(ZxNode *child) {
+ ZxNode *p1;
+
+ if (child->parent || child->next) {
+ return;
+ }
+ if (firstChild) {
+ for (p1 = firstChild; p1->next; p1 = p1->next) ;
+ p1->next = child;
+ } else {
+ firstChild = child;
+ }
+ child->parent = this;
+}
+
+void ZxNode::insertChildAfter(ZxNode *child, ZxNode *prev) {
+ if (child->parent || child->next || (prev && prev->parent != this)) {
+ return;
+ }
+ if (prev) {
+ child->next = prev->next;
+ prev->next = child;
+ } else {
+ child->next = firstChild;
+ firstChild = child;
+ }
+ child->parent = this;
+}
+
ZxElement *ZxNode::findFirstElement(const char *type) {
ZxNode *child;
ZxElement *result;
@@ -199,6 +248,21 @@ ZxDoc *ZxDoc::loadFile(const char *fileName) {
ZxDoc::~ZxDoc() {
}
+static bool writeToFileFunc(void *stream, const char *data, int length) {
+ return (int)fwrite(data, 1, length, (FILE *)stream) == length;
+}
+
+bool ZxDoc::writeFile(const char *fileName) {
+ FILE *f;
+
+ if (!(f = fopen(fileName, "wb"))) {
+ return false;
+ }
+ write(&writeToFileFunc, f);
+ fclose(f);
+ return true;
+}
+
void ZxDoc::addChild(ZxNode *node) {
if (node->isXMLDecl() && !xmlDecl) {
xmlDecl = (ZxXMLDecl *)node;
@@ -733,6 +797,20 @@ bool ZxDoc::match(const char *s) {
return parseEnd - parsePtr >= n && !strncmp(parsePtr, s, n);
}
+bool ZxDoc::write(ZxWriteFunc writeFunc, void *stream) {
+ ZxNode *child;
+
+ for (child = getFirstChild(); child; child = child->getNextChild()) {
+ if (!child->write(writeFunc, stream)) {
+ return false;
+ }
+ if (!(*writeFunc)(stream, "\n", 1)) {
+ return false;
+ }
+ }
+ return true;
+}
+
//------------------------------------------------------------------------
ZxXMLDecl::ZxXMLDecl(GString *versionA, GString *encodingA, bool standaloneA) {
@@ -748,6 +826,27 @@ ZxXMLDecl::~ZxXMLDecl() {
}
}
+bool ZxXMLDecl::write(ZxWriteFunc writeFunc, void *stream) {
+ GString *s;
+ bool ok;
+
+ s = new GString("<?xml version=\"");
+ s->append(version);
+ s->append("\"");
+ if (encoding) {
+ s->append(" encoding=\"");
+ s->append(encoding);
+ s->append("\"");
+ }
+ if (standalone) {
+ s->append(" standlone=\"yes\"");
+ }
+ s->append("?>");
+ ok = (*writeFunc)(stream, s->getCString(), s->getLength());
+ delete s;
+ return ok;
+}
+
//------------------------------------------------------------------------
ZxDocTypeDecl::ZxDocTypeDecl(GString *nameA) {
@@ -758,6 +857,18 @@ ZxDocTypeDecl::~ZxDocTypeDecl() {
delete name;
}
+bool ZxDocTypeDecl::write(ZxWriteFunc writeFunc, void *stream) {
+ GString *s;
+ bool ok;
+
+ s = new GString("<!DOCTYPE ");
+ s->append(name);
+ s->append(">");
+ ok = (*writeFunc)(stream, s->getCString(), s->getLength());
+ delete s;
+ return ok;
+}
+
//------------------------------------------------------------------------
ZxComment::ZxComment(GString *textA) {
@@ -768,6 +879,18 @@ ZxComment::~ZxComment() {
delete text;
}
+bool ZxComment::write(ZxWriteFunc writeFunc, void *stream) {
+ GString *s;
+ bool ok;
+
+ s = new GString("<!--");
+ s->append(text);
+ s->append("-->");
+ ok = (*writeFunc)(stream, s->getCString(), s->getLength());
+ delete s;
+ return ok;
+}
+
//------------------------------------------------------------------------
ZxPI::ZxPI(GString *targetA, GString *textA) {
@@ -780,6 +903,20 @@ ZxPI::~ZxPI() {
delete text;
}
+bool ZxPI::write(ZxWriteFunc writeFunc, void *stream) {
+ GString *s;
+ bool ok;
+
+ s = new GString("<?");
+ s->append(target);
+ s->append(" ");
+ s->append(text);
+ s->append("?>");
+ ok = (*writeFunc)(stream, s->getCString(), s->getLength());
+ delete s;
+ return ok;
+}
+
//------------------------------------------------------------------------
ZxElement::ZxElement(GString *typeA) {
@@ -813,6 +950,70 @@ void ZxElement::addAttr(ZxAttr *attr) {
attr->next = NULL;
}
+bool ZxElement::write(ZxWriteFunc writeFunc, void *stream) {
+ GString *s;
+ ZxAttr *attr;
+ ZxNode *child;
+ bool ok;
+
+ s = new GString("<");
+ s->append(type);
+ for (attr = firstAttr; attr; attr = attr->getNextAttr()) {
+ s->append(" ");
+ s->append(attr->name);
+ s->append("=\"");
+ appendEscapedAttrValue(s, attr->value);
+ s->append("\"");
+ }
+ if ((child = getFirstChild())) {
+ s->append(">");
+ } else {
+ s->append("/>");
+ }
+ ok = (*writeFunc)(stream, s->getCString(), s->getLength());
+ delete s;
+ if (!ok) {
+ return false;
+ }
+ if (child) {
+ for (; child; child = child->getNextChild()) {
+ if (!child->write(writeFunc, stream)) {
+ return false;
+ }
+ }
+ s = new GString();
+ s->append("</");
+ s->append(type);
+ s->append(">");
+ ok = (*writeFunc)(stream, s->getCString(), s->getLength());
+ delete s;
+ if (!ok) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void ZxElement::appendEscapedAttrValue(GString *out, GString *s) {
+ char c;
+ int i;
+
+ for (i = 0; i < s->getLength(); ++i) {
+ c = s->getChar(i);
+ if (c == '<') {
+ out->append("&lt;");
+ } else if (c == '>') {
+ out->append("&gt;");
+ } else if (c == '&') {
+ out->append("&amp;");
+ } else if (c == '"') {
+ out->append("&quot;");
+ } else {
+ out->append(c);
+ }
+ }
+}
+
//------------------------------------------------------------------------
ZxAttr::ZxAttr(GString *nameA, GString *valueA) {
@@ -837,3 +1038,33 @@ ZxCharData::ZxCharData(GString *dataA, bool parsedA) {
ZxCharData::~ZxCharData() {
delete data;
}
+
+bool ZxCharData::write(ZxWriteFunc writeFunc, void *stream) {
+ GString *s;
+ char c;
+ int i;
+ bool ok;
+
+ s = new GString();
+ if (parsed) {
+ for (i = 0; i < data->getLength(); ++i) {
+ c = data->getChar(i);
+ if (c == '<') {
+ s->append("&lt;");
+ } else if (c == '>') {
+ s->append("&gt;");
+ } else if (c == '&') {
+ s->append("&amp;");
+ } else {
+ s->append(c);
+ }
+ }
+ } else {
+ s->append("<![CDATA[");
+ s->append(data);
+ s->append("]]>");
+ }
+ ok = (*writeFunc)(stream, s->getCString(), s->getLength());
+ delete s;
+ return ok;
+}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h b/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h
index 091f72e10a9..49f9f6b1da8 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Zoox.h
@@ -26,6 +26,10 @@ class ZxXMLDecl;
//------------------------------------------------------------------------
+typedef bool (*ZxWriteFunc)(void *stream, const char *data, int length);
+
+//------------------------------------------------------------------------
+
class ZxNode {
public:
@@ -42,12 +46,18 @@ public:
virtual bool isCharData() { return false; }
virtual ZxNode *getFirstChild() { return firstChild; }
virtual ZxNode *getNextChild() { return next; }
+ ZxNode *getParent() { return parent; }
+ ZxNode *deleteChild(ZxNode *child);
+ void appendChild(ZxNode *child);
+ void insertChildAfter(ZxNode *child, ZxNode *prev);
ZxElement *findFirstElement(const char *type);
ZxElement *findFirstChildElement(const char *type);
GList *findAllElements(const char *type);
GList *findAllChildElements(const char *type);
virtual void addChild(ZxNode *child);
+ virtual bool write(ZxWriteFunc writeFunc, void *stream) = 0;
+
protected:
void findAllElements(const char *type, GList *results);
@@ -73,12 +83,17 @@ public:
virtual ~ZxDoc();
+ // Write to disk. Returns false on error.
+ bool writeFile(const char *fileName);
+
virtual bool isDoc() { return true; }
ZxXMLDecl *getXMLDecl() { return xmlDecl; }
ZxDocTypeDecl *getDocTypeDecl() { return docTypeDecl; }
ZxElement *getRoot() { return root; }
virtual void addChild(ZxNode *node);
+ virtual bool write(ZxWriteFunc writeFunc, void *stream);
+
private:
bool parse(const char *data, Guint dataLen);
@@ -119,6 +134,8 @@ public:
GString *getEncoding() { return encoding; }
bool getStandalone() { return standalone; }
+ virtual bool write(ZxWriteFunc writeFunc, void *stream);
+
private:
GString *version;
@@ -137,6 +154,8 @@ public:
virtual bool isDocTypeDecl() { return true; }
GString *getName() { return name; }
+ virtual bool write(ZxWriteFunc writeFunc, void *stream);
+
private:
GString *name;
@@ -153,6 +172,8 @@ public:
virtual bool isComment() { return true; }
GString *getText() { return text; }
+ virtual bool write(ZxWriteFunc writeFunc, void *stream);
+
private:
GString *text;
@@ -170,6 +191,8 @@ public:
GString *getTarget() { return target; }
GString *getText() { return text; }
+ virtual bool write(ZxWriteFunc writeFunc, void *stream);
+
private:
GString *target;
@@ -191,8 +214,12 @@ public:
ZxAttr *getFirstAttr() { return firstAttr; }
void addAttr(ZxAttr *attr);
+ virtual bool write(ZxWriteFunc writeFunc, void *stream);
+
private:
+ void appendEscapedAttrValue(GString *out, GString *s);
+
GString *type;
GHash *attrs; // [ZxAttr]
ZxAttr *firstAttr, *lastAttr;
@@ -209,6 +236,7 @@ public:
GString *getName() { return name; }
GString *getValue() { return value; }
ZxAttr *getNextAttr() { return next; }
+ ZxNode *getParent() { return parent; }
private:
@@ -232,6 +260,8 @@ public:
GString *getData() { return data; }
bool isParsed() { return parsed; }
+ virtual bool write(ZxWriteFunc writeFunc, void *stream);
+
private:
GString *data; // in UTF-8 format
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/about-text.h b/Build/source/libs/xpdf/xpdf-src/xpdf/about-text.h
deleted file mode 100644
index 2ea7588a368..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/about-text.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//========================================================================
-//
-// about-text.h
-//
-// Copyright 2002-2007 Glyph & Cog, LLC
-//
-//========================================================================
-
-static const char *aboutWinText[] = {
- "http://www.foolabs.com/xpdf/",
- "derekn@foolabs.com",
- " ",
- "Licensed under the GNU General Public License (GPL) v2 or v3.",
- "See the 'README' file for details.",
- " ",
- "Supports PDF version " supportedPDFVersionStr ".",
- " ",
- "The PDF data structures, operators, and specification",
- "are copyright 1985-2006 Adobe Systems Inc.",
- " ",
- "For more information (including key and mouse bindings)",
- "please read the xpdf(1) man page.",
- NULL
-};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/about.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/about.xbm
deleted file mode 100644
index 86f84720c9b..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/about.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define about_width 10
-#define about_height 15
-static unsigned char about_bits[] = {
- 0x78, 0x00, 0xfc, 0x00, 0xce, 0x01, 0x86, 0x01, 0x80, 0x01, 0x80, 0x01,
- 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00,
- 0x00, 0x00, 0x30, 0x00, 0x30, 0x00};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/backArrow.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/backArrow.xbm
deleted file mode 100644
index 47f49e19073..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/backArrow.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define backArrow_width 16
-#define backArrow_height 15
-static unsigned char backArrow_bits[] = {
- 0x80, 0x00, 0xc0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0xfc, 0xcc,
- 0xfe, 0xcc, 0xff, 0xcc, 0xfe, 0xcc, 0xfc, 0xcc, 0xf8, 0xcc, 0xf0, 0x00,
- 0xe0, 0x00, 0xc0, 0x00, 0x80, 0x00};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/backArrowDis.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/backArrowDis.xbm
deleted file mode 100644
index 752963963a7..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/backArrowDis.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define backArrowDis_width 16
-#define backArrowDis_height 15
-static unsigned char backArrowDis_bits[] = {
- 0x80, 0x00, 0x40, 0x00, 0xa0, 0x00, 0x50, 0x00, 0xa8, 0x00, 0x54, 0x44,
- 0xaa, 0x88, 0x55, 0x44, 0xaa, 0x88, 0x54, 0x44, 0xa8, 0x88, 0x50, 0x00,
- 0xa0, 0x00, 0x40, 0x00, 0x80, 0x00};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/config.h b/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
index 6bf406860bf..2ce6362d289 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/config.h
@@ -2,7 +2,7 @@
//
// config.h
//
-// Copyright 1996-2014 Glyph & Cog, LLC
+// Copyright 1996-2017 Glyph & Cog, LLC
//
//========================================================================
@@ -14,13 +14,13 @@
//------------------------------------------------------------------------
// xpdf version
-#define xpdfVersion "3.04"
-#define xpdfVersionNum 3.04
-#define xpdfMajorVersion 3
-#define xpdfMinorVersion 4
+#define xpdfVersion "4.00"
+#define xpdfVersionNum 4.00
+#define xpdfMajorVersion 4
+#define xpdfMinorVersion 0
#define xpdfUpdateVersion 0
-#define xpdfMajorVersionStr "3"
-#define xpdfMinorVersionStr "4"
+#define xpdfMajorVersionStr "4"
+#define xpdfMinorVersionStr "0"
#define xpdfUpdateVersionStr "0"
// supported PDF version
@@ -28,11 +28,11 @@
#define supportedPDFVersionNum 1.7
// copyright notice
-#define xpdfCopyright "Copyright 1996-2014 Glyph & Cog, LLC"
+#define xpdfCopyright "Copyright 1996-2017 Glyph & Cog, LLC"
// Windows resource file stuff
-#define winxpdfVersion "WinXpdf 3.04"
-#define xpdfCopyrightAmp "Copyright 1996-2014 Glyph && Cog, LLC"
+#define winxpdfVersion "WinXpdf 4.00"
+#define xpdfCopyrightAmp "Copyright 1996-2017 Glyph && Cog, LLC"
//------------------------------------------------------------------------
// paper size
@@ -78,7 +78,7 @@
// popen
//------------------------------------------------------------------------
-#if defined(VMS) || defined(VMCMS) || defined(DOS) || defined(OS2) || defined(__EMX__) || defined(_WIN32) || defined(__DJGPP__) || defined(MACOS)
+#if defined(VMS) || defined(VMCMS) || defined(DOS) || defined(OS2) || defined(__EMX__) || defined(_WIN32) || defined(__DJGPP__)
#define POPEN_READ_MODE "rb"
#else
#define POPEN_READ_MODE "r"
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/dblLeftArrow.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/dblLeftArrow.xbm
deleted file mode 100644
index 616d2bd37fc..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/dblLeftArrow.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define dblLeftArrow_width 16
-#define dblLeftArrow_height 15
-static unsigned char dblLeftArrow_bits[] = {
- 0x80, 0x80, 0xc0, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf8, 0xf8, 0xfc, 0xfc,
- 0xfe, 0xfe, 0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0,
- 0xe0, 0xe0, 0xc0, 0xc0, 0x80, 0x80};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/dblLeftArrowDis.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/dblLeftArrowDis.xbm
deleted file mode 100644
index 3fb78d80c8d..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/dblLeftArrowDis.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define dblLeftArrowDis_width 16
-#define dblLeftArrowDis_height 15
-static unsigned char dblLeftArrowDis_bits[] = {
- 0x80, 0x80, 0x40, 0x40, 0xa0, 0xa0, 0x50, 0x50, 0xa8, 0xa8, 0x54, 0x54,
- 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x54, 0x54, 0xa8, 0xa8, 0x50, 0x50,
- 0xa0, 0xa0, 0x40, 0x40, 0x80, 0x80};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/dblRightArrow.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/dblRightArrow.xbm
deleted file mode 100644
index 0072810ebca..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/dblRightArrow.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define dblRightArrow_width 16
-#define dblRightArrow_height 15
-static unsigned char dblRightArrow_bits[] = {
- 0x01, 0x01, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x0f, 0x1f, 0x1f, 0x3f, 0x3f,
- 0x7f, 0x7f, 0xff, 0xff, 0x7f, 0x7f, 0x3f, 0x3f, 0x1f, 0x1f, 0x0f, 0x0f,
- 0x07, 0x07, 0x03, 0x03, 0x01, 0x01};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/dblRightArrowDis.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/dblRightArrowDis.xbm
deleted file mode 100644
index a6c1e3708cd..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/dblRightArrowDis.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define dblRightArrowDis_width 16
-#define dblRightArrowDis_height 15
-static unsigned char dblRightArrowDis_bits[] = {
- 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x0a, 0x0a, 0x15, 0x15, 0x2a, 0x2a,
- 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0x2a, 0x2a, 0x15, 0x15, 0x0a, 0x0a,
- 0x05, 0x05, 0x02, 0x02, 0x01, 0x01};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/find.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/find.xbm
deleted file mode 100644
index 206da875fbd..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/find.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define find_width 15
-#define find_height 15
-static unsigned char find_bits[] = {
- 0x38, 0x0e, 0x28, 0x0a, 0x2e, 0x3a, 0xfe, 0x3f, 0x7f, 0x7f, 0x61, 0x43,
- 0x61, 0x43, 0x61, 0x43, 0x61, 0x43, 0xe1, 0x43, 0x21, 0x42, 0x21, 0x42,
- 0x21, 0x42, 0x21, 0x42, 0x3f, 0x7e};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/findDis.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/findDis.xbm
deleted file mode 100644
index cf666f2493c..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/findDis.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define findDis_width 15
-#define findDis_height 15
-static unsigned char findDis_bits[] = {
- 0x10, 0x04, 0x28, 0x0a, 0x04, 0x10, 0xaa, 0x2a, 0x55, 0x55, 0x20, 0x02,
- 0x41, 0x41, 0x20, 0x02, 0x41, 0x41, 0xa0, 0x02, 0x01, 0x40, 0x20, 0x02,
- 0x01, 0x40, 0x20, 0x02, 0x15, 0x54};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/forwardArrow.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/forwardArrow.xbm
deleted file mode 100644
index e3875352b8e..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/forwardArrow.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define forwardArrow_width 16
-#define forwardArrow_height 15
-static unsigned char forwardArrow_bits[] = {
- 0x00, 0x01, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x33, 0x3f,
- 0x33, 0x7f, 0x33, 0xff, 0x33, 0x7f, 0x33, 0x3f, 0x00, 0x1f, 0x00, 0x0f,
- 0x00, 0x07, 0x00, 0x03, 0x00, 0x01};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/forwardArrowDis.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/forwardArrowDis.xbm
deleted file mode 100644
index 58d0cc0f00b..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/forwardArrowDis.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define forwardArrowDis_width 16
-#define forwardArrowDis_height 15
-static unsigned char forwardArrowDis_bits[] = {
- 0x00, 0x01, 0x00, 0x02, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x15, 0x22, 0x2a,
- 0x11, 0x55, 0x22, 0xaa, 0x11, 0x55, 0x22, 0x2a, 0x00, 0x15, 0x00, 0x0a,
- 0x00, 0x05, 0x00, 0x02, 0x00, 0x01};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/leftArrow.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/leftArrow.xbm
deleted file mode 100644
index 367e4e604ce..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/leftArrow.xbm
+++ /dev/null
@@ -1,5 +0,0 @@
-#define leftArrow_width 8
-#define leftArrow_height 15
-static unsigned char leftArrow_bits[] = {
- 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xfe, 0xfc, 0xf8, 0xf0,
- 0xe0, 0xc0, 0x80};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/leftArrowDis.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/leftArrowDis.xbm
deleted file mode 100644
index 953092a6e24..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/leftArrowDis.xbm
+++ /dev/null
@@ -1,5 +0,0 @@
-#define leftArrowDis_width 8
-#define leftArrowDis_height 15
-static unsigned char leftArrowDis_bits[] = {
- 0x80, 0x40, 0xa0, 0x50, 0xa8, 0x54, 0xaa, 0x55, 0xaa, 0x54, 0xa8, 0x50,
- 0xa0, 0x40, 0x80};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc
index 35339526cbb..b44bedbb1a7 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfdetach.cc
@@ -10,6 +10,7 @@
#include <stdio.h>
#include "gtypes.h"
#include "gmem.h"
+#include "gmempp.h"
#include "parseargs.h"
#include "GlobalParams.h"
#include "PDFDoc.h"
@@ -74,9 +75,6 @@ int main(int argc, char *argv[]) {
exitCode = 99;
-#ifdef _MSC_VER
- (void)kpse_set_program_name(argv[0], NULL);
-#endif
// parse args
ok = parseArgs(argDesc, &argc, argv);
if ((doList ? 1 : 0) +
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
index b97940546ca..71a0ee8d4d3 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc
@@ -13,9 +13,10 @@
#include <string.h>
#include <math.h>
#include <limits.h>
+#include "gmem.h"
+#include "gmempp.h"
#include "parseargs.h"
#include "GString.h"
-#include "gmem.h"
#include "GlobalParams.h"
#include "Error.h"
#include "Object.h"
@@ -107,9 +108,6 @@ int main(int argc, char *argv[]) {
exitCode = 99;
-#ifdef _MSC_VER
- (void)kpse_set_program_name(argv[0], NULL);
-#endif
// parse args
ok = parseArgs(argDesc, &argc, argv);
if (!ok || argc != 2 || printVersion || printHelp) {
@@ -159,11 +157,11 @@ int main(int argc, char *argv[]) {
// scan the fonts
if (showFontLoc || showFontLocPS) {
- printf("name type emb sub uni 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 object ID\n");
- printf("------------------------------------ ----------------- --- --- --- ---------\n");
+ printf("name type emb sub uni prob object ID\n");
+ printf("------------------------------------ ----------------- --- --- --- ---- ---------\n");
}
fonts = NULL;
fontsLen = fontsSize = 0;
@@ -380,12 +378,13 @@ static void scanFont(GfxFont *font, PDFDoc *doc) {
}
// print the font info
- printf("%-36s %-17s %-3s %-3s %-3s",
+ printf("%-36s %-17s %-3s %-3s %-3s %-4s",
name ? name->getCString() : "[none]",
fontTypeNames[font->getType()],
emb ? "yes" : "no",
subset ? "yes" : "no",
- hasToUnicode ? "yes" : "no");
+ hasToUnicode ? "yes" : "no",
+ font->problematicForUnicode() ? " X" : "");
if (fontRef.gen >= 100000) {
printf(" [none]");
} else {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc
index 65a68db0aa6..d5ae9e426b9 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfimages.cc
@@ -11,9 +11,10 @@
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
+#include "gmem.h"
+#include "gmempp.h"
#include "parseargs.h"
#include "GString.h"
-#include "gmem.h"
#include "GlobalParams.h"
#include "Object.h"
#include "Stream.h"
@@ -30,6 +31,8 @@
static int firstPage = 1;
static int lastPage = 0;
static GBool dumpJPEG = gFalse;
+static GBool dumpRaw = gFalse;
+static GBool list = gFalse;
static char ownerPassword[33] = "\001";
static char userPassword[33] = "\001";
static GBool quiet = gFalse;
@@ -44,6 +47,10 @@ static ArgDesc argDesc[] = {
"last page to convert"},
{"-j", argFlag, &dumpJPEG, 0,
"write JPEG images as JPEG files"},
+ {"-raw", argFlag, &dumpRaw, 0,
+ "write raw data in PDF-native formats"},
+ {"-list", argFlag, &list, 0,
+ "write information to stdout for each image"},
{"-opw", argString, ownerPassword, sizeof(ownerPassword),
"owner password (for encrypted files)"},
{"-upw", argString, userPassword, sizeof(userPassword),
@@ -76,9 +83,6 @@ int main(int argc, char *argv[]) {
exitCode = 99;
-#ifdef _MSC_VER
- (void)kpse_set_program_name(argv[0], NULL);
-#endif
// parse args
ok = parseArgs(argDesc, &argc, argv);
if (!ok || argc != 3 || printVersion || printHelp) {
@@ -136,7 +140,7 @@ int main(int argc, char *argv[]) {
lastPage = doc->getNumPages();
// write image files
- imgOut = new ImageOutputDev(imgRoot, dumpJPEG);
+ imgOut = new ImageOutputDev(imgRoot, dumpJPEG, dumpRaw, list);
if (imgOut->isOk()) {
doc->displayPages(imgOut, firstPage, lastPage, 72, 72, 0,
gFalse, gTrue, gFalse);
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc
index 933b00f2e43..ef36bcecfc3 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdfinfo.cc
@@ -13,9 +13,10 @@
#include <string.h>
#include <time.h>
#include <math.h>
+#include "gmem.h"
+#include "gmempp.h"
#include "parseargs.h"
#include "GString.h"
-#include "gmem.h"
#include "gfile.h"
#include "GlobalParams.h"
#include "Object.h"
@@ -100,9 +101,6 @@ int main(int argc, char *argv[]) {
exitCode = 99;
-#ifdef _MSC_VER
- (void)kpse_set_program_name(argv[0], NULL);
-#endif
// parse args
ok = parseArgs(argDesc, &argc, argv);
if (!ok || argc != 2 || printVersion || printHelp) {
@@ -194,7 +192,11 @@ int main(int argc, char *argv[]) {
if ((acroForm = doc->getCatalog()->getAcroForm())->isDict()) {
acroForm->dictLookup("XFA", &xfa);
if (xfa.isStream() || xfa.isArray()) {
- printf("Form: XFA\n");
+ if (doc->getCatalog()->getNeedsRendering()) {
+ printf("Form: dynamic XFA\n");
+ } else {
+ printf("Form: static XFA\n");
+ }
} else {
printf("Form: AcroForm\n");
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
index ac5dbcff707..1f081384e1c 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftohtml.cc
@@ -9,8 +9,9 @@
#include <aconf.h>
#include <stdio.h>
#include <stdlib.h>
-#include "parseargs.h"
#include "gmem.h"
+#include "gmempp.h"
+#include "parseargs.h"
#include "gfile.h"
#include "GString.h"
#include "GlobalParams.h"
@@ -28,8 +29,10 @@ static GBool createIndex(char *htmlDir);
static int firstPage = 1;
static int lastPage = 0;
+static double zoom = 1;
static int resolution = 150;
static GBool skipInvisible = gFalse;
+static GBool allInvisible = gFalse;
static char ownerPassword[33] = "\001";
static char userPassword[33] = "\001";
static GBool quiet = gFalse;
@@ -42,10 +45,14 @@ static ArgDesc argDesc[] = {
"first page to convert"},
{"-l", argInt, &lastPage, 0,
"last page to convert"},
+ {"-z", argFP, &zoom, 0,
+ "initial zoom level (1.0 means 72dpi)"},
{"-r", argInt, &resolution, 0,
"resolution, in DPI (default is 150)"},
{"-skipinvisible", argFlag, &skipInvisible, 0,
"do not draw invisible text"},
+ {"-allinvisible", argFlag, &allInvisible, 0,
+ "treat all text as invisible"},
{"-opw", argString, ownerPassword, sizeof(ownerPassword),
"owner password (for encrypted files)"},
{"-upw", argString, userPassword, sizeof(userPassword),
@@ -86,9 +93,6 @@ int main(int argc, char *argv[]) {
exitCode = 99;
-#ifdef _MSC_VER
- (void)kpse_set_program_name(argv[0], NULL);
-#endif
// parse args
ok = parseArgs(argDesc, &argc, argv);
if (!ok || argc != 3 || printVersion || printHelp) {
@@ -163,7 +167,9 @@ int main(int argc, char *argv[]) {
exitCode = 99;
goto err1;
}
+ htmlGen->setZoom(zoom);
htmlGen->setDrawInvisibleText(!skipInvisible);
+ htmlGen->setAllTextInvisible(allInvisible);
htmlGen->startDoc(doc);
// convert the pages
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
index 9cc57cb40ff..223ab665cba 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftopng.cc
@@ -10,8 +10,13 @@
#include <stdlib.h>
#include <stdio.h>
#include <png.h>
-#include "parseargs.h"
+#ifdef _WIN32
+# include <io.h>
+# include <fcntl.h>
+#endif
#include "gmem.h"
+#include "gmempp.h"
+#include "parseargs.h"
#include "GString.h"
#include "GlobalParams.h"
#include "Object.h"
@@ -23,9 +28,10 @@
static int firstPage = 1;
static int lastPage = 0;
-static int resolution = 150;
+static double resolution = 150;
static GBool mono = gFalse;
static GBool gray = gFalse;
+static GBool pngAlpha = gFalse;
static char enableFreeTypeStr[16] = "";
static char antialiasStr[16] = "";
static char vectorAntialiasStr[16] = "";
@@ -41,13 +47,15 @@ static ArgDesc argDesc[] = {
"first page to print"},
{"-l", argInt, &lastPage, 0,
"last page to print"},
- {"-r", argInt, &resolution, 0,
+ {"-r", argFP, &resolution, 0,
"resolution, in DPI (default is 150)"},
{"-mono", argFlag, &mono, 0,
- "generate a monochrome PBM file"},
+ "generate a monochrome PNG file"},
{"-gray", argFlag, &gray, 0,
- "generate a grayscale PGM file"},
-#if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H
+ "generate a grayscale PNG file"},
+ {"-alpha", argFlag, &pngAlpha, 0,
+ "include an alpha channel in the PNG file"},
+#if HAVE_FREETYPE_H
{"-freetype", argString, enableFreeTypeStr, sizeof(enableFreeTypeStr),
"enable FreeType font rasterizer: yes, no"},
#endif
@@ -77,7 +85,7 @@ static ArgDesc argDesc[] = {
};
static void setupPNG(png_structp *png, png_infop *pngInfo, FILE *f,
- int bitDepth, int colorType,
+ int bitDepth, int colorType, double res,
SplashBitmap *bitmap);
static void writePNGData(png_structp png, SplashBitmap *bitmap);
static void finishPNG(png_structp *png, png_infop *pngInfo);
@@ -99,13 +107,15 @@ int main(int argc, char *argv[]) {
exitCode = 99;
-#ifdef _MSC_VER
- (void)kpse_set_program_name(argv[0], NULL);
-#endif
// parse args
ok = parseArgs(argDesc, &argc, argv);
if (mono && gray) {
- ok = gFalse;
+ fprintf(stderr, "Specify one of -mono or -gray\n");
+ goto err0;
+ }
+ if (mono && pngAlpha) {
+ fprintf(stderr, "The -alpha flag cannot be used with -mono\n");
+ goto err0;
}
if (!ok || argc != 3 || printVersion || printHelp) {
fprintf(stderr, "pdftopng version %s\n", xpdfVersion);
@@ -181,6 +191,9 @@ int main(int argc, char *argv[]) {
paperColor[0] = paperColor[1] = paperColor[2] = 0xff;
splashOut = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor);
}
+ if (pngAlpha) {
+ splashOut->setNoComposite(gTrue);
+ }
splashOut->startDoc(doc->getXRef());
for (pg = firstPage; pg <= lastPage; ++pg) {
doc->displayPage(splashOut, pg, resolution, resolution, 0,
@@ -188,6 +201,9 @@ int main(int argc, char *argv[]) {
if (mono) {
if (!strcmp(pngRoot, "-")) {
f = stdout;
+#ifdef _WIN32
+ _setmode(_fileno(f), _O_BINARY);
+#endif
} else {
pngFile = GString::format("{0:s}-{1:06d}.png", pngRoot, pg);
if (!(f = fopen(pngFile->getCString(), "wb"))) {
@@ -196,13 +212,16 @@ int main(int argc, char *argv[]) {
delete pngFile;
}
setupPNG(&png, &pngInfo, f,
- 1, PNG_COLOR_TYPE_GRAY, splashOut->getBitmap());
+ 1, PNG_COLOR_TYPE_GRAY, resolution, splashOut->getBitmap());
writePNGData(png, splashOut->getBitmap());
finishPNG(&png, &pngInfo);
fclose(f);
} else if (gray) {
if (!strcmp(pngRoot, "-")) {
f = stdout;
+#ifdef _WIN32
+ _setmode(_fileno(f), _O_BINARY);
+#endif
} else {
pngFile = GString::format("{0:s}-{1:06d}.png", pngRoot, pg);
if (!(f = fopen(pngFile->getCString(), "wb"))) {
@@ -211,13 +230,17 @@ int main(int argc, char *argv[]) {
delete pngFile;
}
setupPNG(&png, &pngInfo, f,
- 8, PNG_COLOR_TYPE_GRAY, splashOut->getBitmap());
+ 8, pngAlpha ? PNG_COLOR_TYPE_GRAY_ALPHA : PNG_COLOR_TYPE_GRAY,
+ resolution, splashOut->getBitmap());
writePNGData(png, splashOut->getBitmap());
finishPNG(&png, &pngInfo);
fclose(f);
} else { // RGB
if (!strcmp(pngRoot, "-")) {
f = stdout;
+#ifdef _WIN32
+ _setmode(_fileno(f), _O_BINARY);
+#endif
} else {
pngFile = GString::format("{0:s}-{1:06d}.png", pngRoot, pg);
if (!(f = fopen(pngFile->getCString(), "wb"))) {
@@ -226,7 +249,8 @@ int main(int argc, char *argv[]) {
delete pngFile;
}
setupPNG(&png, &pngInfo, f,
- 8, PNG_COLOR_TYPE_RGB, splashOut->getBitmap());
+ 8, pngAlpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
+ resolution, splashOut->getBitmap());
writePNGData(png, splashOut->getBitmap());
finishPNG(&png, &pngInfo);
fclose(f);
@@ -250,8 +274,11 @@ int main(int argc, char *argv[]) {
}
static void setupPNG(png_structp *png, png_infop *pngInfo, FILE *f,
- int bitDepth, int colorType,
+ int bitDepth, int colorType, double res,
SplashBitmap *bitmap) {
+ png_color_16 background;
+ int pixelsPerMeter;
+
if (!(*png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL)) ||
!(*pngInfo = png_create_info_struct(*png))) {
@@ -264,20 +291,61 @@ static void setupPNG(png_structp *png, png_infop *pngInfo, FILE *f,
png_set_IHDR(*png, *pngInfo, bitmap->getWidth(), bitmap->getHeight(),
bitDepth, colorType, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+ if (colorType == PNG_COLOR_TYPE_GRAY_ALPHA ||
+ colorType == PNG_COLOR_TYPE_RGB_ALPHA) {
+ background.index = 0;
+ background.red = 0xff;
+ background.green = 0xff;
+ background.blue = 0xff;
+ background.gray = 0xff;
+ png_set_bKGD(*png, *pngInfo, &background);
+ }
+ pixelsPerMeter = (int)(res * (1000 / 25.4) + 0.5);
+ png_set_pHYs(*png, *pngInfo, pixelsPerMeter, pixelsPerMeter,
+ PNG_RESOLUTION_METER);
png_write_info(*png, *pngInfo);
}
static void writePNGData(png_structp png, SplashBitmap *bitmap) {
- Guchar *p;
- int y;
+ Guchar *p, *alpha, *rowBuf, *rowBufPtr;
+ int y, x;
if (setjmp(png_jmpbuf(png))) {
exit(2);
}
p = bitmap->getDataPtr();
- for (y = 0; y < bitmap->getHeight(); ++y) {
- png_write_row(png, (png_bytep)p);
- p += bitmap->getRowSize();
+ if (pngAlpha) {
+ alpha = bitmap->getAlphaPtr();
+ if (bitmap->getMode() == splashModeMono8) {
+ rowBuf = (Guchar *)gmallocn(bitmap->getWidth(), 2);
+ for (y = 0; y < bitmap->getHeight(); ++y) {
+ rowBufPtr = rowBuf;
+ for (x = 0; x < bitmap->getWidth(); ++x) {
+ *rowBufPtr++ = *p++;
+ *rowBufPtr++ = *alpha++;
+ }
+ png_write_row(png, (png_bytep)rowBuf);
+ }
+ gfree(rowBuf);
+ } else { // splashModeRGB8
+ rowBuf = (Guchar *)gmallocn(bitmap->getWidth(), 4);
+ for (y = 0; y < bitmap->getHeight(); ++y) {
+ rowBufPtr = rowBuf;
+ for (x = 0; x < bitmap->getWidth(); ++x) {
+ *rowBufPtr++ = *p++;
+ *rowBufPtr++ = *p++;
+ *rowBufPtr++ = *p++;
+ *rowBufPtr++ = *alpha++;
+ }
+ png_write_row(png, (png_bytep)rowBuf);
+ }
+ gfree(rowBuf);
+ }
+ } else {
+ for (y = 0; y < bitmap->getHeight(); ++y) {
+ png_write_row(png, (png_bytep)p);
+ p += bitmap->getRowSize();
+ }
}
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc
index d7b6a442324..886b4433dcd 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftoppm.cc
@@ -16,8 +16,9 @@
# include <fenv.h>
# include <fpu_control.h>
#endif
-#include "parseargs.h"
#include "gmem.h"
+#include "gmempp.h"
+#include "parseargs.h"
#include "GString.h"
#include "GlobalParams.h"
#include "Object.h"
@@ -29,9 +30,12 @@
static int firstPage = 1;
static int lastPage = 0;
-static int resolution = 150;
+static double resolution = 150;
static GBool mono = gFalse;
static GBool gray = gFalse;
+#if SPLASH_CMYK
+static GBool cmyk = gFalse;
+#endif
static char enableFreeTypeStr[16] = "";
static char antialiasStr[16] = "";
static char vectorAntialiasStr[16] = "";
@@ -47,13 +51,17 @@ static ArgDesc argDesc[] = {
"first page to print"},
{"-l", argInt, &lastPage, 0,
"last page to print"},
- {"-r", argInt, &resolution, 0,
+ {"-r", argFP, &resolution, 0,
"resolution, in DPI (default is 150)"},
{"-mono", argFlag, &mono, 0,
"generate a monochrome PBM file"},
{"-gray", argFlag, &gray, 0,
"generate a grayscale PGM file"},
-#if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H
+#if SPLASH_CMYK
+ {"-cmyk", argFlag, &cmyk, 0,
+ "generate a CMYK PAM file"},
+#endif
+#if HAVE_FREETYPE_H
{"-freetype", argString, enableFreeTypeStr, sizeof(enableFreeTypeStr),
"enable FreeType font rasterizer: yes, no"},
#endif
@@ -92,7 +100,8 @@ int main(int argc, char *argv[]) {
SplashOutputDev *splashOut;
GBool ok;
int exitCode;
- int pg;
+ int pg, n;
+ const char *ext;
#ifdef DEBUG_FP_LINUX
// enable exceptions on floating point div-by-zero
@@ -103,7 +112,7 @@ int main(int argc, char *argv[]) {
// emulation (yes, this is a kludge; but it's pretty much
// unavoidable given the x87 instruction set; see gcc bug 323 for
// more info)
- fpu_control_t cw;
+ fpu_control_t cw;
_FPU_GETCW(cw);
cw = (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
_FPU_SETCW(cw);
@@ -111,12 +120,15 @@ int main(int argc, char *argv[]) {
exitCode = 99;
-#ifdef _MSC_VER
- (void)kpse_set_program_name(argv[0], NULL);
-#endif
// parse args
ok = parseArgs(argDesc, &argc, argv);
- if (mono && gray) {
+ n = 0;
+ n += mono ? 1 : 0;
+ n += gray ? 1 : 0;
+#if SPLASH_CMYK
+ n += cmyk ? 1 : 0;
+#endif
+ if (n > 1) {
ok = gFalse;
}
if (!ok || argc != 3 || printVersion || printHelp) {
@@ -181,6 +193,19 @@ int main(int argc, char *argv[]) {
if (lastPage < 1 || lastPage > doc->getNumPages())
lastPage = doc->getNumPages();
+ // file name extension
+ if (mono) {
+ ext = "pbm";
+ } else if (gray) {
+ ext = "pgm";
+#if SPLASH_CMYK
+ } else if (cmyk) {
+ ext = "pam";
+#endif
+ } else {
+ ext = "ppm";
+ }
+
// write PPM files
if (mono) {
@@ -189,6 +214,11 @@ int main(int argc, char *argv[]) {
} else if (gray) {
paperColor[0] = 0xff;
splashOut = new SplashOutputDev(splashModeMono8, 1, gFalse, paperColor);
+#if SPLASH_CMYK
+ } else if (cmyk) {
+ paperColor[0] = paperColor[1] = paperColor[2] = paperColor[3] = 0;
+ splashOut = new SplashOutputDev(splashModeCMYK8, 1, gFalse, paperColor);
+#endif
} else {
paperColor[0] = paperColor[1] = paperColor[2] = 0xff;
splashOut = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor);
@@ -203,9 +233,7 @@ int main(int argc, char *argv[]) {
#endif
splashOut->getBitmap()->writePNMFile(stdout);
} else {
- ppmFile = GString::format("{0:s}-{1:06d}.{2:s}",
- ppmRoot, pg,
- mono ? "pbm" : gray ? "pgm" : "ppm");
+ ppmFile = GString::format("{0:s}-{1:06d}.{2:s}", ppmRoot, pg, ext);
splashOut->getBitmap()->writePNMFile(ppmFile->getCString());
delete ppmFile;
}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc
index f6715058bc1..155a4117904 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftops.cc
@@ -15,9 +15,10 @@
# include <fenv.h>
# include <fpu_control.h>
#endif
+#include "gmem.h"
+#include "gmempp.h"
#include "parseargs.h"
#include "GString.h"
-#include "gmem.h"
#include "GlobalParams.h"
#include "Object.h"
#include "Stream.h"
@@ -36,11 +37,14 @@ static int lastPage = 0;
static GBool level1 = gFalse;
static GBool level1Sep = gFalse;
static GBool level2 = gFalse;
+static GBool level2Gray = gFalse;
static GBool level2Sep = gFalse;
static GBool level3 = gFalse;
+static GBool level3Gray = gFalse;
static GBool level3Sep = gFalse;
static GBool doEPS = gFalse;
static GBool doForm = gFalse;
+static GBool forceMono = gFalse;
#if OPI_SUPPORT
static GBool doOPI = gFalse;
#endif
@@ -57,6 +61,7 @@ static GBool expand = gFalse;
static GBool noShrink = gFalse;
static GBool noCenter = gFalse;
static GBool pageCrop = gFalse;
+static GBool userUnit = gFalse;
static GBool duplex = gFalse;
static char ownerPassword[33] = "\001";
static char userPassword[33] = "\001";
@@ -76,16 +81,22 @@ static ArgDesc argDesc[] = {
"generate Level 1 separable PostScript"},
{"-level2", argFlag, &level2, 0,
"generate Level 2 PostScript"},
+ {"-level2gray", argFlag, &level2Gray, 0,
+ "generate Level 2 grayscale PostScript"},
{"-level2sep", argFlag, &level2Sep, 0,
"generate Level 2 separable PostScript"},
{"-level3", argFlag, &level3, 0,
"generate Level 3 PostScript"},
+ {"-level3gray", argFlag, &level3Gray, 0,
+ "generate Level 3 grayscale PostScript"},
{"-level3sep", argFlag, &level3Sep, 0,
"generate Level 3 separable PostScript"},
{"-eps", argFlag, &doEPS, 0,
"generate Encapsulated PostScript (EPS)"},
{"-form", argFlag, &doForm, 0,
"generate a PostScript form"},
+ {"-mono", argFlag, &forceMono, 0,
+ "force monochrome (grayscale) output"},
#if OPI_SUPPORT
{"-opi", argFlag, &doOPI, 0,
"generate OPI comments"},
@@ -116,6 +127,8 @@ static ArgDesc argDesc[] = {
"don't center pages smaller than the paper size"},
{"-pagecrop", argFlag, &pageCrop, 0,
"treat the CropBox as the page size"},
+ {"-userunit", argFlag, &userUnit, 0,
+ "honor the UserUnit"},
{"-duplex", argFlag, &duplex, 0,
"enable duplex printing"},
{"-opw", argString, ownerPassword, sizeof(ownerPassword),
@@ -160,7 +173,7 @@ int main(int argc, char *argv[]) {
// emulation (yes, this is a kludge; but it's pretty much
// unavoidable given the x87 instruction set; see gcc bug 323 for
// more info)
- fpu_control_t cw;
+ fpu_control_t cw;
_FPU_GETCW(cw);
cw = (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
_FPU_SETCW(cw);
@@ -168,9 +181,6 @@ int main(int argc, char *argv[]) {
exitCode = 99;
-#ifdef _MSC_VER
- (void)kpse_set_program_name(argv[0], NULL);
-#endif
// parse args
ok = parseArgs(argDesc, &argc, argv);
if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) {
@@ -184,8 +194,10 @@ int main(int argc, char *argv[]) {
if ((level1 ? 1 : 0) +
(level1Sep ? 1 : 0) +
(level2 ? 1 : 0) +
+ (level2Gray ? 1 : 0) +
(level2Sep ? 1 : 0) +
(level3 ? 1 : 0) +
+ (level3Gray ? 1 : 0) +
(level3Sep ? 1 : 0) > 1) {
fprintf(stderr, "Error: use only one of the 'level' options.\n");
exit(1);
@@ -198,10 +210,14 @@ int main(int argc, char *argv[]) {
level = psLevel1;
} else if (level1Sep) {
level = psLevel1Sep;
+ } else if (level2Gray) {
+ level = psLevel2Gray;
} else if (level2Sep) {
level = psLevel2Sep;
} else if (level3) {
level = psLevel3;
+ } else if (level3Gray) {
+ level = psLevel3Gray;
} else if (level3Sep) {
level = psLevel3Sep;
} else {
@@ -253,7 +269,9 @@ int main(int argc, char *argv[]) {
if (duplex) {
globalParams->setPSDuplex(duplex);
}
- if (level1 || level1Sep || level2 || level2Sep || level3 || level3Sep) {
+ if (level1 || level1Sep ||
+ level2 || level2Gray || level2Sep ||
+ level3 || level3Gray || level3Sep) {
globalParams->setPSLevel(level);
}
if (noEmbedT1Fonts) {
@@ -340,16 +358,16 @@ int main(int argc, char *argv[]) {
// write PostScript file
psOut = new PSOutputDev(psFileName->getCString(), doc,
- firstPage, lastPage, mode);
- if (psOut->isOk()) {
- doc->displayPages(psOut, firstPage, lastPage, 72, 72,
- 0, !globalParams->getPSUseCropBoxAsPage(),
- globalParams->getPSCrop(), gTrue);
- } else {
+ firstPage, lastPage, mode,
+ 0, 0, 0, 0, gFalse, NULL, NULL, userUnit);
+ if (!psOut->isOk()) {
delete psOut;
exitCode = 2;
goto err2;
}
+ doc->displayPages(psOut, firstPage, lastPage, 72, 72,
+ 0, !globalParams->getPSUseCropBoxAsPage(),
+ globalParams->getPSCrop(), gTrue);
exitCode = 0;
if (!psOut->checkIO()) {
exitCode = 2;
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
index 02b45f9c304..49513be5f83 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdftotext.cc
@@ -15,9 +15,10 @@
# include <fenv.h>
# include <fpu_control.h>
#endif
+#include "gmem.h"
+#include "gmempp.h"
#include "parseargs.h"
#include "GString.h"
-#include "gmem.h"
#include "GlobalParams.h"
#include "Object.h"
#include "Stream.h"
@@ -37,15 +38,18 @@
static int firstPage = 1;
static int lastPage = 0;
static GBool physLayout = gFalse;
+static GBool simpleLayout = gFalse;
static GBool tableLayout = gFalse;
static GBool linePrinter = gFalse;
static GBool rawOrder = gFalse;
static double fixedPitch = 0;
static double fixedLineSpacing = 0;
static GBool clipText = gFalse;
+static GBool discardDiag = gFalse;
static char textEncName[128] = "";
static char textEOL[16] = "";
static GBool noPageBreaks = gFalse;
+static GBool insertBOM = gFalse;
static char ownerPassword[33] = "\001";
static char userPassword[33] = "\001";
static GBool quiet = gFalse;
@@ -60,6 +64,8 @@ static ArgDesc argDesc[] = {
"last page to convert"},
{"-layout", argFlag, &physLayout, 0,
"maintain original physical layout"},
+ {"-simple", argFlag, &simpleLayout, 0,
+ "simple one-column page layout"},
{"-table", argFlag, &tableLayout, 0,
"similar to -layout, but optimized for tables"},
{"-lineprinter", argFlag, &linePrinter, 0,
@@ -72,12 +78,16 @@ static ArgDesc argDesc[] = {
"fixed line spacing for LinePrinter mode"},
{"-clip", argFlag, &clipText, 0,
"separate clipped text"},
+ {"-nodiag", argFlag, &discardDiag, 0,
+ "discard diagonal text"},
{"-enc", argString, textEncName, sizeof(textEncName),
"output text encoding name"},
{"-eol", argString, textEOL, sizeof(textEOL),
"output end-of-line convention (unix, dos, or mac)"},
{"-nopgbrk", argFlag, &noPageBreaks, 0,
"don't insert page breaks between pages"},
+ {"-bom", argFlag, &insertBOM, 0,
+ "insert a Unicode BOM at the start of the text file"},
{"-opw", argString, ownerPassword, sizeof(ownerPassword),
"owner password (for encrypted files)"},
{"-upw", argString, userPassword, sizeof(userPassword),
@@ -121,7 +131,7 @@ int main(int argc, char *argv[]) {
// emulation (yes, this is a kludge; but it's pretty much
// unavoidable given the x87 instruction set; see gcc bug 323 for
// more info)
- fpu_control_t cw;
+ fpu_control_t cw;
_FPU_GETCW(cw);
cw = (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
_FPU_SETCW(cw);
@@ -129,9 +139,6 @@ int main(int argc, char *argv[]) {
exitCode = 99;
-#ifdef _MSC_VER
- (void)kpse_set_program_name(argv[0], NULL);
-#endif
// parse args
ok = parseArgs(argDesc, &argc, argv);
if (!ok || argc < 2 || argc > 3 || printVersion || printHelp) {
@@ -228,6 +235,8 @@ int main(int argc, char *argv[]) {
} else if (physLayout) {
textOutControl.mode = textOutPhysLayout;
textOutControl.fixedPitch = fixedPitch;
+ } else if (simpleLayout) {
+ textOutControl.mode = textOutSimpleLayout;
} else if (linePrinter) {
textOutControl.mode = textOutLinePrinter;
textOutControl.fixedPitch = fixedPitch;
@@ -238,6 +247,8 @@ int main(int argc, char *argv[]) {
textOutControl.mode = textOutReadingOrder;
}
textOutControl.clipText = clipText;
+ textOutControl.discardDiagonalText = discardDiag;
+ textOutControl.insertBOM = insertBOM;
textOut = new TextOutputDev(textFileName->getCString(), &textOutControl,
gFalse);
if (textOut->isOk()) {
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/print.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/print.xbm
deleted file mode 100644
index 209eb43583f..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/print.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define print_width 15
-#define print_height 15
-static unsigned char print_bits[] = {
- 0xf0, 0x7f, 0x10, 0x40, 0x10, 0x40, 0xc8, 0x23, 0x08, 0x20, 0x68, 0x23,
- 0x04, 0x10, 0x34, 0x10, 0x04, 0x10, 0xff, 0x7f, 0x55, 0x55, 0xab, 0x6a,
- 0x55, 0x55, 0xab, 0x6a, 0xfe, 0x3f};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/printDis.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/printDis.xbm
deleted file mode 100644
index 19e962d5fbe..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/printDis.xbm
+++ /dev/null
@@ -1,6 +0,0 @@
-#define printDis_width 15
-#define printDis_height 15
-static unsigned char printDis_bits[] = {
- 0xa0, 0x2a, 0x10, 0x40, 0x00, 0x00, 0x40, 0x01, 0x08, 0x20, 0x40, 0x01,
- 0x00, 0x00, 0x14, 0x10, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x01, 0x40,
- 0x00, 0x00, 0x01, 0x40, 0xaa, 0x2a};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/rightArrow.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/rightArrow.xbm
deleted file mode 100644
index 4ccb16b1e32..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/rightArrow.xbm
+++ /dev/null
@@ -1,5 +0,0 @@
-#define rightArrow_width 8
-#define rightArrow_height 15
-static unsigned char rightArrow_bits[] = {
- 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff, 0x7f, 0x3f, 0x1f, 0x0f,
- 0x07, 0x03, 0x01};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/rightArrowDis.xbm b/Build/source/libs/xpdf/xpdf-src/xpdf/rightArrowDis.xbm
deleted file mode 100644
index 1216c47f10e..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/rightArrowDis.xbm
+++ /dev/null
@@ -1,5 +0,0 @@
-#define rightArrowDis_width 8
-#define rightArrowDis_height 15
-static unsigned char rightArrowDis_bits[] = {
- 0x01, 0x02, 0x05, 0x0a, 0x15, 0x2a, 0x55, 0xaa, 0x55, 0x2a, 0x15, 0x0a,
- 0x05, 0x02, 0x01};
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/xpdf.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/xpdf.cc
deleted file mode 100644
index 1041265a3f1..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/xpdf.cc
+++ /dev/null
@@ -1,334 +0,0 @@
-//========================================================================
-//
-// xpdf.cc
-//
-// Copyright 1996-2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-#include <aconf.h>
-#include "gtypes.h"
-#include "GString.h"
-#include "parseargs.h"
-#include "gfile.h"
-#include "gmem.h"
-#include "GlobalParams.h"
-#include "Object.h"
-#include "XPDFApp.h"
-#include "config.h"
-
-//------------------------------------------------------------------------
-// command line options
-//------------------------------------------------------------------------
-
-static GBool contView = gFalse;
-static char enableFreeTypeStr[16] = "";
-static char antialiasStr[16] = "";
-static char vectorAntialiasStr[16] = "";
-static char psFileArg[256];
-static char paperSize[15] = "";
-static int paperWidth = 0;
-static int paperHeight = 0;
-static GBool level1 = gFalse;
-static char textEncName[128] = "";
-static char textEOL[16] = "";
-static char ownerPassword[33] = "\001";
-static char userPassword[33] = "\001";
-static GBool fullScreen = gFalse;
-static char remoteName[100] = "xpdf_";
-static char remoteCmd[512] = "";
-static GBool doRemoteReload = gFalse;
-static GBool doRemoteRaise = gFalse;
-static GBool doRemoteQuit = gFalse;
-static GBool printCommands = gFalse;
-static GBool quiet = gFalse;
-static char cfgFileName[256] = "";
-static GBool printVersion = gFalse;
-static GBool printHelp = gFalse;
-
-static ArgDesc argDesc[] = {
- {"-g", argStringDummy, NULL, 0,
- "initial window geometry"},
- {"-geometry", argStringDummy, NULL, 0,
- "initial window geometry"},
- {"-title", argStringDummy, NULL, 0,
- "window title"},
- {"-cmap", argFlagDummy, NULL, 0,
- "install a private colormap"},
- {"-rgb", argIntDummy, NULL, 0,
- "biggest RGB cube to allocate (default is 5)"},
- {"-rv", argFlagDummy, NULL, 0,
- "reverse video"},
- {"-papercolor", argStringDummy, NULL, 0,
- "color of paper background"},
- {"-z", argStringDummy, NULL, 0,
- "initial zoom level (percent, 'page', 'width')"},
- {"-cont", argFlag, &contView, 0,
- "start in continuous view mode" },
-#if HAVE_FREETYPE_FREETYPE_H | HAVE_FREETYPE_H
- {"-freetype", argString, enableFreeTypeStr, sizeof(enableFreeTypeStr),
- "enable FreeType font rasterizer: yes, no"},
-#endif
- {"-aa", argString, antialiasStr, sizeof(antialiasStr),
- "enable font anti-aliasing: yes, no"},
- {"-aaVector", argString, vectorAntialiasStr, sizeof(vectorAntialiasStr),
- "enable vector anti-aliasing: yes, no"},
- {"-ps", argString, psFileArg, sizeof(psFileArg),
- "default PostScript file name or command"},
- {"-paper", argString, paperSize, sizeof(paperSize),
- "paper size (letter, legal, A4, A3, match)"},
- {"-paperw", argInt, &paperWidth, 0,
- "paper width, in points"},
- {"-paperh", argInt, &paperHeight, 0,
- "paper height, in points"},
- {"-level1", argFlag, &level1, 0,
- "generate Level 1 PostScript"},
- {"-enc", argString, textEncName, sizeof(textEncName),
- "output text encoding name"},
- {"-eol", argString, textEOL, sizeof(textEOL),
- "output end-of-line convention (unix, dos, or mac)"},
- {"-opw", argString, ownerPassword, sizeof(ownerPassword),
- "owner password (for encrypted files)"},
- {"-upw", argString, userPassword, sizeof(userPassword),
- "user password (for encrypted files)"},
- {"-fullscreen", argFlag, &fullScreen, 0,
- "run in full-screen (presentation) mode"},
- {"-remote", argString, remoteName + 5, sizeof(remoteName) - 5,
- "start/contact xpdf remote server with specified name"},
- {"-exec", argString, remoteCmd, sizeof(remoteCmd),
- "execute command on xpdf remote server (with -remote only)"},
- {"-reload", argFlag, &doRemoteReload, 0,
- "reload xpdf remote server window (with -remote only)"},
- {"-raise", argFlag, &doRemoteRaise, 0,
- "raise xpdf remote server window (with -remote only)"},
- {"-quit", argFlag, &doRemoteQuit, 0,
- "kill xpdf remote server (with -remote only)"},
- {"-cmd", argFlag, &printCommands, 0,
- "print commands as they're executed"},
- {"-q", argFlag, &quiet, 0,
- "don't print any messages or errors"},
- {"-cfg", argString, cfgFileName, sizeof(cfgFileName),
- "configuration file to use in place of .xpdfrc"},
- {"-v", argFlag, &printVersion, 0,
- "print copyright and version info"},
- {"-h", argFlag, &printHelp, 0,
- "print usage information"},
- {"-help", argFlag, &printHelp, 0,
- "print usage information"},
- {"--help", argFlag, &printHelp, 0,
- "print usage information"},
- {"-?", argFlag, &printHelp, 0,
- "print usage information"},
- {NULL}
-};
-
-//------------------------------------------------------------------------
-
-int main(int argc, char *argv[]) {
- XPDFApp *app;
- GString *fileName;
- int pg;
- GString *destName;
- GString *userPasswordStr, *ownerPasswordStr;
- GBool ok;
- int exitCode;
-
- exitCode = 0;
- userPasswordStr = ownerPasswordStr = NULL;
-
- // parse args
- ok = parseArgs(argDesc, &argc, argv);
- if (!ok || printVersion || printHelp) {
- fprintf(stderr, "xpdf version %s\n", xpdfVersion);
- fprintf(stderr, "%s\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("xpdf", "[<PDF-file> [<page> | +<dest>]]", argDesc);
- }
- exitCode = 99;
- goto done0;
- }
-
- // read config file
- globalParams = new GlobalParams(cfgFileName);
- globalParams->setupBaseFonts(NULL);
- if (contView) {
- globalParams->setContinuousView(contView);
- }
- if (psFileArg[0]) {
- globalParams->setPSFile(psFileArg);
- }
- if (paperSize[0]) {
- if (!globalParams->setPSPaperSize(paperSize)) {
- fprintf(stderr, "Invalid paper size\n");
- }
- } else {
- if (paperWidth) {
- globalParams->setPSPaperWidth(paperWidth);
- }
- if (paperHeight) {
- globalParams->setPSPaperHeight(paperHeight);
- }
- }
- if (level1) {
- globalParams->setPSLevel(psLevel1);
- }
- if (textEncName[0]) {
- globalParams->setTextEncoding(textEncName);
- }
- if (textEOL[0]) {
- if (!globalParams->setTextEOL(textEOL)) {
- fprintf(stderr, "Bad '-eol' value on command line\n");
- }
- }
- if (enableFreeTypeStr[0]) {
- if (!globalParams->setEnableFreeType(enableFreeTypeStr)) {
- fprintf(stderr, "Bad '-freetype' value on command line\n");
- }
- }
- if (antialiasStr[0]) {
- if (!globalParams->setAntialias(antialiasStr)) {
- fprintf(stderr, "Bad '-aa' value on command line\n");
- }
- }
- if (vectorAntialiasStr[0]) {
- if (!globalParams->setVectorAntialias(vectorAntialiasStr)) {
- fprintf(stderr, "Bad '-aaVector' value on command line\n");
- }
- }
- if (printCommands) {
- globalParams->setPrintCommands(printCommands);
- }
- if (quiet) {
- globalParams->setErrQuiet(quiet);
- }
-
- // create the XPDFApp object
- app = new XPDFApp(&argc, argv);
-
- // the initialZoom parameter can be set in either the config file or
- // as an X resource (or command line arg)
- if (app->getInitialZoom()) {
- globalParams->setInitialZoom(app->getInitialZoom()->getCString());
- }
-
- // check command line
- ok = ok && argc >= 1 && argc <= 3;
- if (remoteCmd[0]) {
- ok = ok && remoteName[5] && !doRemoteReload && !doRemoteRaise &&
- !doRemoteQuit && argc == 1;
- }
- if (doRemoteReload) {
- ok = ok && remoteName[5] && !doRemoteQuit && argc == 1;
- }
- if (doRemoteRaise) {
- ok = ok && remoteName[5] && !doRemoteQuit;
- }
- if (doRemoteQuit) {
- ok = ok && remoteName[5] && argc == 1;
- }
- if (!ok || printVersion || printHelp) {
- fprintf(stderr, "xpdf version %s\n", xpdfVersion);
- fprintf(stderr, "%s\n", xpdfCopyright);
- if (!printVersion) {
- printUsage("xpdf", "[<PDF-file> [<page> | +<dest>]]", argDesc);
- }
- exitCode = 99;
- goto done1;
- }
- if (argc >= 2) {
- fileName = new GString(argv[1]);
- } else {
- fileName = NULL;
- }
- pg = 1;
- destName = NULL;
- if (argc == 3) {
- if (argv[2][0] == '+') {
- destName = new GString(&argv[2][1]);
- } else {
- pg = atoi(argv[2]);
- if (pg < 0) {
- fprintf(stderr, "Invalid page number (%d)\n", pg);
- exitCode = 99;
- goto done2;
- }
- }
- }
-
- // handle remote server stuff
- if (remoteName[5]) {
- app->setRemoteName(remoteName);
- if (app->remoteServerRunning()) {
- if (fileName) {
- if (destName) {
- app->remoteOpenAtDest(fileName, destName, doRemoteRaise);
- } else {
- app->remoteOpen(fileName, pg, doRemoteRaise);
- }
- } else if (remoteCmd[0]) {
- app->remoteExec(remoteCmd);
- } else if (doRemoteReload) {
- app->remoteReload(doRemoteRaise);
- } else if (doRemoteRaise) {
- app->remoteRaise();
- } else if (doRemoteQuit) {
- app->remoteQuit();
- }
- goto done2;
- }
- if (doRemoteQuit) {
- goto done2;
- }
- }
-
- // set options
- app->setFullScreen(fullScreen);
-
- // check for password string(s)
- ownerPasswordStr = ownerPassword[0] != '\001' ? new GString(ownerPassword)
- : (GString *)NULL;
- userPasswordStr = userPassword[0] != '\001' ? new GString(userPassword)
- : (GString *)NULL;
-
- // open the file and run the main loop
- if (destName) {
- if (!app->openAtDest(fileName, destName,
- ownerPasswordStr, userPasswordStr)) {
- exitCode = 1;
- goto done2;
- }
- } else {
- if (!app->open(fileName, pg, ownerPasswordStr, userPasswordStr)) {
- exitCode = 1;
- goto done2;
- }
- }
- app->run();
-
- exitCode = 0;
-
- // clean up
- done2:
- if (userPasswordStr) {
- delete userPasswordStr;
- }
- if (ownerPasswordStr) {
- delete ownerPasswordStr;
- }
- if (destName) {
- delete destName;
- }
- if (fileName) {
- delete fileName;
- }
- done1:
- delete app;
- delete globalParams;
-
- // check for memory leaks
- done0:
- Object::memCheck(stderr);
- gMemReport(stderr);
-
- return exitCode;
-}
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/xpdfIcon.xpm b/Build/source/libs/xpdf/xpdf-src/xpdf/xpdfIcon.xpm
deleted file mode 100644
index 5e05d20e2c0..00000000000
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/xpdfIcon.xpm
+++ /dev/null
@@ -1,62 +0,0 @@
-/* XPM */
-static char *xpdfIcon[] = {
-/* width height num_colors chars_per_pixel */
-" 48 48 7 1",
-/* colors */
-". c #000000",
-"# c #a00000",
-"a c #a0a0a0",
-"b c #c0c0c0",
-"c c #e00000",
-"d c #e0e0e0",
-"e c #ffffff",
-/* pixels */
-"................................................",
-"................................................",
-"................................................",
-"................................................",
-"#ccccccc#................................#ccc#..",
-".#ccccccc#..............................#ccc#...",
-"..#ccccccc#............................#ccc#....",
-"...#ccccccc#................bbba.....abbbc#.....",
-"....#ccccccc#...............beea....debbed......",
-".....#ccccccc#...............ee....bebccee......",
-"......#ccccccc#..............ee....eecc#bb......",
-".......#ccccccc#............aee...#eec#.........",
-"........#ccccccc#...........bed..#beb#..........",
-".........#ccccccc#..........beb.#cbeb...........",
-"..........#ccccccc#.........beb#ccbeb...........",
-"...........#ccccccc#........bebcccbeb...........",
-"............#ccccccc#.......eebcc#dea...........",
-".............#ccccccc#......eecc#.ee............",
-".........ae...#ccccccc#....#eec#..ee............",
-"........aeeaeeeebcccccabeeeaee#.beeeeee.........",
-".......aeeeea..debcccaed##ceee....ee............",
-"......addee.....eeccaedccccbed...beb............",
-"......a.bee.....ee#cbeaccccbeb...beb............",
-"........beb.....ee.#eecccccbeb...beb............",
-"........beb.....ee..eecccccbeb...beb............",
-"........beb.....ee..eeccccceeb...dea............",
-"........deb....aeb.#eeccccceec#..ee.............",
-"........eea....dea#cee##ccceecc#.ee.............",
-"........eee...dea#ccbeda#cdeeccc#ee.............",
-"........eeaeeeba#ccc#beeeeaeeecceeee............",
-"........ee.....#ccc#......#ccccccc#.............",
-".......bee....#ccc#........#ccccccc#............",
-".......beb...#ccc#..........#ccccccc#...........",
-".......beb..#ccc#............#ccccccc#..........",
-".......beb.#ccc#..............#ccccccc#.........",
-".......deb#ccc#................#ccccccc#........",
-".......eeaccc#..................#ccccccc#.......",
-".......eeccc#....................#ccccccc#......",
-".......eecc#......................#ccccccc#.....",
-"......beeb#........................#ccccccc#....",
-".....#bbbb..........................#ccccccc#...",
-"....#ccc#............................#ccccccc#..",
-"...#ccc#..............................#ccccccc#.",
-"..#ccc#................................#ccccccc.",
-"................................................",
-"................................................",
-"................................................",
-"................................................"
-};