pdf2json 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +9 -0
- data/bin/.gitkeep +0 -0
- data/ext/extconf.rb +30 -0
- data/lib/pdf2json.rb +8 -0
- data/pdf2json-0.52-source/AUTHORS +24 -0
- data/pdf2json-0.52-source/CHANGES +11 -0
- data/pdf2json-0.52-source/Makefile +84 -0
- data/pdf2json-0.52-source/Makefile.in +84 -0
- data/pdf2json-0.52-source/aclocal.m4 +274 -0
- data/pdf2json-0.52-source/aconf-win32.h +86 -0
- data/pdf2json-0.52-source/aconf.h +42 -0
- data/pdf2json-0.52-source/aconf.h.in +41 -0
- data/pdf2json-0.52-source/autom4te.cache/output.0 +6908 -0
- data/pdf2json-0.52-source/autom4te.cache/requests +76 -0
- data/pdf2json-0.52-source/autom4te.cache/traces.0 +466 -0
- data/pdf2json-0.52-source/config.log +1259 -0
- data/pdf2json-0.52-source/config.status +1050 -0
- data/pdf2json-0.52-source/configure +6908 -0
- data/pdf2json-0.52-source/configure.ac +93 -0
- data/pdf2json-0.52-source/doc/pdffonts.1 +130 -0
- data/pdf2json-0.52-source/doc/pdffonts.cat +107 -0
- data/pdf2json-0.52-source/doc/pdffonts.hlp +117 -0
- data/pdf2json-0.52-source/doc/pdfimages.1 +102 -0
- data/pdf2json-0.52-source/doc/pdfimages.cat +92 -0
- data/pdf2json-0.52-source/doc/pdfimages.hlp +101 -0
- data/pdf2json-0.52-source/doc/pdfinfo.1 +158 -0
- data/pdf2json-0.52-source/doc/pdfinfo.cat +119 -0
- data/pdf2json-0.52-source/doc/pdfinfo.hlp +129 -0
- data/pdf2json-0.52-source/doc/pdftoppm.1 +115 -0
- data/pdf2json-0.52-source/doc/pdftoppm.cat +105 -0
- data/pdf2json-0.52-source/doc/pdftoppm.hlp +114 -0
- data/pdf2json-0.52-source/doc/pdftops.1 +229 -0
- data/pdf2json-0.52-source/doc/pdftops.cat +221 -0
- data/pdf2json-0.52-source/doc/pdftops.hlp +231 -0
- data/pdf2json-0.52-source/doc/pdftotext.1 +137 -0
- data/pdf2json-0.52-source/doc/pdftotext.cat +120 -0
- data/pdf2json-0.52-source/doc/pdftotext.hlp +133 -0
- data/pdf2json-0.52-source/doc/sample-xpdfrc +91 -0
- data/pdf2json-0.52-source/doc/xpdf.1 +513 -0
- data/pdf2json-0.52-source/doc/xpdf.cat +476 -0
- data/pdf2json-0.52-source/doc/xpdf.hlp +489 -0
- data/pdf2json-0.52-source/doc/xpdfrc.5 +480 -0
- data/pdf2json-0.52-source/doc/xpdfrc.cat +474 -0
- data/pdf2json-0.52-source/doc/xpdfrc.hlp +479 -0
- data/pdf2json-0.52-source/fofi/.DS_Store +0 -0
- data/pdf2json-0.52-source/fofi/FoFiBase.cc +156 -0
- data/pdf2json-0.52-source/fofi/FoFiBase.h +57 -0
- data/pdf2json-0.52-source/fofi/FoFiBase.o +0 -0
- data/pdf2json-0.52-source/fofi/FoFiEncodings.cc +994 -0
- data/pdf2json-0.52-source/fofi/FoFiEncodings.h +36 -0
- data/pdf2json-0.52-source/fofi/FoFiEncodings.o +0 -0
- data/pdf2json-0.52-source/fofi/FoFiTrueType.cc +2027 -0
- data/pdf2json-0.52-source/fofi/FoFiTrueType.h +174 -0
- data/pdf2json-0.52-source/fofi/FoFiTrueType.o +0 -0
- data/pdf2json-0.52-source/fofi/FoFiType1.cc +252 -0
- data/pdf2json-0.52-source/fofi/FoFiType1.h +59 -0
- data/pdf2json-0.52-source/fofi/FoFiType1.o +0 -0
- data/pdf2json-0.52-source/fofi/FoFiType1C.cc +2603 -0
- data/pdf2json-0.52-source/fofi/FoFiType1C.h +233 -0
- data/pdf2json-0.52-source/fofi/FoFiType1C.o +0 -0
- data/pdf2json-0.52-source/fofi/Makefile +70 -0
- data/pdf2json-0.52-source/fofi/Makefile.dep +0 -0
- data/pdf2json-0.52-source/fofi/Makefile.in +70 -0
- data/pdf2json-0.52-source/fofi/libfofi.a +0 -0
- data/pdf2json-0.52-source/fofi/vms_make.com +0 -0
- data/pdf2json-0.52-source/freetype.win32/.DS_Store +0 -0
- data/pdf2json-0.52-source/freetype.win32/include/.DS_Store +0 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftconfig.h +528 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftheader.h +780 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftmodule.h +32 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftoption.h +733 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftstdlib.h +173 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/freetype.h +3919 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftadvanc.h +179 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbbox.h +94 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbdf.h +209 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbitmap.h +227 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcache.h +1128 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftchapters.h +103 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcid.h +166 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrdef.h +244 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrors.h +206 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgasp.h +120 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftglyph.h +613 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgxval.h +358 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgzip.h +102 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftimage.h +1313 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftincrem.h +353 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlcdfil.h +213 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlist.h +277 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlzw.h +99 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmac.h +274 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmm.h +378 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmodapi.h +483 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmoderr.h +155 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftotval.h +203 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftoutln.h +537 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftpfr.h +172 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftrender.h +230 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsizes.h +159 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsnames.h +200 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftstroke.h +716 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsynth.h +80 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsystem.h +347 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/fttrigon.h +350 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/fttypes.h +588 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftwinfnt.h +274 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ftxf86.h +83 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/autohint.h +231 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftcalc.h +179 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdebug.h +250 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdriver.h +422 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftgloadr.h +168 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftmemory.h +380 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftobjs.h +1428 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftpic.h +67 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftrfork.h +196 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftserv.h +620 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftstream.h +539 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/fttrace.h +139 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftvalid.h +150 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/internal.h +51 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pcftypes.h +56 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/psaux.h +873 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pshints.h +712 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svbdf.h +77 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svcid.h +83 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgldict.h +82 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgxval.h +72 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svkern.h +51 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svmm.h +104 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svotval.h +55 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpfr.h +66 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpostnm.h +79 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpscmap.h +164 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpsinfo.h +92 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svsfnt.h +102 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttcmap.h +106 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svtteng.h +53 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttglyf.h +67 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svwinfnt.h +50 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svxf86nm.h +55 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/sfnt.h +897 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/t1types.h +270 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/tttypes.h +1543 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/t1tables.h +504 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ttnameid.h +1247 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/tttables.h +759 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/tttags.h +107 -0
- data/pdf2json-0.52-source/freetype.win32/include/freetype/ttunpat.h +59 -0
- data/pdf2json-0.52-source/freetype.win32/include/ft2build.h +39 -0
- data/pdf2json-0.52-source/freetype.win32/lib/freetype_a.lib +0 -0
- data/pdf2json-0.52-source/goo/.DS_Store +0 -0
- data/pdf2json-0.52-source/goo/FixedPoint.cc +118 -0
- data/pdf2json-0.52-source/goo/FixedPoint.h +155 -0
- data/pdf2json-0.52-source/goo/FixedPoint.o +0 -0
- data/pdf2json-0.52-source/goo/GHash.cc +380 -0
- data/pdf2json-0.52-source/goo/GHash.h +78 -0
- data/pdf2json-0.52-source/goo/GHash.o +0 -0
- data/pdf2json-0.52-source/goo/GList.cc +97 -0
- data/pdf2json-0.52-source/goo/GList.h +96 -0
- data/pdf2json-0.52-source/goo/GList.o +0 -0
- data/pdf2json-0.52-source/goo/GMutex.h +49 -0
- data/pdf2json-0.52-source/goo/GString.cc +724 -0
- data/pdf2json-0.52-source/goo/GString.cc.fixed +718 -0
- data/pdf2json-0.52-source/goo/GString.h +136 -0
- data/pdf2json-0.52-source/goo/GString.o +0 -0
- data/pdf2json-0.52-source/goo/ImgWriter.o +0 -0
- data/pdf2json-0.52-source/goo/JpegWriter.o +0 -0
- data/pdf2json-0.52-source/goo/Makefile +72 -0
- data/pdf2json-0.52-source/goo/Makefile.dep +0 -0
- data/pdf2json-0.52-source/goo/Makefile.in +72 -0
- data/pdf2json-0.52-source/goo/PNGWriter.o +0 -0
- data/pdf2json-0.52-source/goo/gfile.cc +731 -0
- data/pdf2json-0.52-source/goo/gfile.h +138 -0
- data/pdf2json-0.52-source/goo/gfile.o +0 -0
- data/pdf2json-0.52-source/goo/gmem.cc +264 -0
- data/pdf2json-0.52-source/goo/gmem.h +79 -0
- data/pdf2json-0.52-source/goo/gmem.o +0 -0
- data/pdf2json-0.52-source/goo/gmempp.cc +32 -0
- data/pdf2json-0.52-source/goo/gmempp.o +0 -0
- data/pdf2json-0.52-source/goo/gtypes.h +29 -0
- data/pdf2json-0.52-source/goo/libGoo.a +0 -0
- data/pdf2json-0.52-source/goo/parseargs.c +190 -0
- data/pdf2json-0.52-source/goo/parseargs.h +71 -0
- data/pdf2json-0.52-source/goo/parseargs.o +0 -0
- data/pdf2json-0.52-source/goo/vms_directory.c +214 -0
- data/pdf2json-0.52-source/goo/vms_dirent.h +67 -0
- data/pdf2json-0.52-source/goo/vms_make.com +82 -0
- data/pdf2json-0.52-source/goo/vms_sys_dirent.h +54 -0
- data/pdf2json-0.52-source/goo/vms_unix_time.h +102 -0
- data/pdf2json-0.52-source/goo/vms_unix_times.c +42 -0
- data/pdf2json-0.52-source/goo/vms_unlink.c +22 -0
- data/pdf2json-0.52-source/ms_make.bat +199 -0
- data/pdf2json-0.52-source/splash/.DS_Store +0 -0
- data/pdf2json-0.52-source/splash/Makefile +103 -0
- data/pdf2json-0.52-source/splash/Makefile.dep +0 -0
- data/pdf2json-0.52-source/splash/Makefile.in +103 -0
- data/pdf2json-0.52-source/splash/Splash.cc +3310 -0
- data/pdf2json-0.52-source/splash/Splash.h +293 -0
- data/pdf2json-0.52-source/splash/Splash.o +0 -0
- data/pdf2json-0.52-source/splash/SplashBitmap.cc +188 -0
- data/pdf2json-0.52-source/splash/SplashBitmap.h +64 -0
- data/pdf2json-0.52-source/splash/SplashBitmap.o +0 -0
- data/pdf2json-0.52-source/splash/SplashClip.cc +382 -0
- data/pdf2json-0.52-source/splash/SplashClip.h +107 -0
- data/pdf2json-0.52-source/splash/SplashClip.o +0 -0
- data/pdf2json-0.52-source/splash/SplashErrorCodes.h +32 -0
- data/pdf2json-0.52-source/splash/SplashFTFont.cc +357 -0
- data/pdf2json-0.52-source/splash/SplashFTFont.h +58 -0
- data/pdf2json-0.52-source/splash/SplashFTFont.o +0 -0
- data/pdf2json-0.52-source/splash/SplashFTFontEngine.cc +179 -0
- data/pdf2json-0.52-source/splash/SplashFTFontEngine.h +65 -0
- data/pdf2json-0.52-source/splash/SplashFTFontEngine.o +0 -0
- data/pdf2json-0.52-source/splash/SplashFTFontFile.cc +114 -0
- data/pdf2json-0.52-source/splash/SplashFTFontFile.h +73 -0
- data/pdf2json-0.52-source/splash/SplashFTFontFile.o +0 -0
- data/pdf2json-0.52-source/splash/SplashFont.cc +176 -0
- data/pdf2json-0.52-source/splash/SplashFont.h +104 -0
- data/pdf2json-0.52-source/splash/SplashFont.o +0 -0
- data/pdf2json-0.52-source/splash/SplashFontEngine.cc +317 -0
- data/pdf2json-0.52-source/splash/SplashFontEngine.h +91 -0
- data/pdf2json-0.52-source/splash/SplashFontEngine.o +0 -0
- data/pdf2json-0.52-source/splash/SplashFontFile.cc +55 -0
- data/pdf2json-0.52-source/splash/SplashFontFile.h +60 -0
- data/pdf2json-0.52-source/splash/SplashFontFile.o +0 -0
- data/pdf2json-0.52-source/splash/SplashFontFileID.cc +23 -0
- data/pdf2json-0.52-source/splash/SplashFontFileID.h +30 -0
- data/pdf2json-0.52-source/splash/SplashFontFileID.o +0 -0
- data/pdf2json-0.52-source/splash/SplashGlyphBitmap.h +26 -0
- data/pdf2json-0.52-source/splash/SplashMath.h +89 -0
- data/pdf2json-0.52-source/splash/SplashPath.cc +184 -0
- data/pdf2json-0.52-source/splash/SplashPath.h +121 -0
- data/pdf2json-0.52-source/splash/SplashPath.o +0 -0
- data/pdf2json-0.52-source/splash/SplashPattern.cc +40 -0
- data/pdf2json-0.52-source/splash/SplashPattern.h +65 -0
- data/pdf2json-0.52-source/splash/SplashPattern.o +0 -0
- data/pdf2json-0.52-source/splash/SplashScreen.cc +383 -0
- data/pdf2json-0.52-source/splash/SplashScreen.h +56 -0
- data/pdf2json-0.52-source/splash/SplashScreen.o +0 -0
- data/pdf2json-0.52-source/splash/SplashState.cc +165 -0
- data/pdf2json-0.52-source/splash/SplashState.h +103 -0
- data/pdf2json-0.52-source/splash/SplashState.o +0 -0
- data/pdf2json-0.52-source/splash/SplashT1Font.cc +287 -0
- data/pdf2json-0.52-source/splash/SplashT1Font.h +57 -0
- data/pdf2json-0.52-source/splash/SplashT1Font.o +0 -0
- data/pdf2json-0.52-source/splash/SplashT1FontEngine.cc +124 -0
- data/pdf2json-0.52-source/splash/SplashT1FontEngine.h +53 -0
- data/pdf2json-0.52-source/splash/SplashT1FontEngine.o +0 -0
- data/pdf2json-0.52-source/splash/SplashT1FontFile.cc +97 -0
- data/pdf2json-0.52-source/splash/SplashT1FontFile.h +58 -0
- data/pdf2json-0.52-source/splash/SplashT1FontFile.o +0 -0
- data/pdf2json-0.52-source/splash/SplashTypes.h +132 -0
- data/pdf2json-0.52-source/splash/SplashXPath.cc +438 -0
- data/pdf2json-0.52-source/splash/SplashXPath.h +100 -0
- data/pdf2json-0.52-source/splash/SplashXPath.o +0 -0
- data/pdf2json-0.52-source/splash/SplashXPathScanner.cc +428 -0
- data/pdf2json-0.52-source/splash/SplashXPathScanner.h +87 -0
- data/pdf2json-0.52-source/splash/SplashXPathScanner.o +0 -0
- data/pdf2json-0.52-source/splash/libsplash.a +0 -0
- data/pdf2json-0.52-source/splash/vms_make.com +0 -0
- data/pdf2json-0.52-source/src/.DS_Store +0 -0
- data/pdf2json-0.52-source/src/GVector.h +101 -0
- data/pdf2json-0.52-source/src/ImgOutputDev.cc +1243 -0
- data/pdf2json-0.52-source/src/ImgOutputDev.h +307 -0
- data/pdf2json-0.52-source/src/ImgOutputDev.o +0 -0
- data/pdf2json-0.52-source/src/Makefile +68 -0
- data/pdf2json-0.52-source/src/Makefile.in +68 -0
- data/pdf2json-0.52-source/src/XmlFonts.cc +367 -0
- data/pdf2json-0.52-source/src/XmlFonts.h +91 -0
- data/pdf2json-0.52-source/src/XmlFonts.o +0 -0
- data/pdf2json-0.52-source/src/XmlLinks.cc +101 -0
- data/pdf2json-0.52-source/src/XmlLinks.h +54 -0
- data/pdf2json-0.52-source/src/XmlLinks.o +0 -0
- data/pdf2json-0.52-source/src/pdf2json +0 -0
- data/pdf2json-0.52-source/src/pdf2json.cc +343 -0
- data/pdf2json-0.52-source/src/pdf2json.o +0 -0
- data/pdf2json-0.52-source/src/pdf2xml.dtd +22 -0
- data/pdf2json-0.52-source/src/pdf2xmljson.dtd +9 -0
- data/pdf2json-0.52-source/xpdf/.DS_Store +0 -0
- data/pdf2json-0.52-source/xpdf/Annot.cc +1556 -0
- data/pdf2json-0.52-source/xpdf/Annot.h +142 -0
- data/pdf2json-0.52-source/xpdf/Annot.o +0 -0
- data/pdf2json-0.52-source/xpdf/Array.cc +73 -0
- data/pdf2json-0.52-source/xpdf/Array.h +58 -0
- data/pdf2json-0.52-source/xpdf/Array.o +0 -0
- data/pdf2json-0.52-source/xpdf/BuiltinFont.cc +65 -0
- data/pdf2json-0.52-source/xpdf/BuiltinFont.h +57 -0
- data/pdf2json-0.52-source/xpdf/BuiltinFont.o +0 -0
- data/pdf2json-0.52-source/xpdf/BuiltinFontTables.cc +4284 -0
- data/pdf2json-0.52-source/xpdf/BuiltinFontTables.h +23 -0
- data/pdf2json-0.52-source/xpdf/BuiltinFontTables.o +0 -0
- data/pdf2json-0.52-source/xpdf/CMap.cc +408 -0
- data/pdf2json-0.52-source/xpdf/CMap.h +102 -0
- data/pdf2json-0.52-source/xpdf/CMap.o +0 -0
- data/pdf2json-0.52-source/xpdf/Catalog.cc +374 -0
- data/pdf2json-0.52-source/xpdf/Catalog.h +97 -0
- data/pdf2json-0.52-source/xpdf/Catalog.o +0 -0
- data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.cc +540 -0
- data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.h +117 -0
- data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.o +0 -0
- data/pdf2json-0.52-source/xpdf/CharTypes.h +24 -0
- data/pdf2json-0.52-source/xpdf/CompactFontTables.h +464 -0
- data/pdf2json-0.52-source/xpdf/CoreOutputDev.cc +61 -0
- data/pdf2json-0.52-source/xpdf/CoreOutputDev.h +61 -0
- data/pdf2json-0.52-source/xpdf/Decrypt.cc +776 -0
- data/pdf2json-0.52-source/xpdf/Decrypt.h +95 -0
- data/pdf2json-0.52-source/xpdf/Decrypt.o +0 -0
- data/pdf2json-0.52-source/xpdf/Dict.cc +95 -0
- data/pdf2json-0.52-source/xpdf/Dict.h +77 -0
- data/pdf2json-0.52-source/xpdf/Dict.o +0 -0
- data/pdf2json-0.52-source/xpdf/Error.cc +38 -0
- data/pdf2json-0.52-source/xpdf/Error.h +23 -0
- data/pdf2json-0.52-source/xpdf/Error.o +0 -0
- data/pdf2json-0.52-source/xpdf/ErrorCodes.h +36 -0
- data/pdf2json-0.52-source/xpdf/FontEncodingTables.cc +1824 -0
- data/pdf2json-0.52-source/xpdf/FontEncodingTables.h +20 -0
- data/pdf2json-0.52-source/xpdf/FontEncodingTables.o +0 -0
- data/pdf2json-0.52-source/xpdf/Function.cc +1573 -0
- data/pdf2json-0.52-source/xpdf/Function.h +229 -0
- data/pdf2json-0.52-source/xpdf/Function.o +0 -0
- data/pdf2json-0.52-source/xpdf/Gfx.cc +4187 -0
- data/pdf2json-0.52-source/xpdf/Gfx.h +312 -0
- data/pdf2json-0.52-source/xpdf/Gfx.o +0 -0
- data/pdf2json-0.52-source/xpdf/GfxFont.cc +1568 -0
- data/pdf2json-0.52-source/xpdf/GfxFont.h +320 -0
- data/pdf2json-0.52-source/xpdf/GfxFont.o +0 -0
- data/pdf2json-0.52-source/xpdf/GfxState.cc +4137 -0
- data/pdf2json-0.52-source/xpdf/GfxState.h +1244 -0
- data/pdf2json-0.52-source/xpdf/GfxState.o +0 -0
- data/pdf2json-0.52-source/xpdf/GlobalParams.cc +2924 -0
- data/pdf2json-0.52-source/xpdf/GlobalParams.cc.old +2908 -0
- data/pdf2json-0.52-source/xpdf/GlobalParams.h +466 -0
- data/pdf2json-0.52-source/xpdf/GlobalParams.h.old +463 -0
- data/pdf2json-0.52-source/xpdf/GlobalParams.o +0 -0
- data/pdf2json-0.52-source/xpdf/ImageOutputDev.cc +195 -0
- data/pdf2json-0.52-source/xpdf/ImageOutputDev.h +76 -0
- data/pdf2json-0.52-source/xpdf/ImageOutputDev.o +0 -0
- data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.cc +322 -0
- data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.h +109 -0
- data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.o +0 -0
- data/pdf2json-0.52-source/xpdf/JBIG2Stream.cc +3413 -0
- data/pdf2json-0.52-source/xpdf/JBIG2Stream.h +145 -0
- data/pdf2json-0.52-source/xpdf/JBIG2Stream.o +0 -0
- data/pdf2json-0.52-source/xpdf/JPXStream.cc +3144 -0
- data/pdf2json-0.52-source/xpdf/JPXStream.h +351 -0
- data/pdf2json-0.52-source/xpdf/JPXStream.o +0 -0
- data/pdf2json-0.52-source/xpdf/Lexer.cc +485 -0
- data/pdf2json-0.52-source/xpdf/Lexer.h +80 -0
- data/pdf2json-0.52-source/xpdf/Lexer.o +0 -0
- data/pdf2json-0.52-source/xpdf/Link.cc +806 -0
- data/pdf2json-0.52-source/xpdf/Link.cc.old +784 -0
- data/pdf2json-0.52-source/xpdf/Link.h +415 -0
- data/pdf2json-0.52-source/xpdf/Link.h.old +369 -0
- data/pdf2json-0.52-source/xpdf/Link.o +0 -0
- data/pdf2json-0.52-source/xpdf/Makefile +232 -0
- data/pdf2json-0.52-source/xpdf/Makefile.dep +0 -0
- data/pdf2json-0.52-source/xpdf/Makefile.in +232 -0
- data/pdf2json-0.52-source/xpdf/NameToCharCode.cc +116 -0
- data/pdf2json-0.52-source/xpdf/NameToCharCode.h +42 -0
- data/pdf2json-0.52-source/xpdf/NameToCharCode.o +0 -0
- data/pdf2json-0.52-source/xpdf/NameToUnicodeTable.h +1097 -0
- data/pdf2json-0.52-source/xpdf/Object.cc +231 -0
- data/pdf2json-0.52-source/xpdf/Object.h +303 -0
- data/pdf2json-0.52-source/xpdf/Object.o +0 -0
- data/pdf2json-0.52-source/xpdf/Outline.cc +151 -0
- data/pdf2json-0.52-source/xpdf/Outline.h +76 -0
- data/pdf2json-0.52-source/xpdf/Outline.o +0 -0
- data/pdf2json-0.52-source/xpdf/OutputDev.cc +131 -0
- data/pdf2json-0.52-source/xpdf/OutputDev.h +253 -0
- data/pdf2json-0.52-source/xpdf/OutputDev.o +0 -0
- data/pdf2json-0.52-source/xpdf/PDFCore.cc +2044 -0
- data/pdf2json-0.52-source/xpdf/PDFCore.h +321 -0
- data/pdf2json-0.52-source/xpdf/PDFDoc.cc +404 -0
- data/pdf2json-0.52-source/xpdf/PDFDoc.h +183 -0
- data/pdf2json-0.52-source/xpdf/PDFDoc.o +0 -0
- data/pdf2json-0.52-source/xpdf/PDFDocEncoding.cc +44 -0
- data/pdf2json-0.52-source/xpdf/PDFDocEncoding.h +16 -0
- data/pdf2json-0.52-source/xpdf/PDFDocEncoding.o +0 -0
- data/pdf2json-0.52-source/xpdf/PSOutputDev.cc +6224 -0
- data/pdf2json-0.52-source/xpdf/PSOutputDev.h +395 -0
- data/pdf2json-0.52-source/xpdf/PSOutputDev.o +0 -0
- data/pdf2json-0.52-source/xpdf/PSTokenizer.cc +135 -0
- data/pdf2json-0.52-source/xpdf/PSTokenizer.h +41 -0
- data/pdf2json-0.52-source/xpdf/PSTokenizer.o +0 -0
- data/pdf2json-0.52-source/xpdf/Page.cc +454 -0
- data/pdf2json-0.52-source/xpdf/Page.h +187 -0
- data/pdf2json-0.52-source/xpdf/Page.o +0 -0
- data/pdf2json-0.52-source/xpdf/Parser.cc +227 -0
- data/pdf2json-0.52-source/xpdf/Parser.h +59 -0
- data/pdf2json-0.52-source/xpdf/Parser.o +0 -0
- data/pdf2json-0.52-source/xpdf/PreScanOutputDev.cc +257 -0
- data/pdf2json-0.52-source/xpdf/PreScanOutputDev.h +130 -0
- data/pdf2json-0.52-source/xpdf/PreScanOutputDev.o +0 -0
- data/pdf2json-0.52-source/xpdf/SecurityHandler.cc +390 -0
- data/pdf2json-0.52-source/xpdf/SecurityHandler.h +160 -0
- data/pdf2json-0.52-source/xpdf/SecurityHandler.o +0 -0
- data/pdf2json-0.52-source/xpdf/SplashOutputDev.cc +2845 -0
- data/pdf2json-0.52-source/xpdf/SplashOutputDev.h +247 -0
- data/pdf2json-0.52-source/xpdf/SplashOutputDev.o +0 -0
- data/pdf2json-0.52-source/xpdf/Stream-CCITT.h +459 -0
- data/pdf2json-0.52-source/xpdf/Stream.cc +4627 -0
- data/pdf2json-0.52-source/xpdf/Stream.h +858 -0
- data/pdf2json-0.52-source/xpdf/Stream.o +0 -0
- data/pdf2json-0.52-source/xpdf/TextOutputDev.cc +4090 -0
- data/pdf2json-0.52-source/xpdf/TextOutputDev.h +661 -0
- data/pdf2json-0.52-source/xpdf/TextOutputDev.o +0 -0
- data/pdf2json-0.52-source/xpdf/UTF8.h +56 -0
- data/pdf2json-0.52-source/xpdf/UnicodeMap.cc +302 -0
- data/pdf2json-0.52-source/xpdf/UnicodeMap.cc.old +293 -0
- data/pdf2json-0.52-source/xpdf/UnicodeMap.h +135 -0
- data/pdf2json-0.52-source/xpdf/UnicodeMap.h.old +123 -0
- data/pdf2json-0.52-source/xpdf/UnicodeMap.o +0 -0
- data/pdf2json-0.52-source/xpdf/UnicodeMapTables.h +361 -0
- data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.cc +949 -0
- data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.h +20 -0
- data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.o +0 -0
- data/pdf2json-0.52-source/xpdf/XPDFApp.cc +447 -0
- data/pdf2json-0.52-source/xpdf/XPDFApp.h +114 -0
- data/pdf2json-0.52-source/xpdf/XPDFCore.cc +1655 -0
- data/pdf2json-0.52-source/xpdf/XPDFCore.h +251 -0
- data/pdf2json-0.52-source/xpdf/XPDFTree.cc +931 -0
- data/pdf2json-0.52-source/xpdf/XPDFTree.h +45 -0
- data/pdf2json-0.52-source/xpdf/XPDFTreeP.h +87 -0
- data/pdf2json-0.52-source/xpdf/XPDFViewer.cc +3488 -0
- data/pdf2json-0.52-source/xpdf/XPDFViewer.h +352 -0
- data/pdf2json-0.52-source/xpdf/XRef.cc +896 -0
- data/pdf2json-0.52-source/xpdf/XRef.h +133 -0
- data/pdf2json-0.52-source/xpdf/XRef.o +0 -0
- data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.cc +262 -0
- data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.h +341 -0
- data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.o +0 -0
- data/pdf2json-0.52-source/xpdf/about-text.h +48 -0
- data/pdf2json-0.52-source/xpdf/about.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/backArrow.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/backArrowDis.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/config.h +112 -0
- data/pdf2json-0.52-source/xpdf/dblLeftArrow.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/dblLeftArrowDis.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/dblRightArrow.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/dblRightArrowDis.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/find.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/findDis.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/forwardArrow.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/forwardArrowDis.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/leftArrow.xbm +5 -0
- data/pdf2json-0.52-source/xpdf/leftArrowDis.xbm +5 -0
- data/pdf2json-0.52-source/xpdf/libXpdf.a +0 -0
- data/pdf2json-0.52-source/xpdf/pdffonts +0 -0
- data/pdf2json-0.52-source/xpdf/pdffonts.cc +298 -0
- data/pdf2json-0.52-source/xpdf/pdffonts.o +0 -0
- data/pdf2json-0.52-source/xpdf/pdfimages +0 -0
- data/pdf2json-0.52-source/xpdf/pdfimages.cc +155 -0
- data/pdf2json-0.52-source/xpdf/pdfimages.o +0 -0
- data/pdf2json-0.52-source/xpdf/pdfinfo +0 -0
- data/pdf2json-0.52-source/xpdf/pdfinfo.cc +387 -0
- data/pdf2json-0.52-source/xpdf/pdfinfo.o +0 -0
- data/pdf2json-0.52-source/xpdf/pdftoppm.cc +203 -0
- data/pdf2json-0.52-source/xpdf/pdftops +0 -0
- data/pdf2json-0.52-source/xpdf/pdftops.cc +344 -0
- data/pdf2json-0.52-source/xpdf/pdftops.o +0 -0
- data/pdf2json-0.52-source/xpdf/pdftotext +0 -0
- data/pdf2json-0.52-source/xpdf/pdftotext.cc +333 -0
- data/pdf2json-0.52-source/xpdf/pdftotext.o +0 -0
- data/pdf2json-0.52-source/xpdf/print.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/printDis.xbm +6 -0
- data/pdf2json-0.52-source/xpdf/rightArrow.xbm +5 -0
- data/pdf2json-0.52-source/xpdf/rightArrowDis.xbm +5 -0
- data/pdf2json-0.52-source/xpdf/vms_make.com +129 -0
- data/pdf2json-0.52-source/xpdf/xpdf.cc +344 -0
- data/pdf2json-0.52-source/xpdf/xpdfIcon.xpm +62 -0
- data/pdf2json.gemspec +29 -0
- metadata +518 -0
@@ -0,0 +1,160 @@
|
|
1
|
+
//========================================================================
|
2
|
+
//
|
3
|
+
// SecurityHandler.h
|
4
|
+
//
|
5
|
+
// Copyright 2004 Glyph & Cog, LLC
|
6
|
+
//
|
7
|
+
//========================================================================
|
8
|
+
|
9
|
+
#ifndef SECURITYHANDLER_H
|
10
|
+
#define SECURITYHANDLER_H
|
11
|
+
|
12
|
+
#include <aconf.h>
|
13
|
+
|
14
|
+
#ifdef USE_GCC_PRAGMAS
|
15
|
+
#pragma interface
|
16
|
+
#endif
|
17
|
+
|
18
|
+
#include "gtypes.h"
|
19
|
+
#include "Object.h"
|
20
|
+
|
21
|
+
class GString;
|
22
|
+
class PDFDoc;
|
23
|
+
struct XpdfSecurityHandler;
|
24
|
+
|
25
|
+
//------------------------------------------------------------------------
|
26
|
+
// SecurityHandler
|
27
|
+
//------------------------------------------------------------------------
|
28
|
+
|
29
|
+
class SecurityHandler {
|
30
|
+
public:
|
31
|
+
|
32
|
+
static SecurityHandler *make(PDFDoc *docA, Object *encryptDictA);
|
33
|
+
|
34
|
+
SecurityHandler(PDFDoc *docA);
|
35
|
+
virtual ~SecurityHandler();
|
36
|
+
|
37
|
+
// Check the document's encryption. If the document is encrypted,
|
38
|
+
// this will first try <ownerPassword> and <userPassword> (in
|
39
|
+
// "batch" mode), and if those fail, it will attempt to request a
|
40
|
+
// password from the user. This is the high-level function that
|
41
|
+
// calls the lower level functions for the specific security handler
|
42
|
+
// (requesting a password three times, etc.). Returns true if the
|
43
|
+
// document can be opened (if it's unencrypted, or if a correct
|
44
|
+
// password is obtained); false otherwise (encrypted and no correct
|
45
|
+
// password).
|
46
|
+
GBool checkEncryption(GString *ownerPassword,
|
47
|
+
GString *userPassword);
|
48
|
+
|
49
|
+
// Create authorization data for the specified owner and user
|
50
|
+
// passwords. If the security handler doesn't support "batch" mode,
|
51
|
+
// this function should return NULL.
|
52
|
+
virtual void *makeAuthData(GString *ownerPassword,
|
53
|
+
GString *userPassword) = 0;
|
54
|
+
|
55
|
+
// Construct authorization data, typically by prompting the user for
|
56
|
+
// a password. Returns an authorization data object, or NULL to
|
57
|
+
// cancel.
|
58
|
+
virtual void *getAuthData() = 0;
|
59
|
+
|
60
|
+
// Free the authorization data returned by makeAuthData or
|
61
|
+
// getAuthData.
|
62
|
+
virtual void freeAuthData(void *authData) = 0;
|
63
|
+
|
64
|
+
// Attempt to authorize the document, using the supplied
|
65
|
+
// authorization data (which may be NULL). Returns true if
|
66
|
+
// successful (i.e., if at least the right to open the document was
|
67
|
+
// granted).
|
68
|
+
virtual GBool authorize(void *authData) = 0;
|
69
|
+
|
70
|
+
// Return the various authorization parameters. These are only
|
71
|
+
// valid after authorize has returned true.
|
72
|
+
virtual int getPermissionFlags() = 0;
|
73
|
+
virtual GBool getOwnerPasswordOk() = 0;
|
74
|
+
virtual Guchar *getFileKey() = 0;
|
75
|
+
virtual int getFileKeyLength() = 0;
|
76
|
+
virtual int getEncVersion() = 0;
|
77
|
+
virtual CryptAlgorithm getEncAlgorithm() = 0;
|
78
|
+
|
79
|
+
protected:
|
80
|
+
|
81
|
+
PDFDoc *doc;
|
82
|
+
};
|
83
|
+
|
84
|
+
//------------------------------------------------------------------------
|
85
|
+
// StandardSecurityHandler
|
86
|
+
//------------------------------------------------------------------------
|
87
|
+
|
88
|
+
class StandardSecurityHandler: public SecurityHandler {
|
89
|
+
public:
|
90
|
+
|
91
|
+
StandardSecurityHandler(PDFDoc *docA, Object *encryptDictA);
|
92
|
+
virtual ~StandardSecurityHandler();
|
93
|
+
|
94
|
+
virtual void *makeAuthData(GString *ownerPassword,
|
95
|
+
GString *userPassword);
|
96
|
+
virtual void *getAuthData();
|
97
|
+
virtual void freeAuthData(void *authData);
|
98
|
+
virtual GBool authorize(void *authData);
|
99
|
+
virtual int getPermissionFlags() { return permFlags; }
|
100
|
+
virtual GBool getOwnerPasswordOk() { return ownerPasswordOk; }
|
101
|
+
virtual Guchar *getFileKey() { return fileKey; }
|
102
|
+
virtual int getFileKeyLength() { return fileKeyLength; }
|
103
|
+
virtual int getEncVersion() { return encVersion; }
|
104
|
+
virtual CryptAlgorithm getEncAlgorithm() { return encAlgorithm; }
|
105
|
+
|
106
|
+
private:
|
107
|
+
|
108
|
+
int permFlags;
|
109
|
+
GBool ownerPasswordOk;
|
110
|
+
Guchar fileKey[16];
|
111
|
+
int fileKeyLength;
|
112
|
+
int encVersion;
|
113
|
+
int encRevision;
|
114
|
+
CryptAlgorithm encAlgorithm;
|
115
|
+
GBool encryptMetadata;
|
116
|
+
|
117
|
+
GString *ownerKey, *userKey;
|
118
|
+
GString *fileID;
|
119
|
+
GBool ok;
|
120
|
+
};
|
121
|
+
|
122
|
+
#ifdef ENABLE_PLUGINS
|
123
|
+
//------------------------------------------------------------------------
|
124
|
+
// ExternalSecurityHandler
|
125
|
+
//------------------------------------------------------------------------
|
126
|
+
|
127
|
+
class ExternalSecurityHandler: public SecurityHandler {
|
128
|
+
public:
|
129
|
+
|
130
|
+
ExternalSecurityHandler(PDFDoc *docA, Object *encryptDictA,
|
131
|
+
XpdfSecurityHandler *xshA);
|
132
|
+
virtual ~ExternalSecurityHandler();
|
133
|
+
|
134
|
+
virtual void *makeAuthData(GString *ownerPassword,
|
135
|
+
GString *userPassword);
|
136
|
+
virtual void *getAuthData();
|
137
|
+
virtual void freeAuthData(void *authData);
|
138
|
+
virtual GBool authorize(void *authData);
|
139
|
+
virtual int getPermissionFlags() { return permFlags; }
|
140
|
+
virtual GBool getOwnerPasswordOk() { return gFalse; }
|
141
|
+
virtual Guchar *getFileKey() { return fileKey; }
|
142
|
+
virtual int getFileKeyLength() { return fileKeyLength; }
|
143
|
+
virtual int getEncVersion() { return encVersion; }
|
144
|
+
virtual CryptAlgorithm getEncAlgorithm() { return encAlgorithm; }
|
145
|
+
|
146
|
+
private:
|
147
|
+
|
148
|
+
Object encryptDict;
|
149
|
+
XpdfSecurityHandler *xsh;
|
150
|
+
void *docData;
|
151
|
+
int permFlags;
|
152
|
+
Guchar fileKey[16];
|
153
|
+
int fileKeyLength;
|
154
|
+
int encVersion;
|
155
|
+
CryptAlgorithm encAlgorithm;
|
156
|
+
GBool ok;
|
157
|
+
};
|
158
|
+
#endif // ENABLE_PLUGINS
|
159
|
+
|
160
|
+
#endif
|
Binary file
|
@@ -0,0 +1,2845 @@
|
|
1
|
+
//========================================================================
|
2
|
+
//
|
3
|
+
// SplashOutputDev.cc
|
4
|
+
//
|
5
|
+
// Copyright 2003 Glyph & Cog, LLC
|
6
|
+
//
|
7
|
+
//========================================================================
|
8
|
+
|
9
|
+
#include <aconf.h>
|
10
|
+
|
11
|
+
#ifdef USE_GCC_PRAGMAS
|
12
|
+
#pragma implementation
|
13
|
+
#endif
|
14
|
+
|
15
|
+
#include <string.h>
|
16
|
+
#include <math.h>
|
17
|
+
#include "gfile.h"
|
18
|
+
#include "GlobalParams.h"
|
19
|
+
#include "Error.h"
|
20
|
+
#include "Object.h"
|
21
|
+
#include "GfxFont.h"
|
22
|
+
#include "Link.h"
|
23
|
+
#include "CharCodeToUnicode.h"
|
24
|
+
#include "FontEncodingTables.h"
|
25
|
+
#include "FoFiTrueType.h"
|
26
|
+
#include "SplashBitmap.h"
|
27
|
+
#include "SplashGlyphBitmap.h"
|
28
|
+
#include "SplashPattern.h"
|
29
|
+
#include "SplashScreen.h"
|
30
|
+
#include "SplashPath.h"
|
31
|
+
#include "SplashState.h"
|
32
|
+
#include "SplashErrorCodes.h"
|
33
|
+
#include "SplashFontEngine.h"
|
34
|
+
#include "SplashFont.h"
|
35
|
+
#include "SplashFontFile.h"
|
36
|
+
#include "SplashFontFileID.h"
|
37
|
+
#include "Splash.h"
|
38
|
+
#include "SplashOutputDev.h"
|
39
|
+
|
40
|
+
#ifdef VMS
|
41
|
+
#if (__VMS_VER < 70000000)
|
42
|
+
extern "C" int unlink(char *filename);
|
43
|
+
#endif
|
44
|
+
#endif
|
45
|
+
|
46
|
+
//------------------------------------------------------------------------
|
47
|
+
|
48
|
+
// Divide a 16-bit value (in [0, 255*255]) by 255, returning an 8-bit result.
|
49
|
+
static inline Guchar div255(int x) {
|
50
|
+
return (Guchar)((x + (x >> 8) + 0x80) >> 8);
|
51
|
+
}
|
52
|
+
|
53
|
+
//------------------------------------------------------------------------
|
54
|
+
// Blend functions
|
55
|
+
//------------------------------------------------------------------------
|
56
|
+
|
57
|
+
static void splashOutBlendMultiply(SplashColorPtr src, SplashColorPtr dest,
|
58
|
+
SplashColorPtr blend, SplashColorMode cm) {
|
59
|
+
int i;
|
60
|
+
|
61
|
+
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
|
62
|
+
blend[i] = (dest[i] * src[i]) / 255;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
static void splashOutBlendScreen(SplashColorPtr src, SplashColorPtr dest,
|
67
|
+
SplashColorPtr blend, SplashColorMode cm) {
|
68
|
+
int i;
|
69
|
+
|
70
|
+
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
|
71
|
+
blend[i] = dest[i] + src[i] - (dest[i] * src[i]) / 255;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
static void splashOutBlendOverlay(SplashColorPtr src, SplashColorPtr dest,
|
76
|
+
SplashColorPtr blend, SplashColorMode cm) {
|
77
|
+
int i;
|
78
|
+
|
79
|
+
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
|
80
|
+
blend[i] = dest[i] < 0x80
|
81
|
+
? (src[i] * 2 * dest[i]) / 255
|
82
|
+
: 255 - 2 * ((255 - src[i]) * (255 - dest[i])) / 255;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
static void splashOutBlendDarken(SplashColorPtr src, SplashColorPtr dest,
|
87
|
+
SplashColorPtr blend, SplashColorMode cm) {
|
88
|
+
int i;
|
89
|
+
|
90
|
+
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
|
91
|
+
blend[i] = dest[i] < src[i] ? dest[i] : src[i];
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
static void splashOutBlendLighten(SplashColorPtr src, SplashColorPtr dest,
|
96
|
+
SplashColorPtr blend, SplashColorMode cm) {
|
97
|
+
int i;
|
98
|
+
|
99
|
+
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
|
100
|
+
blend[i] = dest[i] > src[i] ? dest[i] : src[i];
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
static void splashOutBlendColorDodge(SplashColorPtr src, SplashColorPtr dest,
|
105
|
+
SplashColorPtr blend,
|
106
|
+
SplashColorMode cm) {
|
107
|
+
int i, x;
|
108
|
+
|
109
|
+
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
|
110
|
+
if (src[i] == 255) {
|
111
|
+
blend[i] = 255;
|
112
|
+
} else {
|
113
|
+
x = (dest[i] * 255) / (255 - src[i]);
|
114
|
+
blend[i] = x <= 255 ? x : 255;
|
115
|
+
}
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
static void splashOutBlendColorBurn(SplashColorPtr src, SplashColorPtr dest,
|
120
|
+
SplashColorPtr blend, SplashColorMode cm) {
|
121
|
+
int i, x;
|
122
|
+
|
123
|
+
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
|
124
|
+
if (src[i] == 0) {
|
125
|
+
blend[i] = 0;
|
126
|
+
} else {
|
127
|
+
x = ((255 - dest[i]) * 255) / src[i];
|
128
|
+
blend[i] = x <= 255 ? 255 - x : 0;
|
129
|
+
}
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
static void splashOutBlendHardLight(SplashColorPtr src, SplashColorPtr dest,
|
134
|
+
SplashColorPtr blend, SplashColorMode cm) {
|
135
|
+
int i;
|
136
|
+
|
137
|
+
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
|
138
|
+
blend[i] = src[i] < 0x80
|
139
|
+
? (dest[i] * 2 * src[i]) / 255
|
140
|
+
: 255 - 2 * ((255 - dest[i]) * (255 - src[i])) / 255;
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
static void splashOutBlendSoftLight(SplashColorPtr src, SplashColorPtr dest,
|
145
|
+
SplashColorPtr blend, SplashColorMode cm) {
|
146
|
+
int i, x;
|
147
|
+
|
148
|
+
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
|
149
|
+
if (src[i] < 0x80) {
|
150
|
+
blend[i] = dest[i] - (255 - 2 * src[i]) * dest[i] * (255 - dest[i]) /
|
151
|
+
(255 * 255);
|
152
|
+
} else {
|
153
|
+
if (dest[i] < 0x40) {
|
154
|
+
x = (((((16 * dest[i] - 12 * 255) * dest[i]) / 255)
|
155
|
+
+ 4 * 255) * dest[i]) / 255;
|
156
|
+
} else {
|
157
|
+
x = (int)sqrt(255.0 * dest[i]);
|
158
|
+
}
|
159
|
+
blend[i] = dest[i] + (2 * src[i] - 255) * (x - dest[i]) / 255;
|
160
|
+
}
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
static void splashOutBlendDifference(SplashColorPtr src, SplashColorPtr dest,
|
165
|
+
SplashColorPtr blend,
|
166
|
+
SplashColorMode cm) {
|
167
|
+
int i;
|
168
|
+
|
169
|
+
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
|
170
|
+
blend[i] = dest[i] < src[i] ? src[i] - dest[i] : dest[i] - src[i];
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
static void splashOutBlendExclusion(SplashColorPtr src, SplashColorPtr dest,
|
175
|
+
SplashColorPtr blend, SplashColorMode cm) {
|
176
|
+
int i;
|
177
|
+
|
178
|
+
for (i = 0; i < splashColorModeNComps[cm]; ++i) {
|
179
|
+
blend[i] = dest[i] + src[i] - (2 * dest[i] * src[i]) / 255;
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
static void cvtRGBToHSV(Guchar r, Guchar g, Guchar b, int *h, int *s, int *v) {
|
184
|
+
int cmax, cmid, cmin, x;
|
185
|
+
|
186
|
+
if (r >= g) {
|
187
|
+
if (g >= b) { x = 0; cmax = r; cmid = g; cmin = b; }
|
188
|
+
else if (b >= r) { x = 4; cmax = b; cmid = r; cmin = g; }
|
189
|
+
else { x = 5; cmax = r; cmid = b; cmin = g; }
|
190
|
+
} else {
|
191
|
+
if (r >= b) { x = 1; cmax = g; cmid = r; cmin = b; }
|
192
|
+
else if (g >= b) { x = 2; cmax = g; cmid = b; cmin = r; }
|
193
|
+
else { x = 3; cmax = b; cmid = g; cmin = r; }
|
194
|
+
}
|
195
|
+
if (cmax == cmin) {
|
196
|
+
*h = *s = 0;
|
197
|
+
} else {
|
198
|
+
*h = x * 60;
|
199
|
+
if (x & 1) {
|
200
|
+
*h += ((cmax - cmid) * 60) / (cmax - cmin);
|
201
|
+
} else {
|
202
|
+
*h += ((cmid - cmin) * 60) / (cmax - cmin);
|
203
|
+
}
|
204
|
+
*s = (255 * (cmax - cmin)) / cmax;
|
205
|
+
}
|
206
|
+
*v = cmax;
|
207
|
+
}
|
208
|
+
|
209
|
+
static void cvtHSVToRGB(int h, int s, int v, Guchar *r, Guchar *g, Guchar *b) {
|
210
|
+
int x, f, cmax, cmid, cmin;
|
211
|
+
|
212
|
+
if (s == 0) {
|
213
|
+
*r = *g = *b = v;
|
214
|
+
} else {
|
215
|
+
x = h / 60;
|
216
|
+
f = h % 60;
|
217
|
+
cmax = v;
|
218
|
+
if (x & 1) {
|
219
|
+
cmid = div255(v * 255 - ((s * f) / 60));
|
220
|
+
} else {
|
221
|
+
cmid = div255(v * (255 - ((s * (60 - f)) / 60)));
|
222
|
+
}
|
223
|
+
cmin = div255(v * (255 - s));
|
224
|
+
switch (x) {
|
225
|
+
case 0: *r = cmax; *g = cmid; *b = cmin; break;
|
226
|
+
case 1: *g = cmax; *r = cmid; *b = cmin; break;
|
227
|
+
case 2: *g = cmax; *b = cmid; *r = cmin; break;
|
228
|
+
case 3: *b = cmax; *g = cmid; *r = cmin; break;
|
229
|
+
case 4: *b = cmax; *r = cmid; *g = cmin; break;
|
230
|
+
case 5: *r = cmax; *b = cmid; *g = cmin; break;
|
231
|
+
}
|
232
|
+
}
|
233
|
+
}
|
234
|
+
|
235
|
+
static void splashOutBlendHue(SplashColorPtr src, SplashColorPtr dest,
|
236
|
+
SplashColorPtr blend, SplashColorMode cm) {
|
237
|
+
int hs, ss, vs, hd, sd, vd;
|
238
|
+
#if SPLASH_CMYK
|
239
|
+
Guchar r, g, b;
|
240
|
+
#endif
|
241
|
+
|
242
|
+
switch (cm) {
|
243
|
+
case splashModeMono1:
|
244
|
+
case splashModeMono8:
|
245
|
+
blend[0] = dest[0];
|
246
|
+
break;
|
247
|
+
case splashModeRGB8:
|
248
|
+
case splashModeBGR8:
|
249
|
+
cvtRGBToHSV(src[0], src[1], src[2], &hs, &ss, &vs);
|
250
|
+
cvtRGBToHSV(dest[0], dest[1], dest[2], &hd, &sd, &vd);
|
251
|
+
cvtHSVToRGB(hs, sd, vd, &blend[0], &blend[1], &blend[2]);
|
252
|
+
break;
|
253
|
+
#if SPLASH_CMYK
|
254
|
+
case splashModeCMYK8:
|
255
|
+
//~ (0xff - ...) should be clipped
|
256
|
+
cvtRGBToHSV(0xff - (src[0] + src[3]),
|
257
|
+
0xff - (src[1] + src[3]),
|
258
|
+
0xff - (src[2] + src[3]), &hs, &ss, &vs);
|
259
|
+
cvtRGBToHSV(0xff - (dest[0] + dest[3]),
|
260
|
+
0xff - (dest[1] + dest[3]),
|
261
|
+
0xff - (dest[2] + dest[3]), &hd, &sd, &vd);
|
262
|
+
cvtHSVToRGB(hs, sd, vd, &r, &g, &b);
|
263
|
+
//~ should do black generation
|
264
|
+
blend[0] = 0xff - r;
|
265
|
+
blend[1] = 0xff - g;
|
266
|
+
blend[2] = 0xff - b;
|
267
|
+
blend[3] = 0;
|
268
|
+
break;
|
269
|
+
#endif
|
270
|
+
}
|
271
|
+
}
|
272
|
+
|
273
|
+
static void splashOutBlendSaturation(SplashColorPtr src, SplashColorPtr dest,
|
274
|
+
SplashColorPtr blend,
|
275
|
+
SplashColorMode cm) {
|
276
|
+
int hs, ss, vs, hd, sd, vd;
|
277
|
+
#if SPLASH_CMYK
|
278
|
+
Guchar r, g, b;
|
279
|
+
#endif
|
280
|
+
|
281
|
+
switch (cm) {
|
282
|
+
case splashModeMono1:
|
283
|
+
case splashModeMono8:
|
284
|
+
blend[0] = dest[0];
|
285
|
+
break;
|
286
|
+
case splashModeRGB8:
|
287
|
+
case splashModeBGR8:
|
288
|
+
cvtRGBToHSV(src[0], src[1], src[2], &hs, &ss, &vs);
|
289
|
+
cvtRGBToHSV(dest[0], dest[1], dest[2], &hd, &sd, &vd);
|
290
|
+
cvtHSVToRGB(hd, ss, vd, &blend[0], &blend[1], &blend[2]);
|
291
|
+
break;
|
292
|
+
#if SPLASH_CMYK
|
293
|
+
case splashModeCMYK8:
|
294
|
+
//~ (0xff - ...) should be clipped
|
295
|
+
cvtRGBToHSV(0xff - (src[0] + src[3]),
|
296
|
+
0xff - (src[1] + src[3]),
|
297
|
+
0xff - (src[2] + src[3]), &hs, &ss, &vs);
|
298
|
+
cvtRGBToHSV(0xff - (dest[0] + dest[3]),
|
299
|
+
0xff - (dest[1] + dest[3]),
|
300
|
+
0xff - (dest[2] + dest[3]), &hd, &sd, &vd);
|
301
|
+
cvtHSVToRGB(hd, ss, vd, &r, &g, &b);
|
302
|
+
//~ should do black generation
|
303
|
+
blend[0] = 0xff - r;
|
304
|
+
blend[1] = 0xff - g;
|
305
|
+
blend[2] = 0xff - b;
|
306
|
+
blend[3] = 0;
|
307
|
+
break;
|
308
|
+
#endif
|
309
|
+
}
|
310
|
+
}
|
311
|
+
|
312
|
+
static void splashOutBlendColor(SplashColorPtr src, SplashColorPtr dest,
|
313
|
+
SplashColorPtr blend, SplashColorMode cm) {
|
314
|
+
int hs, ss, vs, hd, sd, vd;
|
315
|
+
#if SPLASH_CMYK
|
316
|
+
Guchar r, g, b;
|
317
|
+
#endif
|
318
|
+
|
319
|
+
switch (cm) {
|
320
|
+
case splashModeMono1:
|
321
|
+
case splashModeMono8:
|
322
|
+
blend[0] = dest[0];
|
323
|
+
break;
|
324
|
+
case splashModeRGB8:
|
325
|
+
case splashModeBGR8:
|
326
|
+
cvtRGBToHSV(src[0], src[1], src[2], &hs, &ss, &vs);
|
327
|
+
cvtRGBToHSV(dest[0], dest[1], dest[2], &hd, &sd, &vd);
|
328
|
+
cvtHSVToRGB(hs, ss, vd, &blend[0], &blend[1], &blend[2]);
|
329
|
+
break;
|
330
|
+
#if SPLASH_CMYK
|
331
|
+
case splashModeCMYK8:
|
332
|
+
//~ (0xff - ...) should be clipped
|
333
|
+
cvtRGBToHSV(0xff - (src[0] + src[3]),
|
334
|
+
0xff - (src[1] + src[3]),
|
335
|
+
0xff - (src[2] + src[3]), &hs, &ss, &vs);
|
336
|
+
cvtRGBToHSV(0xff - (dest[0] + dest[3]),
|
337
|
+
0xff - (dest[1] + dest[3]),
|
338
|
+
0xff - (dest[2] + dest[3]), &hd, &sd, &vd);
|
339
|
+
cvtHSVToRGB(hs, ss, vd, &r, &g, &b);
|
340
|
+
//~ should do black generation
|
341
|
+
blend[0] = 0xff - r;
|
342
|
+
blend[1] = 0xff - g;
|
343
|
+
blend[2] = 0xff - b;
|
344
|
+
blend[3] = 0;
|
345
|
+
break;
|
346
|
+
#endif
|
347
|
+
}
|
348
|
+
}
|
349
|
+
|
350
|
+
static void splashOutBlendLuminosity(SplashColorPtr src, SplashColorPtr dest,
|
351
|
+
SplashColorPtr blend,
|
352
|
+
SplashColorMode cm) {
|
353
|
+
int hs, ss, vs, hd, sd, vd;
|
354
|
+
#if SPLASH_CMYK
|
355
|
+
Guchar r, g, b;
|
356
|
+
#endif
|
357
|
+
|
358
|
+
switch (cm) {
|
359
|
+
case splashModeMono1:
|
360
|
+
case splashModeMono8:
|
361
|
+
blend[0] = dest[0];
|
362
|
+
break;
|
363
|
+
case splashModeRGB8:
|
364
|
+
case splashModeBGR8:
|
365
|
+
cvtRGBToHSV(src[0], src[1], src[2], &hs, &ss, &vs);
|
366
|
+
cvtRGBToHSV(dest[0], dest[1], dest[2], &hd, &sd, &vd);
|
367
|
+
cvtHSVToRGB(hd, sd, vs, &blend[0], &blend[1], &blend[2]);
|
368
|
+
break;
|
369
|
+
#if SPLASH_CMYK
|
370
|
+
case splashModeCMYK8:
|
371
|
+
//~ (0xff - ...) should be clipped
|
372
|
+
cvtRGBToHSV(0xff - (src[0] + src[3]),
|
373
|
+
0xff - (src[1] + src[3]),
|
374
|
+
0xff - (src[2] + src[3]), &hs, &ss, &vs);
|
375
|
+
cvtRGBToHSV(0xff - (dest[0] + dest[3]),
|
376
|
+
0xff - (dest[1] + dest[3]),
|
377
|
+
0xff - (dest[2] + dest[3]), &hd, &sd, &vd);
|
378
|
+
cvtHSVToRGB(hd, sd, vs, &r, &g, &b);
|
379
|
+
//~ should do black generation
|
380
|
+
blend[0] = 0xff - r;
|
381
|
+
blend[1] = 0xff - g;
|
382
|
+
blend[2] = 0xff - b;
|
383
|
+
blend[3] = 0;
|
384
|
+
break;
|
385
|
+
#endif
|
386
|
+
}
|
387
|
+
}
|
388
|
+
|
389
|
+
// NB: This must match the GfxBlendMode enum defined in GfxState.h.
|
390
|
+
SplashBlendFunc splashOutBlendFuncs[] = {
|
391
|
+
NULL,
|
392
|
+
&splashOutBlendMultiply,
|
393
|
+
&splashOutBlendScreen,
|
394
|
+
&splashOutBlendOverlay,
|
395
|
+
&splashOutBlendDarken,
|
396
|
+
&splashOutBlendLighten,
|
397
|
+
&splashOutBlendColorDodge,
|
398
|
+
&splashOutBlendColorBurn,
|
399
|
+
&splashOutBlendHardLight,
|
400
|
+
&splashOutBlendSoftLight,
|
401
|
+
&splashOutBlendDifference,
|
402
|
+
&splashOutBlendExclusion,
|
403
|
+
&splashOutBlendHue,
|
404
|
+
&splashOutBlendSaturation,
|
405
|
+
&splashOutBlendColor,
|
406
|
+
&splashOutBlendLuminosity
|
407
|
+
};
|
408
|
+
|
409
|
+
//------------------------------------------------------------------------
|
410
|
+
// Font substitutions
|
411
|
+
//------------------------------------------------------------------------
|
412
|
+
|
413
|
+
struct SplashOutFontSubst {
|
414
|
+
char *name;
|
415
|
+
double mWidth;
|
416
|
+
};
|
417
|
+
|
418
|
+
// index: {symbolic:12, fixed:8, serif:4, sans-serif:0} + bold*2 + italic
|
419
|
+
static SplashOutFontSubst splashOutSubstFonts[16] = {
|
420
|
+
{"Helvetica", 0.833},
|
421
|
+
{"Helvetica-Oblique", 0.833},
|
422
|
+
{"Helvetica-Bold", 0.889},
|
423
|
+
{"Helvetica-BoldOblique", 0.889},
|
424
|
+
{"Times-Roman", 0.788},
|
425
|
+
{"Times-Italic", 0.722},
|
426
|
+
{"Times-Bold", 0.833},
|
427
|
+
{"Times-BoldItalic", 0.778},
|
428
|
+
{"Courier", 0.600},
|
429
|
+
{"Courier-Oblique", 0.600},
|
430
|
+
{"Courier-Bold", 0.600},
|
431
|
+
{"Courier-BoldOblique", 0.600},
|
432
|
+
{"Symbol", 0.576},
|
433
|
+
{"Symbol", 0.576},
|
434
|
+
{"Symbol", 0.576},
|
435
|
+
{"Symbol", 0.576}
|
436
|
+
};
|
437
|
+
|
438
|
+
//------------------------------------------------------------------------
|
439
|
+
// SplashOutFontFileID
|
440
|
+
//------------------------------------------------------------------------
|
441
|
+
|
442
|
+
class SplashOutFontFileID: public SplashFontFileID {
|
443
|
+
public:
|
444
|
+
|
445
|
+
SplashOutFontFileID(Ref *rA) { r = *rA; substIdx = -1; }
|
446
|
+
|
447
|
+
~SplashOutFontFileID() {}
|
448
|
+
|
449
|
+
GBool matches(SplashFontFileID *id) {
|
450
|
+
return ((SplashOutFontFileID *)id)->r.num == r.num &&
|
451
|
+
((SplashOutFontFileID *)id)->r.gen == r.gen;
|
452
|
+
}
|
453
|
+
|
454
|
+
void setSubstIdx(int substIdxA) { substIdx = substIdxA; }
|
455
|
+
int getSubstIdx() { return substIdx; }
|
456
|
+
|
457
|
+
private:
|
458
|
+
|
459
|
+
Ref r;
|
460
|
+
int substIdx;
|
461
|
+
};
|
462
|
+
|
463
|
+
//------------------------------------------------------------------------
|
464
|
+
// T3FontCache
|
465
|
+
//------------------------------------------------------------------------
|
466
|
+
|
467
|
+
struct T3FontCacheTag {
|
468
|
+
Gushort code;
|
469
|
+
Gushort mru; // valid bit (0x8000) and MRU index
|
470
|
+
};
|
471
|
+
|
472
|
+
class T3FontCache {
|
473
|
+
public:
|
474
|
+
|
475
|
+
T3FontCache(Ref *fontID, double m11A, double m12A,
|
476
|
+
double m21A, double m22A,
|
477
|
+
int glyphXA, int glyphYA, int glyphWA, int glyphHA,
|
478
|
+
GBool aa, GBool validBBoxA);
|
479
|
+
~T3FontCache();
|
480
|
+
GBool matches(Ref *idA, double m11A, double m12A,
|
481
|
+
double m21A, double m22A)
|
482
|
+
{ return fontID.num == idA->num && fontID.gen == idA->gen &&
|
483
|
+
m11 == m11A && m12 == m12A && m21 == m21A && m22 == m22A; }
|
484
|
+
|
485
|
+
Ref fontID; // PDF font ID
|
486
|
+
double m11, m12, m21, m22; // transform matrix
|
487
|
+
int glyphX, glyphY; // pixel offset of glyph bitmaps
|
488
|
+
int glyphW, glyphH; // size of glyph bitmaps, in pixels
|
489
|
+
GBool validBBox; // false if the bbox was [0 0 0 0]
|
490
|
+
int glyphSize; // size of glyph bitmaps, in bytes
|
491
|
+
int cacheSets; // number of sets in cache
|
492
|
+
int cacheAssoc; // cache associativity (glyphs per set)
|
493
|
+
Guchar *cacheData; // glyph pixmap cache
|
494
|
+
T3FontCacheTag *cacheTags; // cache tags, i.e., char codes
|
495
|
+
};
|
496
|
+
|
497
|
+
T3FontCache::T3FontCache(Ref *fontIDA, double m11A, double m12A,
|
498
|
+
double m21A, double m22A,
|
499
|
+
int glyphXA, int glyphYA, int glyphWA, int glyphHA,
|
500
|
+
GBool validBBoxA, GBool aa) {
|
501
|
+
int i;
|
502
|
+
|
503
|
+
fontID = *fontIDA;
|
504
|
+
m11 = m11A;
|
505
|
+
m12 = m12A;
|
506
|
+
m21 = m21A;
|
507
|
+
m22 = m22A;
|
508
|
+
glyphX = glyphXA;
|
509
|
+
glyphY = glyphYA;
|
510
|
+
glyphW = glyphWA;
|
511
|
+
glyphH = glyphHA;
|
512
|
+
validBBox = validBBoxA;
|
513
|
+
if (aa) {
|
514
|
+
glyphSize = glyphW * glyphH;
|
515
|
+
} else {
|
516
|
+
glyphSize = ((glyphW + 7) >> 3) * glyphH;
|
517
|
+
}
|
518
|
+
cacheAssoc = 8;
|
519
|
+
if (glyphSize <= 256) {
|
520
|
+
cacheSets = 8;
|
521
|
+
} else if (glyphSize <= 512) {
|
522
|
+
cacheSets = 4;
|
523
|
+
} else if (glyphSize <= 1024) {
|
524
|
+
cacheSets = 2;
|
525
|
+
} else {
|
526
|
+
cacheSets = 1;
|
527
|
+
}
|
528
|
+
cacheData = (Guchar *)gmallocn(cacheSets * cacheAssoc, glyphSize);
|
529
|
+
cacheTags = (T3FontCacheTag *)gmallocn(cacheSets * cacheAssoc,
|
530
|
+
sizeof(T3FontCacheTag));
|
531
|
+
for (i = 0; i < cacheSets * cacheAssoc; ++i) {
|
532
|
+
cacheTags[i].mru = i & (cacheAssoc - 1);
|
533
|
+
}
|
534
|
+
}
|
535
|
+
|
536
|
+
T3FontCache::~T3FontCache() {
|
537
|
+
gfree(cacheData);
|
538
|
+
gfree(cacheTags);
|
539
|
+
}
|
540
|
+
|
541
|
+
struct T3GlyphStack {
|
542
|
+
Gushort code; // character code
|
543
|
+
|
544
|
+
//----- cache info
|
545
|
+
T3FontCache *cache; // font cache for the current font
|
546
|
+
T3FontCacheTag *cacheTag; // pointer to cache tag for the glyph
|
547
|
+
Guchar *cacheData; // pointer to cache data for the glyph
|
548
|
+
|
549
|
+
//----- saved state
|
550
|
+
SplashBitmap *origBitmap;
|
551
|
+
Splash *origSplash;
|
552
|
+
double origCTM4, origCTM5;
|
553
|
+
|
554
|
+
T3GlyphStack *next; // next object on stack
|
555
|
+
};
|
556
|
+
|
557
|
+
//------------------------------------------------------------------------
|
558
|
+
// SplashTransparencyGroup
|
559
|
+
//------------------------------------------------------------------------
|
560
|
+
|
561
|
+
struct SplashTransparencyGroup {
|
562
|
+
int tx, ty; // translation coordinates
|
563
|
+
SplashBitmap *tBitmap; // bitmap for transparency group
|
564
|
+
GfxColorSpace *blendingColorSpace;
|
565
|
+
GBool isolated;
|
566
|
+
|
567
|
+
//----- saved state
|
568
|
+
SplashBitmap *origBitmap;
|
569
|
+
Splash *origSplash;
|
570
|
+
|
571
|
+
SplashTransparencyGroup *next;
|
572
|
+
};
|
573
|
+
|
574
|
+
//------------------------------------------------------------------------
|
575
|
+
// SplashOutputDev
|
576
|
+
//------------------------------------------------------------------------
|
577
|
+
|
578
|
+
SplashOutputDev::SplashOutputDev(SplashColorMode colorModeA,
|
579
|
+
int bitmapRowPadA,
|
580
|
+
GBool reverseVideoA,
|
581
|
+
SplashColorPtr paperColorA,
|
582
|
+
GBool bitmapTopDownA,
|
583
|
+
GBool allowAntialiasA) {
|
584
|
+
colorMode = colorModeA;
|
585
|
+
bitmapRowPad = bitmapRowPadA;
|
586
|
+
bitmapTopDown = bitmapTopDownA;
|
587
|
+
allowAntialias = allowAntialiasA;
|
588
|
+
vectorAntialias = allowAntialias &&
|
589
|
+
globalParams->getVectorAntialias() &&
|
590
|
+
colorMode != splashModeMono1;
|
591
|
+
setupScreenParams(72.0, 72.0);
|
592
|
+
reverseVideo = reverseVideoA;
|
593
|
+
splashColorCopy(paperColor, paperColorA);
|
594
|
+
|
595
|
+
xref = NULL;
|
596
|
+
|
597
|
+
bitmap = new SplashBitmap(1, 1, bitmapRowPad, colorMode,
|
598
|
+
colorMode != splashModeMono1, bitmapTopDown);
|
599
|
+
splash = new Splash(bitmap, vectorAntialias, &screenParams);
|
600
|
+
splash->clear(paperColor, 0);
|
601
|
+
|
602
|
+
fontEngine = NULL;
|
603
|
+
|
604
|
+
nT3Fonts = 0;
|
605
|
+
t3GlyphStack = NULL;
|
606
|
+
|
607
|
+
font = NULL;
|
608
|
+
needFontUpdate = gFalse;
|
609
|
+
textClipPath = NULL;
|
610
|
+
|
611
|
+
transpGroupStack = NULL;
|
612
|
+
}
|
613
|
+
|
614
|
+
void SplashOutputDev::setupScreenParams(double hDPI, double vDPI) {
|
615
|
+
screenParams.size = globalParams->getScreenSize();
|
616
|
+
screenParams.dotRadius = globalParams->getScreenDotRadius();
|
617
|
+
screenParams.gamma = (SplashCoord)globalParams->getScreenGamma();
|
618
|
+
screenParams.blackThreshold =
|
619
|
+
(SplashCoord)globalParams->getScreenBlackThreshold();
|
620
|
+
screenParams.whiteThreshold =
|
621
|
+
(SplashCoord)globalParams->getScreenWhiteThreshold();
|
622
|
+
switch (globalParams->getScreenType()) {
|
623
|
+
case screenDispersed:
|
624
|
+
screenParams.type = splashScreenDispersed;
|
625
|
+
if (screenParams.size < 0) {
|
626
|
+
screenParams.size = 4;
|
627
|
+
}
|
628
|
+
break;
|
629
|
+
case screenClustered:
|
630
|
+
screenParams.type = splashScreenClustered;
|
631
|
+
if (screenParams.size < 0) {
|
632
|
+
screenParams.size = 10;
|
633
|
+
}
|
634
|
+
break;
|
635
|
+
case screenStochasticClustered:
|
636
|
+
screenParams.type = splashScreenStochasticClustered;
|
637
|
+
if (screenParams.size < 0) {
|
638
|
+
screenParams.size = 100;
|
639
|
+
}
|
640
|
+
if (screenParams.dotRadius < 0) {
|
641
|
+
screenParams.dotRadius = 2;
|
642
|
+
}
|
643
|
+
break;
|
644
|
+
case screenUnset:
|
645
|
+
default:
|
646
|
+
// use clustered dithering for resolution >= 300 dpi
|
647
|
+
// (compare to 299.9 to avoid floating point issues)
|
648
|
+
if (hDPI > 299.9 && vDPI > 299.9) {
|
649
|
+
screenParams.type = splashScreenStochasticClustered;
|
650
|
+
if (screenParams.size < 0) {
|
651
|
+
screenParams.size = 100;
|
652
|
+
}
|
653
|
+
if (screenParams.dotRadius < 0) {
|
654
|
+
screenParams.dotRadius = 2;
|
655
|
+
}
|
656
|
+
} else {
|
657
|
+
screenParams.type = splashScreenDispersed;
|
658
|
+
if (screenParams.size < 0) {
|
659
|
+
screenParams.size = 4;
|
660
|
+
}
|
661
|
+
}
|
662
|
+
}
|
663
|
+
}
|
664
|
+
|
665
|
+
SplashOutputDev::~SplashOutputDev() {
|
666
|
+
int i;
|
667
|
+
|
668
|
+
for (i = 0; i < nT3Fonts; ++i) {
|
669
|
+
delete t3FontCache[i];
|
670
|
+
}
|
671
|
+
if (fontEngine) {
|
672
|
+
delete fontEngine;
|
673
|
+
}
|
674
|
+
if (splash) {
|
675
|
+
delete splash;
|
676
|
+
}
|
677
|
+
if (bitmap) {
|
678
|
+
delete bitmap;
|
679
|
+
}
|
680
|
+
}
|
681
|
+
|
682
|
+
void SplashOutputDev::startDoc(XRef *xrefA) {
|
683
|
+
int i;
|
684
|
+
|
685
|
+
xref = xrefA;
|
686
|
+
if (fontEngine) {
|
687
|
+
delete fontEngine;
|
688
|
+
}
|
689
|
+
fontEngine = new SplashFontEngine(
|
690
|
+
#if HAVE_T1LIB_H
|
691
|
+
globalParams->getEnableT1lib(),
|
692
|
+
#endif
|
693
|
+
#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
|
694
|
+
globalParams->getEnableFreeType(),
|
695
|
+
#endif
|
696
|
+
allowAntialias &&
|
697
|
+
globalParams->getAntialias() &&
|
698
|
+
colorMode != splashModeMono1);
|
699
|
+
for (i = 0; i < nT3Fonts; ++i) {
|
700
|
+
delete t3FontCache[i];
|
701
|
+
}
|
702
|
+
nT3Fonts = 0;
|
703
|
+
}
|
704
|
+
|
705
|
+
void SplashOutputDev::startPage(int pageNum, GfxState *state) {
|
706
|
+
int w, h;
|
707
|
+
double *ctm;
|
708
|
+
SplashCoord mat[6];
|
709
|
+
SplashColor color;
|
710
|
+
|
711
|
+
if (state) {
|
712
|
+
setupScreenParams(state->getHDPI(), state->getVDPI());
|
713
|
+
w = (int)(state->getPageWidth() + 0.5);
|
714
|
+
if (w <= 0) {
|
715
|
+
w = 1;
|
716
|
+
}
|
717
|
+
h = (int)(state->getPageHeight() + 0.5);
|
718
|
+
if (h <= 0) {
|
719
|
+
h = 1;
|
720
|
+
}
|
721
|
+
} else {
|
722
|
+
w = h = 1;
|
723
|
+
}
|
724
|
+
if (splash) {
|
725
|
+
delete splash;
|
726
|
+
}
|
727
|
+
if (!bitmap || w != bitmap->getWidth() || h != bitmap->getHeight()) {
|
728
|
+
if (bitmap) {
|
729
|
+
delete bitmap;
|
730
|
+
}
|
731
|
+
bitmap = new SplashBitmap(w, h, bitmapRowPad, colorMode,
|
732
|
+
colorMode != splashModeMono1, bitmapTopDown);
|
733
|
+
}
|
734
|
+
splash = new Splash(bitmap, vectorAntialias, &screenParams);
|
735
|
+
if (state) {
|
736
|
+
ctm = state->getCTM();
|
737
|
+
mat[0] = (SplashCoord)ctm[0];
|
738
|
+
mat[1] = (SplashCoord)ctm[1];
|
739
|
+
mat[2] = (SplashCoord)ctm[2];
|
740
|
+
mat[3] = (SplashCoord)ctm[3];
|
741
|
+
mat[4] = (SplashCoord)ctm[4];
|
742
|
+
mat[5] = (SplashCoord)ctm[5];
|
743
|
+
splash->setMatrix(mat);
|
744
|
+
}
|
745
|
+
switch (colorMode) {
|
746
|
+
case splashModeMono1:
|
747
|
+
case splashModeMono8:
|
748
|
+
color[0] = 0;
|
749
|
+
break;
|
750
|
+
case splashModeRGB8:
|
751
|
+
case splashModeBGR8:
|
752
|
+
color[0] = color[1] = color[2] = 0;
|
753
|
+
break;
|
754
|
+
#if SPLASH_CMYK
|
755
|
+
case splashModeCMYK8:
|
756
|
+
color[0] = color[1] = color[2] = color[3] = 0;
|
757
|
+
break;
|
758
|
+
#endif
|
759
|
+
}
|
760
|
+
splash->setStrokePattern(new SplashSolidColor(color));
|
761
|
+
splash->setFillPattern(new SplashSolidColor(color));
|
762
|
+
splash->setLineCap(splashLineCapButt);
|
763
|
+
splash->setLineJoin(splashLineJoinMiter);
|
764
|
+
splash->setLineDash(NULL, 0, 0);
|
765
|
+
splash->setMiterLimit(10);
|
766
|
+
splash->setFlatness(1);
|
767
|
+
// the SA parameter supposedly defaults to false, but Acrobat
|
768
|
+
// apparently hardwires it to true
|
769
|
+
splash->setStrokeAdjust(globalParams->getStrokeAdjust());
|
770
|
+
splash->clear(paperColor, 0);
|
771
|
+
}
|
772
|
+
|
773
|
+
void SplashOutputDev::endPage() {
|
774
|
+
if (colorMode != splashModeMono1) {
|
775
|
+
splash->compositeBackground(paperColor);
|
776
|
+
}
|
777
|
+
}
|
778
|
+
|
779
|
+
void SplashOutputDev::saveState(GfxState *state) {
|
780
|
+
splash->saveState();
|
781
|
+
}
|
782
|
+
|
783
|
+
void SplashOutputDev::restoreState(GfxState *state) {
|
784
|
+
splash->restoreState();
|
785
|
+
needFontUpdate = gTrue;
|
786
|
+
}
|
787
|
+
|
788
|
+
void SplashOutputDev::updateAll(GfxState *state) {
|
789
|
+
updateLineDash(state);
|
790
|
+
updateLineJoin(state);
|
791
|
+
updateLineCap(state);
|
792
|
+
updateLineWidth(state);
|
793
|
+
updateFlatness(state);
|
794
|
+
updateMiterLimit(state);
|
795
|
+
updateStrokeAdjust(state);
|
796
|
+
updateFillColor(state);
|
797
|
+
updateStrokeColor(state);
|
798
|
+
needFontUpdate = gTrue;
|
799
|
+
}
|
800
|
+
|
801
|
+
void SplashOutputDev::updateCTM(GfxState *state, double m11, double m12,
|
802
|
+
double m21, double m22,
|
803
|
+
double m31, double m32) {
|
804
|
+
double *ctm;
|
805
|
+
SplashCoord mat[6];
|
806
|
+
|
807
|
+
ctm = state->getCTM();
|
808
|
+
mat[0] = (SplashCoord)ctm[0];
|
809
|
+
mat[1] = (SplashCoord)ctm[1];
|
810
|
+
mat[2] = (SplashCoord)ctm[2];
|
811
|
+
mat[3] = (SplashCoord)ctm[3];
|
812
|
+
mat[4] = (SplashCoord)ctm[4];
|
813
|
+
mat[5] = (SplashCoord)ctm[5];
|
814
|
+
splash->setMatrix(mat);
|
815
|
+
}
|
816
|
+
|
817
|
+
void SplashOutputDev::updateLineDash(GfxState *state) {
|
818
|
+
double *dashPattern;
|
819
|
+
int dashLength;
|
820
|
+
double dashStart;
|
821
|
+
SplashCoord dash[20];
|
822
|
+
int i;
|
823
|
+
|
824
|
+
state->getLineDash(&dashPattern, &dashLength, &dashStart);
|
825
|
+
if (dashLength > 20) {
|
826
|
+
dashLength = 20;
|
827
|
+
}
|
828
|
+
for (i = 0; i < dashLength; ++i) {
|
829
|
+
dash[i] = (SplashCoord)dashPattern[i];
|
830
|
+
if (dash[i] < 0) {
|
831
|
+
dash[i] = 0;
|
832
|
+
}
|
833
|
+
}
|
834
|
+
splash->setLineDash(dash, dashLength, (SplashCoord)dashStart);
|
835
|
+
}
|
836
|
+
|
837
|
+
void SplashOutputDev::updateFlatness(GfxState *state) {
|
838
|
+
splash->setFlatness(state->getFlatness());
|
839
|
+
}
|
840
|
+
|
841
|
+
void SplashOutputDev::updateLineJoin(GfxState *state) {
|
842
|
+
splash->setLineJoin(state->getLineJoin());
|
843
|
+
}
|
844
|
+
|
845
|
+
void SplashOutputDev::updateLineCap(GfxState *state) {
|
846
|
+
splash->setLineCap(state->getLineCap());
|
847
|
+
}
|
848
|
+
|
849
|
+
void SplashOutputDev::updateMiterLimit(GfxState *state) {
|
850
|
+
splash->setMiterLimit(state->getMiterLimit());
|
851
|
+
}
|
852
|
+
|
853
|
+
void SplashOutputDev::updateLineWidth(GfxState *state) {
|
854
|
+
splash->setLineWidth(state->getLineWidth());
|
855
|
+
}
|
856
|
+
|
857
|
+
void SplashOutputDev::updateStrokeAdjust(GfxState *state) {
|
858
|
+
#if 0 // the SA parameter supposedly defaults to false, but Acrobat
|
859
|
+
// apparently hardwires it to true
|
860
|
+
splash->setStrokeAdjust(state->getStrokeAdjust());
|
861
|
+
#endif
|
862
|
+
}
|
863
|
+
|
864
|
+
void SplashOutputDev::updateFillColor(GfxState *state) {
|
865
|
+
GfxGray gray;
|
866
|
+
GfxRGB rgb;
|
867
|
+
#if SPLASH_CMYK
|
868
|
+
GfxCMYK cmyk;
|
869
|
+
#endif
|
870
|
+
|
871
|
+
state->getFillGray(&gray);
|
872
|
+
state->getFillRGB(&rgb);
|
873
|
+
#if SPLASH_CMYK
|
874
|
+
state->getFillCMYK(&cmyk);
|
875
|
+
splash->setFillPattern(getColor(gray, &rgb, &cmyk));
|
876
|
+
#else
|
877
|
+
splash->setFillPattern(getColor(gray, &rgb));
|
878
|
+
#endif
|
879
|
+
}
|
880
|
+
|
881
|
+
void SplashOutputDev::updateStrokeColor(GfxState *state) {
|
882
|
+
GfxGray gray;
|
883
|
+
GfxRGB rgb;
|
884
|
+
#if SPLASH_CMYK
|
885
|
+
GfxCMYK cmyk;
|
886
|
+
#endif
|
887
|
+
|
888
|
+
state->getStrokeGray(&gray);
|
889
|
+
state->getStrokeRGB(&rgb);
|
890
|
+
#if SPLASH_CMYK
|
891
|
+
state->getStrokeCMYK(&cmyk);
|
892
|
+
splash->setStrokePattern(getColor(gray, &rgb, &cmyk));
|
893
|
+
#else
|
894
|
+
splash->setStrokePattern(getColor(gray, &rgb));
|
895
|
+
#endif
|
896
|
+
}
|
897
|
+
|
898
|
+
#if SPLASH_CMYK
|
899
|
+
SplashPattern *SplashOutputDev::getColor(GfxGray gray, GfxRGB *rgb,
|
900
|
+
GfxCMYK *cmyk) {
|
901
|
+
#else
|
902
|
+
SplashPattern *SplashOutputDev::getColor(GfxGray gray, GfxRGB *rgb) {
|
903
|
+
#endif
|
904
|
+
SplashPattern *pattern;
|
905
|
+
SplashColor color;
|
906
|
+
GfxColorComp r, g, b;
|
907
|
+
|
908
|
+
if (reverseVideo) {
|
909
|
+
gray = gfxColorComp1 - gray;
|
910
|
+
r = gfxColorComp1 - rgb->r;
|
911
|
+
g = gfxColorComp1 - rgb->g;
|
912
|
+
b = gfxColorComp1 - rgb->b;
|
913
|
+
} else {
|
914
|
+
r = rgb->r;
|
915
|
+
g = rgb->g;
|
916
|
+
b = rgb->b;
|
917
|
+
}
|
918
|
+
|
919
|
+
pattern = NULL; // make gcc happy
|
920
|
+
switch (colorMode) {
|
921
|
+
case splashModeMono1:
|
922
|
+
case splashModeMono8:
|
923
|
+
color[0] = colToByte(gray);
|
924
|
+
pattern = new SplashSolidColor(color);
|
925
|
+
break;
|
926
|
+
case splashModeRGB8:
|
927
|
+
case splashModeBGR8:
|
928
|
+
color[0] = colToByte(r);
|
929
|
+
color[1] = colToByte(g);
|
930
|
+
color[2] = colToByte(b);
|
931
|
+
pattern = new SplashSolidColor(color);
|
932
|
+
break;
|
933
|
+
#if SPLASH_CMYK
|
934
|
+
case splashModeCMYK8:
|
935
|
+
color[0] = colToByte(cmyk->c);
|
936
|
+
color[1] = colToByte(cmyk->m);
|
937
|
+
color[2] = colToByte(cmyk->y);
|
938
|
+
color[3] = colToByte(cmyk->k);
|
939
|
+
pattern = new SplashSolidColor(color);
|
940
|
+
break;
|
941
|
+
#endif
|
942
|
+
}
|
943
|
+
|
944
|
+
return pattern;
|
945
|
+
}
|
946
|
+
|
947
|
+
void SplashOutputDev::updateBlendMode(GfxState *state) {
|
948
|
+
splash->setBlendFunc(splashOutBlendFuncs[state->getBlendMode()]);
|
949
|
+
}
|
950
|
+
|
951
|
+
void SplashOutputDev::updateFillOpacity(GfxState *state) {
|
952
|
+
splash->setFillAlpha((SplashCoord)state->getFillOpacity());
|
953
|
+
}
|
954
|
+
|
955
|
+
void SplashOutputDev::updateStrokeOpacity(GfxState *state) {
|
956
|
+
splash->setStrokeAlpha((SplashCoord)state->getStrokeOpacity());
|
957
|
+
}
|
958
|
+
|
959
|
+
void SplashOutputDev::updateFont(GfxState *state) {
|
960
|
+
needFontUpdate = gTrue;
|
961
|
+
}
|
962
|
+
|
963
|
+
void SplashOutputDev::doUpdateFont(GfxState *state) {
|
964
|
+
GfxFont *gfxFont;
|
965
|
+
GfxFontType fontType;
|
966
|
+
SplashOutFontFileID *id;
|
967
|
+
SplashFontFile *fontFile;
|
968
|
+
FoFiTrueType *ff;
|
969
|
+
Ref embRef;
|
970
|
+
Object refObj, strObj;
|
971
|
+
GString *tmpFileName, *fileName, *substName;
|
972
|
+
FILE *tmpFile;
|
973
|
+
Gushort *codeToGID;
|
974
|
+
DisplayFontParam *dfp;
|
975
|
+
CharCodeToUnicode *ctu;
|
976
|
+
double *textMat;
|
977
|
+
double m11, m12, m21, m22, w1, w2, fontSize;
|
978
|
+
SplashCoord mat[4];
|
979
|
+
char *name;
|
980
|
+
Unicode uBuf[8];
|
981
|
+
int c, substIdx, n, code, cmap;
|
982
|
+
|
983
|
+
needFontUpdate = gFalse;
|
984
|
+
font = NULL;
|
985
|
+
tmpFileName = NULL;
|
986
|
+
substIdx = -1;
|
987
|
+
dfp = NULL;
|
988
|
+
|
989
|
+
if (!(gfxFont = state->getFont())) {
|
990
|
+
goto err1;
|
991
|
+
}
|
992
|
+
fontType = gfxFont->getType();
|
993
|
+
if (fontType == fontType3) {
|
994
|
+
goto err1;
|
995
|
+
}
|
996
|
+
|
997
|
+
// check the font file cache
|
998
|
+
id = new SplashOutFontFileID(gfxFont->getID());
|
999
|
+
if ((fontFile = fontEngine->getFontFile(id))) {
|
1000
|
+
delete id;
|
1001
|
+
|
1002
|
+
} else {
|
1003
|
+
|
1004
|
+
// if there is an embedded font, write it to disk
|
1005
|
+
if (gfxFont->getEmbeddedFontID(&embRef)) {
|
1006
|
+
if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL)) {
|
1007
|
+
error(-1, "Couldn't create temporary font file");
|
1008
|
+
goto err2;
|
1009
|
+
}
|
1010
|
+
refObj.initRef(embRef.num, embRef.gen);
|
1011
|
+
refObj.fetch(xref, &strObj);
|
1012
|
+
refObj.free();
|
1013
|
+
if (!strObj.isStream()) {
|
1014
|
+
error(-1, "Embedded font object is wrong type");
|
1015
|
+
strObj.free();
|
1016
|
+
fclose(tmpFile);
|
1017
|
+
goto err2;
|
1018
|
+
}
|
1019
|
+
strObj.streamReset();
|
1020
|
+
while ((c = strObj.streamGetChar()) != EOF) {
|
1021
|
+
fputc(c, tmpFile);
|
1022
|
+
}
|
1023
|
+
strObj.streamClose();
|
1024
|
+
strObj.free();
|
1025
|
+
fclose(tmpFile);
|
1026
|
+
fileName = tmpFileName;
|
1027
|
+
|
1028
|
+
// if there is an external font file, use it
|
1029
|
+
} else if (!(fileName = gfxFont->getExtFontFile())) {
|
1030
|
+
|
1031
|
+
// look for a display font mapping or a substitute font
|
1032
|
+
if (gfxFont->isCIDFont()) {
|
1033
|
+
if (((GfxCIDFont *)gfxFont)->getCollection()) {
|
1034
|
+
dfp = globalParams->
|
1035
|
+
getDisplayCIDFont(gfxFont->getName(),
|
1036
|
+
((GfxCIDFont *)gfxFont)->getCollection());
|
1037
|
+
}
|
1038
|
+
} else {
|
1039
|
+
if (gfxFont->getName()) {
|
1040
|
+
dfp = globalParams->getDisplayFont(gfxFont->getName());
|
1041
|
+
}
|
1042
|
+
if (!dfp) {
|
1043
|
+
// 8-bit font substitution
|
1044
|
+
if (gfxFont->isFixedWidth()) {
|
1045
|
+
substIdx = 8;
|
1046
|
+
} else if (gfxFont->isSerif()) {
|
1047
|
+
substIdx = 4;
|
1048
|
+
} else {
|
1049
|
+
substIdx = 0;
|
1050
|
+
}
|
1051
|
+
if (gfxFont->isBold()) {
|
1052
|
+
substIdx += 2;
|
1053
|
+
}
|
1054
|
+
if (gfxFont->isItalic()) {
|
1055
|
+
substIdx += 1;
|
1056
|
+
}
|
1057
|
+
substName = new GString(splashOutSubstFonts[substIdx].name);
|
1058
|
+
dfp = globalParams->getDisplayFont(substName);
|
1059
|
+
delete substName;
|
1060
|
+
id->setSubstIdx(substIdx);
|
1061
|
+
}
|
1062
|
+
}
|
1063
|
+
if (!dfp) {
|
1064
|
+
error(-1, "Couldn't find a font for '%s'",
|
1065
|
+
gfxFont->getName() ? gfxFont->getName()->getCString()
|
1066
|
+
: "(unnamed)");
|
1067
|
+
goto err2;
|
1068
|
+
}
|
1069
|
+
switch (dfp->kind) {
|
1070
|
+
case displayFontT1:
|
1071
|
+
fileName = dfp->t1.fileName;
|
1072
|
+
fontType = gfxFont->isCIDFont() ? fontCIDType0 : fontType1;
|
1073
|
+
break;
|
1074
|
+
case displayFontTT:
|
1075
|
+
fileName = dfp->tt.fileName;
|
1076
|
+
fontType = gfxFont->isCIDFont() ? fontCIDType2 : fontTrueType;
|
1077
|
+
break;
|
1078
|
+
}
|
1079
|
+
}
|
1080
|
+
|
1081
|
+
// load the font file
|
1082
|
+
switch (fontType) {
|
1083
|
+
case fontType1:
|
1084
|
+
if (!(fontFile = fontEngine->loadType1Font(
|
1085
|
+
id,
|
1086
|
+
fileName->getCString(),
|
1087
|
+
fileName == tmpFileName,
|
1088
|
+
((Gfx8BitFont *)gfxFont)->getEncoding()))) {
|
1089
|
+
error(-1, "Couldn't create a font for '%s'",
|
1090
|
+
gfxFont->getName() ? gfxFont->getName()->getCString()
|
1091
|
+
: "(unnamed)");
|
1092
|
+
goto err2;
|
1093
|
+
}
|
1094
|
+
break;
|
1095
|
+
case fontType1C:
|
1096
|
+
if (!(fontFile = fontEngine->loadType1CFont(
|
1097
|
+
id,
|
1098
|
+
fileName->getCString(),
|
1099
|
+
fileName == tmpFileName,
|
1100
|
+
((Gfx8BitFont *)gfxFont)->getEncoding()))) {
|
1101
|
+
error(-1, "Couldn't create a font for '%s'",
|
1102
|
+
gfxFont->getName() ? gfxFont->getName()->getCString()
|
1103
|
+
: "(unnamed)");
|
1104
|
+
goto err2;
|
1105
|
+
}
|
1106
|
+
break;
|
1107
|
+
case fontType1COT:
|
1108
|
+
if (!(fontFile = fontEngine->loadOpenTypeT1CFont(
|
1109
|
+
id,
|
1110
|
+
fileName->getCString(),
|
1111
|
+
fileName == tmpFileName,
|
1112
|
+
((Gfx8BitFont *)gfxFont)->getEncoding()))) {
|
1113
|
+
error(-1, "Couldn't create a font for '%s'",
|
1114
|
+
gfxFont->getName() ? gfxFont->getName()->getCString()
|
1115
|
+
: "(unnamed)");
|
1116
|
+
goto err2;
|
1117
|
+
}
|
1118
|
+
break;
|
1119
|
+
case fontTrueType:
|
1120
|
+
case fontTrueTypeOT:
|
1121
|
+
if ((ff = FoFiTrueType::load(fileName->getCString()))) {
|
1122
|
+
codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff);
|
1123
|
+
n = 256;
|
1124
|
+
delete ff;
|
1125
|
+
} else {
|
1126
|
+
codeToGID = NULL;
|
1127
|
+
n = 0;
|
1128
|
+
}
|
1129
|
+
if (!(fontFile = fontEngine->loadTrueTypeFont(
|
1130
|
+
id,
|
1131
|
+
fileName->getCString(),
|
1132
|
+
fileName == tmpFileName,
|
1133
|
+
codeToGID, n))) {
|
1134
|
+
error(-1, "Couldn't create a font for '%s'",
|
1135
|
+
gfxFont->getName() ? gfxFont->getName()->getCString()
|
1136
|
+
: "(unnamed)");
|
1137
|
+
goto err2;
|
1138
|
+
}
|
1139
|
+
break;
|
1140
|
+
case fontCIDType0:
|
1141
|
+
case fontCIDType0C:
|
1142
|
+
if (!(fontFile = fontEngine->loadCIDFont(
|
1143
|
+
id,
|
1144
|
+
fileName->getCString(),
|
1145
|
+
fileName == tmpFileName))) {
|
1146
|
+
error(-1, "Couldn't create a font for '%s'",
|
1147
|
+
gfxFont->getName() ? gfxFont->getName()->getCString()
|
1148
|
+
: "(unnamed)");
|
1149
|
+
goto err2;
|
1150
|
+
}
|
1151
|
+
break;
|
1152
|
+
case fontCIDType0COT:
|
1153
|
+
if (!(fontFile = fontEngine->loadOpenTypeCFFFont(
|
1154
|
+
id,
|
1155
|
+
fileName->getCString(),
|
1156
|
+
fileName == tmpFileName))) {
|
1157
|
+
error(-1, "Couldn't create a font for '%s'",
|
1158
|
+
gfxFont->getName() ? gfxFont->getName()->getCString()
|
1159
|
+
: "(unnamed)");
|
1160
|
+
goto err2;
|
1161
|
+
}
|
1162
|
+
break;
|
1163
|
+
case fontCIDType2:
|
1164
|
+
case fontCIDType2OT:
|
1165
|
+
codeToGID = NULL;
|
1166
|
+
n = 0;
|
1167
|
+
if (dfp) {
|
1168
|
+
// create a CID-to-GID mapping, via Unicode
|
1169
|
+
if ((ctu = ((GfxCIDFont *)gfxFont)->getToUnicode())) {
|
1170
|
+
if ((ff = FoFiTrueType::load(fileName->getCString()))) {
|
1171
|
+
// look for a Unicode cmap
|
1172
|
+
for (cmap = 0; cmap < ff->getNumCmaps(); ++cmap) {
|
1173
|
+
if ((ff->getCmapPlatform(cmap) == 3 &&
|
1174
|
+
ff->getCmapEncoding(cmap) == 1) ||
|
1175
|
+
ff->getCmapPlatform(cmap) == 0) {
|
1176
|
+
break;
|
1177
|
+
}
|
1178
|
+
}
|
1179
|
+
if (cmap < ff->getNumCmaps()) {
|
1180
|
+
// map CID -> Unicode -> GID
|
1181
|
+
n = ctu->getLength();
|
1182
|
+
codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort));
|
1183
|
+
for (code = 0; code < n; ++code) {
|
1184
|
+
if (ctu->mapToUnicode(code, uBuf, 8) > 0) {
|
1185
|
+
codeToGID[code] = ff->mapCodeToGID(cmap, uBuf[0]);
|
1186
|
+
} else {
|
1187
|
+
codeToGID[code] = 0;
|
1188
|
+
}
|
1189
|
+
}
|
1190
|
+
}
|
1191
|
+
delete ff;
|
1192
|
+
}
|
1193
|
+
ctu->decRefCnt();
|
1194
|
+
} else {
|
1195
|
+
error(-1, "Couldn't find a mapping to Unicode for font '%s'",
|
1196
|
+
gfxFont->getName() ? gfxFont->getName()->getCString()
|
1197
|
+
: "(unnamed)");
|
1198
|
+
}
|
1199
|
+
} else {
|
1200
|
+
if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
|
1201
|
+
n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
|
1202
|
+
codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort));
|
1203
|
+
memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
|
1204
|
+
n * sizeof(Gushort));
|
1205
|
+
}
|
1206
|
+
}
|
1207
|
+
if (!(fontFile = fontEngine->loadTrueTypeFont(
|
1208
|
+
id,
|
1209
|
+
fileName->getCString(),
|
1210
|
+
fileName == tmpFileName,
|
1211
|
+
codeToGID, n))) {
|
1212
|
+
error(-1, "Couldn't create a font for '%s'",
|
1213
|
+
gfxFont->getName() ? gfxFont->getName()->getCString()
|
1214
|
+
: "(unnamed)");
|
1215
|
+
goto err2;
|
1216
|
+
}
|
1217
|
+
break;
|
1218
|
+
default:
|
1219
|
+
// this shouldn't happen
|
1220
|
+
goto err2;
|
1221
|
+
}
|
1222
|
+
}
|
1223
|
+
|
1224
|
+
// get the font matrix
|
1225
|
+
textMat = state->getTextMat();
|
1226
|
+
fontSize = state->getFontSize();
|
1227
|
+
m11 = textMat[0] * fontSize * state->getHorizScaling();
|
1228
|
+
m12 = textMat[1] * fontSize * state->getHorizScaling();
|
1229
|
+
m21 = textMat[2] * fontSize;
|
1230
|
+
m22 = textMat[3] * fontSize;
|
1231
|
+
|
1232
|
+
// for substituted fonts: adjust the font matrix -- compare the
|
1233
|
+
// width of 'm' in the original font and the substituted font
|
1234
|
+
substIdx = ((SplashOutFontFileID *)fontFile->getID())->getSubstIdx();
|
1235
|
+
if (substIdx >= 0) {
|
1236
|
+
for (code = 0; code < 256; ++code) {
|
1237
|
+
if ((name = ((Gfx8BitFont *)gfxFont)->getCharName(code)) &&
|
1238
|
+
name[0] == 'm' && name[1] == '\0') {
|
1239
|
+
break;
|
1240
|
+
}
|
1241
|
+
}
|
1242
|
+
if (code < 256) {
|
1243
|
+
w1 = ((Gfx8BitFont *)gfxFont)->getWidth(code);
|
1244
|
+
w2 = splashOutSubstFonts[substIdx].mWidth;
|
1245
|
+
if (!gfxFont->isSymbolic()) {
|
1246
|
+
// if real font is substantially narrower than substituted
|
1247
|
+
// font, reduce the font size accordingly
|
1248
|
+
if (w1 > 0.01 && w1 < 0.9 * w2) {
|
1249
|
+
w1 /= w2;
|
1250
|
+
m11 *= w1;
|
1251
|
+
m21 *= w1;
|
1252
|
+
}
|
1253
|
+
}
|
1254
|
+
}
|
1255
|
+
}
|
1256
|
+
|
1257
|
+
// create the scaled font
|
1258
|
+
mat[0] = m11; mat[1] = m12;
|
1259
|
+
mat[2] = m21; mat[3] = m22;
|
1260
|
+
font = fontEngine->getFont(fontFile, mat, splash->getMatrix());
|
1261
|
+
|
1262
|
+
if (tmpFileName) {
|
1263
|
+
delete tmpFileName;
|
1264
|
+
}
|
1265
|
+
return;
|
1266
|
+
|
1267
|
+
err2:
|
1268
|
+
delete id;
|
1269
|
+
err1:
|
1270
|
+
if (tmpFileName) {
|
1271
|
+
unlink(tmpFileName->getCString());
|
1272
|
+
delete tmpFileName;
|
1273
|
+
}
|
1274
|
+
return;
|
1275
|
+
}
|
1276
|
+
|
1277
|
+
void SplashOutputDev::stroke(GfxState *state) {
|
1278
|
+
SplashPath *path;
|
1279
|
+
|
1280
|
+
if (state->getStrokeColorSpace()->isNonMarking()) {
|
1281
|
+
return;
|
1282
|
+
}
|
1283
|
+
path = convertPath(state, state->getPath());
|
1284
|
+
splash->stroke(path);
|
1285
|
+
delete path;
|
1286
|
+
}
|
1287
|
+
|
1288
|
+
void SplashOutputDev::fill(GfxState *state) {
|
1289
|
+
SplashPath *path;
|
1290
|
+
|
1291
|
+
if (state->getFillColorSpace()->isNonMarking()) {
|
1292
|
+
return;
|
1293
|
+
}
|
1294
|
+
path = convertPath(state, state->getPath());
|
1295
|
+
splash->fill(path, gFalse);
|
1296
|
+
delete path;
|
1297
|
+
}
|
1298
|
+
|
1299
|
+
void SplashOutputDev::eoFill(GfxState *state) {
|
1300
|
+
SplashPath *path;
|
1301
|
+
|
1302
|
+
if (state->getFillColorSpace()->isNonMarking()) {
|
1303
|
+
return;
|
1304
|
+
}
|
1305
|
+
path = convertPath(state, state->getPath());
|
1306
|
+
splash->fill(path, gTrue);
|
1307
|
+
delete path;
|
1308
|
+
}
|
1309
|
+
|
1310
|
+
void SplashOutputDev::clip(GfxState *state) {
|
1311
|
+
SplashPath *path;
|
1312
|
+
|
1313
|
+
path = convertPath(state, state->getPath());
|
1314
|
+
splash->clipToPath(path, gFalse);
|
1315
|
+
delete path;
|
1316
|
+
}
|
1317
|
+
|
1318
|
+
void SplashOutputDev::eoClip(GfxState *state) {
|
1319
|
+
SplashPath *path;
|
1320
|
+
|
1321
|
+
path = convertPath(state, state->getPath());
|
1322
|
+
splash->clipToPath(path, gTrue);
|
1323
|
+
delete path;
|
1324
|
+
}
|
1325
|
+
|
1326
|
+
void SplashOutputDev::clipToStrokePath(GfxState *state) {
|
1327
|
+
SplashPath *path, *path2;
|
1328
|
+
|
1329
|
+
path = convertPath(state, state->getPath());
|
1330
|
+
path2 = splash->makeStrokePath(path);
|
1331
|
+
delete path;
|
1332
|
+
splash->clipToPath(path2, gFalse);
|
1333
|
+
delete path2;
|
1334
|
+
}
|
1335
|
+
|
1336
|
+
SplashPath *SplashOutputDev::convertPath(GfxState *state, GfxPath *path) {
|
1337
|
+
SplashPath *sPath;
|
1338
|
+
GfxSubpath *subpath;
|
1339
|
+
int i, j;
|
1340
|
+
|
1341
|
+
sPath = new SplashPath();
|
1342
|
+
for (i = 0; i < path->getNumSubpaths(); ++i) {
|
1343
|
+
subpath = path->getSubpath(i);
|
1344
|
+
if (subpath->getNumPoints() > 0) {
|
1345
|
+
sPath->moveTo((SplashCoord)subpath->getX(0),
|
1346
|
+
(SplashCoord)subpath->getY(0));
|
1347
|
+
j = 1;
|
1348
|
+
while (j < subpath->getNumPoints()) {
|
1349
|
+
if (subpath->getCurve(j)) {
|
1350
|
+
sPath->curveTo((SplashCoord)subpath->getX(j),
|
1351
|
+
(SplashCoord)subpath->getY(j),
|
1352
|
+
(SplashCoord)subpath->getX(j+1),
|
1353
|
+
(SplashCoord)subpath->getY(j+1),
|
1354
|
+
(SplashCoord)subpath->getX(j+2),
|
1355
|
+
(SplashCoord)subpath->getY(j+2));
|
1356
|
+
j += 3;
|
1357
|
+
} else {
|
1358
|
+
sPath->lineTo((SplashCoord)subpath->getX(j),
|
1359
|
+
(SplashCoord)subpath->getY(j));
|
1360
|
+
++j;
|
1361
|
+
}
|
1362
|
+
}
|
1363
|
+
if (subpath->isClosed()) {
|
1364
|
+
sPath->close();
|
1365
|
+
}
|
1366
|
+
}
|
1367
|
+
}
|
1368
|
+
return sPath;
|
1369
|
+
}
|
1370
|
+
|
1371
|
+
void SplashOutputDev::drawChar(GfxState *state, double x, double y,
|
1372
|
+
double dx, double dy,
|
1373
|
+
double originX, double originY,
|
1374
|
+
CharCode code, int nBytes,
|
1375
|
+
Unicode *u, int uLen) {
|
1376
|
+
SplashPath *path;
|
1377
|
+
int render;
|
1378
|
+
|
1379
|
+
// check for invisible text -- this is used by Acrobat Capture
|
1380
|
+
render = state->getRender();
|
1381
|
+
if (render == 3) {
|
1382
|
+
return;
|
1383
|
+
}
|
1384
|
+
|
1385
|
+
if (needFontUpdate) {
|
1386
|
+
doUpdateFont(state);
|
1387
|
+
}
|
1388
|
+
if (!font) {
|
1389
|
+
return;
|
1390
|
+
}
|
1391
|
+
|
1392
|
+
x -= originX;
|
1393
|
+
y -= originY;
|
1394
|
+
|
1395
|
+
// fill
|
1396
|
+
if (!(render & 1)) {
|
1397
|
+
if (!state->getFillColorSpace()->isNonMarking()) {
|
1398
|
+
splash->fillChar((SplashCoord)x, (SplashCoord)y, code, font);
|
1399
|
+
}
|
1400
|
+
}
|
1401
|
+
|
1402
|
+
// stroke
|
1403
|
+
if ((render & 3) == 1 || (render & 3) == 2) {
|
1404
|
+
if (!state->getStrokeColorSpace()->isNonMarking()) {
|
1405
|
+
if ((path = font->getGlyphPath(code))) {
|
1406
|
+
path->offset((SplashCoord)x, (SplashCoord)y);
|
1407
|
+
splash->stroke(path);
|
1408
|
+
delete path;
|
1409
|
+
}
|
1410
|
+
}
|
1411
|
+
}
|
1412
|
+
|
1413
|
+
// clip
|
1414
|
+
if (render & 4) {
|
1415
|
+
if ((path = font->getGlyphPath(code))) {
|
1416
|
+
path->offset((SplashCoord)x, (SplashCoord)y);
|
1417
|
+
if (textClipPath) {
|
1418
|
+
textClipPath->append(path);
|
1419
|
+
delete path;
|
1420
|
+
} else {
|
1421
|
+
textClipPath = path;
|
1422
|
+
}
|
1423
|
+
}
|
1424
|
+
}
|
1425
|
+
}
|
1426
|
+
|
1427
|
+
GBool SplashOutputDev::beginType3Char(GfxState *state, double x, double y,
|
1428
|
+
double dx, double dy,
|
1429
|
+
CharCode code, Unicode *u, int uLen) {
|
1430
|
+
GfxFont *gfxFont;
|
1431
|
+
Ref *fontID;
|
1432
|
+
double *ctm, *bbox;
|
1433
|
+
T3FontCache *t3Font;
|
1434
|
+
T3GlyphStack *t3gs;
|
1435
|
+
GBool validBBox;
|
1436
|
+
double x1, y1, xMin, yMin, xMax, yMax, xt, yt;
|
1437
|
+
int i, j;
|
1438
|
+
|
1439
|
+
if (!(gfxFont = state->getFont())) {
|
1440
|
+
return gFalse;
|
1441
|
+
}
|
1442
|
+
fontID = gfxFont->getID();
|
1443
|
+
ctm = state->getCTM();
|
1444
|
+
state->transform(0, 0, &xt, &yt);
|
1445
|
+
|
1446
|
+
// is it the first (MRU) font in the cache?
|
1447
|
+
if (!(nT3Fonts > 0 &&
|
1448
|
+
t3FontCache[0]->matches(fontID, ctm[0], ctm[1], ctm[2], ctm[3]))) {
|
1449
|
+
|
1450
|
+
// is the font elsewhere in the cache?
|
1451
|
+
for (i = 1; i < nT3Fonts; ++i) {
|
1452
|
+
if (t3FontCache[i]->matches(fontID, ctm[0], ctm[1], ctm[2], ctm[3])) {
|
1453
|
+
t3Font = t3FontCache[i];
|
1454
|
+
for (j = i; j > 0; --j) {
|
1455
|
+
t3FontCache[j] = t3FontCache[j - 1];
|
1456
|
+
}
|
1457
|
+
t3FontCache[0] = t3Font;
|
1458
|
+
break;
|
1459
|
+
}
|
1460
|
+
}
|
1461
|
+
if (i >= nT3Fonts) {
|
1462
|
+
|
1463
|
+
// create new entry in the font cache
|
1464
|
+
if (nT3Fonts == splashOutT3FontCacheSize) {
|
1465
|
+
delete t3FontCache[nT3Fonts - 1];
|
1466
|
+
--nT3Fonts;
|
1467
|
+
}
|
1468
|
+
for (j = nT3Fonts; j > 0; --j) {
|
1469
|
+
t3FontCache[j] = t3FontCache[j - 1];
|
1470
|
+
}
|
1471
|
+
++nT3Fonts;
|
1472
|
+
bbox = gfxFont->getFontBBox();
|
1473
|
+
if (bbox[0] == 0 && bbox[1] == 0 && bbox[2] == 0 && bbox[3] == 0) {
|
1474
|
+
// unspecified bounding box -- just take a guess
|
1475
|
+
xMin = xt - 5;
|
1476
|
+
xMax = xMin + 30;
|
1477
|
+
yMax = yt + 15;
|
1478
|
+
yMin = yMax - 45;
|
1479
|
+
validBBox = gFalse;
|
1480
|
+
} else {
|
1481
|
+
state->transform(bbox[0], bbox[1], &x1, &y1);
|
1482
|
+
xMin = xMax = x1;
|
1483
|
+
yMin = yMax = y1;
|
1484
|
+
state->transform(bbox[0], bbox[3], &x1, &y1);
|
1485
|
+
if (x1 < xMin) {
|
1486
|
+
xMin = x1;
|
1487
|
+
} else if (x1 > xMax) {
|
1488
|
+
xMax = x1;
|
1489
|
+
}
|
1490
|
+
if (y1 < yMin) {
|
1491
|
+
yMin = y1;
|
1492
|
+
} else if (y1 > yMax) {
|
1493
|
+
yMax = y1;
|
1494
|
+
}
|
1495
|
+
state->transform(bbox[2], bbox[1], &x1, &y1);
|
1496
|
+
if (x1 < xMin) {
|
1497
|
+
xMin = x1;
|
1498
|
+
} else if (x1 > xMax) {
|
1499
|
+
xMax = x1;
|
1500
|
+
}
|
1501
|
+
if (y1 < yMin) {
|
1502
|
+
yMin = y1;
|
1503
|
+
} else if (y1 > yMax) {
|
1504
|
+
yMax = y1;
|
1505
|
+
}
|
1506
|
+
state->transform(bbox[2], bbox[3], &x1, &y1);
|
1507
|
+
if (x1 < xMin) {
|
1508
|
+
xMin = x1;
|
1509
|
+
} else if (x1 > xMax) {
|
1510
|
+
xMax = x1;
|
1511
|
+
}
|
1512
|
+
if (y1 < yMin) {
|
1513
|
+
yMin = y1;
|
1514
|
+
} else if (y1 > yMax) {
|
1515
|
+
yMax = y1;
|
1516
|
+
}
|
1517
|
+
validBBox = gTrue;
|
1518
|
+
}
|
1519
|
+
t3FontCache[0] = new T3FontCache(fontID, ctm[0], ctm[1], ctm[2], ctm[3],
|
1520
|
+
(int)floor(xMin - xt),
|
1521
|
+
(int)floor(yMin - yt),
|
1522
|
+
(int)ceil(xMax) - (int)floor(xMin) + 3,
|
1523
|
+
(int)ceil(yMax) - (int)floor(yMin) + 3,
|
1524
|
+
validBBox,
|
1525
|
+
colorMode != splashModeMono1);
|
1526
|
+
}
|
1527
|
+
}
|
1528
|
+
t3Font = t3FontCache[0];
|
1529
|
+
|
1530
|
+
// is the glyph in the cache?
|
1531
|
+
i = (code & (t3Font->cacheSets - 1)) * t3Font->cacheAssoc;
|
1532
|
+
for (j = 0; j < t3Font->cacheAssoc; ++j) {
|
1533
|
+
if ((t3Font->cacheTags[i+j].mru & 0x8000) &&
|
1534
|
+
t3Font->cacheTags[i+j].code == code) {
|
1535
|
+
drawType3Glyph(t3Font, &t3Font->cacheTags[i+j],
|
1536
|
+
t3Font->cacheData + (i+j) * t3Font->glyphSize);
|
1537
|
+
return gTrue;
|
1538
|
+
}
|
1539
|
+
}
|
1540
|
+
|
1541
|
+
// push a new Type 3 glyph record
|
1542
|
+
t3gs = new T3GlyphStack();
|
1543
|
+
t3gs->next = t3GlyphStack;
|
1544
|
+
t3GlyphStack = t3gs;
|
1545
|
+
t3GlyphStack->code = code;
|
1546
|
+
t3GlyphStack->cache = t3Font;
|
1547
|
+
t3GlyphStack->cacheTag = NULL;
|
1548
|
+
t3GlyphStack->cacheData = NULL;
|
1549
|
+
|
1550
|
+
return gFalse;
|
1551
|
+
}
|
1552
|
+
|
1553
|
+
void SplashOutputDev::endType3Char(GfxState *state) {
|
1554
|
+
T3GlyphStack *t3gs;
|
1555
|
+
double *ctm;
|
1556
|
+
|
1557
|
+
if (t3GlyphStack->cacheTag) {
|
1558
|
+
memcpy(t3GlyphStack->cacheData, bitmap->getDataPtr(),
|
1559
|
+
t3GlyphStack->cache->glyphSize);
|
1560
|
+
delete bitmap;
|
1561
|
+
delete splash;
|
1562
|
+
bitmap = t3GlyphStack->origBitmap;
|
1563
|
+
splash = t3GlyphStack->origSplash;
|
1564
|
+
ctm = state->getCTM();
|
1565
|
+
state->setCTM(ctm[0], ctm[1], ctm[2], ctm[3],
|
1566
|
+
t3GlyphStack->origCTM4, t3GlyphStack->origCTM5);
|
1567
|
+
updateCTM(state, 0, 0, 0, 0, 0, 0);
|
1568
|
+
drawType3Glyph(t3GlyphStack->cache,
|
1569
|
+
t3GlyphStack->cacheTag, t3GlyphStack->cacheData);
|
1570
|
+
}
|
1571
|
+
t3gs = t3GlyphStack;
|
1572
|
+
t3GlyphStack = t3gs->next;
|
1573
|
+
delete t3gs;
|
1574
|
+
}
|
1575
|
+
|
1576
|
+
void SplashOutputDev::type3D0(GfxState *state, double wx, double wy) {
|
1577
|
+
}
|
1578
|
+
|
1579
|
+
void SplashOutputDev::type3D1(GfxState *state, double wx, double wy,
|
1580
|
+
double llx, double lly, double urx, double ury) {
|
1581
|
+
double *ctm;
|
1582
|
+
T3FontCache *t3Font;
|
1583
|
+
SplashColor color;
|
1584
|
+
double xt, yt, xMin, xMax, yMin, yMax, x1, y1;
|
1585
|
+
int i, j;
|
1586
|
+
|
1587
|
+
t3Font = t3GlyphStack->cache;
|
1588
|
+
|
1589
|
+
// check for a valid bbox
|
1590
|
+
state->transform(0, 0, &xt, &yt);
|
1591
|
+
state->transform(llx, lly, &x1, &y1);
|
1592
|
+
xMin = xMax = x1;
|
1593
|
+
yMin = yMax = y1;
|
1594
|
+
state->transform(llx, ury, &x1, &y1);
|
1595
|
+
if (x1 < xMin) {
|
1596
|
+
xMin = x1;
|
1597
|
+
} else if (x1 > xMax) {
|
1598
|
+
xMax = x1;
|
1599
|
+
}
|
1600
|
+
if (y1 < yMin) {
|
1601
|
+
yMin = y1;
|
1602
|
+
} else if (y1 > yMax) {
|
1603
|
+
yMax = y1;
|
1604
|
+
}
|
1605
|
+
state->transform(urx, lly, &x1, &y1);
|
1606
|
+
if (x1 < xMin) {
|
1607
|
+
xMin = x1;
|
1608
|
+
} else if (x1 > xMax) {
|
1609
|
+
xMax = x1;
|
1610
|
+
}
|
1611
|
+
if (y1 < yMin) {
|
1612
|
+
yMin = y1;
|
1613
|
+
} else if (y1 > yMax) {
|
1614
|
+
yMax = y1;
|
1615
|
+
}
|
1616
|
+
state->transform(urx, ury, &x1, &y1);
|
1617
|
+
if (x1 < xMin) {
|
1618
|
+
xMin = x1;
|
1619
|
+
} else if (x1 > xMax) {
|
1620
|
+
xMax = x1;
|
1621
|
+
}
|
1622
|
+
if (y1 < yMin) {
|
1623
|
+
yMin = y1;
|
1624
|
+
} else if (y1 > yMax) {
|
1625
|
+
yMax = y1;
|
1626
|
+
}
|
1627
|
+
if (xMin - xt < t3Font->glyphX ||
|
1628
|
+
yMin - yt < t3Font->glyphY ||
|
1629
|
+
xMax - xt > t3Font->glyphX + t3Font->glyphW ||
|
1630
|
+
yMax - yt > t3Font->glyphY + t3Font->glyphH) {
|
1631
|
+
if (t3Font->validBBox) {
|
1632
|
+
error(-1, "Bad bounding box in Type 3 glyph");
|
1633
|
+
}
|
1634
|
+
return;
|
1635
|
+
}
|
1636
|
+
|
1637
|
+
// allocate a cache entry
|
1638
|
+
i = (t3GlyphStack->code & (t3Font->cacheSets - 1)) * t3Font->cacheAssoc;
|
1639
|
+
for (j = 0; j < t3Font->cacheAssoc; ++j) {
|
1640
|
+
if ((t3Font->cacheTags[i+j].mru & 0x7fff) == t3Font->cacheAssoc - 1) {
|
1641
|
+
t3Font->cacheTags[i+j].mru = 0x8000;
|
1642
|
+
t3Font->cacheTags[i+j].code = t3GlyphStack->code;
|
1643
|
+
t3GlyphStack->cacheTag = &t3Font->cacheTags[i+j];
|
1644
|
+
t3GlyphStack->cacheData = t3Font->cacheData + (i+j) * t3Font->glyphSize;
|
1645
|
+
} else {
|
1646
|
+
++t3Font->cacheTags[i+j].mru;
|
1647
|
+
}
|
1648
|
+
}
|
1649
|
+
|
1650
|
+
// save state
|
1651
|
+
t3GlyphStack->origBitmap = bitmap;
|
1652
|
+
t3GlyphStack->origSplash = splash;
|
1653
|
+
ctm = state->getCTM();
|
1654
|
+
t3GlyphStack->origCTM4 = ctm[4];
|
1655
|
+
t3GlyphStack->origCTM5 = ctm[5];
|
1656
|
+
|
1657
|
+
// create the temporary bitmap
|
1658
|
+
if (colorMode == splashModeMono1) {
|
1659
|
+
bitmap = new SplashBitmap(t3Font->glyphW, t3Font->glyphH, 1,
|
1660
|
+
splashModeMono1, gFalse);
|
1661
|
+
splash = new Splash(bitmap, gFalse,
|
1662
|
+
t3GlyphStack->origSplash->getScreen());
|
1663
|
+
color[0] = 0;
|
1664
|
+
splash->clear(color);
|
1665
|
+
color[0] = 1;
|
1666
|
+
} else {
|
1667
|
+
bitmap = new SplashBitmap(t3Font->glyphW, t3Font->glyphH, 1,
|
1668
|
+
splashModeMono8, gFalse);
|
1669
|
+
splash = new Splash(bitmap, vectorAntialias,
|
1670
|
+
t3GlyphStack->origSplash->getScreen());
|
1671
|
+
color[0] = 0x00;
|
1672
|
+
splash->clear(color);
|
1673
|
+
color[0] = 0xff;
|
1674
|
+
}
|
1675
|
+
splash->setFillPattern(new SplashSolidColor(color));
|
1676
|
+
splash->setStrokePattern(new SplashSolidColor(color));
|
1677
|
+
//~ this should copy other state from t3GlyphStack->origSplash?
|
1678
|
+
state->setCTM(ctm[0], ctm[1], ctm[2], ctm[3],
|
1679
|
+
-t3Font->glyphX, -t3Font->glyphY);
|
1680
|
+
updateCTM(state, 0, 0, 0, 0, 0, 0);
|
1681
|
+
}
|
1682
|
+
|
1683
|
+
void SplashOutputDev::drawType3Glyph(T3FontCache *t3Font,
|
1684
|
+
T3FontCacheTag *tag, Guchar *data) {
|
1685
|
+
SplashGlyphBitmap glyph;
|
1686
|
+
|
1687
|
+
glyph.x = -t3Font->glyphX;
|
1688
|
+
glyph.y = -t3Font->glyphY;
|
1689
|
+
glyph.w = t3Font->glyphW;
|
1690
|
+
glyph.h = t3Font->glyphH;
|
1691
|
+
glyph.aa = colorMode != splashModeMono1;
|
1692
|
+
glyph.data = data;
|
1693
|
+
glyph.freeData = gFalse;
|
1694
|
+
splash->fillGlyph(0, 0, &glyph);
|
1695
|
+
}
|
1696
|
+
|
1697
|
+
void SplashOutputDev::endTextObject(GfxState *state) {
|
1698
|
+
if (textClipPath) {
|
1699
|
+
splash->clipToPath(textClipPath, gFalse);
|
1700
|
+
delete textClipPath;
|
1701
|
+
textClipPath = NULL;
|
1702
|
+
}
|
1703
|
+
}
|
1704
|
+
|
1705
|
+
struct SplashOutImageMaskData {
|
1706
|
+
ImageStream *imgStr;
|
1707
|
+
GBool invert;
|
1708
|
+
int width, height, y;
|
1709
|
+
};
|
1710
|
+
|
1711
|
+
GBool SplashOutputDev::imageMaskSrc(void *data, SplashColorPtr line) {
|
1712
|
+
SplashOutImageMaskData *imgMaskData = (SplashOutImageMaskData *)data;
|
1713
|
+
Guchar *p;
|
1714
|
+
SplashColorPtr q;
|
1715
|
+
int x;
|
1716
|
+
|
1717
|
+
if (imgMaskData->y == imgMaskData->height) {
|
1718
|
+
return gFalse;
|
1719
|
+
}
|
1720
|
+
for (x = 0, p = imgMaskData->imgStr->getLine(), q = line;
|
1721
|
+
x < imgMaskData->width;
|
1722
|
+
++x) {
|
1723
|
+
*q++ = *p++ ^ imgMaskData->invert;
|
1724
|
+
}
|
1725
|
+
++imgMaskData->y;
|
1726
|
+
return gTrue;
|
1727
|
+
}
|
1728
|
+
|
1729
|
+
void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
|
1730
|
+
int width, int height, GBool invert,
|
1731
|
+
GBool inlineImg) {
|
1732
|
+
double *ctm;
|
1733
|
+
SplashCoord mat[6];
|
1734
|
+
SplashOutImageMaskData imgMaskData;
|
1735
|
+
|
1736
|
+
if (state->getFillColorSpace()->isNonMarking()) {
|
1737
|
+
return;
|
1738
|
+
}
|
1739
|
+
|
1740
|
+
ctm = state->getCTM();
|
1741
|
+
mat[0] = ctm[0];
|
1742
|
+
mat[1] = ctm[1];
|
1743
|
+
mat[2] = -ctm[2];
|
1744
|
+
mat[3] = -ctm[3];
|
1745
|
+
mat[4] = ctm[2] + ctm[4];
|
1746
|
+
mat[5] = ctm[3] + ctm[5];
|
1747
|
+
|
1748
|
+
imgMaskData.imgStr = new ImageStream(str, width, 1, 1);
|
1749
|
+
imgMaskData.imgStr->reset();
|
1750
|
+
imgMaskData.invert = invert ? 0 : 1;
|
1751
|
+
imgMaskData.width = width;
|
1752
|
+
imgMaskData.height = height;
|
1753
|
+
imgMaskData.y = 0;
|
1754
|
+
|
1755
|
+
splash->fillImageMask(&imageMaskSrc, &imgMaskData, width, height, mat,
|
1756
|
+
t3GlyphStack != NULL);
|
1757
|
+
if (inlineImg) {
|
1758
|
+
while (imgMaskData.y < height) {
|
1759
|
+
imgMaskData.imgStr->getLine();
|
1760
|
+
++imgMaskData.y;
|
1761
|
+
}
|
1762
|
+
}
|
1763
|
+
|
1764
|
+
delete imgMaskData.imgStr;
|
1765
|
+
str->close();
|
1766
|
+
}
|
1767
|
+
|
1768
|
+
struct SplashOutImageData {
|
1769
|
+
ImageStream *imgStr;
|
1770
|
+
GfxImageColorMap *colorMap;
|
1771
|
+
SplashColorPtr lookup;
|
1772
|
+
int *maskColors;
|
1773
|
+
SplashColorMode colorMode;
|
1774
|
+
int width, height, y;
|
1775
|
+
};
|
1776
|
+
|
1777
|
+
GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr colorLine,
|
1778
|
+
Guchar *alphaLine) {
|
1779
|
+
SplashOutImageData *imgData = (SplashOutImageData *)data;
|
1780
|
+
Guchar *p;
|
1781
|
+
SplashColorPtr q, col;
|
1782
|
+
GfxRGB rgb;
|
1783
|
+
GfxGray gray;
|
1784
|
+
#if SPLASH_CMYK
|
1785
|
+
GfxCMYK cmyk;
|
1786
|
+
#endif
|
1787
|
+
int nComps, x;
|
1788
|
+
|
1789
|
+
if (imgData->y == imgData->height) {
|
1790
|
+
return gFalse;
|
1791
|
+
}
|
1792
|
+
|
1793
|
+
nComps = imgData->colorMap->getNumPixelComps();
|
1794
|
+
|
1795
|
+
if (imgData->lookup) {
|
1796
|
+
switch (imgData->colorMode) {
|
1797
|
+
case splashModeMono1:
|
1798
|
+
case splashModeMono8:
|
1799
|
+
for (x = 0, p = imgData->imgStr->getLine(), q = colorLine;
|
1800
|
+
x < imgData->width;
|
1801
|
+
++x, ++p) {
|
1802
|
+
*q++ = imgData->lookup[*p];
|
1803
|
+
}
|
1804
|
+
break;
|
1805
|
+
case splashModeRGB8:
|
1806
|
+
case splashModeBGR8:
|
1807
|
+
for (x = 0, p = imgData->imgStr->getLine(), q = colorLine;
|
1808
|
+
x < imgData->width;
|
1809
|
+
++x, ++p) {
|
1810
|
+
col = &imgData->lookup[3 * *p];
|
1811
|
+
*q++ = col[0];
|
1812
|
+
*q++ = col[1];
|
1813
|
+
*q++ = col[2];
|
1814
|
+
}
|
1815
|
+
break;
|
1816
|
+
#if SPLASH_CMYK
|
1817
|
+
case splashModeCMYK8:
|
1818
|
+
for (x = 0, p = imgData->imgStr->getLine(), q = colorLine;
|
1819
|
+
x < imgData->width;
|
1820
|
+
++x, ++p) {
|
1821
|
+
col = &imgData->lookup[4 * *p];
|
1822
|
+
*q++ = col[0];
|
1823
|
+
*q++ = col[1];
|
1824
|
+
*q++ = col[2];
|
1825
|
+
*q++ = col[3];
|
1826
|
+
}
|
1827
|
+
break;
|
1828
|
+
#endif
|
1829
|
+
}
|
1830
|
+
} else {
|
1831
|
+
switch (imgData->colorMode) {
|
1832
|
+
case splashModeMono1:
|
1833
|
+
case splashModeMono8:
|
1834
|
+
for (x = 0, p = imgData->imgStr->getLine(), q = colorLine;
|
1835
|
+
x < imgData->width;
|
1836
|
+
++x, p += nComps) {
|
1837
|
+
imgData->colorMap->getGray(p, &gray);
|
1838
|
+
*q++ = colToByte(gray);
|
1839
|
+
}
|
1840
|
+
break;
|
1841
|
+
case splashModeRGB8:
|
1842
|
+
case splashModeBGR8:
|
1843
|
+
for (x = 0, p = imgData->imgStr->getLine(), q = colorLine;
|
1844
|
+
x < imgData->width;
|
1845
|
+
++x, p += nComps) {
|
1846
|
+
imgData->colorMap->getRGB(p, &rgb);
|
1847
|
+
*q++ = colToByte(rgb.r);
|
1848
|
+
*q++ = colToByte(rgb.g);
|
1849
|
+
*q++ = colToByte(rgb.b);
|
1850
|
+
}
|
1851
|
+
break;
|
1852
|
+
#if SPLASH_CMYK
|
1853
|
+
case splashModeCMYK8:
|
1854
|
+
for (x = 0, p = imgData->imgStr->getLine(), q = colorLine;
|
1855
|
+
x < imgData->width;
|
1856
|
+
++x, p += nComps) {
|
1857
|
+
imgData->colorMap->getCMYK(p, &cmyk);
|
1858
|
+
*q++ = colToByte(cmyk.c);
|
1859
|
+
*q++ = colToByte(cmyk.m);
|
1860
|
+
*q++ = colToByte(cmyk.y);
|
1861
|
+
*q++ = colToByte(cmyk.k);
|
1862
|
+
}
|
1863
|
+
break;
|
1864
|
+
#endif
|
1865
|
+
}
|
1866
|
+
}
|
1867
|
+
|
1868
|
+
++imgData->y;
|
1869
|
+
return gTrue;
|
1870
|
+
}
|
1871
|
+
|
1872
|
+
GBool SplashOutputDev::alphaImageSrc(void *data, SplashColorPtr colorLine,
|
1873
|
+
Guchar *alphaLine) {
|
1874
|
+
SplashOutImageData *imgData = (SplashOutImageData *)data;
|
1875
|
+
Guchar *p, *aq;
|
1876
|
+
SplashColorPtr q, col;
|
1877
|
+
GfxRGB rgb;
|
1878
|
+
GfxGray gray;
|
1879
|
+
#if SPLASH_CMYK
|
1880
|
+
GfxCMYK cmyk;
|
1881
|
+
#endif
|
1882
|
+
Guchar alpha;
|
1883
|
+
int nComps, x, i;
|
1884
|
+
|
1885
|
+
if (imgData->y == imgData->height) {
|
1886
|
+
return gFalse;
|
1887
|
+
}
|
1888
|
+
|
1889
|
+
nComps = imgData->colorMap->getNumPixelComps();
|
1890
|
+
|
1891
|
+
for (x = 0, p = imgData->imgStr->getLine(), q = colorLine, aq = alphaLine;
|
1892
|
+
x < imgData->width;
|
1893
|
+
++x, p += nComps) {
|
1894
|
+
alpha = 0;
|
1895
|
+
for (i = 0; i < nComps; ++i) {
|
1896
|
+
if (p[i] < imgData->maskColors[2*i] ||
|
1897
|
+
p[i] > imgData->maskColors[2*i+1]) {
|
1898
|
+
alpha = 0xff;
|
1899
|
+
break;
|
1900
|
+
}
|
1901
|
+
}
|
1902
|
+
if (imgData->lookup) {
|
1903
|
+
switch (imgData->colorMode) {
|
1904
|
+
case splashModeMono1:
|
1905
|
+
case splashModeMono8:
|
1906
|
+
*q++ = imgData->lookup[*p];
|
1907
|
+
*aq++ = alpha;
|
1908
|
+
break;
|
1909
|
+
case splashModeRGB8:
|
1910
|
+
case splashModeBGR8:
|
1911
|
+
col = &imgData->lookup[3 * *p];
|
1912
|
+
*q++ = col[0];
|
1913
|
+
*q++ = col[1];
|
1914
|
+
*q++ = col[2];
|
1915
|
+
*aq++ = alpha;
|
1916
|
+
break;
|
1917
|
+
#if SPLASH_CMYK
|
1918
|
+
case splashModeCMYK8:
|
1919
|
+
col = &imgData->lookup[4 * *p];
|
1920
|
+
*q++ = col[0];
|
1921
|
+
*q++ = col[1];
|
1922
|
+
*q++ = col[2];
|
1923
|
+
*q++ = col[3];
|
1924
|
+
*aq++ = alpha;
|
1925
|
+
break;
|
1926
|
+
#endif
|
1927
|
+
}
|
1928
|
+
} else {
|
1929
|
+
switch (imgData->colorMode) {
|
1930
|
+
case splashModeMono1:
|
1931
|
+
case splashModeMono8:
|
1932
|
+
imgData->colorMap->getGray(p, &gray);
|
1933
|
+
*q++ = colToByte(gray);
|
1934
|
+
*aq++ = alpha;
|
1935
|
+
break;
|
1936
|
+
case splashModeRGB8:
|
1937
|
+
case splashModeBGR8:
|
1938
|
+
imgData->colorMap->getRGB(p, &rgb);
|
1939
|
+
*q++ = colToByte(rgb.r);
|
1940
|
+
*q++ = colToByte(rgb.g);
|
1941
|
+
*q++ = colToByte(rgb.b);
|
1942
|
+
*aq++ = alpha;
|
1943
|
+
break;
|
1944
|
+
#if SPLASH_CMYK
|
1945
|
+
case splashModeCMYK8:
|
1946
|
+
imgData->colorMap->getCMYK(p, &cmyk);
|
1947
|
+
*q++ = colToByte(cmyk.c);
|
1948
|
+
*q++ = colToByte(cmyk.m);
|
1949
|
+
*q++ = colToByte(cmyk.y);
|
1950
|
+
*q++ = colToByte(cmyk.k);
|
1951
|
+
*aq++ = alpha;
|
1952
|
+
break;
|
1953
|
+
#endif
|
1954
|
+
}
|
1955
|
+
}
|
1956
|
+
}
|
1957
|
+
|
1958
|
+
++imgData->y;
|
1959
|
+
return gTrue;
|
1960
|
+
}
|
1961
|
+
|
1962
|
+
void SplashOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
|
1963
|
+
int width, int height,
|
1964
|
+
GfxImageColorMap *colorMap,
|
1965
|
+
int *maskColors, GBool inlineImg) {
|
1966
|
+
double *ctm;
|
1967
|
+
SplashCoord mat[6];
|
1968
|
+
SplashOutImageData imgData;
|
1969
|
+
SplashColorMode srcMode;
|
1970
|
+
SplashImageSource src;
|
1971
|
+
GfxGray gray;
|
1972
|
+
GfxRGB rgb;
|
1973
|
+
#if SPLASH_CMYK
|
1974
|
+
GfxCMYK cmyk;
|
1975
|
+
#endif
|
1976
|
+
Guchar pix;
|
1977
|
+
int n, i;
|
1978
|
+
|
1979
|
+
ctm = state->getCTM();
|
1980
|
+
mat[0] = ctm[0];
|
1981
|
+
mat[1] = ctm[1];
|
1982
|
+
mat[2] = -ctm[2];
|
1983
|
+
mat[3] = -ctm[3];
|
1984
|
+
mat[4] = ctm[2] + ctm[4];
|
1985
|
+
mat[5] = ctm[3] + ctm[5];
|
1986
|
+
|
1987
|
+
imgData.imgStr = new ImageStream(str, width,
|
1988
|
+
colorMap->getNumPixelComps(),
|
1989
|
+
colorMap->getBits());
|
1990
|
+
imgData.imgStr->reset();
|
1991
|
+
imgData.colorMap = colorMap;
|
1992
|
+
imgData.maskColors = maskColors;
|
1993
|
+
imgData.colorMode = colorMode;
|
1994
|
+
imgData.width = width;
|
1995
|
+
imgData.height = height;
|
1996
|
+
imgData.y = 0;
|
1997
|
+
|
1998
|
+
// special case for one-channel (monochrome/gray/separation) images:
|
1999
|
+
// build a lookup table here
|
2000
|
+
imgData.lookup = NULL;
|
2001
|
+
if (colorMap->getNumPixelComps() == 1) {
|
2002
|
+
n = 1 << colorMap->getBits();
|
2003
|
+
switch (colorMode) {
|
2004
|
+
case splashModeMono1:
|
2005
|
+
case splashModeMono8:
|
2006
|
+
imgData.lookup = (SplashColorPtr)gmalloc(n);
|
2007
|
+
for (i = 0; i < n; ++i) {
|
2008
|
+
pix = (Guchar)i;
|
2009
|
+
colorMap->getGray(&pix, &gray);
|
2010
|
+
imgData.lookup[i] = colToByte(gray);
|
2011
|
+
}
|
2012
|
+
break;
|
2013
|
+
case splashModeRGB8:
|
2014
|
+
case splashModeBGR8:
|
2015
|
+
imgData.lookup = (SplashColorPtr)gmalloc(3 * n);
|
2016
|
+
for (i = 0; i < n; ++i) {
|
2017
|
+
pix = (Guchar)i;
|
2018
|
+
colorMap->getRGB(&pix, &rgb);
|
2019
|
+
imgData.lookup[3*i] = colToByte(rgb.r);
|
2020
|
+
imgData.lookup[3*i+1] = colToByte(rgb.g);
|
2021
|
+
imgData.lookup[3*i+2] = colToByte(rgb.b);
|
2022
|
+
}
|
2023
|
+
break;
|
2024
|
+
#if SPLASH_CMYK
|
2025
|
+
case splashModeCMYK8:
|
2026
|
+
imgData.lookup = (SplashColorPtr)gmalloc(4 * n);
|
2027
|
+
for (i = 0; i < n; ++i) {
|
2028
|
+
pix = (Guchar)i;
|
2029
|
+
colorMap->getCMYK(&pix, &cmyk);
|
2030
|
+
imgData.lookup[4*i] = colToByte(cmyk.c);
|
2031
|
+
imgData.lookup[4*i+1] = colToByte(cmyk.m);
|
2032
|
+
imgData.lookup[4*i+2] = colToByte(cmyk.y);
|
2033
|
+
imgData.lookup[4*i+3] = colToByte(cmyk.k);
|
2034
|
+
}
|
2035
|
+
break;
|
2036
|
+
#endif
|
2037
|
+
break;
|
2038
|
+
}
|
2039
|
+
}
|
2040
|
+
|
2041
|
+
if (colorMode == splashModeMono1) {
|
2042
|
+
srcMode = splashModeMono8;
|
2043
|
+
} else {
|
2044
|
+
srcMode = colorMode;
|
2045
|
+
}
|
2046
|
+
src = maskColors ? &alphaImageSrc : &imageSrc;
|
2047
|
+
splash->drawImage(src, &imgData, srcMode, maskColors ? gTrue : gFalse,
|
2048
|
+
width, height, mat);
|
2049
|
+
if (inlineImg) {
|
2050
|
+
while (imgData.y < height) {
|
2051
|
+
imgData.imgStr->getLine();
|
2052
|
+
++imgData.y;
|
2053
|
+
}
|
2054
|
+
}
|
2055
|
+
|
2056
|
+
gfree(imgData.lookup);
|
2057
|
+
delete imgData.imgStr;
|
2058
|
+
str->close();
|
2059
|
+
}
|
2060
|
+
|
2061
|
+
struct SplashOutMaskedImageData {
|
2062
|
+
ImageStream *imgStr;
|
2063
|
+
GfxImageColorMap *colorMap;
|
2064
|
+
SplashBitmap *mask;
|
2065
|
+
SplashColorPtr lookup;
|
2066
|
+
SplashColorMode colorMode;
|
2067
|
+
int width, height, y;
|
2068
|
+
};
|
2069
|
+
|
2070
|
+
GBool SplashOutputDev::maskedImageSrc(void *data, SplashColorPtr colorLine,
|
2071
|
+
Guchar *alphaLine) {
|
2072
|
+
SplashOutMaskedImageData *imgData = (SplashOutMaskedImageData *)data;
|
2073
|
+
Guchar *p, *aq;
|
2074
|
+
SplashColor maskColor;
|
2075
|
+
SplashColorPtr q, col;
|
2076
|
+
GfxRGB rgb;
|
2077
|
+
GfxGray gray;
|
2078
|
+
#if SPLASH_CMYK
|
2079
|
+
GfxCMYK cmyk;
|
2080
|
+
#endif
|
2081
|
+
Guchar alpha;
|
2082
|
+
int nComps, x;
|
2083
|
+
|
2084
|
+
if (imgData->y == imgData->height) {
|
2085
|
+
return gFalse;
|
2086
|
+
}
|
2087
|
+
|
2088
|
+
nComps = imgData->colorMap->getNumPixelComps();
|
2089
|
+
|
2090
|
+
for (x = 0, p = imgData->imgStr->getLine(), q = colorLine, aq = alphaLine;
|
2091
|
+
x < imgData->width;
|
2092
|
+
++x, p += nComps) {
|
2093
|
+
imgData->mask->getPixel(x, imgData->y, maskColor);
|
2094
|
+
alpha = maskColor[0] ? 0xff : 0x00;
|
2095
|
+
if (imgData->lookup) {
|
2096
|
+
switch (imgData->colorMode) {
|
2097
|
+
case splashModeMono1:
|
2098
|
+
case splashModeMono8:
|
2099
|
+
*q++ = imgData->lookup[*p];
|
2100
|
+
*aq++ = alpha;
|
2101
|
+
break;
|
2102
|
+
case splashModeRGB8:
|
2103
|
+
case splashModeBGR8:
|
2104
|
+
col = &imgData->lookup[3 * *p];
|
2105
|
+
*q++ = col[0];
|
2106
|
+
*q++ = col[1];
|
2107
|
+
*q++ = col[2];
|
2108
|
+
*aq++ = alpha;
|
2109
|
+
break;
|
2110
|
+
#if SPLASH_CMYK
|
2111
|
+
case splashModeCMYK8:
|
2112
|
+
col = &imgData->lookup[4 * *p];
|
2113
|
+
*q++ = col[0];
|
2114
|
+
*q++ = col[1];
|
2115
|
+
*q++ = col[2];
|
2116
|
+
*q++ = col[3];
|
2117
|
+
*aq++ = alpha;
|
2118
|
+
break;
|
2119
|
+
#endif
|
2120
|
+
}
|
2121
|
+
} else {
|
2122
|
+
switch (imgData->colorMode) {
|
2123
|
+
case splashModeMono1:
|
2124
|
+
case splashModeMono8:
|
2125
|
+
imgData->colorMap->getGray(p, &gray);
|
2126
|
+
*q++ = colToByte(gray);
|
2127
|
+
*aq++ = alpha;
|
2128
|
+
break;
|
2129
|
+
case splashModeRGB8:
|
2130
|
+
case splashModeBGR8:
|
2131
|
+
imgData->colorMap->getRGB(p, &rgb);
|
2132
|
+
*q++ = colToByte(rgb.r);
|
2133
|
+
*q++ = colToByte(rgb.g);
|
2134
|
+
*q++ = colToByte(rgb.b);
|
2135
|
+
*aq++ = alpha;
|
2136
|
+
break;
|
2137
|
+
#if SPLASH_CMYK
|
2138
|
+
case splashModeCMYK8:
|
2139
|
+
imgData->colorMap->getCMYK(p, &cmyk);
|
2140
|
+
*q++ = colToByte(cmyk.c);
|
2141
|
+
*q++ = colToByte(cmyk.m);
|
2142
|
+
*q++ = colToByte(cmyk.y);
|
2143
|
+
*q++ = colToByte(cmyk.k);
|
2144
|
+
*aq++ = alpha;
|
2145
|
+
break;
|
2146
|
+
#endif
|
2147
|
+
}
|
2148
|
+
}
|
2149
|
+
}
|
2150
|
+
|
2151
|
+
++imgData->y;
|
2152
|
+
return gTrue;
|
2153
|
+
}
|
2154
|
+
|
2155
|
+
void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
|
2156
|
+
Stream *str, int width, int height,
|
2157
|
+
GfxImageColorMap *colorMap,
|
2158
|
+
Stream *maskStr, int maskWidth,
|
2159
|
+
int maskHeight, GBool maskInvert) {
|
2160
|
+
GfxImageColorMap *maskColorMap;
|
2161
|
+
Object maskDecode, decodeLow, decodeHigh;
|
2162
|
+
double *ctm;
|
2163
|
+
SplashCoord mat[6];
|
2164
|
+
SplashOutMaskedImageData imgData;
|
2165
|
+
SplashOutImageMaskData imgMaskData;
|
2166
|
+
SplashColorMode srcMode;
|
2167
|
+
SplashBitmap *maskBitmap;
|
2168
|
+
Splash *maskSplash;
|
2169
|
+
SplashColor maskColor;
|
2170
|
+
GfxGray gray;
|
2171
|
+
GfxRGB rgb;
|
2172
|
+
#if SPLASH_CMYK
|
2173
|
+
GfxCMYK cmyk;
|
2174
|
+
#endif
|
2175
|
+
Guchar pix;
|
2176
|
+
int n, i;
|
2177
|
+
|
2178
|
+
// If the mask is higher resolution than the image, use
|
2179
|
+
// drawSoftMaskedImage() instead.
|
2180
|
+
if (maskWidth > width || maskHeight > height) {
|
2181
|
+
decodeLow.initInt(maskInvert ? 0 : 1);
|
2182
|
+
decodeHigh.initInt(maskInvert ? 1 : 0);
|
2183
|
+
maskDecode.initArray(xref);
|
2184
|
+
maskDecode.arrayAdd(&decodeLow);
|
2185
|
+
maskDecode.arrayAdd(&decodeHigh);
|
2186
|
+
maskColorMap = new GfxImageColorMap(1, &maskDecode,
|
2187
|
+
new GfxDeviceGrayColorSpace());
|
2188
|
+
maskDecode.free();
|
2189
|
+
drawSoftMaskedImage(state, ref, str, width, height, colorMap,
|
2190
|
+
maskStr, maskWidth, maskHeight, maskColorMap);
|
2191
|
+
delete maskColorMap;
|
2192
|
+
|
2193
|
+
} else {
|
2194
|
+
|
2195
|
+
//----- scale the mask image to the same size as the source image
|
2196
|
+
|
2197
|
+
mat[0] = (SplashCoord)width;
|
2198
|
+
mat[1] = 0;
|
2199
|
+
mat[2] = 0;
|
2200
|
+
mat[3] = (SplashCoord)height;
|
2201
|
+
mat[4] = 0;
|
2202
|
+
mat[5] = 0;
|
2203
|
+
imgMaskData.imgStr = new ImageStream(maskStr, maskWidth, 1, 1);
|
2204
|
+
imgMaskData.imgStr->reset();
|
2205
|
+
imgMaskData.invert = maskInvert ? 0 : 1;
|
2206
|
+
imgMaskData.width = maskWidth;
|
2207
|
+
imgMaskData.height = maskHeight;
|
2208
|
+
imgMaskData.y = 0;
|
2209
|
+
maskBitmap = new SplashBitmap(width, height, 1, splashModeMono1, gFalse);
|
2210
|
+
maskSplash = new Splash(maskBitmap, gFalse);
|
2211
|
+
maskColor[0] = 0;
|
2212
|
+
maskSplash->clear(maskColor);
|
2213
|
+
maskColor[0] = 0xff;
|
2214
|
+
maskSplash->setFillPattern(new SplashSolidColor(maskColor));
|
2215
|
+
maskSplash->fillImageMask(&imageMaskSrc, &imgMaskData,
|
2216
|
+
maskWidth, maskHeight, mat, gFalse);
|
2217
|
+
delete imgMaskData.imgStr;
|
2218
|
+
maskStr->close();
|
2219
|
+
delete maskSplash;
|
2220
|
+
|
2221
|
+
//----- draw the source image
|
2222
|
+
|
2223
|
+
ctm = state->getCTM();
|
2224
|
+
mat[0] = ctm[0];
|
2225
|
+
mat[1] = ctm[1];
|
2226
|
+
mat[2] = -ctm[2];
|
2227
|
+
mat[3] = -ctm[3];
|
2228
|
+
mat[4] = ctm[2] + ctm[4];
|
2229
|
+
mat[5] = ctm[3] + ctm[5];
|
2230
|
+
|
2231
|
+
imgData.imgStr = new ImageStream(str, width,
|
2232
|
+
colorMap->getNumPixelComps(),
|
2233
|
+
colorMap->getBits());
|
2234
|
+
imgData.imgStr->reset();
|
2235
|
+
imgData.colorMap = colorMap;
|
2236
|
+
imgData.mask = maskBitmap;
|
2237
|
+
imgData.colorMode = colorMode;
|
2238
|
+
imgData.width = width;
|
2239
|
+
imgData.height = height;
|
2240
|
+
imgData.y = 0;
|
2241
|
+
|
2242
|
+
// special case for one-channel (monochrome/gray/separation) images:
|
2243
|
+
// build a lookup table here
|
2244
|
+
imgData.lookup = NULL;
|
2245
|
+
if (colorMap->getNumPixelComps() == 1) {
|
2246
|
+
n = 1 << colorMap->getBits();
|
2247
|
+
switch (colorMode) {
|
2248
|
+
case splashModeMono1:
|
2249
|
+
case splashModeMono8:
|
2250
|
+
imgData.lookup = (SplashColorPtr)gmalloc(n);
|
2251
|
+
for (i = 0; i < n; ++i) {
|
2252
|
+
pix = (Guchar)i;
|
2253
|
+
colorMap->getGray(&pix, &gray);
|
2254
|
+
imgData.lookup[i] = colToByte(gray);
|
2255
|
+
}
|
2256
|
+
break;
|
2257
|
+
case splashModeRGB8:
|
2258
|
+
case splashModeBGR8:
|
2259
|
+
imgData.lookup = (SplashColorPtr)gmalloc(3 * n);
|
2260
|
+
for (i = 0; i < n; ++i) {
|
2261
|
+
pix = (Guchar)i;
|
2262
|
+
colorMap->getRGB(&pix, &rgb);
|
2263
|
+
imgData.lookup[3*i] = colToByte(rgb.r);
|
2264
|
+
imgData.lookup[3*i+1] = colToByte(rgb.g);
|
2265
|
+
imgData.lookup[3*i+2] = colToByte(rgb.b);
|
2266
|
+
}
|
2267
|
+
break;
|
2268
|
+
#if SPLASH_CMYK
|
2269
|
+
case splashModeCMYK8:
|
2270
|
+
imgData.lookup = (SplashColorPtr)gmalloc(4 * n);
|
2271
|
+
for (i = 0; i < n; ++i) {
|
2272
|
+
pix = (Guchar)i;
|
2273
|
+
colorMap->getCMYK(&pix, &cmyk);
|
2274
|
+
imgData.lookup[4*i] = colToByte(cmyk.c);
|
2275
|
+
imgData.lookup[4*i+1] = colToByte(cmyk.m);
|
2276
|
+
imgData.lookup[4*i+2] = colToByte(cmyk.y);
|
2277
|
+
imgData.lookup[4*i+3] = colToByte(cmyk.k);
|
2278
|
+
}
|
2279
|
+
break;
|
2280
|
+
#endif
|
2281
|
+
}
|
2282
|
+
}
|
2283
|
+
|
2284
|
+
if (colorMode == splashModeMono1) {
|
2285
|
+
srcMode = splashModeMono8;
|
2286
|
+
} else {
|
2287
|
+
srcMode = colorMode;
|
2288
|
+
}
|
2289
|
+
splash->drawImage(&maskedImageSrc, &imgData, srcMode, gTrue,
|
2290
|
+
width, height, mat);
|
2291
|
+
|
2292
|
+
delete maskBitmap;
|
2293
|
+
gfree(imgData.lookup);
|
2294
|
+
delete imgData.imgStr;
|
2295
|
+
str->close();
|
2296
|
+
}
|
2297
|
+
}
|
2298
|
+
|
2299
|
+
void SplashOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref,
|
2300
|
+
Stream *str, int width, int height,
|
2301
|
+
GfxImageColorMap *colorMap,
|
2302
|
+
Stream *maskStr,
|
2303
|
+
int maskWidth, int maskHeight,
|
2304
|
+
GfxImageColorMap *maskColorMap) {
|
2305
|
+
double *ctm;
|
2306
|
+
SplashCoord mat[6];
|
2307
|
+
SplashOutImageData imgData;
|
2308
|
+
SplashOutImageData imgMaskData;
|
2309
|
+
SplashColorMode srcMode;
|
2310
|
+
SplashBitmap *maskBitmap;
|
2311
|
+
Splash *maskSplash;
|
2312
|
+
SplashColor maskColor;
|
2313
|
+
GfxGray gray;
|
2314
|
+
GfxRGB rgb;
|
2315
|
+
#if SPLASH_CMYK
|
2316
|
+
GfxCMYK cmyk;
|
2317
|
+
#endif
|
2318
|
+
Guchar pix;
|
2319
|
+
int n, i;
|
2320
|
+
|
2321
|
+
ctm = state->getCTM();
|
2322
|
+
mat[0] = ctm[0];
|
2323
|
+
mat[1] = ctm[1];
|
2324
|
+
mat[2] = -ctm[2];
|
2325
|
+
mat[3] = -ctm[3];
|
2326
|
+
mat[4] = ctm[2] + ctm[4];
|
2327
|
+
mat[5] = ctm[3] + ctm[5];
|
2328
|
+
|
2329
|
+
//----- set up the soft mask
|
2330
|
+
|
2331
|
+
imgMaskData.imgStr = new ImageStream(maskStr, maskWidth,
|
2332
|
+
maskColorMap->getNumPixelComps(),
|
2333
|
+
maskColorMap->getBits());
|
2334
|
+
imgMaskData.imgStr->reset();
|
2335
|
+
imgMaskData.colorMap = maskColorMap;
|
2336
|
+
imgMaskData.maskColors = NULL;
|
2337
|
+
imgMaskData.colorMode = splashModeMono8;
|
2338
|
+
imgMaskData.width = maskWidth;
|
2339
|
+
imgMaskData.height = maskHeight;
|
2340
|
+
imgMaskData.y = 0;
|
2341
|
+
n = 1 << maskColorMap->getBits();
|
2342
|
+
imgMaskData.lookup = (SplashColorPtr)gmalloc(n);
|
2343
|
+
for (i = 0; i < n; ++i) {
|
2344
|
+
pix = (Guchar)i;
|
2345
|
+
maskColorMap->getGray(&pix, &gray);
|
2346
|
+
imgMaskData.lookup[i] = colToByte(gray);
|
2347
|
+
}
|
2348
|
+
maskBitmap = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
|
2349
|
+
1, splashModeMono8, gFalse);
|
2350
|
+
maskSplash = new Splash(maskBitmap, vectorAntialias);
|
2351
|
+
maskColor[0] = 0;
|
2352
|
+
maskSplash->clear(maskColor);
|
2353
|
+
maskSplash->drawImage(&imageSrc, &imgMaskData, splashModeMono8, gFalse,
|
2354
|
+
maskWidth, maskHeight, mat);
|
2355
|
+
delete imgMaskData.imgStr;
|
2356
|
+
maskStr->close();
|
2357
|
+
gfree(imgMaskData.lookup);
|
2358
|
+
delete maskSplash;
|
2359
|
+
splash->setSoftMask(maskBitmap);
|
2360
|
+
|
2361
|
+
//----- draw the source image
|
2362
|
+
|
2363
|
+
imgData.imgStr = new ImageStream(str, width,
|
2364
|
+
colorMap->getNumPixelComps(),
|
2365
|
+
colorMap->getBits());
|
2366
|
+
imgData.imgStr->reset();
|
2367
|
+
imgData.colorMap = colorMap;
|
2368
|
+
imgData.maskColors = NULL;
|
2369
|
+
imgData.colorMode = colorMode;
|
2370
|
+
imgData.width = width;
|
2371
|
+
imgData.height = height;
|
2372
|
+
imgData.y = 0;
|
2373
|
+
|
2374
|
+
// special case for one-channel (monochrome/gray/separation) images:
|
2375
|
+
// build a lookup table here
|
2376
|
+
imgData.lookup = NULL;
|
2377
|
+
if (colorMap->getNumPixelComps() == 1) {
|
2378
|
+
n = 1 << colorMap->getBits();
|
2379
|
+
switch (colorMode) {
|
2380
|
+
case splashModeMono1:
|
2381
|
+
case splashModeMono8:
|
2382
|
+
imgData.lookup = (SplashColorPtr)gmalloc(n);
|
2383
|
+
for (i = 0; i < n; ++i) {
|
2384
|
+
pix = (Guchar)i;
|
2385
|
+
colorMap->getGray(&pix, &gray);
|
2386
|
+
imgData.lookup[i] = colToByte(gray);
|
2387
|
+
}
|
2388
|
+
break;
|
2389
|
+
case splashModeRGB8:
|
2390
|
+
case splashModeBGR8:
|
2391
|
+
imgData.lookup = (SplashColorPtr)gmalloc(3 * n);
|
2392
|
+
for (i = 0; i < n; ++i) {
|
2393
|
+
pix = (Guchar)i;
|
2394
|
+
colorMap->getRGB(&pix, &rgb);
|
2395
|
+
imgData.lookup[3*i] = colToByte(rgb.r);
|
2396
|
+
imgData.lookup[3*i+1] = colToByte(rgb.g);
|
2397
|
+
imgData.lookup[3*i+2] = colToByte(rgb.b);
|
2398
|
+
}
|
2399
|
+
break;
|
2400
|
+
#if SPLASH_CMYK
|
2401
|
+
case splashModeCMYK8:
|
2402
|
+
imgData.lookup = (SplashColorPtr)gmalloc(4 * n);
|
2403
|
+
for (i = 0; i < n; ++i) {
|
2404
|
+
pix = (Guchar)i;
|
2405
|
+
colorMap->getCMYK(&pix, &cmyk);
|
2406
|
+
imgData.lookup[4*i] = colToByte(cmyk.c);
|
2407
|
+
imgData.lookup[4*i+1] = colToByte(cmyk.m);
|
2408
|
+
imgData.lookup[4*i+2] = colToByte(cmyk.y);
|
2409
|
+
imgData.lookup[4*i+3] = colToByte(cmyk.k);
|
2410
|
+
}
|
2411
|
+
break;
|
2412
|
+
#endif
|
2413
|
+
}
|
2414
|
+
}
|
2415
|
+
|
2416
|
+
if (colorMode == splashModeMono1) {
|
2417
|
+
srcMode = splashModeMono8;
|
2418
|
+
} else {
|
2419
|
+
srcMode = colorMode;
|
2420
|
+
}
|
2421
|
+
splash->drawImage(&imageSrc, &imgData, srcMode, gFalse, width, height, mat);
|
2422
|
+
|
2423
|
+
splash->setSoftMask(NULL);
|
2424
|
+
gfree(imgData.lookup);
|
2425
|
+
delete imgData.imgStr;
|
2426
|
+
str->close();
|
2427
|
+
}
|
2428
|
+
|
2429
|
+
void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
|
2430
|
+
GfxColorSpace *blendingColorSpace,
|
2431
|
+
GBool isolated, GBool knockout,
|
2432
|
+
GBool forSoftMask) {
|
2433
|
+
SplashTransparencyGroup *transpGroup;
|
2434
|
+
SplashColor color;
|
2435
|
+
double xMin, yMin, xMax, yMax, x, y;
|
2436
|
+
int tx, ty, w, h;
|
2437
|
+
|
2438
|
+
// transform the bbox
|
2439
|
+
state->transform(bbox[0], bbox[1], &x, &y);
|
2440
|
+
xMin = xMax = x;
|
2441
|
+
yMin = yMax = y;
|
2442
|
+
state->transform(bbox[0], bbox[3], &x, &y);
|
2443
|
+
if (x < xMin) {
|
2444
|
+
xMin = x;
|
2445
|
+
} else if (x > xMax) {
|
2446
|
+
xMax = x;
|
2447
|
+
}
|
2448
|
+
if (y < yMin) {
|
2449
|
+
yMin = y;
|
2450
|
+
} else if (y > yMax) {
|
2451
|
+
yMax = y;
|
2452
|
+
}
|
2453
|
+
state->transform(bbox[2], bbox[1], &x, &y);
|
2454
|
+
if (x < xMin) {
|
2455
|
+
xMin = x;
|
2456
|
+
} else if (x > xMax) {
|
2457
|
+
xMax = x;
|
2458
|
+
}
|
2459
|
+
if (y < yMin) {
|
2460
|
+
yMin = y;
|
2461
|
+
} else if (y > yMax) {
|
2462
|
+
yMax = y;
|
2463
|
+
}
|
2464
|
+
state->transform(bbox[2], bbox[3], &x, &y);
|
2465
|
+
if (x < xMin) {
|
2466
|
+
xMin = x;
|
2467
|
+
} else if (x > xMax) {
|
2468
|
+
xMax = x;
|
2469
|
+
}
|
2470
|
+
if (y < yMin) {
|
2471
|
+
yMin = y;
|
2472
|
+
} else if (y > yMax) {
|
2473
|
+
yMax = y;
|
2474
|
+
}
|
2475
|
+
tx = (int)floor(xMin);
|
2476
|
+
if (tx < 0) {
|
2477
|
+
tx = 0;
|
2478
|
+
} else if (tx > bitmap->getWidth()) {
|
2479
|
+
tx = bitmap->getWidth();
|
2480
|
+
}
|
2481
|
+
ty = (int)floor(yMin);
|
2482
|
+
if (ty < 0) {
|
2483
|
+
ty = 0;
|
2484
|
+
} else if (ty > bitmap->getHeight()) {
|
2485
|
+
ty = bitmap->getHeight();
|
2486
|
+
}
|
2487
|
+
w = (int)ceil(xMax) - tx + 1;
|
2488
|
+
if (tx + w > bitmap->getWidth()) {
|
2489
|
+
w = bitmap->getWidth() - tx;
|
2490
|
+
}
|
2491
|
+
if (w < 1) {
|
2492
|
+
w = 1;
|
2493
|
+
}
|
2494
|
+
h = (int)ceil(yMax) - ty + 1;
|
2495
|
+
if (ty + h > bitmap->getHeight()) {
|
2496
|
+
h = bitmap->getHeight() - ty;
|
2497
|
+
}
|
2498
|
+
if (h < 1) {
|
2499
|
+
h = 1;
|
2500
|
+
}
|
2501
|
+
|
2502
|
+
// push a new stack entry
|
2503
|
+
transpGroup = new SplashTransparencyGroup();
|
2504
|
+
transpGroup->tx = tx;
|
2505
|
+
transpGroup->ty = ty;
|
2506
|
+
transpGroup->blendingColorSpace = blendingColorSpace;
|
2507
|
+
transpGroup->isolated = isolated;
|
2508
|
+
transpGroup->next = transpGroupStack;
|
2509
|
+
transpGroupStack = transpGroup;
|
2510
|
+
|
2511
|
+
// save state
|
2512
|
+
transpGroup->origBitmap = bitmap;
|
2513
|
+
transpGroup->origSplash = splash;
|
2514
|
+
|
2515
|
+
//~ this ignores the blendingColorSpace arg
|
2516
|
+
|
2517
|
+
// create the temporary bitmap
|
2518
|
+
bitmap = new SplashBitmap(w, h, bitmapRowPad, colorMode, gTrue,
|
2519
|
+
bitmapTopDown);
|
2520
|
+
splash = new Splash(bitmap, vectorAntialias,
|
2521
|
+
transpGroup->origSplash->getScreen());
|
2522
|
+
if (isolated) {
|
2523
|
+
switch (colorMode) {
|
2524
|
+
case splashModeMono1:
|
2525
|
+
case splashModeMono8:
|
2526
|
+
color[0] = 0;
|
2527
|
+
break;
|
2528
|
+
case splashModeRGB8:
|
2529
|
+
case splashModeBGR8:
|
2530
|
+
color[0] = color[1] = color[2] = 0;
|
2531
|
+
break;
|
2532
|
+
#if SPLASH_CMYK
|
2533
|
+
case splashModeCMYK8:
|
2534
|
+
color[0] = color[1] = color[2] = color[3] = 0;
|
2535
|
+
break;
|
2536
|
+
#endif
|
2537
|
+
default:
|
2538
|
+
// make gcc happy
|
2539
|
+
break;
|
2540
|
+
}
|
2541
|
+
splash->clear(color, 0);
|
2542
|
+
} else {
|
2543
|
+
splash->blitTransparent(transpGroup->origBitmap, tx, ty, 0, 0, w, h);
|
2544
|
+
splash->setInNonIsolatedGroup(transpGroup->origBitmap, tx, ty);
|
2545
|
+
}
|
2546
|
+
transpGroup->tBitmap = bitmap;
|
2547
|
+
state->shiftCTM(-tx, -ty);
|
2548
|
+
updateCTM(state, 0, 0, 0, 0, 0, 0);
|
2549
|
+
}
|
2550
|
+
|
2551
|
+
void SplashOutputDev::endTransparencyGroup(GfxState *state) {
|
2552
|
+
double *ctm;
|
2553
|
+
|
2554
|
+
// restore state
|
2555
|
+
delete splash;
|
2556
|
+
bitmap = transpGroupStack->origBitmap;
|
2557
|
+
splash = transpGroupStack->origSplash;
|
2558
|
+
ctm = state->getCTM();
|
2559
|
+
state->shiftCTM(transpGroupStack->tx, transpGroupStack->ty);
|
2560
|
+
updateCTM(state, 0, 0, 0, 0, 0, 0);
|
2561
|
+
}
|
2562
|
+
|
2563
|
+
void SplashOutputDev::paintTransparencyGroup(GfxState *state, double *bbox) {
|
2564
|
+
SplashBitmap *tBitmap;
|
2565
|
+
SplashTransparencyGroup *transpGroup;
|
2566
|
+
GBool isolated;
|
2567
|
+
int tx, ty;
|
2568
|
+
|
2569
|
+
tx = transpGroupStack->tx;
|
2570
|
+
ty = transpGroupStack->ty;
|
2571
|
+
tBitmap = transpGroupStack->tBitmap;
|
2572
|
+
isolated = transpGroupStack->isolated;
|
2573
|
+
|
2574
|
+
// paint the transparency group onto the parent bitmap
|
2575
|
+
// - the clip path was set in the parent's state)
|
2576
|
+
splash->composite(tBitmap, 0, 0, tx, ty,
|
2577
|
+
tBitmap->getWidth(), tBitmap->getHeight(),
|
2578
|
+
gFalse, !isolated);
|
2579
|
+
|
2580
|
+
// pop the stack
|
2581
|
+
transpGroup = transpGroupStack;
|
2582
|
+
transpGroupStack = transpGroup->next;
|
2583
|
+
delete transpGroup;
|
2584
|
+
|
2585
|
+
delete tBitmap;
|
2586
|
+
}
|
2587
|
+
|
2588
|
+
void SplashOutputDev::setSoftMask(GfxState *state, double *bbox,
|
2589
|
+
GBool alpha, Function *transferFunc,
|
2590
|
+
GfxColor *backdropColor) {
|
2591
|
+
SplashBitmap *softMask, *tBitmap;
|
2592
|
+
Splash *tSplash;
|
2593
|
+
SplashTransparencyGroup *transpGroup;
|
2594
|
+
SplashColor color;
|
2595
|
+
SplashColorPtr p;
|
2596
|
+
GfxGray gray;
|
2597
|
+
GfxRGB rgb;
|
2598
|
+
#if SPLASH_CMYK
|
2599
|
+
GfxCMYK cmyk;
|
2600
|
+
#endif
|
2601
|
+
double lum, lum2;
|
2602
|
+
int tx, ty, x, y;
|
2603
|
+
|
2604
|
+
tx = transpGroupStack->tx;
|
2605
|
+
ty = transpGroupStack->ty;
|
2606
|
+
tBitmap = transpGroupStack->tBitmap;
|
2607
|
+
|
2608
|
+
// composite with backdrop color
|
2609
|
+
if (!alpha && colorMode != splashModeMono1) {
|
2610
|
+
//~ need to correctly handle the case where no blending color
|
2611
|
+
//~ space is given
|
2612
|
+
tSplash = new Splash(tBitmap, vectorAntialias,
|
2613
|
+
transpGroupStack->origSplash->getScreen());
|
2614
|
+
if (transpGroupStack->blendingColorSpace) {
|
2615
|
+
switch (colorMode) {
|
2616
|
+
case splashModeMono1:
|
2617
|
+
// transparency is not supported in mono1 mode
|
2618
|
+
break;
|
2619
|
+
case splashModeMono8:
|
2620
|
+
transpGroupStack->blendingColorSpace->getGray(backdropColor, &gray);
|
2621
|
+
color[0] = colToByte(gray);
|
2622
|
+
tSplash->compositeBackground(color);
|
2623
|
+
break;
|
2624
|
+
case splashModeRGB8:
|
2625
|
+
case splashModeBGR8:
|
2626
|
+
transpGroupStack->blendingColorSpace->getRGB(backdropColor, &rgb);
|
2627
|
+
color[0] = colToByte(rgb.r);
|
2628
|
+
color[1] = colToByte(rgb.g);
|
2629
|
+
color[2] = colToByte(rgb.b);
|
2630
|
+
tSplash->compositeBackground(color);
|
2631
|
+
break;
|
2632
|
+
#if SPLASH_CMYK
|
2633
|
+
case splashModeCMYK8:
|
2634
|
+
transpGroupStack->blendingColorSpace->getCMYK(backdropColor, &cmyk);
|
2635
|
+
color[0] = colToByte(cmyk.c);
|
2636
|
+
color[1] = colToByte(cmyk.m);
|
2637
|
+
color[2] = colToByte(cmyk.y);
|
2638
|
+
color[3] = colToByte(cmyk.k);
|
2639
|
+
tSplash->compositeBackground(color);
|
2640
|
+
break;
|
2641
|
+
#endif
|
2642
|
+
}
|
2643
|
+
delete tSplash;
|
2644
|
+
}
|
2645
|
+
}
|
2646
|
+
|
2647
|
+
softMask = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(),
|
2648
|
+
1, splashModeMono8, gFalse);
|
2649
|
+
memset(softMask->getDataPtr(), 0,
|
2650
|
+
softMask->getRowSize() * softMask->getHeight());
|
2651
|
+
p = softMask->getDataPtr() + ty * softMask->getRowSize() + tx;
|
2652
|
+
for (y = 0; y < tBitmap->getHeight(); ++y) {
|
2653
|
+
for (x = 0; x < tBitmap->getWidth(); ++x) {
|
2654
|
+
tBitmap->getPixel(x, y, color);
|
2655
|
+
if (alpha) {
|
2656
|
+
//~ unimplemented
|
2657
|
+
} else {
|
2658
|
+
// convert to luminosity
|
2659
|
+
switch (colorMode) {
|
2660
|
+
case splashModeMono1:
|
2661
|
+
case splashModeMono8:
|
2662
|
+
lum = color[0] / 255.0;
|
2663
|
+
break;
|
2664
|
+
case splashModeRGB8:
|
2665
|
+
case splashModeBGR8:
|
2666
|
+
lum = (0.3 / 255.0) * color[0] +
|
2667
|
+
(0.59 / 255.0) * color[1] +
|
2668
|
+
(0.11 / 255.0) * color[2];
|
2669
|
+
break;
|
2670
|
+
#if SPLASH_CMYK
|
2671
|
+
case splashModeCMYK8:
|
2672
|
+
lum = (1 - color[4] / 255.0)
|
2673
|
+
- (0.3 / 255.0) * color[0]
|
2674
|
+
- (0.59 / 255.0) * color[1]
|
2675
|
+
- (0.11 / 255.0) * color[2];
|
2676
|
+
if (lum < 0) {
|
2677
|
+
lum = 0;
|
2678
|
+
}
|
2679
|
+
break;
|
2680
|
+
#endif
|
2681
|
+
}
|
2682
|
+
if (transferFunc) {
|
2683
|
+
transferFunc->transform(&lum, &lum2);
|
2684
|
+
} else {
|
2685
|
+
lum2 = lum;
|
2686
|
+
}
|
2687
|
+
p[x] = (int)(lum2 * 255.0 + 0.5);
|
2688
|
+
}
|
2689
|
+
}
|
2690
|
+
p += softMask->getRowSize();
|
2691
|
+
}
|
2692
|
+
splash->setSoftMask(softMask);
|
2693
|
+
|
2694
|
+
// pop the stack
|
2695
|
+
transpGroup = transpGroupStack;
|
2696
|
+
transpGroupStack = transpGroup->next;
|
2697
|
+
delete transpGroup;
|
2698
|
+
|
2699
|
+
delete tBitmap;
|
2700
|
+
}
|
2701
|
+
|
2702
|
+
void SplashOutputDev::clearSoftMask(GfxState *state) {
|
2703
|
+
splash->setSoftMask(NULL);
|
2704
|
+
}
|
2705
|
+
|
2706
|
+
void SplashOutputDev::setPaperColor(SplashColorPtr paperColorA) {
|
2707
|
+
splashColorCopy(paperColor, paperColorA);
|
2708
|
+
}
|
2709
|
+
|
2710
|
+
int SplashOutputDev::getBitmapWidth() {
|
2711
|
+
return bitmap->getWidth();
|
2712
|
+
}
|
2713
|
+
|
2714
|
+
int SplashOutputDev::getBitmapHeight() {
|
2715
|
+
return bitmap->getHeight();
|
2716
|
+
}
|
2717
|
+
|
2718
|
+
SplashBitmap *SplashOutputDev::takeBitmap() {
|
2719
|
+
SplashBitmap *ret;
|
2720
|
+
|
2721
|
+
ret = bitmap;
|
2722
|
+
bitmap = new SplashBitmap(1, 1, bitmapRowPad, colorMode,
|
2723
|
+
colorMode != splashModeMono1, bitmapTopDown);
|
2724
|
+
return ret;
|
2725
|
+
}
|
2726
|
+
|
2727
|
+
void SplashOutputDev::getModRegion(int *xMin, int *yMin,
|
2728
|
+
int *xMax, int *yMax) {
|
2729
|
+
splash->getModRegion(xMin, yMin, xMax, yMax);
|
2730
|
+
}
|
2731
|
+
|
2732
|
+
void SplashOutputDev::clearModRegion() {
|
2733
|
+
splash->clearModRegion();
|
2734
|
+
}
|
2735
|
+
|
2736
|
+
void SplashOutputDev::setFillColor(int r, int g, int b) {
|
2737
|
+
GfxRGB rgb;
|
2738
|
+
GfxGray gray;
|
2739
|
+
#if SPLASH_CMYK
|
2740
|
+
GfxCMYK cmyk;
|
2741
|
+
#endif
|
2742
|
+
|
2743
|
+
rgb.r = byteToCol(r);
|
2744
|
+
rgb.g = byteToCol(g);
|
2745
|
+
rgb.b = byteToCol(b);
|
2746
|
+
gray = (GfxColorComp)(0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.g + 0.5);
|
2747
|
+
if (gray > gfxColorComp1) {
|
2748
|
+
gray = gfxColorComp1;
|
2749
|
+
}
|
2750
|
+
#if SPLASH_CMYK
|
2751
|
+
cmyk.c = gfxColorComp1 - rgb.r;
|
2752
|
+
cmyk.m = gfxColorComp1 - rgb.g;
|
2753
|
+
cmyk.y = gfxColorComp1 - rgb.b;
|
2754
|
+
cmyk.k = 0;
|
2755
|
+
splash->setFillPattern(getColor(gray, &rgb, &cmyk));
|
2756
|
+
#else
|
2757
|
+
splash->setFillPattern(getColor(gray, &rgb));
|
2758
|
+
#endif
|
2759
|
+
}
|
2760
|
+
|
2761
|
+
SplashFont *SplashOutputDev::getFont(GString *name, double *textMatA) {
|
2762
|
+
DisplayFontParam *dfp;
|
2763
|
+
Ref ref;
|
2764
|
+
SplashOutFontFileID *id;
|
2765
|
+
SplashFontFile *fontFile;
|
2766
|
+
SplashFont *fontObj;
|
2767
|
+
FoFiTrueType *ff;
|
2768
|
+
Gushort *codeToGID;
|
2769
|
+
Unicode u;
|
2770
|
+
SplashCoord textMat[4];
|
2771
|
+
int cmap, i;
|
2772
|
+
|
2773
|
+
for (i = 0; i < 16; ++i) {
|
2774
|
+
if (!name->cmp(splashOutSubstFonts[i].name)) {
|
2775
|
+
break;
|
2776
|
+
}
|
2777
|
+
}
|
2778
|
+
if (i == 16) {
|
2779
|
+
return NULL;
|
2780
|
+
}
|
2781
|
+
ref.num = i;
|
2782
|
+
ref.gen = -1;
|
2783
|
+
id = new SplashOutFontFileID(&ref);
|
2784
|
+
|
2785
|
+
// check the font file cache
|
2786
|
+
if ((fontFile = fontEngine->getFontFile(id))) {
|
2787
|
+
delete id;
|
2788
|
+
|
2789
|
+
// load the font file
|
2790
|
+
} else {
|
2791
|
+
dfp = globalParams->getDisplayFont(name);
|
2792
|
+
if (dfp && dfp->kind == displayFontT1) {
|
2793
|
+
fontFile = fontEngine->loadType1Font(id, dfp->t1.fileName->getCString(),
|
2794
|
+
gFalse, winAnsiEncoding);
|
2795
|
+
} else if (dfp && dfp->kind == displayFontTT) {
|
2796
|
+
if (!(ff = FoFiTrueType::load(dfp->tt.fileName->getCString()))) {
|
2797
|
+
return NULL;
|
2798
|
+
}
|
2799
|
+
for (cmap = 0; cmap < ff->getNumCmaps(); ++cmap) {
|
2800
|
+
if ((ff->getCmapPlatform(cmap) == 3 &&
|
2801
|
+
ff->getCmapEncoding(cmap) == 1) ||
|
2802
|
+
ff->getCmapPlatform(cmap) == 0) {
|
2803
|
+
break;
|
2804
|
+
}
|
2805
|
+
}
|
2806
|
+
if (cmap == ff->getNumCmaps()) {
|
2807
|
+
delete ff;
|
2808
|
+
return NULL;
|
2809
|
+
}
|
2810
|
+
codeToGID = (Gushort *)gmallocn(256, sizeof(Gushort));
|
2811
|
+
for (i = 0; i < 256; ++i) {
|
2812
|
+
codeToGID[i] = 0;
|
2813
|
+
if (winAnsiEncoding[i] &&
|
2814
|
+
(u = globalParams->mapNameToUnicode(winAnsiEncoding[i]))) {
|
2815
|
+
codeToGID[i] = ff->mapCodeToGID(cmap, u);
|
2816
|
+
}
|
2817
|
+
}
|
2818
|
+
delete ff;
|
2819
|
+
fontFile = fontEngine->loadTrueTypeFont(id,
|
2820
|
+
dfp->tt.fileName->getCString(),
|
2821
|
+
gFalse, codeToGID, 256);
|
2822
|
+
} else {
|
2823
|
+
return NULL;
|
2824
|
+
}
|
2825
|
+
}
|
2826
|
+
|
2827
|
+
// create the scaled font
|
2828
|
+
textMat[0] = (SplashCoord)textMatA[0];
|
2829
|
+
textMat[1] = (SplashCoord)textMatA[1];
|
2830
|
+
textMat[2] = (SplashCoord)textMatA[2];
|
2831
|
+
textMat[3] = (SplashCoord)textMatA[3];
|
2832
|
+
fontObj = fontEngine->getFont(fontFile, textMat, splash->getMatrix());
|
2833
|
+
|
2834
|
+
return fontObj;
|
2835
|
+
}
|
2836
|
+
|
2837
|
+
#if 1 //~tmp: turn off anti-aliasing temporarily
|
2838
|
+
GBool SplashOutputDev::getVectorAntialias() {
|
2839
|
+
return splash->getVectorAntialias();
|
2840
|
+
}
|
2841
|
+
|
2842
|
+
void SplashOutputDev::setVectorAntialias(GBool vaa) {
|
2843
|
+
splash->setVectorAntialias(vaa);
|
2844
|
+
}
|
2845
|
+
#endif
|