pdf2json 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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