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.
Files changed (473) hide show
  1. data/README.markdown +9 -0
  2. data/bin/.gitkeep +0 -0
  3. data/ext/extconf.rb +30 -0
  4. data/lib/pdf2json.rb +8 -0
  5. data/pdf2json-0.52-source/AUTHORS +24 -0
  6. data/pdf2json-0.52-source/CHANGES +11 -0
  7. data/pdf2json-0.52-source/Makefile +84 -0
  8. data/pdf2json-0.52-source/Makefile.in +84 -0
  9. data/pdf2json-0.52-source/aclocal.m4 +274 -0
  10. data/pdf2json-0.52-source/aconf-win32.h +86 -0
  11. data/pdf2json-0.52-source/aconf.h +42 -0
  12. data/pdf2json-0.52-source/aconf.h.in +41 -0
  13. data/pdf2json-0.52-source/autom4te.cache/output.0 +6908 -0
  14. data/pdf2json-0.52-source/autom4te.cache/requests +76 -0
  15. data/pdf2json-0.52-source/autom4te.cache/traces.0 +466 -0
  16. data/pdf2json-0.52-source/config.log +1259 -0
  17. data/pdf2json-0.52-source/config.status +1050 -0
  18. data/pdf2json-0.52-source/configure +6908 -0
  19. data/pdf2json-0.52-source/configure.ac +93 -0
  20. data/pdf2json-0.52-source/doc/pdffonts.1 +130 -0
  21. data/pdf2json-0.52-source/doc/pdffonts.cat +107 -0
  22. data/pdf2json-0.52-source/doc/pdffonts.hlp +117 -0
  23. data/pdf2json-0.52-source/doc/pdfimages.1 +102 -0
  24. data/pdf2json-0.52-source/doc/pdfimages.cat +92 -0
  25. data/pdf2json-0.52-source/doc/pdfimages.hlp +101 -0
  26. data/pdf2json-0.52-source/doc/pdfinfo.1 +158 -0
  27. data/pdf2json-0.52-source/doc/pdfinfo.cat +119 -0
  28. data/pdf2json-0.52-source/doc/pdfinfo.hlp +129 -0
  29. data/pdf2json-0.52-source/doc/pdftoppm.1 +115 -0
  30. data/pdf2json-0.52-source/doc/pdftoppm.cat +105 -0
  31. data/pdf2json-0.52-source/doc/pdftoppm.hlp +114 -0
  32. data/pdf2json-0.52-source/doc/pdftops.1 +229 -0
  33. data/pdf2json-0.52-source/doc/pdftops.cat +221 -0
  34. data/pdf2json-0.52-source/doc/pdftops.hlp +231 -0
  35. data/pdf2json-0.52-source/doc/pdftotext.1 +137 -0
  36. data/pdf2json-0.52-source/doc/pdftotext.cat +120 -0
  37. data/pdf2json-0.52-source/doc/pdftotext.hlp +133 -0
  38. data/pdf2json-0.52-source/doc/sample-xpdfrc +91 -0
  39. data/pdf2json-0.52-source/doc/xpdf.1 +513 -0
  40. data/pdf2json-0.52-source/doc/xpdf.cat +476 -0
  41. data/pdf2json-0.52-source/doc/xpdf.hlp +489 -0
  42. data/pdf2json-0.52-source/doc/xpdfrc.5 +480 -0
  43. data/pdf2json-0.52-source/doc/xpdfrc.cat +474 -0
  44. data/pdf2json-0.52-source/doc/xpdfrc.hlp +479 -0
  45. data/pdf2json-0.52-source/fofi/.DS_Store +0 -0
  46. data/pdf2json-0.52-source/fofi/FoFiBase.cc +156 -0
  47. data/pdf2json-0.52-source/fofi/FoFiBase.h +57 -0
  48. data/pdf2json-0.52-source/fofi/FoFiBase.o +0 -0
  49. data/pdf2json-0.52-source/fofi/FoFiEncodings.cc +994 -0
  50. data/pdf2json-0.52-source/fofi/FoFiEncodings.h +36 -0
  51. data/pdf2json-0.52-source/fofi/FoFiEncodings.o +0 -0
  52. data/pdf2json-0.52-source/fofi/FoFiTrueType.cc +2027 -0
  53. data/pdf2json-0.52-source/fofi/FoFiTrueType.h +174 -0
  54. data/pdf2json-0.52-source/fofi/FoFiTrueType.o +0 -0
  55. data/pdf2json-0.52-source/fofi/FoFiType1.cc +252 -0
  56. data/pdf2json-0.52-source/fofi/FoFiType1.h +59 -0
  57. data/pdf2json-0.52-source/fofi/FoFiType1.o +0 -0
  58. data/pdf2json-0.52-source/fofi/FoFiType1C.cc +2603 -0
  59. data/pdf2json-0.52-source/fofi/FoFiType1C.h +233 -0
  60. data/pdf2json-0.52-source/fofi/FoFiType1C.o +0 -0
  61. data/pdf2json-0.52-source/fofi/Makefile +70 -0
  62. data/pdf2json-0.52-source/fofi/Makefile.dep +0 -0
  63. data/pdf2json-0.52-source/fofi/Makefile.in +70 -0
  64. data/pdf2json-0.52-source/fofi/libfofi.a +0 -0
  65. data/pdf2json-0.52-source/fofi/vms_make.com +0 -0
  66. data/pdf2json-0.52-source/freetype.win32/.DS_Store +0 -0
  67. data/pdf2json-0.52-source/freetype.win32/include/.DS_Store +0 -0
  68. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftconfig.h +528 -0
  69. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftheader.h +780 -0
  70. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftmodule.h +32 -0
  71. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftoption.h +733 -0
  72. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftstdlib.h +173 -0
  73. data/pdf2json-0.52-source/freetype.win32/include/freetype/freetype.h +3919 -0
  74. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftadvanc.h +179 -0
  75. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbbox.h +94 -0
  76. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbdf.h +209 -0
  77. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbitmap.h +227 -0
  78. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcache.h +1128 -0
  79. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftchapters.h +103 -0
  80. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcid.h +166 -0
  81. data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrdef.h +244 -0
  82. data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrors.h +206 -0
  83. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgasp.h +120 -0
  84. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftglyph.h +613 -0
  85. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgxval.h +358 -0
  86. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgzip.h +102 -0
  87. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftimage.h +1313 -0
  88. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftincrem.h +353 -0
  89. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlcdfil.h +213 -0
  90. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlist.h +277 -0
  91. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlzw.h +99 -0
  92. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmac.h +274 -0
  93. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmm.h +378 -0
  94. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmodapi.h +483 -0
  95. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmoderr.h +155 -0
  96. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftotval.h +203 -0
  97. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftoutln.h +537 -0
  98. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftpfr.h +172 -0
  99. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftrender.h +230 -0
  100. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsizes.h +159 -0
  101. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsnames.h +200 -0
  102. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftstroke.h +716 -0
  103. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsynth.h +80 -0
  104. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsystem.h +347 -0
  105. data/pdf2json-0.52-source/freetype.win32/include/freetype/fttrigon.h +350 -0
  106. data/pdf2json-0.52-source/freetype.win32/include/freetype/fttypes.h +588 -0
  107. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftwinfnt.h +274 -0
  108. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftxf86.h +83 -0
  109. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/autohint.h +231 -0
  110. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftcalc.h +179 -0
  111. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdebug.h +250 -0
  112. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdriver.h +422 -0
  113. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftgloadr.h +168 -0
  114. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftmemory.h +380 -0
  115. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftobjs.h +1428 -0
  116. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftpic.h +67 -0
  117. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftrfork.h +196 -0
  118. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftserv.h +620 -0
  119. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftstream.h +539 -0
  120. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/fttrace.h +139 -0
  121. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftvalid.h +150 -0
  122. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/internal.h +51 -0
  123. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pcftypes.h +56 -0
  124. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/psaux.h +873 -0
  125. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pshints.h +712 -0
  126. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svbdf.h +77 -0
  127. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svcid.h +83 -0
  128. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgldict.h +82 -0
  129. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgxval.h +72 -0
  130. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svkern.h +51 -0
  131. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svmm.h +104 -0
  132. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svotval.h +55 -0
  133. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpfr.h +66 -0
  134. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpostnm.h +79 -0
  135. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpscmap.h +164 -0
  136. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpsinfo.h +92 -0
  137. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svsfnt.h +102 -0
  138. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttcmap.h +106 -0
  139. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svtteng.h +53 -0
  140. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttglyf.h +67 -0
  141. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svwinfnt.h +50 -0
  142. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svxf86nm.h +55 -0
  143. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/sfnt.h +897 -0
  144. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/t1types.h +270 -0
  145. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/tttypes.h +1543 -0
  146. data/pdf2json-0.52-source/freetype.win32/include/freetype/t1tables.h +504 -0
  147. data/pdf2json-0.52-source/freetype.win32/include/freetype/ttnameid.h +1247 -0
  148. data/pdf2json-0.52-source/freetype.win32/include/freetype/tttables.h +759 -0
  149. data/pdf2json-0.52-source/freetype.win32/include/freetype/tttags.h +107 -0
  150. data/pdf2json-0.52-source/freetype.win32/include/freetype/ttunpat.h +59 -0
  151. data/pdf2json-0.52-source/freetype.win32/include/ft2build.h +39 -0
  152. data/pdf2json-0.52-source/freetype.win32/lib/freetype_a.lib +0 -0
  153. data/pdf2json-0.52-source/goo/.DS_Store +0 -0
  154. data/pdf2json-0.52-source/goo/FixedPoint.cc +118 -0
  155. data/pdf2json-0.52-source/goo/FixedPoint.h +155 -0
  156. data/pdf2json-0.52-source/goo/FixedPoint.o +0 -0
  157. data/pdf2json-0.52-source/goo/GHash.cc +380 -0
  158. data/pdf2json-0.52-source/goo/GHash.h +78 -0
  159. data/pdf2json-0.52-source/goo/GHash.o +0 -0
  160. data/pdf2json-0.52-source/goo/GList.cc +97 -0
  161. data/pdf2json-0.52-source/goo/GList.h +96 -0
  162. data/pdf2json-0.52-source/goo/GList.o +0 -0
  163. data/pdf2json-0.52-source/goo/GMutex.h +49 -0
  164. data/pdf2json-0.52-source/goo/GString.cc +724 -0
  165. data/pdf2json-0.52-source/goo/GString.cc.fixed +718 -0
  166. data/pdf2json-0.52-source/goo/GString.h +136 -0
  167. data/pdf2json-0.52-source/goo/GString.o +0 -0
  168. data/pdf2json-0.52-source/goo/ImgWriter.o +0 -0
  169. data/pdf2json-0.52-source/goo/JpegWriter.o +0 -0
  170. data/pdf2json-0.52-source/goo/Makefile +72 -0
  171. data/pdf2json-0.52-source/goo/Makefile.dep +0 -0
  172. data/pdf2json-0.52-source/goo/Makefile.in +72 -0
  173. data/pdf2json-0.52-source/goo/PNGWriter.o +0 -0
  174. data/pdf2json-0.52-source/goo/gfile.cc +731 -0
  175. data/pdf2json-0.52-source/goo/gfile.h +138 -0
  176. data/pdf2json-0.52-source/goo/gfile.o +0 -0
  177. data/pdf2json-0.52-source/goo/gmem.cc +264 -0
  178. data/pdf2json-0.52-source/goo/gmem.h +79 -0
  179. data/pdf2json-0.52-source/goo/gmem.o +0 -0
  180. data/pdf2json-0.52-source/goo/gmempp.cc +32 -0
  181. data/pdf2json-0.52-source/goo/gmempp.o +0 -0
  182. data/pdf2json-0.52-source/goo/gtypes.h +29 -0
  183. data/pdf2json-0.52-source/goo/libGoo.a +0 -0
  184. data/pdf2json-0.52-source/goo/parseargs.c +190 -0
  185. data/pdf2json-0.52-source/goo/parseargs.h +71 -0
  186. data/pdf2json-0.52-source/goo/parseargs.o +0 -0
  187. data/pdf2json-0.52-source/goo/vms_directory.c +214 -0
  188. data/pdf2json-0.52-source/goo/vms_dirent.h +67 -0
  189. data/pdf2json-0.52-source/goo/vms_make.com +82 -0
  190. data/pdf2json-0.52-source/goo/vms_sys_dirent.h +54 -0
  191. data/pdf2json-0.52-source/goo/vms_unix_time.h +102 -0
  192. data/pdf2json-0.52-source/goo/vms_unix_times.c +42 -0
  193. data/pdf2json-0.52-source/goo/vms_unlink.c +22 -0
  194. data/pdf2json-0.52-source/ms_make.bat +199 -0
  195. data/pdf2json-0.52-source/splash/.DS_Store +0 -0
  196. data/pdf2json-0.52-source/splash/Makefile +103 -0
  197. data/pdf2json-0.52-source/splash/Makefile.dep +0 -0
  198. data/pdf2json-0.52-source/splash/Makefile.in +103 -0
  199. data/pdf2json-0.52-source/splash/Splash.cc +3310 -0
  200. data/pdf2json-0.52-source/splash/Splash.h +293 -0
  201. data/pdf2json-0.52-source/splash/Splash.o +0 -0
  202. data/pdf2json-0.52-source/splash/SplashBitmap.cc +188 -0
  203. data/pdf2json-0.52-source/splash/SplashBitmap.h +64 -0
  204. data/pdf2json-0.52-source/splash/SplashBitmap.o +0 -0
  205. data/pdf2json-0.52-source/splash/SplashClip.cc +382 -0
  206. data/pdf2json-0.52-source/splash/SplashClip.h +107 -0
  207. data/pdf2json-0.52-source/splash/SplashClip.o +0 -0
  208. data/pdf2json-0.52-source/splash/SplashErrorCodes.h +32 -0
  209. data/pdf2json-0.52-source/splash/SplashFTFont.cc +357 -0
  210. data/pdf2json-0.52-source/splash/SplashFTFont.h +58 -0
  211. data/pdf2json-0.52-source/splash/SplashFTFont.o +0 -0
  212. data/pdf2json-0.52-source/splash/SplashFTFontEngine.cc +179 -0
  213. data/pdf2json-0.52-source/splash/SplashFTFontEngine.h +65 -0
  214. data/pdf2json-0.52-source/splash/SplashFTFontEngine.o +0 -0
  215. data/pdf2json-0.52-source/splash/SplashFTFontFile.cc +114 -0
  216. data/pdf2json-0.52-source/splash/SplashFTFontFile.h +73 -0
  217. data/pdf2json-0.52-source/splash/SplashFTFontFile.o +0 -0
  218. data/pdf2json-0.52-source/splash/SplashFont.cc +176 -0
  219. data/pdf2json-0.52-source/splash/SplashFont.h +104 -0
  220. data/pdf2json-0.52-source/splash/SplashFont.o +0 -0
  221. data/pdf2json-0.52-source/splash/SplashFontEngine.cc +317 -0
  222. data/pdf2json-0.52-source/splash/SplashFontEngine.h +91 -0
  223. data/pdf2json-0.52-source/splash/SplashFontEngine.o +0 -0
  224. data/pdf2json-0.52-source/splash/SplashFontFile.cc +55 -0
  225. data/pdf2json-0.52-source/splash/SplashFontFile.h +60 -0
  226. data/pdf2json-0.52-source/splash/SplashFontFile.o +0 -0
  227. data/pdf2json-0.52-source/splash/SplashFontFileID.cc +23 -0
  228. data/pdf2json-0.52-source/splash/SplashFontFileID.h +30 -0
  229. data/pdf2json-0.52-source/splash/SplashFontFileID.o +0 -0
  230. data/pdf2json-0.52-source/splash/SplashGlyphBitmap.h +26 -0
  231. data/pdf2json-0.52-source/splash/SplashMath.h +89 -0
  232. data/pdf2json-0.52-source/splash/SplashPath.cc +184 -0
  233. data/pdf2json-0.52-source/splash/SplashPath.h +121 -0
  234. data/pdf2json-0.52-source/splash/SplashPath.o +0 -0
  235. data/pdf2json-0.52-source/splash/SplashPattern.cc +40 -0
  236. data/pdf2json-0.52-source/splash/SplashPattern.h +65 -0
  237. data/pdf2json-0.52-source/splash/SplashPattern.o +0 -0
  238. data/pdf2json-0.52-source/splash/SplashScreen.cc +383 -0
  239. data/pdf2json-0.52-source/splash/SplashScreen.h +56 -0
  240. data/pdf2json-0.52-source/splash/SplashScreen.o +0 -0
  241. data/pdf2json-0.52-source/splash/SplashState.cc +165 -0
  242. data/pdf2json-0.52-source/splash/SplashState.h +103 -0
  243. data/pdf2json-0.52-source/splash/SplashState.o +0 -0
  244. data/pdf2json-0.52-source/splash/SplashT1Font.cc +287 -0
  245. data/pdf2json-0.52-source/splash/SplashT1Font.h +57 -0
  246. data/pdf2json-0.52-source/splash/SplashT1Font.o +0 -0
  247. data/pdf2json-0.52-source/splash/SplashT1FontEngine.cc +124 -0
  248. data/pdf2json-0.52-source/splash/SplashT1FontEngine.h +53 -0
  249. data/pdf2json-0.52-source/splash/SplashT1FontEngine.o +0 -0
  250. data/pdf2json-0.52-source/splash/SplashT1FontFile.cc +97 -0
  251. data/pdf2json-0.52-source/splash/SplashT1FontFile.h +58 -0
  252. data/pdf2json-0.52-source/splash/SplashT1FontFile.o +0 -0
  253. data/pdf2json-0.52-source/splash/SplashTypes.h +132 -0
  254. data/pdf2json-0.52-source/splash/SplashXPath.cc +438 -0
  255. data/pdf2json-0.52-source/splash/SplashXPath.h +100 -0
  256. data/pdf2json-0.52-source/splash/SplashXPath.o +0 -0
  257. data/pdf2json-0.52-source/splash/SplashXPathScanner.cc +428 -0
  258. data/pdf2json-0.52-source/splash/SplashXPathScanner.h +87 -0
  259. data/pdf2json-0.52-source/splash/SplashXPathScanner.o +0 -0
  260. data/pdf2json-0.52-source/splash/libsplash.a +0 -0
  261. data/pdf2json-0.52-source/splash/vms_make.com +0 -0
  262. data/pdf2json-0.52-source/src/.DS_Store +0 -0
  263. data/pdf2json-0.52-source/src/GVector.h +101 -0
  264. data/pdf2json-0.52-source/src/ImgOutputDev.cc +1243 -0
  265. data/pdf2json-0.52-source/src/ImgOutputDev.h +307 -0
  266. data/pdf2json-0.52-source/src/ImgOutputDev.o +0 -0
  267. data/pdf2json-0.52-source/src/Makefile +68 -0
  268. data/pdf2json-0.52-source/src/Makefile.in +68 -0
  269. data/pdf2json-0.52-source/src/XmlFonts.cc +367 -0
  270. data/pdf2json-0.52-source/src/XmlFonts.h +91 -0
  271. data/pdf2json-0.52-source/src/XmlFonts.o +0 -0
  272. data/pdf2json-0.52-source/src/XmlLinks.cc +101 -0
  273. data/pdf2json-0.52-source/src/XmlLinks.h +54 -0
  274. data/pdf2json-0.52-source/src/XmlLinks.o +0 -0
  275. data/pdf2json-0.52-source/src/pdf2json +0 -0
  276. data/pdf2json-0.52-source/src/pdf2json.cc +343 -0
  277. data/pdf2json-0.52-source/src/pdf2json.o +0 -0
  278. data/pdf2json-0.52-source/src/pdf2xml.dtd +22 -0
  279. data/pdf2json-0.52-source/src/pdf2xmljson.dtd +9 -0
  280. data/pdf2json-0.52-source/xpdf/.DS_Store +0 -0
  281. data/pdf2json-0.52-source/xpdf/Annot.cc +1556 -0
  282. data/pdf2json-0.52-source/xpdf/Annot.h +142 -0
  283. data/pdf2json-0.52-source/xpdf/Annot.o +0 -0
  284. data/pdf2json-0.52-source/xpdf/Array.cc +73 -0
  285. data/pdf2json-0.52-source/xpdf/Array.h +58 -0
  286. data/pdf2json-0.52-source/xpdf/Array.o +0 -0
  287. data/pdf2json-0.52-source/xpdf/BuiltinFont.cc +65 -0
  288. data/pdf2json-0.52-source/xpdf/BuiltinFont.h +57 -0
  289. data/pdf2json-0.52-source/xpdf/BuiltinFont.o +0 -0
  290. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.cc +4284 -0
  291. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.h +23 -0
  292. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.o +0 -0
  293. data/pdf2json-0.52-source/xpdf/CMap.cc +408 -0
  294. data/pdf2json-0.52-source/xpdf/CMap.h +102 -0
  295. data/pdf2json-0.52-source/xpdf/CMap.o +0 -0
  296. data/pdf2json-0.52-source/xpdf/Catalog.cc +374 -0
  297. data/pdf2json-0.52-source/xpdf/Catalog.h +97 -0
  298. data/pdf2json-0.52-source/xpdf/Catalog.o +0 -0
  299. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.cc +540 -0
  300. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.h +117 -0
  301. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.o +0 -0
  302. data/pdf2json-0.52-source/xpdf/CharTypes.h +24 -0
  303. data/pdf2json-0.52-source/xpdf/CompactFontTables.h +464 -0
  304. data/pdf2json-0.52-source/xpdf/CoreOutputDev.cc +61 -0
  305. data/pdf2json-0.52-source/xpdf/CoreOutputDev.h +61 -0
  306. data/pdf2json-0.52-source/xpdf/Decrypt.cc +776 -0
  307. data/pdf2json-0.52-source/xpdf/Decrypt.h +95 -0
  308. data/pdf2json-0.52-source/xpdf/Decrypt.o +0 -0
  309. data/pdf2json-0.52-source/xpdf/Dict.cc +95 -0
  310. data/pdf2json-0.52-source/xpdf/Dict.h +77 -0
  311. data/pdf2json-0.52-source/xpdf/Dict.o +0 -0
  312. data/pdf2json-0.52-source/xpdf/Error.cc +38 -0
  313. data/pdf2json-0.52-source/xpdf/Error.h +23 -0
  314. data/pdf2json-0.52-source/xpdf/Error.o +0 -0
  315. data/pdf2json-0.52-source/xpdf/ErrorCodes.h +36 -0
  316. data/pdf2json-0.52-source/xpdf/FontEncodingTables.cc +1824 -0
  317. data/pdf2json-0.52-source/xpdf/FontEncodingTables.h +20 -0
  318. data/pdf2json-0.52-source/xpdf/FontEncodingTables.o +0 -0
  319. data/pdf2json-0.52-source/xpdf/Function.cc +1573 -0
  320. data/pdf2json-0.52-source/xpdf/Function.h +229 -0
  321. data/pdf2json-0.52-source/xpdf/Function.o +0 -0
  322. data/pdf2json-0.52-source/xpdf/Gfx.cc +4187 -0
  323. data/pdf2json-0.52-source/xpdf/Gfx.h +312 -0
  324. data/pdf2json-0.52-source/xpdf/Gfx.o +0 -0
  325. data/pdf2json-0.52-source/xpdf/GfxFont.cc +1568 -0
  326. data/pdf2json-0.52-source/xpdf/GfxFont.h +320 -0
  327. data/pdf2json-0.52-source/xpdf/GfxFont.o +0 -0
  328. data/pdf2json-0.52-source/xpdf/GfxState.cc +4137 -0
  329. data/pdf2json-0.52-source/xpdf/GfxState.h +1244 -0
  330. data/pdf2json-0.52-source/xpdf/GfxState.o +0 -0
  331. data/pdf2json-0.52-source/xpdf/GlobalParams.cc +2924 -0
  332. data/pdf2json-0.52-source/xpdf/GlobalParams.cc.old +2908 -0
  333. data/pdf2json-0.52-source/xpdf/GlobalParams.h +466 -0
  334. data/pdf2json-0.52-source/xpdf/GlobalParams.h.old +463 -0
  335. data/pdf2json-0.52-source/xpdf/GlobalParams.o +0 -0
  336. data/pdf2json-0.52-source/xpdf/ImageOutputDev.cc +195 -0
  337. data/pdf2json-0.52-source/xpdf/ImageOutputDev.h +76 -0
  338. data/pdf2json-0.52-source/xpdf/ImageOutputDev.o +0 -0
  339. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.cc +322 -0
  340. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.h +109 -0
  341. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.o +0 -0
  342. data/pdf2json-0.52-source/xpdf/JBIG2Stream.cc +3413 -0
  343. data/pdf2json-0.52-source/xpdf/JBIG2Stream.h +145 -0
  344. data/pdf2json-0.52-source/xpdf/JBIG2Stream.o +0 -0
  345. data/pdf2json-0.52-source/xpdf/JPXStream.cc +3144 -0
  346. data/pdf2json-0.52-source/xpdf/JPXStream.h +351 -0
  347. data/pdf2json-0.52-source/xpdf/JPXStream.o +0 -0
  348. data/pdf2json-0.52-source/xpdf/Lexer.cc +485 -0
  349. data/pdf2json-0.52-source/xpdf/Lexer.h +80 -0
  350. data/pdf2json-0.52-source/xpdf/Lexer.o +0 -0
  351. data/pdf2json-0.52-source/xpdf/Link.cc +806 -0
  352. data/pdf2json-0.52-source/xpdf/Link.cc.old +784 -0
  353. data/pdf2json-0.52-source/xpdf/Link.h +415 -0
  354. data/pdf2json-0.52-source/xpdf/Link.h.old +369 -0
  355. data/pdf2json-0.52-source/xpdf/Link.o +0 -0
  356. data/pdf2json-0.52-source/xpdf/Makefile +232 -0
  357. data/pdf2json-0.52-source/xpdf/Makefile.dep +0 -0
  358. data/pdf2json-0.52-source/xpdf/Makefile.in +232 -0
  359. data/pdf2json-0.52-source/xpdf/NameToCharCode.cc +116 -0
  360. data/pdf2json-0.52-source/xpdf/NameToCharCode.h +42 -0
  361. data/pdf2json-0.52-source/xpdf/NameToCharCode.o +0 -0
  362. data/pdf2json-0.52-source/xpdf/NameToUnicodeTable.h +1097 -0
  363. data/pdf2json-0.52-source/xpdf/Object.cc +231 -0
  364. data/pdf2json-0.52-source/xpdf/Object.h +303 -0
  365. data/pdf2json-0.52-source/xpdf/Object.o +0 -0
  366. data/pdf2json-0.52-source/xpdf/Outline.cc +151 -0
  367. data/pdf2json-0.52-source/xpdf/Outline.h +76 -0
  368. data/pdf2json-0.52-source/xpdf/Outline.o +0 -0
  369. data/pdf2json-0.52-source/xpdf/OutputDev.cc +131 -0
  370. data/pdf2json-0.52-source/xpdf/OutputDev.h +253 -0
  371. data/pdf2json-0.52-source/xpdf/OutputDev.o +0 -0
  372. data/pdf2json-0.52-source/xpdf/PDFCore.cc +2044 -0
  373. data/pdf2json-0.52-source/xpdf/PDFCore.h +321 -0
  374. data/pdf2json-0.52-source/xpdf/PDFDoc.cc +404 -0
  375. data/pdf2json-0.52-source/xpdf/PDFDoc.h +183 -0
  376. data/pdf2json-0.52-source/xpdf/PDFDoc.o +0 -0
  377. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.cc +44 -0
  378. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.h +16 -0
  379. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.o +0 -0
  380. data/pdf2json-0.52-source/xpdf/PSOutputDev.cc +6224 -0
  381. data/pdf2json-0.52-source/xpdf/PSOutputDev.h +395 -0
  382. data/pdf2json-0.52-source/xpdf/PSOutputDev.o +0 -0
  383. data/pdf2json-0.52-source/xpdf/PSTokenizer.cc +135 -0
  384. data/pdf2json-0.52-source/xpdf/PSTokenizer.h +41 -0
  385. data/pdf2json-0.52-source/xpdf/PSTokenizer.o +0 -0
  386. data/pdf2json-0.52-source/xpdf/Page.cc +454 -0
  387. data/pdf2json-0.52-source/xpdf/Page.h +187 -0
  388. data/pdf2json-0.52-source/xpdf/Page.o +0 -0
  389. data/pdf2json-0.52-source/xpdf/Parser.cc +227 -0
  390. data/pdf2json-0.52-source/xpdf/Parser.h +59 -0
  391. data/pdf2json-0.52-source/xpdf/Parser.o +0 -0
  392. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.cc +257 -0
  393. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.h +130 -0
  394. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.o +0 -0
  395. data/pdf2json-0.52-source/xpdf/SecurityHandler.cc +390 -0
  396. data/pdf2json-0.52-source/xpdf/SecurityHandler.h +160 -0
  397. data/pdf2json-0.52-source/xpdf/SecurityHandler.o +0 -0
  398. data/pdf2json-0.52-source/xpdf/SplashOutputDev.cc +2845 -0
  399. data/pdf2json-0.52-source/xpdf/SplashOutputDev.h +247 -0
  400. data/pdf2json-0.52-source/xpdf/SplashOutputDev.o +0 -0
  401. data/pdf2json-0.52-source/xpdf/Stream-CCITT.h +459 -0
  402. data/pdf2json-0.52-source/xpdf/Stream.cc +4627 -0
  403. data/pdf2json-0.52-source/xpdf/Stream.h +858 -0
  404. data/pdf2json-0.52-source/xpdf/Stream.o +0 -0
  405. data/pdf2json-0.52-source/xpdf/TextOutputDev.cc +4090 -0
  406. data/pdf2json-0.52-source/xpdf/TextOutputDev.h +661 -0
  407. data/pdf2json-0.52-source/xpdf/TextOutputDev.o +0 -0
  408. data/pdf2json-0.52-source/xpdf/UTF8.h +56 -0
  409. data/pdf2json-0.52-source/xpdf/UnicodeMap.cc +302 -0
  410. data/pdf2json-0.52-source/xpdf/UnicodeMap.cc.old +293 -0
  411. data/pdf2json-0.52-source/xpdf/UnicodeMap.h +135 -0
  412. data/pdf2json-0.52-source/xpdf/UnicodeMap.h.old +123 -0
  413. data/pdf2json-0.52-source/xpdf/UnicodeMap.o +0 -0
  414. data/pdf2json-0.52-source/xpdf/UnicodeMapTables.h +361 -0
  415. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.cc +949 -0
  416. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.h +20 -0
  417. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.o +0 -0
  418. data/pdf2json-0.52-source/xpdf/XPDFApp.cc +447 -0
  419. data/pdf2json-0.52-source/xpdf/XPDFApp.h +114 -0
  420. data/pdf2json-0.52-source/xpdf/XPDFCore.cc +1655 -0
  421. data/pdf2json-0.52-source/xpdf/XPDFCore.h +251 -0
  422. data/pdf2json-0.52-source/xpdf/XPDFTree.cc +931 -0
  423. data/pdf2json-0.52-source/xpdf/XPDFTree.h +45 -0
  424. data/pdf2json-0.52-source/xpdf/XPDFTreeP.h +87 -0
  425. data/pdf2json-0.52-source/xpdf/XPDFViewer.cc +3488 -0
  426. data/pdf2json-0.52-source/xpdf/XPDFViewer.h +352 -0
  427. data/pdf2json-0.52-source/xpdf/XRef.cc +896 -0
  428. data/pdf2json-0.52-source/xpdf/XRef.h +133 -0
  429. data/pdf2json-0.52-source/xpdf/XRef.o +0 -0
  430. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.cc +262 -0
  431. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.h +341 -0
  432. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.o +0 -0
  433. data/pdf2json-0.52-source/xpdf/about-text.h +48 -0
  434. data/pdf2json-0.52-source/xpdf/about.xbm +6 -0
  435. data/pdf2json-0.52-source/xpdf/backArrow.xbm +6 -0
  436. data/pdf2json-0.52-source/xpdf/backArrowDis.xbm +6 -0
  437. data/pdf2json-0.52-source/xpdf/config.h +112 -0
  438. data/pdf2json-0.52-source/xpdf/dblLeftArrow.xbm +6 -0
  439. data/pdf2json-0.52-source/xpdf/dblLeftArrowDis.xbm +6 -0
  440. data/pdf2json-0.52-source/xpdf/dblRightArrow.xbm +6 -0
  441. data/pdf2json-0.52-source/xpdf/dblRightArrowDis.xbm +6 -0
  442. data/pdf2json-0.52-source/xpdf/find.xbm +6 -0
  443. data/pdf2json-0.52-source/xpdf/findDis.xbm +6 -0
  444. data/pdf2json-0.52-source/xpdf/forwardArrow.xbm +6 -0
  445. data/pdf2json-0.52-source/xpdf/forwardArrowDis.xbm +6 -0
  446. data/pdf2json-0.52-source/xpdf/leftArrow.xbm +5 -0
  447. data/pdf2json-0.52-source/xpdf/leftArrowDis.xbm +5 -0
  448. data/pdf2json-0.52-source/xpdf/libXpdf.a +0 -0
  449. data/pdf2json-0.52-source/xpdf/pdffonts +0 -0
  450. data/pdf2json-0.52-source/xpdf/pdffonts.cc +298 -0
  451. data/pdf2json-0.52-source/xpdf/pdffonts.o +0 -0
  452. data/pdf2json-0.52-source/xpdf/pdfimages +0 -0
  453. data/pdf2json-0.52-source/xpdf/pdfimages.cc +155 -0
  454. data/pdf2json-0.52-source/xpdf/pdfimages.o +0 -0
  455. data/pdf2json-0.52-source/xpdf/pdfinfo +0 -0
  456. data/pdf2json-0.52-source/xpdf/pdfinfo.cc +387 -0
  457. data/pdf2json-0.52-source/xpdf/pdfinfo.o +0 -0
  458. data/pdf2json-0.52-source/xpdf/pdftoppm.cc +203 -0
  459. data/pdf2json-0.52-source/xpdf/pdftops +0 -0
  460. data/pdf2json-0.52-source/xpdf/pdftops.cc +344 -0
  461. data/pdf2json-0.52-source/xpdf/pdftops.o +0 -0
  462. data/pdf2json-0.52-source/xpdf/pdftotext +0 -0
  463. data/pdf2json-0.52-source/xpdf/pdftotext.cc +333 -0
  464. data/pdf2json-0.52-source/xpdf/pdftotext.o +0 -0
  465. data/pdf2json-0.52-source/xpdf/print.xbm +6 -0
  466. data/pdf2json-0.52-source/xpdf/printDis.xbm +6 -0
  467. data/pdf2json-0.52-source/xpdf/rightArrow.xbm +5 -0
  468. data/pdf2json-0.52-source/xpdf/rightArrowDis.xbm +5 -0
  469. data/pdf2json-0.52-source/xpdf/vms_make.com +129 -0
  470. data/pdf2json-0.52-source/xpdf/xpdf.cc +344 -0
  471. data/pdf2json-0.52-source/xpdf/xpdfIcon.xpm +62 -0
  472. data/pdf2json.gemspec +29 -0
  473. 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
@@ -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