pdf2json 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. data/README.markdown +9 -0
  2. data/bin/.gitkeep +0 -0
  3. data/ext/extconf.rb +30 -0
  4. data/lib/pdf2json.rb +8 -0
  5. data/pdf2json-0.52-source/AUTHORS +24 -0
  6. data/pdf2json-0.52-source/CHANGES +11 -0
  7. data/pdf2json-0.52-source/Makefile +84 -0
  8. data/pdf2json-0.52-source/Makefile.in +84 -0
  9. data/pdf2json-0.52-source/aclocal.m4 +274 -0
  10. data/pdf2json-0.52-source/aconf-win32.h +86 -0
  11. data/pdf2json-0.52-source/aconf.h +42 -0
  12. data/pdf2json-0.52-source/aconf.h.in +41 -0
  13. data/pdf2json-0.52-source/autom4te.cache/output.0 +6908 -0
  14. data/pdf2json-0.52-source/autom4te.cache/requests +76 -0
  15. data/pdf2json-0.52-source/autom4te.cache/traces.0 +466 -0
  16. data/pdf2json-0.52-source/config.log +1259 -0
  17. data/pdf2json-0.52-source/config.status +1050 -0
  18. data/pdf2json-0.52-source/configure +6908 -0
  19. data/pdf2json-0.52-source/configure.ac +93 -0
  20. data/pdf2json-0.52-source/doc/pdffonts.1 +130 -0
  21. data/pdf2json-0.52-source/doc/pdffonts.cat +107 -0
  22. data/pdf2json-0.52-source/doc/pdffonts.hlp +117 -0
  23. data/pdf2json-0.52-source/doc/pdfimages.1 +102 -0
  24. data/pdf2json-0.52-source/doc/pdfimages.cat +92 -0
  25. data/pdf2json-0.52-source/doc/pdfimages.hlp +101 -0
  26. data/pdf2json-0.52-source/doc/pdfinfo.1 +158 -0
  27. data/pdf2json-0.52-source/doc/pdfinfo.cat +119 -0
  28. data/pdf2json-0.52-source/doc/pdfinfo.hlp +129 -0
  29. data/pdf2json-0.52-source/doc/pdftoppm.1 +115 -0
  30. data/pdf2json-0.52-source/doc/pdftoppm.cat +105 -0
  31. data/pdf2json-0.52-source/doc/pdftoppm.hlp +114 -0
  32. data/pdf2json-0.52-source/doc/pdftops.1 +229 -0
  33. data/pdf2json-0.52-source/doc/pdftops.cat +221 -0
  34. data/pdf2json-0.52-source/doc/pdftops.hlp +231 -0
  35. data/pdf2json-0.52-source/doc/pdftotext.1 +137 -0
  36. data/pdf2json-0.52-source/doc/pdftotext.cat +120 -0
  37. data/pdf2json-0.52-source/doc/pdftotext.hlp +133 -0
  38. data/pdf2json-0.52-source/doc/sample-xpdfrc +91 -0
  39. data/pdf2json-0.52-source/doc/xpdf.1 +513 -0
  40. data/pdf2json-0.52-source/doc/xpdf.cat +476 -0
  41. data/pdf2json-0.52-source/doc/xpdf.hlp +489 -0
  42. data/pdf2json-0.52-source/doc/xpdfrc.5 +480 -0
  43. data/pdf2json-0.52-source/doc/xpdfrc.cat +474 -0
  44. data/pdf2json-0.52-source/doc/xpdfrc.hlp +479 -0
  45. data/pdf2json-0.52-source/fofi/.DS_Store +0 -0
  46. data/pdf2json-0.52-source/fofi/FoFiBase.cc +156 -0
  47. data/pdf2json-0.52-source/fofi/FoFiBase.h +57 -0
  48. data/pdf2json-0.52-source/fofi/FoFiBase.o +0 -0
  49. data/pdf2json-0.52-source/fofi/FoFiEncodings.cc +994 -0
  50. data/pdf2json-0.52-source/fofi/FoFiEncodings.h +36 -0
  51. data/pdf2json-0.52-source/fofi/FoFiEncodings.o +0 -0
  52. data/pdf2json-0.52-source/fofi/FoFiTrueType.cc +2027 -0
  53. data/pdf2json-0.52-source/fofi/FoFiTrueType.h +174 -0
  54. data/pdf2json-0.52-source/fofi/FoFiTrueType.o +0 -0
  55. data/pdf2json-0.52-source/fofi/FoFiType1.cc +252 -0
  56. data/pdf2json-0.52-source/fofi/FoFiType1.h +59 -0
  57. data/pdf2json-0.52-source/fofi/FoFiType1.o +0 -0
  58. data/pdf2json-0.52-source/fofi/FoFiType1C.cc +2603 -0
  59. data/pdf2json-0.52-source/fofi/FoFiType1C.h +233 -0
  60. data/pdf2json-0.52-source/fofi/FoFiType1C.o +0 -0
  61. data/pdf2json-0.52-source/fofi/Makefile +70 -0
  62. data/pdf2json-0.52-source/fofi/Makefile.dep +0 -0
  63. data/pdf2json-0.52-source/fofi/Makefile.in +70 -0
  64. data/pdf2json-0.52-source/fofi/libfofi.a +0 -0
  65. data/pdf2json-0.52-source/fofi/vms_make.com +0 -0
  66. data/pdf2json-0.52-source/freetype.win32/.DS_Store +0 -0
  67. data/pdf2json-0.52-source/freetype.win32/include/.DS_Store +0 -0
  68. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftconfig.h +528 -0
  69. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftheader.h +780 -0
  70. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftmodule.h +32 -0
  71. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftoption.h +733 -0
  72. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftstdlib.h +173 -0
  73. data/pdf2json-0.52-source/freetype.win32/include/freetype/freetype.h +3919 -0
  74. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftadvanc.h +179 -0
  75. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbbox.h +94 -0
  76. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbdf.h +209 -0
  77. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbitmap.h +227 -0
  78. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcache.h +1128 -0
  79. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftchapters.h +103 -0
  80. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcid.h +166 -0
  81. data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrdef.h +244 -0
  82. data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrors.h +206 -0
  83. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgasp.h +120 -0
  84. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftglyph.h +613 -0
  85. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgxval.h +358 -0
  86. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgzip.h +102 -0
  87. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftimage.h +1313 -0
  88. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftincrem.h +353 -0
  89. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlcdfil.h +213 -0
  90. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlist.h +277 -0
  91. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlzw.h +99 -0
  92. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmac.h +274 -0
  93. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmm.h +378 -0
  94. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmodapi.h +483 -0
  95. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmoderr.h +155 -0
  96. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftotval.h +203 -0
  97. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftoutln.h +537 -0
  98. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftpfr.h +172 -0
  99. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftrender.h +230 -0
  100. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsizes.h +159 -0
  101. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsnames.h +200 -0
  102. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftstroke.h +716 -0
  103. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsynth.h +80 -0
  104. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsystem.h +347 -0
  105. data/pdf2json-0.52-source/freetype.win32/include/freetype/fttrigon.h +350 -0
  106. data/pdf2json-0.52-source/freetype.win32/include/freetype/fttypes.h +588 -0
  107. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftwinfnt.h +274 -0
  108. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftxf86.h +83 -0
  109. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/autohint.h +231 -0
  110. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftcalc.h +179 -0
  111. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdebug.h +250 -0
  112. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdriver.h +422 -0
  113. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftgloadr.h +168 -0
  114. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftmemory.h +380 -0
  115. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftobjs.h +1428 -0
  116. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftpic.h +67 -0
  117. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftrfork.h +196 -0
  118. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftserv.h +620 -0
  119. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftstream.h +539 -0
  120. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/fttrace.h +139 -0
  121. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftvalid.h +150 -0
  122. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/internal.h +51 -0
  123. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pcftypes.h +56 -0
  124. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/psaux.h +873 -0
  125. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pshints.h +712 -0
  126. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svbdf.h +77 -0
  127. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svcid.h +83 -0
  128. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgldict.h +82 -0
  129. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgxval.h +72 -0
  130. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svkern.h +51 -0
  131. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svmm.h +104 -0
  132. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svotval.h +55 -0
  133. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpfr.h +66 -0
  134. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpostnm.h +79 -0
  135. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpscmap.h +164 -0
  136. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpsinfo.h +92 -0
  137. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svsfnt.h +102 -0
  138. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttcmap.h +106 -0
  139. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svtteng.h +53 -0
  140. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttglyf.h +67 -0
  141. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svwinfnt.h +50 -0
  142. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svxf86nm.h +55 -0
  143. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/sfnt.h +897 -0
  144. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/t1types.h +270 -0
  145. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/tttypes.h +1543 -0
  146. data/pdf2json-0.52-source/freetype.win32/include/freetype/t1tables.h +504 -0
  147. data/pdf2json-0.52-source/freetype.win32/include/freetype/ttnameid.h +1247 -0
  148. data/pdf2json-0.52-source/freetype.win32/include/freetype/tttables.h +759 -0
  149. data/pdf2json-0.52-source/freetype.win32/include/freetype/tttags.h +107 -0
  150. data/pdf2json-0.52-source/freetype.win32/include/freetype/ttunpat.h +59 -0
  151. data/pdf2json-0.52-source/freetype.win32/include/ft2build.h +39 -0
  152. data/pdf2json-0.52-source/freetype.win32/lib/freetype_a.lib +0 -0
  153. data/pdf2json-0.52-source/goo/.DS_Store +0 -0
  154. data/pdf2json-0.52-source/goo/FixedPoint.cc +118 -0
  155. data/pdf2json-0.52-source/goo/FixedPoint.h +155 -0
  156. data/pdf2json-0.52-source/goo/FixedPoint.o +0 -0
  157. data/pdf2json-0.52-source/goo/GHash.cc +380 -0
  158. data/pdf2json-0.52-source/goo/GHash.h +78 -0
  159. data/pdf2json-0.52-source/goo/GHash.o +0 -0
  160. data/pdf2json-0.52-source/goo/GList.cc +97 -0
  161. data/pdf2json-0.52-source/goo/GList.h +96 -0
  162. data/pdf2json-0.52-source/goo/GList.o +0 -0
  163. data/pdf2json-0.52-source/goo/GMutex.h +49 -0
  164. data/pdf2json-0.52-source/goo/GString.cc +724 -0
  165. data/pdf2json-0.52-source/goo/GString.cc.fixed +718 -0
  166. data/pdf2json-0.52-source/goo/GString.h +136 -0
  167. data/pdf2json-0.52-source/goo/GString.o +0 -0
  168. data/pdf2json-0.52-source/goo/ImgWriter.o +0 -0
  169. data/pdf2json-0.52-source/goo/JpegWriter.o +0 -0
  170. data/pdf2json-0.52-source/goo/Makefile +72 -0
  171. data/pdf2json-0.52-source/goo/Makefile.dep +0 -0
  172. data/pdf2json-0.52-source/goo/Makefile.in +72 -0
  173. data/pdf2json-0.52-source/goo/PNGWriter.o +0 -0
  174. data/pdf2json-0.52-source/goo/gfile.cc +731 -0
  175. data/pdf2json-0.52-source/goo/gfile.h +138 -0
  176. data/pdf2json-0.52-source/goo/gfile.o +0 -0
  177. data/pdf2json-0.52-source/goo/gmem.cc +264 -0
  178. data/pdf2json-0.52-source/goo/gmem.h +79 -0
  179. data/pdf2json-0.52-source/goo/gmem.o +0 -0
  180. data/pdf2json-0.52-source/goo/gmempp.cc +32 -0
  181. data/pdf2json-0.52-source/goo/gmempp.o +0 -0
  182. data/pdf2json-0.52-source/goo/gtypes.h +29 -0
  183. data/pdf2json-0.52-source/goo/libGoo.a +0 -0
  184. data/pdf2json-0.52-source/goo/parseargs.c +190 -0
  185. data/pdf2json-0.52-source/goo/parseargs.h +71 -0
  186. data/pdf2json-0.52-source/goo/parseargs.o +0 -0
  187. data/pdf2json-0.52-source/goo/vms_directory.c +214 -0
  188. data/pdf2json-0.52-source/goo/vms_dirent.h +67 -0
  189. data/pdf2json-0.52-source/goo/vms_make.com +82 -0
  190. data/pdf2json-0.52-source/goo/vms_sys_dirent.h +54 -0
  191. data/pdf2json-0.52-source/goo/vms_unix_time.h +102 -0
  192. data/pdf2json-0.52-source/goo/vms_unix_times.c +42 -0
  193. data/pdf2json-0.52-source/goo/vms_unlink.c +22 -0
  194. data/pdf2json-0.52-source/ms_make.bat +199 -0
  195. data/pdf2json-0.52-source/splash/.DS_Store +0 -0
  196. data/pdf2json-0.52-source/splash/Makefile +103 -0
  197. data/pdf2json-0.52-source/splash/Makefile.dep +0 -0
  198. data/pdf2json-0.52-source/splash/Makefile.in +103 -0
  199. data/pdf2json-0.52-source/splash/Splash.cc +3310 -0
  200. data/pdf2json-0.52-source/splash/Splash.h +293 -0
  201. data/pdf2json-0.52-source/splash/Splash.o +0 -0
  202. data/pdf2json-0.52-source/splash/SplashBitmap.cc +188 -0
  203. data/pdf2json-0.52-source/splash/SplashBitmap.h +64 -0
  204. data/pdf2json-0.52-source/splash/SplashBitmap.o +0 -0
  205. data/pdf2json-0.52-source/splash/SplashClip.cc +382 -0
  206. data/pdf2json-0.52-source/splash/SplashClip.h +107 -0
  207. data/pdf2json-0.52-source/splash/SplashClip.o +0 -0
  208. data/pdf2json-0.52-source/splash/SplashErrorCodes.h +32 -0
  209. data/pdf2json-0.52-source/splash/SplashFTFont.cc +357 -0
  210. data/pdf2json-0.52-source/splash/SplashFTFont.h +58 -0
  211. data/pdf2json-0.52-source/splash/SplashFTFont.o +0 -0
  212. data/pdf2json-0.52-source/splash/SplashFTFontEngine.cc +179 -0
  213. data/pdf2json-0.52-source/splash/SplashFTFontEngine.h +65 -0
  214. data/pdf2json-0.52-source/splash/SplashFTFontEngine.o +0 -0
  215. data/pdf2json-0.52-source/splash/SplashFTFontFile.cc +114 -0
  216. data/pdf2json-0.52-source/splash/SplashFTFontFile.h +73 -0
  217. data/pdf2json-0.52-source/splash/SplashFTFontFile.o +0 -0
  218. data/pdf2json-0.52-source/splash/SplashFont.cc +176 -0
  219. data/pdf2json-0.52-source/splash/SplashFont.h +104 -0
  220. data/pdf2json-0.52-source/splash/SplashFont.o +0 -0
  221. data/pdf2json-0.52-source/splash/SplashFontEngine.cc +317 -0
  222. data/pdf2json-0.52-source/splash/SplashFontEngine.h +91 -0
  223. data/pdf2json-0.52-source/splash/SplashFontEngine.o +0 -0
  224. data/pdf2json-0.52-source/splash/SplashFontFile.cc +55 -0
  225. data/pdf2json-0.52-source/splash/SplashFontFile.h +60 -0
  226. data/pdf2json-0.52-source/splash/SplashFontFile.o +0 -0
  227. data/pdf2json-0.52-source/splash/SplashFontFileID.cc +23 -0
  228. data/pdf2json-0.52-source/splash/SplashFontFileID.h +30 -0
  229. data/pdf2json-0.52-source/splash/SplashFontFileID.o +0 -0
  230. data/pdf2json-0.52-source/splash/SplashGlyphBitmap.h +26 -0
  231. data/pdf2json-0.52-source/splash/SplashMath.h +89 -0
  232. data/pdf2json-0.52-source/splash/SplashPath.cc +184 -0
  233. data/pdf2json-0.52-source/splash/SplashPath.h +121 -0
  234. data/pdf2json-0.52-source/splash/SplashPath.o +0 -0
  235. data/pdf2json-0.52-source/splash/SplashPattern.cc +40 -0
  236. data/pdf2json-0.52-source/splash/SplashPattern.h +65 -0
  237. data/pdf2json-0.52-source/splash/SplashPattern.o +0 -0
  238. data/pdf2json-0.52-source/splash/SplashScreen.cc +383 -0
  239. data/pdf2json-0.52-source/splash/SplashScreen.h +56 -0
  240. data/pdf2json-0.52-source/splash/SplashScreen.o +0 -0
  241. data/pdf2json-0.52-source/splash/SplashState.cc +165 -0
  242. data/pdf2json-0.52-source/splash/SplashState.h +103 -0
  243. data/pdf2json-0.52-source/splash/SplashState.o +0 -0
  244. data/pdf2json-0.52-source/splash/SplashT1Font.cc +287 -0
  245. data/pdf2json-0.52-source/splash/SplashT1Font.h +57 -0
  246. data/pdf2json-0.52-source/splash/SplashT1Font.o +0 -0
  247. data/pdf2json-0.52-source/splash/SplashT1FontEngine.cc +124 -0
  248. data/pdf2json-0.52-source/splash/SplashT1FontEngine.h +53 -0
  249. data/pdf2json-0.52-source/splash/SplashT1FontEngine.o +0 -0
  250. data/pdf2json-0.52-source/splash/SplashT1FontFile.cc +97 -0
  251. data/pdf2json-0.52-source/splash/SplashT1FontFile.h +58 -0
  252. data/pdf2json-0.52-source/splash/SplashT1FontFile.o +0 -0
  253. data/pdf2json-0.52-source/splash/SplashTypes.h +132 -0
  254. data/pdf2json-0.52-source/splash/SplashXPath.cc +438 -0
  255. data/pdf2json-0.52-source/splash/SplashXPath.h +100 -0
  256. data/pdf2json-0.52-source/splash/SplashXPath.o +0 -0
  257. data/pdf2json-0.52-source/splash/SplashXPathScanner.cc +428 -0
  258. data/pdf2json-0.52-source/splash/SplashXPathScanner.h +87 -0
  259. data/pdf2json-0.52-source/splash/SplashXPathScanner.o +0 -0
  260. data/pdf2json-0.52-source/splash/libsplash.a +0 -0
  261. data/pdf2json-0.52-source/splash/vms_make.com +0 -0
  262. data/pdf2json-0.52-source/src/.DS_Store +0 -0
  263. data/pdf2json-0.52-source/src/GVector.h +101 -0
  264. data/pdf2json-0.52-source/src/ImgOutputDev.cc +1243 -0
  265. data/pdf2json-0.52-source/src/ImgOutputDev.h +307 -0
  266. data/pdf2json-0.52-source/src/ImgOutputDev.o +0 -0
  267. data/pdf2json-0.52-source/src/Makefile +68 -0
  268. data/pdf2json-0.52-source/src/Makefile.in +68 -0
  269. data/pdf2json-0.52-source/src/XmlFonts.cc +367 -0
  270. data/pdf2json-0.52-source/src/XmlFonts.h +91 -0
  271. data/pdf2json-0.52-source/src/XmlFonts.o +0 -0
  272. data/pdf2json-0.52-source/src/XmlLinks.cc +101 -0
  273. data/pdf2json-0.52-source/src/XmlLinks.h +54 -0
  274. data/pdf2json-0.52-source/src/XmlLinks.o +0 -0
  275. data/pdf2json-0.52-source/src/pdf2json +0 -0
  276. data/pdf2json-0.52-source/src/pdf2json.cc +343 -0
  277. data/pdf2json-0.52-source/src/pdf2json.o +0 -0
  278. data/pdf2json-0.52-source/src/pdf2xml.dtd +22 -0
  279. data/pdf2json-0.52-source/src/pdf2xmljson.dtd +9 -0
  280. data/pdf2json-0.52-source/xpdf/.DS_Store +0 -0
  281. data/pdf2json-0.52-source/xpdf/Annot.cc +1556 -0
  282. data/pdf2json-0.52-source/xpdf/Annot.h +142 -0
  283. data/pdf2json-0.52-source/xpdf/Annot.o +0 -0
  284. data/pdf2json-0.52-source/xpdf/Array.cc +73 -0
  285. data/pdf2json-0.52-source/xpdf/Array.h +58 -0
  286. data/pdf2json-0.52-source/xpdf/Array.o +0 -0
  287. data/pdf2json-0.52-source/xpdf/BuiltinFont.cc +65 -0
  288. data/pdf2json-0.52-source/xpdf/BuiltinFont.h +57 -0
  289. data/pdf2json-0.52-source/xpdf/BuiltinFont.o +0 -0
  290. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.cc +4284 -0
  291. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.h +23 -0
  292. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.o +0 -0
  293. data/pdf2json-0.52-source/xpdf/CMap.cc +408 -0
  294. data/pdf2json-0.52-source/xpdf/CMap.h +102 -0
  295. data/pdf2json-0.52-source/xpdf/CMap.o +0 -0
  296. data/pdf2json-0.52-source/xpdf/Catalog.cc +374 -0
  297. data/pdf2json-0.52-source/xpdf/Catalog.h +97 -0
  298. data/pdf2json-0.52-source/xpdf/Catalog.o +0 -0
  299. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.cc +540 -0
  300. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.h +117 -0
  301. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.o +0 -0
  302. data/pdf2json-0.52-source/xpdf/CharTypes.h +24 -0
  303. data/pdf2json-0.52-source/xpdf/CompactFontTables.h +464 -0
  304. data/pdf2json-0.52-source/xpdf/CoreOutputDev.cc +61 -0
  305. data/pdf2json-0.52-source/xpdf/CoreOutputDev.h +61 -0
  306. data/pdf2json-0.52-source/xpdf/Decrypt.cc +776 -0
  307. data/pdf2json-0.52-source/xpdf/Decrypt.h +95 -0
  308. data/pdf2json-0.52-source/xpdf/Decrypt.o +0 -0
  309. data/pdf2json-0.52-source/xpdf/Dict.cc +95 -0
  310. data/pdf2json-0.52-source/xpdf/Dict.h +77 -0
  311. data/pdf2json-0.52-source/xpdf/Dict.o +0 -0
  312. data/pdf2json-0.52-source/xpdf/Error.cc +38 -0
  313. data/pdf2json-0.52-source/xpdf/Error.h +23 -0
  314. data/pdf2json-0.52-source/xpdf/Error.o +0 -0
  315. data/pdf2json-0.52-source/xpdf/ErrorCodes.h +36 -0
  316. data/pdf2json-0.52-source/xpdf/FontEncodingTables.cc +1824 -0
  317. data/pdf2json-0.52-source/xpdf/FontEncodingTables.h +20 -0
  318. data/pdf2json-0.52-source/xpdf/FontEncodingTables.o +0 -0
  319. data/pdf2json-0.52-source/xpdf/Function.cc +1573 -0
  320. data/pdf2json-0.52-source/xpdf/Function.h +229 -0
  321. data/pdf2json-0.52-source/xpdf/Function.o +0 -0
  322. data/pdf2json-0.52-source/xpdf/Gfx.cc +4187 -0
  323. data/pdf2json-0.52-source/xpdf/Gfx.h +312 -0
  324. data/pdf2json-0.52-source/xpdf/Gfx.o +0 -0
  325. data/pdf2json-0.52-source/xpdf/GfxFont.cc +1568 -0
  326. data/pdf2json-0.52-source/xpdf/GfxFont.h +320 -0
  327. data/pdf2json-0.52-source/xpdf/GfxFont.o +0 -0
  328. data/pdf2json-0.52-source/xpdf/GfxState.cc +4137 -0
  329. data/pdf2json-0.52-source/xpdf/GfxState.h +1244 -0
  330. data/pdf2json-0.52-source/xpdf/GfxState.o +0 -0
  331. data/pdf2json-0.52-source/xpdf/GlobalParams.cc +2924 -0
  332. data/pdf2json-0.52-source/xpdf/GlobalParams.cc.old +2908 -0
  333. data/pdf2json-0.52-source/xpdf/GlobalParams.h +466 -0
  334. data/pdf2json-0.52-source/xpdf/GlobalParams.h.old +463 -0
  335. data/pdf2json-0.52-source/xpdf/GlobalParams.o +0 -0
  336. data/pdf2json-0.52-source/xpdf/ImageOutputDev.cc +195 -0
  337. data/pdf2json-0.52-source/xpdf/ImageOutputDev.h +76 -0
  338. data/pdf2json-0.52-source/xpdf/ImageOutputDev.o +0 -0
  339. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.cc +322 -0
  340. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.h +109 -0
  341. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.o +0 -0
  342. data/pdf2json-0.52-source/xpdf/JBIG2Stream.cc +3413 -0
  343. data/pdf2json-0.52-source/xpdf/JBIG2Stream.h +145 -0
  344. data/pdf2json-0.52-source/xpdf/JBIG2Stream.o +0 -0
  345. data/pdf2json-0.52-source/xpdf/JPXStream.cc +3144 -0
  346. data/pdf2json-0.52-source/xpdf/JPXStream.h +351 -0
  347. data/pdf2json-0.52-source/xpdf/JPXStream.o +0 -0
  348. data/pdf2json-0.52-source/xpdf/Lexer.cc +485 -0
  349. data/pdf2json-0.52-source/xpdf/Lexer.h +80 -0
  350. data/pdf2json-0.52-source/xpdf/Lexer.o +0 -0
  351. data/pdf2json-0.52-source/xpdf/Link.cc +806 -0
  352. data/pdf2json-0.52-source/xpdf/Link.cc.old +784 -0
  353. data/pdf2json-0.52-source/xpdf/Link.h +415 -0
  354. data/pdf2json-0.52-source/xpdf/Link.h.old +369 -0
  355. data/pdf2json-0.52-source/xpdf/Link.o +0 -0
  356. data/pdf2json-0.52-source/xpdf/Makefile +232 -0
  357. data/pdf2json-0.52-source/xpdf/Makefile.dep +0 -0
  358. data/pdf2json-0.52-source/xpdf/Makefile.in +232 -0
  359. data/pdf2json-0.52-source/xpdf/NameToCharCode.cc +116 -0
  360. data/pdf2json-0.52-source/xpdf/NameToCharCode.h +42 -0
  361. data/pdf2json-0.52-source/xpdf/NameToCharCode.o +0 -0
  362. data/pdf2json-0.52-source/xpdf/NameToUnicodeTable.h +1097 -0
  363. data/pdf2json-0.52-source/xpdf/Object.cc +231 -0
  364. data/pdf2json-0.52-source/xpdf/Object.h +303 -0
  365. data/pdf2json-0.52-source/xpdf/Object.o +0 -0
  366. data/pdf2json-0.52-source/xpdf/Outline.cc +151 -0
  367. data/pdf2json-0.52-source/xpdf/Outline.h +76 -0
  368. data/pdf2json-0.52-source/xpdf/Outline.o +0 -0
  369. data/pdf2json-0.52-source/xpdf/OutputDev.cc +131 -0
  370. data/pdf2json-0.52-source/xpdf/OutputDev.h +253 -0
  371. data/pdf2json-0.52-source/xpdf/OutputDev.o +0 -0
  372. data/pdf2json-0.52-source/xpdf/PDFCore.cc +2044 -0
  373. data/pdf2json-0.52-source/xpdf/PDFCore.h +321 -0
  374. data/pdf2json-0.52-source/xpdf/PDFDoc.cc +404 -0
  375. data/pdf2json-0.52-source/xpdf/PDFDoc.h +183 -0
  376. data/pdf2json-0.52-source/xpdf/PDFDoc.o +0 -0
  377. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.cc +44 -0
  378. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.h +16 -0
  379. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.o +0 -0
  380. data/pdf2json-0.52-source/xpdf/PSOutputDev.cc +6224 -0
  381. data/pdf2json-0.52-source/xpdf/PSOutputDev.h +395 -0
  382. data/pdf2json-0.52-source/xpdf/PSOutputDev.o +0 -0
  383. data/pdf2json-0.52-source/xpdf/PSTokenizer.cc +135 -0
  384. data/pdf2json-0.52-source/xpdf/PSTokenizer.h +41 -0
  385. data/pdf2json-0.52-source/xpdf/PSTokenizer.o +0 -0
  386. data/pdf2json-0.52-source/xpdf/Page.cc +454 -0
  387. data/pdf2json-0.52-source/xpdf/Page.h +187 -0
  388. data/pdf2json-0.52-source/xpdf/Page.o +0 -0
  389. data/pdf2json-0.52-source/xpdf/Parser.cc +227 -0
  390. data/pdf2json-0.52-source/xpdf/Parser.h +59 -0
  391. data/pdf2json-0.52-source/xpdf/Parser.o +0 -0
  392. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.cc +257 -0
  393. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.h +130 -0
  394. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.o +0 -0
  395. data/pdf2json-0.52-source/xpdf/SecurityHandler.cc +390 -0
  396. data/pdf2json-0.52-source/xpdf/SecurityHandler.h +160 -0
  397. data/pdf2json-0.52-source/xpdf/SecurityHandler.o +0 -0
  398. data/pdf2json-0.52-source/xpdf/SplashOutputDev.cc +2845 -0
  399. data/pdf2json-0.52-source/xpdf/SplashOutputDev.h +247 -0
  400. data/pdf2json-0.52-source/xpdf/SplashOutputDev.o +0 -0
  401. data/pdf2json-0.52-source/xpdf/Stream-CCITT.h +459 -0
  402. data/pdf2json-0.52-source/xpdf/Stream.cc +4627 -0
  403. data/pdf2json-0.52-source/xpdf/Stream.h +858 -0
  404. data/pdf2json-0.52-source/xpdf/Stream.o +0 -0
  405. data/pdf2json-0.52-source/xpdf/TextOutputDev.cc +4090 -0
  406. data/pdf2json-0.52-source/xpdf/TextOutputDev.h +661 -0
  407. data/pdf2json-0.52-source/xpdf/TextOutputDev.o +0 -0
  408. data/pdf2json-0.52-source/xpdf/UTF8.h +56 -0
  409. data/pdf2json-0.52-source/xpdf/UnicodeMap.cc +302 -0
  410. data/pdf2json-0.52-source/xpdf/UnicodeMap.cc.old +293 -0
  411. data/pdf2json-0.52-source/xpdf/UnicodeMap.h +135 -0
  412. data/pdf2json-0.52-source/xpdf/UnicodeMap.h.old +123 -0
  413. data/pdf2json-0.52-source/xpdf/UnicodeMap.o +0 -0
  414. data/pdf2json-0.52-source/xpdf/UnicodeMapTables.h +361 -0
  415. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.cc +949 -0
  416. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.h +20 -0
  417. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.o +0 -0
  418. data/pdf2json-0.52-source/xpdf/XPDFApp.cc +447 -0
  419. data/pdf2json-0.52-source/xpdf/XPDFApp.h +114 -0
  420. data/pdf2json-0.52-source/xpdf/XPDFCore.cc +1655 -0
  421. data/pdf2json-0.52-source/xpdf/XPDFCore.h +251 -0
  422. data/pdf2json-0.52-source/xpdf/XPDFTree.cc +931 -0
  423. data/pdf2json-0.52-source/xpdf/XPDFTree.h +45 -0
  424. data/pdf2json-0.52-source/xpdf/XPDFTreeP.h +87 -0
  425. data/pdf2json-0.52-source/xpdf/XPDFViewer.cc +3488 -0
  426. data/pdf2json-0.52-source/xpdf/XPDFViewer.h +352 -0
  427. data/pdf2json-0.52-source/xpdf/XRef.cc +896 -0
  428. data/pdf2json-0.52-source/xpdf/XRef.h +133 -0
  429. data/pdf2json-0.52-source/xpdf/XRef.o +0 -0
  430. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.cc +262 -0
  431. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.h +341 -0
  432. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.o +0 -0
  433. data/pdf2json-0.52-source/xpdf/about-text.h +48 -0
  434. data/pdf2json-0.52-source/xpdf/about.xbm +6 -0
  435. data/pdf2json-0.52-source/xpdf/backArrow.xbm +6 -0
  436. data/pdf2json-0.52-source/xpdf/backArrowDis.xbm +6 -0
  437. data/pdf2json-0.52-source/xpdf/config.h +112 -0
  438. data/pdf2json-0.52-source/xpdf/dblLeftArrow.xbm +6 -0
  439. data/pdf2json-0.52-source/xpdf/dblLeftArrowDis.xbm +6 -0
  440. data/pdf2json-0.52-source/xpdf/dblRightArrow.xbm +6 -0
  441. data/pdf2json-0.52-source/xpdf/dblRightArrowDis.xbm +6 -0
  442. data/pdf2json-0.52-source/xpdf/find.xbm +6 -0
  443. data/pdf2json-0.52-source/xpdf/findDis.xbm +6 -0
  444. data/pdf2json-0.52-source/xpdf/forwardArrow.xbm +6 -0
  445. data/pdf2json-0.52-source/xpdf/forwardArrowDis.xbm +6 -0
  446. data/pdf2json-0.52-source/xpdf/leftArrow.xbm +5 -0
  447. data/pdf2json-0.52-source/xpdf/leftArrowDis.xbm +5 -0
  448. data/pdf2json-0.52-source/xpdf/libXpdf.a +0 -0
  449. data/pdf2json-0.52-source/xpdf/pdffonts +0 -0
  450. data/pdf2json-0.52-source/xpdf/pdffonts.cc +298 -0
  451. data/pdf2json-0.52-source/xpdf/pdffonts.o +0 -0
  452. data/pdf2json-0.52-source/xpdf/pdfimages +0 -0
  453. data/pdf2json-0.52-source/xpdf/pdfimages.cc +155 -0
  454. data/pdf2json-0.52-source/xpdf/pdfimages.o +0 -0
  455. data/pdf2json-0.52-source/xpdf/pdfinfo +0 -0
  456. data/pdf2json-0.52-source/xpdf/pdfinfo.cc +387 -0
  457. data/pdf2json-0.52-source/xpdf/pdfinfo.o +0 -0
  458. data/pdf2json-0.52-source/xpdf/pdftoppm.cc +203 -0
  459. data/pdf2json-0.52-source/xpdf/pdftops +0 -0
  460. data/pdf2json-0.52-source/xpdf/pdftops.cc +344 -0
  461. data/pdf2json-0.52-source/xpdf/pdftops.o +0 -0
  462. data/pdf2json-0.52-source/xpdf/pdftotext +0 -0
  463. data/pdf2json-0.52-source/xpdf/pdftotext.cc +333 -0
  464. data/pdf2json-0.52-source/xpdf/pdftotext.o +0 -0
  465. data/pdf2json-0.52-source/xpdf/print.xbm +6 -0
  466. data/pdf2json-0.52-source/xpdf/printDis.xbm +6 -0
  467. data/pdf2json-0.52-source/xpdf/rightArrow.xbm +5 -0
  468. data/pdf2json-0.52-source/xpdf/rightArrowDis.xbm +5 -0
  469. data/pdf2json-0.52-source/xpdf/vms_make.com +129 -0
  470. data/pdf2json-0.52-source/xpdf/xpdf.cc +344 -0
  471. data/pdf2json-0.52-source/xpdf/xpdfIcon.xpm +62 -0
  472. data/pdf2json.gemspec +29 -0
  473. metadata +518 -0
@@ -0,0 +1,320 @@
1
+ //========================================================================
2
+ //
3
+ // GfxFont.h
4
+ //
5
+ // Copyright 1996-2003 Glyph & Cog, LLC
6
+ //
7
+ //========================================================================
8
+
9
+ #ifndef GFXFONT_H
10
+ #define GFXFONT_H
11
+
12
+ #include <aconf.h>
13
+
14
+ #ifdef USE_GCC_PRAGMAS
15
+ #pragma interface
16
+ #endif
17
+
18
+ #include "gtypes.h"
19
+ #include "GString.h"
20
+ #include "Object.h"
21
+ #include "CharTypes.h"
22
+
23
+ class Dict;
24
+ class CMap;
25
+ class CharCodeToUnicode;
26
+ class FoFiTrueType;
27
+ struct GfxFontCIDWidths;
28
+
29
+ //------------------------------------------------------------------------
30
+ // GfxFontType
31
+ //------------------------------------------------------------------------
32
+
33
+ enum GfxFontType {
34
+ //----- Gfx8BitFont
35
+ fontUnknownType,
36
+ fontType1,
37
+ fontType1C,
38
+ fontType1COT,
39
+ fontType3,
40
+ fontTrueType,
41
+ fontTrueTypeOT,
42
+ //----- GfxCIDFont
43
+ fontCIDType0,
44
+ fontCIDType0C,
45
+ fontCIDType0COT,
46
+ fontCIDType2,
47
+ fontCIDType2OT
48
+ };
49
+
50
+ //------------------------------------------------------------------------
51
+ // GfxFontCIDWidths
52
+ //------------------------------------------------------------------------
53
+
54
+ struct GfxFontCIDWidthExcep {
55
+ CID first; // this record applies to
56
+ CID last; // CIDs <first>..<last>
57
+ double width; // char width
58
+ };
59
+
60
+ struct GfxFontCIDWidthExcepV {
61
+ CID first; // this record applies to
62
+ CID last; // CIDs <first>..<last>
63
+ double height; // char height
64
+ double vx, vy; // origin position
65
+ };
66
+
67
+ struct GfxFontCIDWidths {
68
+ double defWidth; // default char width
69
+ double defHeight; // default char height
70
+ double defVY; // default origin position
71
+ GfxFontCIDWidthExcep *exceps; // exceptions
72
+ int nExceps; // number of valid entries in exceps
73
+ GfxFontCIDWidthExcepV * // exceptions for vertical font
74
+ excepsV;
75
+ int nExcepsV; // number of valid entries in excepsV
76
+ };
77
+
78
+ //------------------------------------------------------------------------
79
+ // GfxFont
80
+ //------------------------------------------------------------------------
81
+
82
+ #define fontFixedWidth (1 << 0)
83
+ #define fontSerif (1 << 1)
84
+ #define fontSymbolic (1 << 2)
85
+ #define fontItalic (1 << 6)
86
+ #define fontBold (1 << 18)
87
+
88
+ class GfxFont {
89
+ public:
90
+
91
+ // Build a GfxFont object.
92
+ static GfxFont *makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict);
93
+
94
+ GfxFont(char *tagA, Ref idA, GString *nameA);
95
+
96
+ virtual ~GfxFont();
97
+
98
+ GBool isOk() { return ok; }
99
+
100
+ // Get font tag.
101
+ GString *getTag() { return tag; }
102
+
103
+ // Get font dictionary ID.
104
+ Ref *getID() { return &id; }
105
+
106
+ // Does this font match the tag?
107
+ GBool matches(char *tagA) { return !tag->cmp(tagA); }
108
+
109
+ // Get base font name.
110
+ GString *getName() { return name; }
111
+
112
+ // Get the original font name (ignornig any munging that might have
113
+ // been done to map to a canonical Base-14 font name).
114
+ GString *getOrigName() { return origName; }
115
+
116
+ // Get font type.
117
+ GfxFontType getType() { return type; }
118
+ virtual GBool isCIDFont() { return gFalse; }
119
+
120
+ // Get embedded font ID, i.e., a ref for the font file stream.
121
+ // Returns false if there is no embedded font.
122
+ GBool getEmbeddedFontID(Ref *embID)
123
+ { *embID = embFontID; return embFontID.num >= 0; }
124
+
125
+ // Get the PostScript font name for the embedded font. Returns
126
+ // NULL if there is no embedded font.
127
+ GString *getEmbeddedFontName() { return embFontName; }
128
+
129
+ // Get the name of the external font file. Returns NULL if there
130
+ // is no external font file.
131
+ GString *getExtFontFile() { return extFontFile; }
132
+
133
+ // Get font descriptor flags.
134
+ int getFlags() { return flags; }
135
+ GBool isFixedWidth() { return flags & fontFixedWidth; }
136
+ GBool isSerif() { return flags & fontSerif; }
137
+ GBool isSymbolic() { return flags & fontSymbolic; }
138
+ GBool isItalic() { return flags & fontItalic; }
139
+ GBool isBold() { return flags & fontBold; }
140
+
141
+ // Return the font matrix.
142
+ double *getFontMatrix() { return fontMat; }
143
+
144
+ // Return the font bounding box.
145
+ double *getFontBBox() { return fontBBox; }
146
+
147
+ // Return the ascent and descent values.
148
+ double getAscent() { return ascent; }
149
+ double getDescent() { return descent; }
150
+
151
+ // Return the writing mode (0=horizontal, 1=vertical).
152
+ virtual int getWMode() { return 0; }
153
+
154
+ // Read an external or embedded font file into a buffer.
155
+ char *readExtFontFile(int *len);
156
+ char *readEmbFontFile(XRef *xref, int *len);
157
+
158
+ // Get the next char from a string <s> of <len> bytes, returning the
159
+ // char <code>, its Unicode mapping <u>, its displacement vector
160
+ // (<dx>, <dy>), and its origin offset vector (<ox>, <oy>). <uSize>
161
+ // is the number of entries available in <u>, and <uLen> is set to
162
+ // the number actually used. Returns the number of bytes used by
163
+ // the char code.
164
+ virtual int getNextChar(char *s, int len, CharCode *code,
165
+ Unicode *u, int uSize, int *uLen,
166
+ double *dx, double *dy, double *ox, double *oy) = 0;
167
+
168
+ protected:
169
+
170
+ void readFontDescriptor(XRef *xref, Dict *fontDict);
171
+ CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits,
172
+ CharCodeToUnicode *ctu);
173
+ void findExtFontFile();
174
+
175
+ GString *tag; // PDF font tag
176
+ Ref id; // reference (used as unique ID)
177
+ GString *name; // font name
178
+ GString *origName; // original font name
179
+ GfxFontType type; // type of font
180
+ int flags; // font descriptor flags
181
+ GString *embFontName; // name of embedded font
182
+ Ref embFontID; // ref to embedded font file stream
183
+ GString *extFontFile; // external font file name
184
+ double fontMat[6]; // font matrix (Type 3 only)
185
+ double fontBBox[4]; // font bounding box (Type 3 only)
186
+ double missingWidth; // "default" width
187
+ double ascent; // max height above baseline
188
+ double descent; // max depth below baseline
189
+ GBool ok;
190
+ };
191
+
192
+ //------------------------------------------------------------------------
193
+ // Gfx8BitFont
194
+ //------------------------------------------------------------------------
195
+
196
+ class Gfx8BitFont: public GfxFont {
197
+ public:
198
+
199
+ Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
200
+ GfxFontType typeA, Dict *fontDict);
201
+
202
+ virtual ~Gfx8BitFont();
203
+
204
+ virtual int getNextChar(char *s, int len, CharCode *code,
205
+ Unicode *u, int uSize, int *uLen,
206
+ double *dx, double *dy, double *ox, double *oy);
207
+
208
+ // Return the encoding.
209
+ char **getEncoding() { return enc; }
210
+
211
+ // Return the Unicode map.
212
+ CharCodeToUnicode *getToUnicode();
213
+
214
+ // Return the character name associated with <code>.
215
+ char *getCharName(int code) { return enc[code]; }
216
+
217
+ // Returns true if the PDF font specified an encoding.
218
+ GBool getHasEncoding() { return hasEncoding; }
219
+
220
+ // Returns true if the PDF font specified MacRomanEncoding.
221
+ GBool getUsesMacRomanEnc() { return usesMacRomanEnc; }
222
+
223
+ // Get width of a character.
224
+ double getWidth(Guchar c) { return widths[c]; }
225
+
226
+ // Return a char code-to-GID mapping for the provided font file.
227
+ // (This is only useful for TrueType fonts.)
228
+ Gushort *getCodeToGIDMap(FoFiTrueType *ff);
229
+
230
+ // Return the Type 3 CharProc dictionary, or NULL if none.
231
+ Dict *getCharProcs();
232
+
233
+ // Return the Type 3 CharProc for the character associated with <code>.
234
+ Object *getCharProc(int code, Object *proc);
235
+
236
+ // Return the Type 3 Resources dictionary, or NULL if none.
237
+ Dict *getResources();
238
+
239
+ private:
240
+
241
+ char *enc[256]; // char code --> char name
242
+ char encFree[256]; // boolean for each char name: if set,
243
+ // the string is malloc'ed
244
+ CharCodeToUnicode *ctu; // char code --> Unicode
245
+ GBool hasEncoding;
246
+ GBool usesMacRomanEnc;
247
+ double widths[256]; // character widths
248
+ Object charProcs; // Type 3 CharProcs dictionary
249
+ Object resources; // Type 3 Resources dictionary
250
+ };
251
+
252
+ //------------------------------------------------------------------------
253
+ // GfxCIDFont
254
+ //------------------------------------------------------------------------
255
+
256
+ class GfxCIDFont: public GfxFont {
257
+ public:
258
+
259
+ GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
260
+ Dict *fontDict);
261
+
262
+ virtual ~GfxCIDFont();
263
+
264
+ virtual GBool isCIDFont() { return gTrue; }
265
+
266
+ virtual int getNextChar(char *s, int len, CharCode *code,
267
+ Unicode *u, int uSize, int *uLen,
268
+ double *dx, double *dy, double *ox, double *oy);
269
+
270
+ // Return the writing mode (0=horizontal, 1=vertical).
271
+ virtual int getWMode();
272
+
273
+ // Return the Unicode map.
274
+ CharCodeToUnicode *getToUnicode();
275
+
276
+ // Get the collection name (<registry>-<ordering>).
277
+ GString *getCollection();
278
+
279
+ // Return the CID-to-GID mapping table. These should only be called
280
+ // if type is fontCIDType2.
281
+ Gushort *getCIDToGID() { return cidToGID; }
282
+ int getCIDToGIDLen() { return cidToGIDLen; }
283
+
284
+ private:
285
+
286
+ CMap *cMap; // char code --> CID
287
+ CharCodeToUnicode *ctu; // CID --> Unicode
288
+ GfxFontCIDWidths widths; // character widths
289
+ Gushort *cidToGID; // CID --> GID mapping (for embedded
290
+ // TrueType fonts)
291
+ int cidToGIDLen;
292
+ };
293
+
294
+ //------------------------------------------------------------------------
295
+ // GfxFontDict
296
+ //------------------------------------------------------------------------
297
+
298
+ class GfxFontDict {
299
+ public:
300
+
301
+ // Build the font dictionary, given the PDF font dictionary.
302
+ GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict);
303
+
304
+ // Destructor.
305
+ ~GfxFontDict();
306
+
307
+ // Get the specified font.
308
+ GfxFont *lookup(char *tag);
309
+
310
+ // Iterative access.
311
+ int getNumFonts() { return numFonts; }
312
+ GfxFont *getFont(int i) { return fonts[i]; }
313
+
314
+ private:
315
+
316
+ GfxFont **fonts; // list of fonts
317
+ int numFonts; // number of fonts
318
+ };
319
+
320
+ #endif
Binary file
@@ -0,0 +1,4137 @@
1
+ //========================================================================
2
+ //
3
+ // GfxState.cc
4
+ //
5
+ // Copyright 1996-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 <stddef.h>
16
+ #include <math.h>
17
+ #include <string.h>
18
+ #include "gmem.h"
19
+ #include "Error.h"
20
+ #include "Object.h"
21
+ #include "Array.h"
22
+ #include "Page.h"
23
+ #include "GfxState.h"
24
+
25
+ //------------------------------------------------------------------------
26
+
27
+ static inline GfxColorComp clip01(GfxColorComp x) {
28
+ return (x < 0) ? 0 : (x > gfxColorComp1) ? gfxColorComp1 : x;
29
+ }
30
+
31
+ static inline double clip01(double x) {
32
+ return (x < 0) ? 0 : (x > 1) ? 1 : x;
33
+ }
34
+
35
+ //------------------------------------------------------------------------
36
+
37
+ struct GfxBlendModeInfo {
38
+ char *name;
39
+ GfxBlendMode mode;
40
+ };
41
+
42
+ static GfxBlendModeInfo gfxBlendModeNames[] = {
43
+ { "Normal", gfxBlendNormal },
44
+ { "Compatible", gfxBlendNormal },
45
+ { "Multiply", gfxBlendMultiply },
46
+ { "Screen", gfxBlendScreen },
47
+ { "Overlay", gfxBlendOverlay },
48
+ { "Darken", gfxBlendDarken },
49
+ { "Lighten", gfxBlendLighten },
50
+ { "ColorDodge", gfxBlendColorDodge },
51
+ { "ColorBurn", gfxBlendColorBurn },
52
+ { "HardLight", gfxBlendHardLight },
53
+ { "SoftLight", gfxBlendSoftLight },
54
+ { "Difference", gfxBlendDifference },
55
+ { "Exclusion", gfxBlendExclusion },
56
+ { "Hue", gfxBlendHue },
57
+ { "Saturation", gfxBlendSaturation },
58
+ { "Color", gfxBlendColor },
59
+ { "Luminosity", gfxBlendLuminosity }
60
+ };
61
+
62
+ #define nGfxBlendModeNames \
63
+ ((int)((sizeof(gfxBlendModeNames) / sizeof(GfxBlendModeInfo))))
64
+
65
+ //------------------------------------------------------------------------
66
+
67
+ // NB: This must match the GfxColorSpaceMode enum defined in
68
+ // GfxState.h
69
+ static char *gfxColorSpaceModeNames[] = {
70
+ "DeviceGray",
71
+ "CalGray",
72
+ "DeviceRGB",
73
+ "CalRGB",
74
+ "DeviceCMYK",
75
+ "Lab",
76
+ "ICCBased",
77
+ "Indexed",
78
+ "Separation",
79
+ "DeviceN",
80
+ "Pattern"
81
+ };
82
+
83
+ #define nGfxColorSpaceModes ((sizeof(gfxColorSpaceModeNames) / sizeof(char *)))
84
+
85
+ //------------------------------------------------------------------------
86
+ // GfxColorSpace
87
+ //------------------------------------------------------------------------
88
+
89
+ GfxColorSpace::GfxColorSpace() {
90
+ }
91
+
92
+ GfxColorSpace::~GfxColorSpace() {
93
+ }
94
+
95
+ GfxColorSpace *GfxColorSpace::parse(Object *csObj) {
96
+ GfxColorSpace *cs;
97
+ Object obj1;
98
+
99
+ cs = NULL;
100
+ if (csObj->isName()) {
101
+ if (csObj->isName("DeviceGray") || csObj->isName("G")) {
102
+ cs = new GfxDeviceGrayColorSpace();
103
+ } else if (csObj->isName("DeviceRGB") || csObj->isName("RGB")) {
104
+ cs = new GfxDeviceRGBColorSpace();
105
+ } else if (csObj->isName("DeviceCMYK") || csObj->isName("CMYK")) {
106
+ cs = new GfxDeviceCMYKColorSpace();
107
+ } else if (csObj->isName("Pattern")) {
108
+ cs = new GfxPatternColorSpace(NULL);
109
+ } else {
110
+ error(-1, "Bad color space '%s'", csObj->getName());
111
+ }
112
+ } else if (csObj->isArray()) {
113
+ csObj->arrayGet(0, &obj1);
114
+ if (obj1.isName("DeviceGray") || obj1.isName("G")) {
115
+ cs = new GfxDeviceGrayColorSpace();
116
+ } else if (obj1.isName("DeviceRGB") || obj1.isName("RGB")) {
117
+ cs = new GfxDeviceRGBColorSpace();
118
+ } else if (obj1.isName("DeviceCMYK") || obj1.isName("CMYK")) {
119
+ cs = new GfxDeviceCMYKColorSpace();
120
+ } else if (obj1.isName("CalGray")) {
121
+ cs = GfxCalGrayColorSpace::parse(csObj->getArray());
122
+ } else if (obj1.isName("CalRGB")) {
123
+ cs = GfxCalRGBColorSpace::parse(csObj->getArray());
124
+ } else if (obj1.isName("Lab")) {
125
+ cs = GfxLabColorSpace::parse(csObj->getArray());
126
+ } else if (obj1.isName("ICCBased")) {
127
+ cs = GfxICCBasedColorSpace::parse(csObj->getArray());
128
+ } else if (obj1.isName("Indexed") || obj1.isName("I")) {
129
+ cs = GfxIndexedColorSpace::parse(csObj->getArray());
130
+ } else if (obj1.isName("Separation")) {
131
+ cs = GfxSeparationColorSpace::parse(csObj->getArray());
132
+ } else if (obj1.isName("DeviceN")) {
133
+ cs = GfxDeviceNColorSpace::parse(csObj->getArray());
134
+ } else if (obj1.isName("Pattern")) {
135
+ cs = GfxPatternColorSpace::parse(csObj->getArray());
136
+ } else {
137
+ error(-1, "Bad color space");
138
+ }
139
+ obj1.free();
140
+ } else {
141
+ error(-1, "Bad color space - expected name or array");
142
+ }
143
+ return cs;
144
+ }
145
+
146
+ void GfxColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange,
147
+ int maxImgPixel) {
148
+ int i;
149
+
150
+ for (i = 0; i < getNComps(); ++i) {
151
+ decodeLow[i] = 0;
152
+ decodeRange[i] = 1;
153
+ }
154
+ }
155
+
156
+ int GfxColorSpace::getNumColorSpaceModes() {
157
+ return nGfxColorSpaceModes;
158
+ }
159
+
160
+ char *GfxColorSpace::getColorSpaceModeName(int idx) {
161
+ return gfxColorSpaceModeNames[idx];
162
+ }
163
+
164
+ //------------------------------------------------------------------------
165
+ // GfxDeviceGrayColorSpace
166
+ //------------------------------------------------------------------------
167
+
168
+ GfxDeviceGrayColorSpace::GfxDeviceGrayColorSpace() {
169
+ }
170
+
171
+ GfxDeviceGrayColorSpace::~GfxDeviceGrayColorSpace() {
172
+ }
173
+
174
+ GfxColorSpace *GfxDeviceGrayColorSpace::copy() {
175
+ return new GfxDeviceGrayColorSpace();
176
+ }
177
+
178
+ void GfxDeviceGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) {
179
+ *gray = clip01(color->c[0]);
180
+ }
181
+
182
+ void GfxDeviceGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
183
+ rgb->r = rgb->g = rgb->b = clip01(color->c[0]);
184
+ }
185
+
186
+ void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
187
+ cmyk->c = cmyk->m = cmyk->y = 0;
188
+ cmyk->k = clip01(gfxColorComp1 - color->c[0]);
189
+ }
190
+
191
+ void GfxDeviceGrayColorSpace::getDefaultColor(GfxColor *color) {
192
+ color->c[0] = 0;
193
+ }
194
+
195
+ //------------------------------------------------------------------------
196
+ // GfxCalGrayColorSpace
197
+ //------------------------------------------------------------------------
198
+
199
+ GfxCalGrayColorSpace::GfxCalGrayColorSpace() {
200
+ whiteX = whiteY = whiteZ = 1;
201
+ blackX = blackY = blackZ = 0;
202
+ gamma = 1;
203
+ }
204
+
205
+ GfxCalGrayColorSpace::~GfxCalGrayColorSpace() {
206
+ }
207
+
208
+ GfxColorSpace *GfxCalGrayColorSpace::copy() {
209
+ GfxCalGrayColorSpace *cs;
210
+
211
+ cs = new GfxCalGrayColorSpace();
212
+ cs->whiteX = whiteX;
213
+ cs->whiteY = whiteY;
214
+ cs->whiteZ = whiteZ;
215
+ cs->blackX = blackX;
216
+ cs->blackY = blackY;
217
+ cs->blackZ = blackZ;
218
+ cs->gamma = gamma;
219
+ return cs;
220
+ }
221
+
222
+ GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr) {
223
+ GfxCalGrayColorSpace *cs;
224
+ Object obj1, obj2, obj3;
225
+
226
+ arr->get(1, &obj1);
227
+ if (!obj1.isDict()) {
228
+ error(-1, "Bad CalGray color space");
229
+ obj1.free();
230
+ return NULL;
231
+ }
232
+ cs = new GfxCalGrayColorSpace();
233
+ if (obj1.dictLookup("WhitePoint", &obj2)->isArray() &&
234
+ obj2.arrayGetLength() == 3) {
235
+ obj2.arrayGet(0, &obj3);
236
+ cs->whiteX = obj3.getNum();
237
+ obj3.free();
238
+ obj2.arrayGet(1, &obj3);
239
+ cs->whiteY = obj3.getNum();
240
+ obj3.free();
241
+ obj2.arrayGet(2, &obj3);
242
+ cs->whiteZ = obj3.getNum();
243
+ obj3.free();
244
+ }
245
+ obj2.free();
246
+ if (obj1.dictLookup("BlackPoint", &obj2)->isArray() &&
247
+ obj2.arrayGetLength() == 3) {
248
+ obj2.arrayGet(0, &obj3);
249
+ cs->blackX = obj3.getNum();
250
+ obj3.free();
251
+ obj2.arrayGet(1, &obj3);
252
+ cs->blackY = obj3.getNum();
253
+ obj3.free();
254
+ obj2.arrayGet(2, &obj3);
255
+ cs->blackZ = obj3.getNum();
256
+ obj3.free();
257
+ }
258
+ obj2.free();
259
+ if (obj1.dictLookup("Gamma", &obj2)->isNum()) {
260
+ cs->gamma = obj2.getNum();
261
+ }
262
+ obj2.free();
263
+ obj1.free();
264
+ return cs;
265
+ }
266
+
267
+ void GfxCalGrayColorSpace::getGray(GfxColor *color, GfxGray *gray) {
268
+ *gray = clip01(color->c[0]);
269
+ }
270
+
271
+ void GfxCalGrayColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
272
+ rgb->r = rgb->g = rgb->b = clip01(color->c[0]);
273
+ }
274
+
275
+ void GfxCalGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
276
+ cmyk->c = cmyk->m = cmyk->y = 0;
277
+ cmyk->k = clip01(gfxColorComp1 - color->c[0]);
278
+ }
279
+
280
+ void GfxCalGrayColorSpace::getDefaultColor(GfxColor *color) {
281
+ color->c[0] = 0;
282
+ }
283
+
284
+ //------------------------------------------------------------------------
285
+ // GfxDeviceRGBColorSpace
286
+ //------------------------------------------------------------------------
287
+
288
+ GfxDeviceRGBColorSpace::GfxDeviceRGBColorSpace() {
289
+ }
290
+
291
+ GfxDeviceRGBColorSpace::~GfxDeviceRGBColorSpace() {
292
+ }
293
+
294
+ GfxColorSpace *GfxDeviceRGBColorSpace::copy() {
295
+ return new GfxDeviceRGBColorSpace();
296
+ }
297
+
298
+ void GfxDeviceRGBColorSpace::getGray(GfxColor *color, GfxGray *gray) {
299
+ *gray = clip01((GfxColorComp)(0.3 * color->c[0] +
300
+ 0.59 * color->c[1] +
301
+ 0.11 * color->c[2] + 0.5));
302
+ }
303
+
304
+ void GfxDeviceRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
305
+ rgb->r = clip01(color->c[0]);
306
+ rgb->g = clip01(color->c[1]);
307
+ rgb->b = clip01(color->c[2]);
308
+ }
309
+
310
+ void GfxDeviceRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
311
+ GfxColorComp c, m, y, k;
312
+
313
+ c = clip01(gfxColorComp1 - color->c[0]);
314
+ m = clip01(gfxColorComp1 - color->c[1]);
315
+ y = clip01(gfxColorComp1 - color->c[2]);
316
+ k = c;
317
+ if (m < k) {
318
+ k = m;
319
+ }
320
+ if (y < k) {
321
+ k = y;
322
+ }
323
+ cmyk->c = c - k;
324
+ cmyk->m = m - k;
325
+ cmyk->y = y - k;
326
+ cmyk->k = k;
327
+ }
328
+
329
+ void GfxDeviceRGBColorSpace::getDefaultColor(GfxColor *color) {
330
+ color->c[0] = 0;
331
+ color->c[1] = 0;
332
+ color->c[2] = 0;
333
+ }
334
+
335
+ //------------------------------------------------------------------------
336
+ // GfxCalRGBColorSpace
337
+ //------------------------------------------------------------------------
338
+
339
+ GfxCalRGBColorSpace::GfxCalRGBColorSpace() {
340
+ whiteX = whiteY = whiteZ = 1;
341
+ blackX = blackY = blackZ = 0;
342
+ gammaR = gammaG = gammaB = 1;
343
+ mat[0] = 1; mat[1] = 0; mat[2] = 0;
344
+ mat[3] = 0; mat[4] = 1; mat[5] = 0;
345
+ mat[6] = 0; mat[7] = 0; mat[8] = 1;
346
+ }
347
+
348
+ GfxCalRGBColorSpace::~GfxCalRGBColorSpace() {
349
+ }
350
+
351
+ GfxColorSpace *GfxCalRGBColorSpace::copy() {
352
+ GfxCalRGBColorSpace *cs;
353
+ int i;
354
+
355
+ cs = new GfxCalRGBColorSpace();
356
+ cs->whiteX = whiteX;
357
+ cs->whiteY = whiteY;
358
+ cs->whiteZ = whiteZ;
359
+ cs->blackX = blackX;
360
+ cs->blackY = blackY;
361
+ cs->blackZ = blackZ;
362
+ cs->gammaR = gammaR;
363
+ cs->gammaG = gammaG;
364
+ cs->gammaB = gammaB;
365
+ for (i = 0; i < 9; ++i) {
366
+ cs->mat[i] = mat[i];
367
+ }
368
+ return cs;
369
+ }
370
+
371
+ GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr) {
372
+ GfxCalRGBColorSpace *cs;
373
+ Object obj1, obj2, obj3;
374
+ int i;
375
+
376
+ arr->get(1, &obj1);
377
+ if (!obj1.isDict()) {
378
+ error(-1, "Bad CalRGB color space");
379
+ obj1.free();
380
+ return NULL;
381
+ }
382
+ cs = new GfxCalRGBColorSpace();
383
+ if (obj1.dictLookup("WhitePoint", &obj2)->isArray() &&
384
+ obj2.arrayGetLength() == 3) {
385
+ obj2.arrayGet(0, &obj3);
386
+ cs->whiteX = obj3.getNum();
387
+ obj3.free();
388
+ obj2.arrayGet(1, &obj3);
389
+ cs->whiteY = obj3.getNum();
390
+ obj3.free();
391
+ obj2.arrayGet(2, &obj3);
392
+ cs->whiteZ = obj3.getNum();
393
+ obj3.free();
394
+ }
395
+ obj2.free();
396
+ if (obj1.dictLookup("BlackPoint", &obj2)->isArray() &&
397
+ obj2.arrayGetLength() == 3) {
398
+ obj2.arrayGet(0, &obj3);
399
+ cs->blackX = obj3.getNum();
400
+ obj3.free();
401
+ obj2.arrayGet(1, &obj3);
402
+ cs->blackY = obj3.getNum();
403
+ obj3.free();
404
+ obj2.arrayGet(2, &obj3);
405
+ cs->blackZ = obj3.getNum();
406
+ obj3.free();
407
+ }
408
+ obj2.free();
409
+ if (obj1.dictLookup("Gamma", &obj2)->isArray() &&
410
+ obj2.arrayGetLength() == 3) {
411
+ obj2.arrayGet(0, &obj3);
412
+ cs->gammaR = obj3.getNum();
413
+ obj3.free();
414
+ obj2.arrayGet(1, &obj3);
415
+ cs->gammaG = obj3.getNum();
416
+ obj3.free();
417
+ obj2.arrayGet(2, &obj3);
418
+ cs->gammaB = obj3.getNum();
419
+ obj3.free();
420
+ }
421
+ obj2.free();
422
+ if (obj1.dictLookup("Matrix", &obj2)->isArray() &&
423
+ obj2.arrayGetLength() == 9) {
424
+ for (i = 0; i < 9; ++i) {
425
+ obj2.arrayGet(i, &obj3);
426
+ cs->mat[i] = obj3.getNum();
427
+ obj3.free();
428
+ }
429
+ }
430
+ obj2.free();
431
+ obj1.free();
432
+ return cs;
433
+ }
434
+
435
+ void GfxCalRGBColorSpace::getGray(GfxColor *color, GfxGray *gray) {
436
+ *gray = clip01((GfxColorComp)(0.299 * color->c[0] +
437
+ 0.587 * color->c[1] +
438
+ 0.114 * color->c[2] + 0.5));
439
+ }
440
+
441
+ void GfxCalRGBColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
442
+ rgb->r = clip01(color->c[0]);
443
+ rgb->g = clip01(color->c[1]);
444
+ rgb->b = clip01(color->c[2]);
445
+ }
446
+
447
+ void GfxCalRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
448
+ GfxColorComp c, m, y, k;
449
+
450
+ c = clip01(gfxColorComp1 - color->c[0]);
451
+ m = clip01(gfxColorComp1 - color->c[1]);
452
+ y = clip01(gfxColorComp1 - color->c[2]);
453
+ k = c;
454
+ if (m < k) {
455
+ k = m;
456
+ }
457
+ if (y < k) {
458
+ k = y;
459
+ }
460
+ cmyk->c = c - k;
461
+ cmyk->m = m - k;
462
+ cmyk->y = y - k;
463
+ cmyk->k = k;
464
+ }
465
+
466
+ void GfxCalRGBColorSpace::getDefaultColor(GfxColor *color) {
467
+ color->c[0] = 0;
468
+ color->c[1] = 0;
469
+ color->c[2] = 0;
470
+ }
471
+
472
+ //------------------------------------------------------------------------
473
+ // GfxDeviceCMYKColorSpace
474
+ //------------------------------------------------------------------------
475
+
476
+ GfxDeviceCMYKColorSpace::GfxDeviceCMYKColorSpace() {
477
+ }
478
+
479
+ GfxDeviceCMYKColorSpace::~GfxDeviceCMYKColorSpace() {
480
+ }
481
+
482
+ GfxColorSpace *GfxDeviceCMYKColorSpace::copy() {
483
+ return new GfxDeviceCMYKColorSpace();
484
+ }
485
+
486
+ void GfxDeviceCMYKColorSpace::getGray(GfxColor *color, GfxGray *gray) {
487
+ *gray = clip01((GfxColorComp)(gfxColorComp1 - color->c[3]
488
+ - 0.3 * color->c[0]
489
+ - 0.59 * color->c[1]
490
+ - 0.11 * color->c[2] + 0.5));
491
+ }
492
+
493
+ void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
494
+ double c, m, y, k, c1, m1, y1, k1, r, g, b, x;
495
+
496
+ c = colToDbl(color->c[0]);
497
+ m = colToDbl(color->c[1]);
498
+ y = colToDbl(color->c[2]);
499
+ k = colToDbl(color->c[3]);
500
+ c1 = 1 - c;
501
+ m1 = 1 - m;
502
+ y1 = 1 - y;
503
+ k1 = 1 - k;
504
+ // this is a matrix multiplication, unrolled for performance
505
+ // C M Y K
506
+ x = c1 * m1 * y1 * k1; // 0 0 0 0
507
+ r = g = b = x;
508
+ x = c1 * m1 * y1 * k; // 0 0 0 1
509
+ r += 0.1373 * x;
510
+ g += 0.1216 * x;
511
+ b += 0.1255 * x;
512
+ x = c1 * m1 * y * k1; // 0 0 1 0
513
+ r += x;
514
+ g += 0.9490 * x;
515
+ x = c1 * m1 * y * k; // 0 0 1 1
516
+ r += 0.1098 * x;
517
+ g += 0.1020 * x;
518
+ x = c1 * m * y1 * k1; // 0 1 0 0
519
+ r += 0.9255 * x;
520
+ b += 0.5490 * x;
521
+ x = c1 * m * y1 * k; // 0 1 0 1
522
+ r += 0.1412 * x;
523
+ x = c1 * m * y * k1; // 0 1 1 0
524
+ r += 0.9294 * x;
525
+ g += 0.1098 * x;
526
+ b += 0.1412 * x;
527
+ x = c1 * m * y * k; // 0 1 1 1
528
+ r += 0.1333 * x;
529
+ x = c * m1 * y1 * k1; // 1 0 0 0
530
+ g += 0.6784 * x;
531
+ b += 0.9373 * x;
532
+ x = c * m1 * y1 * k; // 1 0 0 1
533
+ g += 0.0588 * x;
534
+ b += 0.1412 * x;
535
+ x = c * m1 * y * k1; // 1 0 1 0
536
+ g += 0.6510 * x;
537
+ b += 0.3137 * x;
538
+ x = c * m1 * y * k; // 1 0 1 1
539
+ g += 0.0745 * x;
540
+ x = c * m * y1 * k1; // 1 1 0 0
541
+ r += 0.1804 * x;
542
+ g += 0.1922 * x;
543
+ b += 0.5725 * x;
544
+ x = c * m * y1 * k; // 1 1 0 1
545
+ b += 0.0078 * x;
546
+ x = c * m * y * k1; // 1 1 1 0
547
+ r += 0.2118 * x;
548
+ g += 0.2119 * x;
549
+ b += 0.2235 * x;
550
+ rgb->r = clip01(dblToCol(r));
551
+ rgb->g = clip01(dblToCol(g));
552
+ rgb->b = clip01(dblToCol(b));
553
+ }
554
+
555
+ void GfxDeviceCMYKColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
556
+ cmyk->c = clip01(color->c[0]);
557
+ cmyk->m = clip01(color->c[1]);
558
+ cmyk->y = clip01(color->c[2]);
559
+ cmyk->k = clip01(color->c[3]);
560
+ }
561
+
562
+ void GfxDeviceCMYKColorSpace::getDefaultColor(GfxColor *color) {
563
+ color->c[0] = 0;
564
+ color->c[1] = 0;
565
+ color->c[2] = 0;
566
+ color->c[3] = gfxColorComp1;
567
+ }
568
+
569
+ //------------------------------------------------------------------------
570
+ // GfxLabColorSpace
571
+ //------------------------------------------------------------------------
572
+
573
+ // This is the inverse of MatrixLMN in Example 4.10 from the PostScript
574
+ // Language Reference, Third Edition.
575
+ static double xyzrgb[3][3] = {
576
+ { 3.240449, -1.537136, -0.498531 },
577
+ { -0.969265, 1.876011, 0.041556 },
578
+ { 0.055643, -0.204026, 1.057229 }
579
+ };
580
+
581
+ GfxLabColorSpace::GfxLabColorSpace() {
582
+ whiteX = whiteY = whiteZ = 1;
583
+ blackX = blackY = blackZ = 0;
584
+ aMin = bMin = -100;
585
+ aMax = bMax = 100;
586
+ }
587
+
588
+ GfxLabColorSpace::~GfxLabColorSpace() {
589
+ }
590
+
591
+ GfxColorSpace *GfxLabColorSpace::copy() {
592
+ GfxLabColorSpace *cs;
593
+
594
+ cs = new GfxLabColorSpace();
595
+ cs->whiteX = whiteX;
596
+ cs->whiteY = whiteY;
597
+ cs->whiteZ = whiteZ;
598
+ cs->blackX = blackX;
599
+ cs->blackY = blackY;
600
+ cs->blackZ = blackZ;
601
+ cs->aMin = aMin;
602
+ cs->aMax = aMax;
603
+ cs->bMin = bMin;
604
+ cs->bMax = bMax;
605
+ cs->kr = kr;
606
+ cs->kg = kg;
607
+ cs->kb = kb;
608
+ return cs;
609
+ }
610
+
611
+ GfxColorSpace *GfxLabColorSpace::parse(Array *arr) {
612
+ GfxLabColorSpace *cs;
613
+ Object obj1, obj2, obj3;
614
+
615
+ arr->get(1, &obj1);
616
+ if (!obj1.isDict()) {
617
+ error(-1, "Bad Lab color space");
618
+ obj1.free();
619
+ return NULL;
620
+ }
621
+ cs = new GfxLabColorSpace();
622
+ if (obj1.dictLookup("WhitePoint", &obj2)->isArray() &&
623
+ obj2.arrayGetLength() == 3) {
624
+ obj2.arrayGet(0, &obj3);
625
+ cs->whiteX = obj3.getNum();
626
+ obj3.free();
627
+ obj2.arrayGet(1, &obj3);
628
+ cs->whiteY = obj3.getNum();
629
+ obj3.free();
630
+ obj2.arrayGet(2, &obj3);
631
+ cs->whiteZ = obj3.getNum();
632
+ obj3.free();
633
+ }
634
+ obj2.free();
635
+ if (obj1.dictLookup("BlackPoint", &obj2)->isArray() &&
636
+ obj2.arrayGetLength() == 3) {
637
+ obj2.arrayGet(0, &obj3);
638
+ cs->blackX = obj3.getNum();
639
+ obj3.free();
640
+ obj2.arrayGet(1, &obj3);
641
+ cs->blackY = obj3.getNum();
642
+ obj3.free();
643
+ obj2.arrayGet(2, &obj3);
644
+ cs->blackZ = obj3.getNum();
645
+ obj3.free();
646
+ }
647
+ obj2.free();
648
+ if (obj1.dictLookup("Range", &obj2)->isArray() &&
649
+ obj2.arrayGetLength() == 4) {
650
+ obj2.arrayGet(0, &obj3);
651
+ cs->aMin = obj3.getNum();
652
+ obj3.free();
653
+ obj2.arrayGet(1, &obj3);
654
+ cs->aMax = obj3.getNum();
655
+ obj3.free();
656
+ obj2.arrayGet(2, &obj3);
657
+ cs->bMin = obj3.getNum();
658
+ obj3.free();
659
+ obj2.arrayGet(3, &obj3);
660
+ cs->bMax = obj3.getNum();
661
+ obj3.free();
662
+ }
663
+ obj2.free();
664
+ obj1.free();
665
+
666
+ cs->kr = 1 / (xyzrgb[0][0] * cs->whiteX +
667
+ xyzrgb[0][1] * cs->whiteY +
668
+ xyzrgb[0][2] * cs->whiteZ);
669
+ cs->kg = 1 / (xyzrgb[1][0] * cs->whiteX +
670
+ xyzrgb[1][1] * cs->whiteY +
671
+ xyzrgb[1][2] * cs->whiteZ);
672
+ cs->kb = 1 / (xyzrgb[2][0] * cs->whiteX +
673
+ xyzrgb[2][1] * cs->whiteY +
674
+ xyzrgb[2][2] * cs->whiteZ);
675
+
676
+ return cs;
677
+ }
678
+
679
+ void GfxLabColorSpace::getGray(GfxColor *color, GfxGray *gray) {
680
+ GfxRGB rgb;
681
+
682
+ getRGB(color, &rgb);
683
+ *gray = clip01((GfxColorComp)(0.299 * rgb.r +
684
+ 0.587 * rgb.g +
685
+ 0.114 * rgb.b + 0.5));
686
+ }
687
+
688
+ void GfxLabColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
689
+ double X, Y, Z;
690
+ double t1, t2;
691
+ double r, g, b;
692
+
693
+ // convert L*a*b* to CIE 1931 XYZ color space
694
+ t1 = (colToDbl(color->c[0]) + 16) / 116;
695
+ t2 = t1 + colToDbl(color->c[1]) / 500;
696
+ if (t2 >= (6.0 / 29.0)) {
697
+ X = t2 * t2 * t2;
698
+ } else {
699
+ X = (108.0 / 841.0) * (t2 - (4.0 / 29.0));
700
+ }
701
+ X *= whiteX;
702
+ if (t1 >= (6.0 / 29.0)) {
703
+ Y = t1 * t1 * t1;
704
+ } else {
705
+ Y = (108.0 / 841.0) * (t1 - (4.0 / 29.0));
706
+ }
707
+ Y *= whiteY;
708
+ t2 = t1 - colToDbl(color->c[2]) / 200;
709
+ if (t2 >= (6.0 / 29.0)) {
710
+ Z = t2 * t2 * t2;
711
+ } else {
712
+ Z = (108.0 / 841.0) * (t2 - (4.0 / 29.0));
713
+ }
714
+ Z *= whiteZ;
715
+
716
+ // convert XYZ to RGB, including gamut mapping and gamma correction
717
+ r = xyzrgb[0][0] * X + xyzrgb[0][1] * Y + xyzrgb[0][2] * Z;
718
+ g = xyzrgb[1][0] * X + xyzrgb[1][1] * Y + xyzrgb[1][2] * Z;
719
+ b = xyzrgb[2][0] * X + xyzrgb[2][1] * Y + xyzrgb[2][2] * Z;
720
+ rgb->r = dblToCol(pow(clip01(r * kr), 0.5));
721
+ rgb->g = dblToCol(pow(clip01(g * kg), 0.5));
722
+ rgb->b = dblToCol(pow(clip01(b * kb), 0.5));
723
+ }
724
+
725
+ void GfxLabColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
726
+ GfxRGB rgb;
727
+ GfxColorComp c, m, y, k;
728
+
729
+ getRGB(color, &rgb);
730
+ c = clip01(gfxColorComp1 - rgb.r);
731
+ m = clip01(gfxColorComp1 - rgb.g);
732
+ y = clip01(gfxColorComp1 - rgb.b);
733
+ k = c;
734
+ if (m < k) {
735
+ k = m;
736
+ }
737
+ if (y < k) {
738
+ k = y;
739
+ }
740
+ cmyk->c = c - k;
741
+ cmyk->m = m - k;
742
+ cmyk->y = y - k;
743
+ cmyk->k = k;
744
+ }
745
+
746
+ void GfxLabColorSpace::getDefaultColor(GfxColor *color) {
747
+ color->c[0] = 0;
748
+ if (aMin > 0) {
749
+ color->c[1] = dblToCol(aMin);
750
+ } else if (aMax < 0) {
751
+ color->c[1] = dblToCol(aMax);
752
+ } else {
753
+ color->c[1] = 0;
754
+ }
755
+ if (bMin > 0) {
756
+ color->c[2] = dblToCol(bMin);
757
+ } else if (bMax < 0) {
758
+ color->c[2] = dblToCol(bMax);
759
+ } else {
760
+ color->c[2] = 0;
761
+ }
762
+ }
763
+
764
+ void GfxLabColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange,
765
+ int maxImgPixel) {
766
+ decodeLow[0] = 0;
767
+ decodeRange[0] = 100;
768
+ decodeLow[1] = aMin;
769
+ decodeRange[1] = aMax - aMin;
770
+ decodeLow[2] = bMin;
771
+ decodeRange[2] = bMax - bMin;
772
+ }
773
+
774
+ //------------------------------------------------------------------------
775
+ // GfxICCBasedColorSpace
776
+ //------------------------------------------------------------------------
777
+
778
+ GfxICCBasedColorSpace::GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA,
779
+ Ref *iccProfileStreamA) {
780
+ nComps = nCompsA;
781
+ alt = altA;
782
+ iccProfileStream = *iccProfileStreamA;
783
+ rangeMin[0] = rangeMin[1] = rangeMin[2] = rangeMin[3] = 0;
784
+ rangeMax[0] = rangeMax[1] = rangeMax[2] = rangeMax[3] = 1;
785
+ }
786
+
787
+ GfxICCBasedColorSpace::~GfxICCBasedColorSpace() {
788
+ delete alt;
789
+ }
790
+
791
+ GfxColorSpace *GfxICCBasedColorSpace::copy() {
792
+ GfxICCBasedColorSpace *cs;
793
+ int i;
794
+
795
+ cs = new GfxICCBasedColorSpace(nComps, alt->copy(), &iccProfileStream);
796
+ for (i = 0; i < 4; ++i) {
797
+ cs->rangeMin[i] = rangeMin[i];
798
+ cs->rangeMax[i] = rangeMax[i];
799
+ }
800
+ return cs;
801
+ }
802
+
803
+ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr) {
804
+ GfxICCBasedColorSpace *cs;
805
+ Ref iccProfileStreamA;
806
+ int nCompsA;
807
+ GfxColorSpace *altA;
808
+ Dict *dict;
809
+ Object obj1, obj2, obj3;
810
+ int i;
811
+
812
+ arr->getNF(1, &obj1);
813
+ if (obj1.isRef()) {
814
+ iccProfileStreamA = obj1.getRef();
815
+ } else {
816
+ iccProfileStreamA.num = 0;
817
+ iccProfileStreamA.gen = 0;
818
+ }
819
+ obj1.free();
820
+ arr->get(1, &obj1);
821
+ if (!obj1.isStream()) {
822
+ error(-1, "Bad ICCBased color space (stream)");
823
+ obj1.free();
824
+ return NULL;
825
+ }
826
+ dict = obj1.streamGetDict();
827
+ if (!dict->lookup("N", &obj2)->isInt()) {
828
+ error(-1, "Bad ICCBased color space (N)");
829
+ obj2.free();
830
+ obj1.free();
831
+ return NULL;
832
+ }
833
+ nCompsA = obj2.getInt();
834
+ obj2.free();
835
+ if (nCompsA > gfxColorMaxComps) {
836
+ error(-1, "ICCBased color space with too many (%d > %d) components",
837
+ nCompsA, gfxColorMaxComps);
838
+ nCompsA = gfxColorMaxComps;
839
+ }
840
+ if (dict->lookup("Alternate", &obj2)->isNull() ||
841
+ !(altA = GfxColorSpace::parse(&obj2))) {
842
+ switch (nCompsA) {
843
+ case 1:
844
+ altA = new GfxDeviceGrayColorSpace();
845
+ break;
846
+ case 3:
847
+ altA = new GfxDeviceRGBColorSpace();
848
+ break;
849
+ case 4:
850
+ altA = new GfxDeviceCMYKColorSpace();
851
+ break;
852
+ default:
853
+ error(-1, "Bad ICCBased color space - invalid N");
854
+ obj2.free();
855
+ obj1.free();
856
+ return NULL;
857
+ }
858
+ }
859
+ obj2.free();
860
+ cs = new GfxICCBasedColorSpace(nCompsA, altA, &iccProfileStreamA);
861
+ if (dict->lookup("Range", &obj2)->isArray() &&
862
+ obj2.arrayGetLength() == 2 * nCompsA) {
863
+ for (i = 0; i < nCompsA; ++i) {
864
+ obj2.arrayGet(2*i, &obj3);
865
+ cs->rangeMin[i] = obj3.getNum();
866
+ obj3.free();
867
+ obj2.arrayGet(2*i+1, &obj3);
868
+ cs->rangeMax[i] = obj3.getNum();
869
+ obj3.free();
870
+ }
871
+ }
872
+ obj2.free();
873
+ obj1.free();
874
+ return cs;
875
+ }
876
+
877
+ void GfxICCBasedColorSpace::getGray(GfxColor *color, GfxGray *gray) {
878
+ alt->getGray(color, gray);
879
+ }
880
+
881
+ void GfxICCBasedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
882
+ alt->getRGB(color, rgb);
883
+ }
884
+
885
+ void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
886
+ alt->getCMYK(color, cmyk);
887
+ }
888
+
889
+ void GfxICCBasedColorSpace::getDefaultColor(GfxColor *color) {
890
+ int i;
891
+
892
+ for (i = 0; i < nComps; ++i) {
893
+ if (rangeMin[i] > 0) {
894
+ color->c[i] = dblToCol(rangeMin[i]);
895
+ } else if (rangeMax[i] < 0) {
896
+ color->c[i] = dblToCol(rangeMax[i]);
897
+ } else {
898
+ color->c[i] = 0;
899
+ }
900
+ }
901
+ }
902
+
903
+ void GfxICCBasedColorSpace::getDefaultRanges(double *decodeLow,
904
+ double *decodeRange,
905
+ int maxImgPixel) {
906
+ alt->getDefaultRanges(decodeLow, decodeRange, maxImgPixel);
907
+
908
+ #if 0
909
+ // this is nominally correct, but some PDF files don't set the
910
+ // correct ranges in the ICCBased dict
911
+ int i;
912
+
913
+ for (i = 0; i < nComps; ++i) {
914
+ decodeLow[i] = rangeMin[i];
915
+ decodeRange[i] = rangeMax[i] - rangeMin[i];
916
+ }
917
+ #endif
918
+ }
919
+
920
+ //------------------------------------------------------------------------
921
+ // GfxIndexedColorSpace
922
+ //------------------------------------------------------------------------
923
+
924
+ GfxIndexedColorSpace::GfxIndexedColorSpace(GfxColorSpace *baseA,
925
+ int indexHighA) {
926
+ base = baseA;
927
+ indexHigh = indexHighA;
928
+ lookup = (Guchar *)gmallocn((indexHigh + 1) * base->getNComps(),
929
+ sizeof(Guchar));
930
+ }
931
+
932
+ GfxIndexedColorSpace::~GfxIndexedColorSpace() {
933
+ delete base;
934
+ gfree(lookup);
935
+ }
936
+
937
+ GfxColorSpace *GfxIndexedColorSpace::copy() {
938
+ GfxIndexedColorSpace *cs;
939
+
940
+ cs = new GfxIndexedColorSpace(base->copy(), indexHigh);
941
+ memcpy(cs->lookup, lookup,
942
+ (indexHigh + 1) * base->getNComps() * sizeof(Guchar));
943
+ return cs;
944
+ }
945
+
946
+ GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr) {
947
+ GfxIndexedColorSpace *cs;
948
+ GfxColorSpace *baseA;
949
+ int indexHighA;
950
+ Object obj1;
951
+ int x;
952
+ char *s;
953
+ int n, i, j;
954
+
955
+ if (arr->getLength() != 4) {
956
+ error(-1, "Bad Indexed color space");
957
+ goto err1;
958
+ }
959
+ arr->get(1, &obj1);
960
+ if (!(baseA = GfxColorSpace::parse(&obj1))) {
961
+ error(-1, "Bad Indexed color space (base color space)");
962
+ goto err2;
963
+ }
964
+ obj1.free();
965
+ if (!arr->get(2, &obj1)->isInt()) {
966
+ error(-1, "Bad Indexed color space (hival)");
967
+ delete baseA;
968
+ goto err2;
969
+ }
970
+ indexHighA = obj1.getInt();
971
+ if (indexHighA < 0 || indexHighA > 255) {
972
+ // the PDF spec requires indexHigh to be in [0,255] -- allowing
973
+ // values larger than 255 creates a security hole: if nComps *
974
+ // indexHigh is greater than 2^31, the loop below may overwrite
975
+ // past the end of the array
976
+ error(-1, "Bad Indexed color space (invalid indexHigh value)");
977
+ delete baseA;
978
+ goto err2;
979
+ }
980
+ obj1.free();
981
+ cs = new GfxIndexedColorSpace(baseA, indexHighA);
982
+ arr->get(3, &obj1);
983
+ n = baseA->getNComps();
984
+ if (obj1.isStream()) {
985
+ obj1.streamReset();
986
+ for (i = 0; i <= indexHighA; ++i) {
987
+ for (j = 0; j < n; ++j) {
988
+ if ((x = obj1.streamGetChar()) == EOF) {
989
+ error(-1, "Bad Indexed color space (lookup table stream too short)");
990
+ goto err3;
991
+ }
992
+ cs->lookup[i*n + j] = (Guchar)x;
993
+ }
994
+ }
995
+ obj1.streamClose();
996
+ } else if (obj1.isString()) {
997
+ if (obj1.getString()->getLength() < (indexHighA + 1) * n) {
998
+ error(-1, "Bad Indexed color space (lookup table string too short)");
999
+ goto err3;
1000
+ }
1001
+ s = obj1.getString()->getCString();
1002
+ for (i = 0; i <= indexHighA; ++i) {
1003
+ for (j = 0; j < n; ++j) {
1004
+ cs->lookup[i*n + j] = (Guchar)*s++;
1005
+ }
1006
+ }
1007
+ } else {
1008
+ error(-1, "Bad Indexed color space (lookup table)");
1009
+ goto err3;
1010
+ }
1011
+ obj1.free();
1012
+ return cs;
1013
+
1014
+ err3:
1015
+ delete cs;
1016
+ err2:
1017
+ obj1.free();
1018
+ err1:
1019
+ return NULL;
1020
+ }
1021
+
1022
+ GfxColor *GfxIndexedColorSpace::mapColorToBase(GfxColor *color,
1023
+ GfxColor *baseColor) {
1024
+ Guchar *p;
1025
+ double low[gfxColorMaxComps], range[gfxColorMaxComps];
1026
+ int n, i;
1027
+
1028
+ n = base->getNComps();
1029
+ base->getDefaultRanges(low, range, indexHigh);
1030
+ p = &lookup[(int)(colToDbl(color->c[0]) + 0.5) * n];
1031
+ for (i = 0; i < n; ++i) {
1032
+ baseColor->c[i] = dblToCol(low[i] + (p[i] / 255.0) * range[i]);
1033
+ }
1034
+ return baseColor;
1035
+ }
1036
+
1037
+ void GfxIndexedColorSpace::getGray(GfxColor *color, GfxGray *gray) {
1038
+ GfxColor color2;
1039
+
1040
+ base->getGray(mapColorToBase(color, &color2), gray);
1041
+ }
1042
+
1043
+ void GfxIndexedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
1044
+ GfxColor color2;
1045
+
1046
+ base->getRGB(mapColorToBase(color, &color2), rgb);
1047
+ }
1048
+
1049
+ void GfxIndexedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
1050
+ GfxColor color2;
1051
+
1052
+ base->getCMYK(mapColorToBase(color, &color2), cmyk);
1053
+ }
1054
+
1055
+ void GfxIndexedColorSpace::getDefaultColor(GfxColor *color) {
1056
+ color->c[0] = 0;
1057
+ }
1058
+
1059
+ void GfxIndexedColorSpace::getDefaultRanges(double *decodeLow,
1060
+ double *decodeRange,
1061
+ int maxImgPixel) {
1062
+ decodeLow[0] = 0;
1063
+ decodeRange[0] = maxImgPixel;
1064
+ }
1065
+
1066
+ //------------------------------------------------------------------------
1067
+ // GfxSeparationColorSpace
1068
+ //------------------------------------------------------------------------
1069
+
1070
+ GfxSeparationColorSpace::GfxSeparationColorSpace(GString *nameA,
1071
+ GfxColorSpace *altA,
1072
+ Function *funcA) {
1073
+ name = nameA;
1074
+ alt = altA;
1075
+ func = funcA;
1076
+ nonMarking = !name->cmp("None");
1077
+ }
1078
+
1079
+ GfxSeparationColorSpace::~GfxSeparationColorSpace() {
1080
+ delete name;
1081
+ delete alt;
1082
+ delete func;
1083
+ }
1084
+
1085
+ GfxColorSpace *GfxSeparationColorSpace::copy() {
1086
+ return new GfxSeparationColorSpace(name->copy(), alt->copy(), func->copy());
1087
+ }
1088
+
1089
+ //~ handle the 'All' and 'None' colorants
1090
+ GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr) {
1091
+ GfxSeparationColorSpace *cs;
1092
+ GString *nameA;
1093
+ GfxColorSpace *altA;
1094
+ Function *funcA;
1095
+ Object obj1;
1096
+
1097
+ if (arr->getLength() != 4) {
1098
+ error(-1, "Bad Separation color space");
1099
+ goto err1;
1100
+ }
1101
+ if (!arr->get(1, &obj1)->isName()) {
1102
+ error(-1, "Bad Separation color space (name)");
1103
+ goto err2;
1104
+ }
1105
+ nameA = new GString(obj1.getName());
1106
+ obj1.free();
1107
+ arr->get(2, &obj1);
1108
+ if (!(altA = GfxColorSpace::parse(&obj1))) {
1109
+ error(-1, "Bad Separation color space (alternate color space)");
1110
+ goto err3;
1111
+ }
1112
+ obj1.free();
1113
+ arr->get(3, &obj1);
1114
+ if (!(funcA = Function::parse(&obj1))) {
1115
+ goto err4;
1116
+ }
1117
+ obj1.free();
1118
+ cs = new GfxSeparationColorSpace(nameA, altA, funcA);
1119
+ return cs;
1120
+
1121
+ err4:
1122
+ delete altA;
1123
+ err3:
1124
+ delete nameA;
1125
+ err2:
1126
+ obj1.free();
1127
+ err1:
1128
+ return NULL;
1129
+ }
1130
+
1131
+ void GfxSeparationColorSpace::getGray(GfxColor *color, GfxGray *gray) {
1132
+ double x;
1133
+ double c[gfxColorMaxComps];
1134
+ GfxColor color2;
1135
+ int i;
1136
+
1137
+ x = colToDbl(color->c[0]);
1138
+ func->transform(&x, c);
1139
+ for (i = 0; i < alt->getNComps(); ++i) {
1140
+ color2.c[i] = dblToCol(c[i]);
1141
+ }
1142
+ alt->getGray(&color2, gray);
1143
+ }
1144
+
1145
+ void GfxSeparationColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
1146
+ double x;
1147
+ double c[gfxColorMaxComps];
1148
+ GfxColor color2;
1149
+ int i;
1150
+
1151
+ x = colToDbl(color->c[0]);
1152
+ func->transform(&x, c);
1153
+ for (i = 0; i < alt->getNComps(); ++i) {
1154
+ color2.c[i] = dblToCol(c[i]);
1155
+ }
1156
+ alt->getRGB(&color2, rgb);
1157
+ }
1158
+
1159
+ void GfxSeparationColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
1160
+ double x;
1161
+ double c[gfxColorMaxComps];
1162
+ GfxColor color2;
1163
+ int i;
1164
+
1165
+ x = colToDbl(color->c[0]);
1166
+ func->transform(&x, c);
1167
+ for (i = 0; i < alt->getNComps(); ++i) {
1168
+ color2.c[i] = dblToCol(c[i]);
1169
+ }
1170
+ alt->getCMYK(&color2, cmyk);
1171
+ }
1172
+
1173
+ void GfxSeparationColorSpace::getDefaultColor(GfxColor *color) {
1174
+ color->c[0] = gfxColorComp1;
1175
+ }
1176
+
1177
+ //------------------------------------------------------------------------
1178
+ // GfxDeviceNColorSpace
1179
+ //------------------------------------------------------------------------
1180
+
1181
+ GfxDeviceNColorSpace::GfxDeviceNColorSpace(int nCompsA,
1182
+ GfxColorSpace *altA,
1183
+ Function *funcA) {
1184
+ nComps = nCompsA;
1185
+ alt = altA;
1186
+ func = funcA;
1187
+ nonMarking = gFalse;
1188
+ }
1189
+
1190
+ GfxDeviceNColorSpace::~GfxDeviceNColorSpace() {
1191
+ int i;
1192
+
1193
+ for (i = 0; i < nComps; ++i) {
1194
+ delete names[i];
1195
+ }
1196
+ delete alt;
1197
+ delete func;
1198
+ }
1199
+
1200
+ GfxColorSpace *GfxDeviceNColorSpace::copy() {
1201
+ GfxDeviceNColorSpace *cs;
1202
+ int i;
1203
+
1204
+ cs = new GfxDeviceNColorSpace(nComps, alt->copy(), func->copy());
1205
+ for (i = 0; i < nComps; ++i) {
1206
+ cs->names[i] = names[i]->copy();
1207
+ }
1208
+ cs->nonMarking = nonMarking;
1209
+ return cs;
1210
+ }
1211
+
1212
+ //~ handle the 'None' colorant
1213
+ GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr) {
1214
+ GfxDeviceNColorSpace *cs;
1215
+ int nCompsA;
1216
+ GString *namesA[gfxColorMaxComps];
1217
+ GfxColorSpace *altA;
1218
+ Function *funcA;
1219
+ Object obj1, obj2;
1220
+ int i;
1221
+
1222
+ if (arr->getLength() != 4 && arr->getLength() != 5) {
1223
+ error(-1, "Bad DeviceN color space");
1224
+ goto err1;
1225
+ }
1226
+ if (!arr->get(1, &obj1)->isArray()) {
1227
+ error(-1, "Bad DeviceN color space (names)");
1228
+ goto err2;
1229
+ }
1230
+ nCompsA = obj1.arrayGetLength();
1231
+ if (nCompsA > gfxColorMaxComps) {
1232
+ error(-1, "DeviceN color space with too many (%d > %d) components",
1233
+ nCompsA, gfxColorMaxComps);
1234
+ nCompsA = gfxColorMaxComps;
1235
+ }
1236
+ for (i = 0; i < nCompsA; ++i) {
1237
+ if (!obj1.arrayGet(i, &obj2)->isName()) {
1238
+ error(-1, "Bad DeviceN color space (names)");
1239
+ obj2.free();
1240
+ goto err2;
1241
+ }
1242
+ namesA[i] = new GString(obj2.getName());
1243
+ obj2.free();
1244
+ }
1245
+ obj1.free();
1246
+ arr->get(2, &obj1);
1247
+ if (!(altA = GfxColorSpace::parse(&obj1))) {
1248
+ error(-1, "Bad DeviceN color space (alternate color space)");
1249
+ goto err3;
1250
+ }
1251
+ obj1.free();
1252
+ arr->get(3, &obj1);
1253
+ if (!(funcA = Function::parse(&obj1))) {
1254
+ goto err4;
1255
+ }
1256
+ obj1.free();
1257
+ cs = new GfxDeviceNColorSpace(nCompsA, altA, funcA);
1258
+ cs->nonMarking = gTrue;
1259
+ for (i = 0; i < nCompsA; ++i) {
1260
+ cs->names[i] = namesA[i];
1261
+ if (namesA[i]->cmp("None")) {
1262
+ cs->nonMarking = gFalse;
1263
+ }
1264
+ }
1265
+ return cs;
1266
+
1267
+ err4:
1268
+ delete altA;
1269
+ err3:
1270
+ for (i = 0; i < nCompsA; ++i) {
1271
+ delete namesA[i];
1272
+ }
1273
+ err2:
1274
+ obj1.free();
1275
+ err1:
1276
+ return NULL;
1277
+ }
1278
+
1279
+ void GfxDeviceNColorSpace::getGray(GfxColor *color, GfxGray *gray) {
1280
+ double x[gfxColorMaxComps], c[gfxColorMaxComps];
1281
+ GfxColor color2;
1282
+ int i;
1283
+
1284
+ for (i = 0; i < nComps; ++i) {
1285
+ x[i] = colToDbl(color->c[i]);
1286
+ }
1287
+ func->transform(x, c);
1288
+ for (i = 0; i < alt->getNComps(); ++i) {
1289
+ color2.c[i] = dblToCol(c[i]);
1290
+ }
1291
+ alt->getGray(&color2, gray);
1292
+ }
1293
+
1294
+ void GfxDeviceNColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
1295
+ double x[gfxColorMaxComps], c[gfxColorMaxComps];
1296
+ GfxColor color2;
1297
+ int i;
1298
+
1299
+ for (i = 0; i < nComps; ++i) {
1300
+ x[i] = colToDbl(color->c[i]);
1301
+ }
1302
+ func->transform(x, c);
1303
+ for (i = 0; i < alt->getNComps(); ++i) {
1304
+ color2.c[i] = dblToCol(c[i]);
1305
+ }
1306
+ alt->getRGB(&color2, rgb);
1307
+ }
1308
+
1309
+ void GfxDeviceNColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
1310
+ double x[gfxColorMaxComps], c[gfxColorMaxComps];
1311
+ GfxColor color2;
1312
+ int i;
1313
+
1314
+ for (i = 0; i < nComps; ++i) {
1315
+ x[i] = colToDbl(color->c[i]);
1316
+ }
1317
+ func->transform(x, c);
1318
+ for (i = 0; i < alt->getNComps(); ++i) {
1319
+ color2.c[i] = dblToCol(c[i]);
1320
+ }
1321
+ alt->getCMYK(&color2, cmyk);
1322
+ }
1323
+
1324
+ void GfxDeviceNColorSpace::getDefaultColor(GfxColor *color) {
1325
+ int i;
1326
+
1327
+ for (i = 0; i < nComps; ++i) {
1328
+ color->c[i] = gfxColorComp1;
1329
+ }
1330
+ }
1331
+
1332
+ //------------------------------------------------------------------------
1333
+ // GfxPatternColorSpace
1334
+ //------------------------------------------------------------------------
1335
+
1336
+ GfxPatternColorSpace::GfxPatternColorSpace(GfxColorSpace *underA) {
1337
+ under = underA;
1338
+ }
1339
+
1340
+ GfxPatternColorSpace::~GfxPatternColorSpace() {
1341
+ if (under) {
1342
+ delete under;
1343
+ }
1344
+ }
1345
+
1346
+ GfxColorSpace *GfxPatternColorSpace::copy() {
1347
+ return new GfxPatternColorSpace(under ? under->copy() :
1348
+ (GfxColorSpace *)NULL);
1349
+ }
1350
+
1351
+ GfxColorSpace *GfxPatternColorSpace::parse(Array *arr) {
1352
+ GfxPatternColorSpace *cs;
1353
+ GfxColorSpace *underA;
1354
+ Object obj1;
1355
+
1356
+ if (arr->getLength() != 1 && arr->getLength() != 2) {
1357
+ error(-1, "Bad Pattern color space");
1358
+ return NULL;
1359
+ }
1360
+ underA = NULL;
1361
+ if (arr->getLength() == 2) {
1362
+ arr->get(1, &obj1);
1363
+ if (!(underA = GfxColorSpace::parse(&obj1))) {
1364
+ error(-1, "Bad Pattern color space (underlying color space)");
1365
+ obj1.free();
1366
+ return NULL;
1367
+ }
1368
+ obj1.free();
1369
+ }
1370
+ cs = new GfxPatternColorSpace(underA);
1371
+ return cs;
1372
+ }
1373
+
1374
+ void GfxPatternColorSpace::getGray(GfxColor *color, GfxGray *gray) {
1375
+ *gray = 0;
1376
+ }
1377
+
1378
+ void GfxPatternColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
1379
+ rgb->r = rgb->g = rgb->b = 0;
1380
+ }
1381
+
1382
+ void GfxPatternColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
1383
+ cmyk->c = cmyk->m = cmyk->y = 0;
1384
+ cmyk->k = 1;
1385
+ }
1386
+
1387
+ void GfxPatternColorSpace::getDefaultColor(GfxColor *color) {
1388
+ // not used
1389
+ }
1390
+
1391
+ //------------------------------------------------------------------------
1392
+ // Pattern
1393
+ //------------------------------------------------------------------------
1394
+
1395
+ GfxPattern::GfxPattern(int typeA) {
1396
+ type = typeA;
1397
+ }
1398
+
1399
+ GfxPattern::~GfxPattern() {
1400
+ }
1401
+
1402
+ GfxPattern *GfxPattern::parse(Object *obj) {
1403
+ GfxPattern *pattern;
1404
+ Object obj1;
1405
+
1406
+ if (obj->isDict()) {
1407
+ obj->dictLookup("PatternType", &obj1);
1408
+ } else if (obj->isStream()) {
1409
+ obj->streamGetDict()->lookup("PatternType", &obj1);
1410
+ } else {
1411
+ return NULL;
1412
+ }
1413
+ pattern = NULL;
1414
+ if (obj1.isInt() && obj1.getInt() == 1) {
1415
+ pattern = GfxTilingPattern::parse(obj);
1416
+ } else if (obj1.isInt() && obj1.getInt() == 2) {
1417
+ pattern = GfxShadingPattern::parse(obj);
1418
+ }
1419
+ obj1.free();
1420
+ return pattern;
1421
+ }
1422
+
1423
+ //------------------------------------------------------------------------
1424
+ // GfxTilingPattern
1425
+ //------------------------------------------------------------------------
1426
+
1427
+ GfxTilingPattern *GfxTilingPattern::parse(Object *patObj) {
1428
+ GfxTilingPattern *pat;
1429
+ Dict *dict;
1430
+ int paintTypeA, tilingTypeA;
1431
+ double bboxA[4], matrixA[6];
1432
+ double xStepA, yStepA;
1433
+ Object resDictA;
1434
+ Object obj1, obj2;
1435
+ int i;
1436
+
1437
+ if (!patObj->isStream()) {
1438
+ return NULL;
1439
+ }
1440
+ dict = patObj->streamGetDict();
1441
+
1442
+ if (dict->lookup("PaintType", &obj1)->isInt()) {
1443
+ paintTypeA = obj1.getInt();
1444
+ } else {
1445
+ paintTypeA = 1;
1446
+ error(-1, "Invalid or missing PaintType in pattern");
1447
+ }
1448
+ obj1.free();
1449
+ if (dict->lookup("TilingType", &obj1)->isInt()) {
1450
+ tilingTypeA = obj1.getInt();
1451
+ } else {
1452
+ tilingTypeA = 1;
1453
+ error(-1, "Invalid or missing TilingType in pattern");
1454
+ }
1455
+ obj1.free();
1456
+ bboxA[0] = bboxA[1] = 0;
1457
+ bboxA[2] = bboxA[3] = 1;
1458
+ if (dict->lookup("BBox", &obj1)->isArray() &&
1459
+ obj1.arrayGetLength() == 4) {
1460
+ for (i = 0; i < 4; ++i) {
1461
+ if (obj1.arrayGet(i, &obj2)->isNum()) {
1462
+ bboxA[i] = obj2.getNum();
1463
+ }
1464
+ obj2.free();
1465
+ }
1466
+ } else {
1467
+ error(-1, "Invalid or missing BBox in pattern");
1468
+ }
1469
+ obj1.free();
1470
+ if (dict->lookup("XStep", &obj1)->isNum()) {
1471
+ xStepA = obj1.getNum();
1472
+ } else {
1473
+ xStepA = 1;
1474
+ error(-1, "Invalid or missing XStep in pattern");
1475
+ }
1476
+ obj1.free();
1477
+ if (dict->lookup("YStep", &obj1)->isNum()) {
1478
+ yStepA = obj1.getNum();
1479
+ } else {
1480
+ yStepA = 1;
1481
+ error(-1, "Invalid or missing YStep in pattern");
1482
+ }
1483
+ obj1.free();
1484
+ if (!dict->lookup("Resources", &resDictA)->isDict()) {
1485
+ resDictA.free();
1486
+ resDictA.initNull();
1487
+ error(-1, "Invalid or missing Resources in pattern");
1488
+ }
1489
+ matrixA[0] = 1; matrixA[1] = 0;
1490
+ matrixA[2] = 0; matrixA[3] = 1;
1491
+ matrixA[4] = 0; matrixA[5] = 0;
1492
+ if (dict->lookup("Matrix", &obj1)->isArray() &&
1493
+ obj1.arrayGetLength() == 6) {
1494
+ for (i = 0; i < 6; ++i) {
1495
+ if (obj1.arrayGet(i, &obj2)->isNum()) {
1496
+ matrixA[i] = obj2.getNum();
1497
+ }
1498
+ obj2.free();
1499
+ }
1500
+ }
1501
+ obj1.free();
1502
+
1503
+ pat = new GfxTilingPattern(paintTypeA, tilingTypeA, bboxA, xStepA, yStepA,
1504
+ &resDictA, matrixA, patObj);
1505
+ resDictA.free();
1506
+ return pat;
1507
+ }
1508
+
1509
+ GfxTilingPattern::GfxTilingPattern(int paintTypeA, int tilingTypeA,
1510
+ double *bboxA, double xStepA, double yStepA,
1511
+ Object *resDictA, double *matrixA,
1512
+ Object *contentStreamA):
1513
+ GfxPattern(1)
1514
+ {
1515
+ int i;
1516
+
1517
+ paintType = paintTypeA;
1518
+ tilingType = tilingTypeA;
1519
+ for (i = 0; i < 4; ++i) {
1520
+ bbox[i] = bboxA[i];
1521
+ }
1522
+ xStep = xStepA;
1523
+ yStep = yStepA;
1524
+ resDictA->copy(&resDict);
1525
+ for (i = 0; i < 6; ++i) {
1526
+ matrix[i] = matrixA[i];
1527
+ }
1528
+ contentStreamA->copy(&contentStream);
1529
+ }
1530
+
1531
+ GfxTilingPattern::~GfxTilingPattern() {
1532
+ resDict.free();
1533
+ contentStream.free();
1534
+ }
1535
+
1536
+ GfxPattern *GfxTilingPattern::copy() {
1537
+ return new GfxTilingPattern(paintType, tilingType, bbox, xStep, yStep,
1538
+ &resDict, matrix, &contentStream);
1539
+ }
1540
+
1541
+ //------------------------------------------------------------------------
1542
+ // GfxShadingPattern
1543
+ //------------------------------------------------------------------------
1544
+
1545
+ GfxShadingPattern *GfxShadingPattern::parse(Object *patObj) {
1546
+ Dict *dict;
1547
+ GfxShading *shadingA;
1548
+ double matrixA[6];
1549
+ Object obj1, obj2;
1550
+ int i;
1551
+
1552
+ if (!patObj->isDict()) {
1553
+ return NULL;
1554
+ }
1555
+ dict = patObj->getDict();
1556
+
1557
+ dict->lookup("Shading", &obj1);
1558
+ shadingA = GfxShading::parse(&obj1);
1559
+ obj1.free();
1560
+ if (!shadingA) {
1561
+ return NULL;
1562
+ }
1563
+
1564
+ matrixA[0] = 1; matrixA[1] = 0;
1565
+ matrixA[2] = 0; matrixA[3] = 1;
1566
+ matrixA[4] = 0; matrixA[5] = 0;
1567
+ if (dict->lookup("Matrix", &obj1)->isArray() &&
1568
+ obj1.arrayGetLength() == 6) {
1569
+ for (i = 0; i < 6; ++i) {
1570
+ if (obj1.arrayGet(i, &obj2)->isNum()) {
1571
+ matrixA[i] = obj2.getNum();
1572
+ }
1573
+ obj2.free();
1574
+ }
1575
+ }
1576
+ obj1.free();
1577
+
1578
+ return new GfxShadingPattern(shadingA, matrixA);
1579
+ }
1580
+
1581
+ GfxShadingPattern::GfxShadingPattern(GfxShading *shadingA, double *matrixA):
1582
+ GfxPattern(2)
1583
+ {
1584
+ int i;
1585
+
1586
+ shading = shadingA;
1587
+ for (i = 0; i < 6; ++i) {
1588
+ matrix[i] = matrixA[i];
1589
+ }
1590
+ }
1591
+
1592
+ GfxShadingPattern::~GfxShadingPattern() {
1593
+ delete shading;
1594
+ }
1595
+
1596
+ GfxPattern *GfxShadingPattern::copy() {
1597
+ return new GfxShadingPattern(shading->copy(), matrix);
1598
+ }
1599
+
1600
+ //------------------------------------------------------------------------
1601
+ // GfxShading
1602
+ //------------------------------------------------------------------------
1603
+
1604
+ GfxShading::GfxShading(int typeA) {
1605
+ type = typeA;
1606
+ colorSpace = NULL;
1607
+ }
1608
+
1609
+ GfxShading::GfxShading(GfxShading *shading) {
1610
+ int i;
1611
+
1612
+ type = shading->type;
1613
+ colorSpace = shading->colorSpace->copy();
1614
+ for (i = 0; i < gfxColorMaxComps; ++i) {
1615
+ background.c[i] = shading->background.c[i];
1616
+ }
1617
+ hasBackground = shading->hasBackground;
1618
+ xMin = shading->xMin;
1619
+ yMin = shading->yMin;
1620
+ xMax = shading->xMax;
1621
+ yMax = shading->yMax;
1622
+ hasBBox = shading->hasBBox;
1623
+ }
1624
+
1625
+ GfxShading::~GfxShading() {
1626
+ if (colorSpace) {
1627
+ delete colorSpace;
1628
+ }
1629
+ }
1630
+
1631
+ GfxShading *GfxShading::parse(Object *obj) {
1632
+ GfxShading *shading;
1633
+ Dict *dict;
1634
+ int typeA;
1635
+ Object obj1;
1636
+
1637
+ if (obj->isDict()) {
1638
+ dict = obj->getDict();
1639
+ } else if (obj->isStream()) {
1640
+ dict = obj->streamGetDict();
1641
+ } else {
1642
+ return NULL;
1643
+ }
1644
+
1645
+ if (!dict->lookup("ShadingType", &obj1)->isInt()) {
1646
+ error(-1, "Invalid ShadingType in shading dictionary");
1647
+ obj1.free();
1648
+ return NULL;
1649
+ }
1650
+ typeA = obj1.getInt();
1651
+ obj1.free();
1652
+
1653
+ switch (typeA) {
1654
+ case 1:
1655
+ shading = GfxFunctionShading::parse(dict);
1656
+ break;
1657
+ case 2:
1658
+ shading = GfxAxialShading::parse(dict);
1659
+ break;
1660
+ case 3:
1661
+ shading = GfxRadialShading::parse(dict);
1662
+ break;
1663
+ case 4:
1664
+ if (obj->isStream()) {
1665
+ shading = GfxGouraudTriangleShading::parse(4, dict, obj->getStream());
1666
+ } else {
1667
+ error(-1, "Invalid Type 4 shading object");
1668
+ goto err1;
1669
+ }
1670
+ break;
1671
+ case 5:
1672
+ if (obj->isStream()) {
1673
+ shading = GfxGouraudTriangleShading::parse(5, dict, obj->getStream());
1674
+ } else {
1675
+ error(-1, "Invalid Type 5 shading object");
1676
+ goto err1;
1677
+ }
1678
+ break;
1679
+ case 6:
1680
+ if (obj->isStream()) {
1681
+ shading = GfxPatchMeshShading::parse(6, dict, obj->getStream());
1682
+ } else {
1683
+ error(-1, "Invalid Type 6 shading object");
1684
+ goto err1;
1685
+ }
1686
+ break;
1687
+ case 7:
1688
+ if (obj->isStream()) {
1689
+ shading = GfxPatchMeshShading::parse(7, dict, obj->getStream());
1690
+ } else {
1691
+ error(-1, "Invalid Type 7 shading object");
1692
+ goto err1;
1693
+ }
1694
+ break;
1695
+ default:
1696
+ error(-1, "Unimplemented shading type %d", typeA);
1697
+ goto err1;
1698
+ }
1699
+
1700
+ return shading;
1701
+
1702
+ err1:
1703
+ return NULL;
1704
+ }
1705
+
1706
+ GBool GfxShading::init(Dict *dict) {
1707
+ Object obj1, obj2;
1708
+ int i;
1709
+
1710
+ dict->lookup("ColorSpace", &obj1);
1711
+ if (!(colorSpace = GfxColorSpace::parse(&obj1))) {
1712
+ error(-1, "Bad color space in shading dictionary");
1713
+ obj1.free();
1714
+ return gFalse;
1715
+ }
1716
+ obj1.free();
1717
+
1718
+ for (i = 0; i < gfxColorMaxComps; ++i) {
1719
+ background.c[i] = 0;
1720
+ }
1721
+ hasBackground = gFalse;
1722
+ if (dict->lookup("Background", &obj1)->isArray()) {
1723
+ if (obj1.arrayGetLength() == colorSpace->getNComps()) {
1724
+ hasBackground = gTrue;
1725
+ for (i = 0; i < colorSpace->getNComps(); ++i) {
1726
+ background.c[i] = dblToCol(obj1.arrayGet(i, &obj2)->getNum());
1727
+ obj2.free();
1728
+ }
1729
+ } else {
1730
+ error(-1, "Bad Background in shading dictionary");
1731
+ }
1732
+ }
1733
+ obj1.free();
1734
+
1735
+ xMin = yMin = xMax = yMax = 0;
1736
+ hasBBox = gFalse;
1737
+ if (dict->lookup("BBox", &obj1)->isArray()) {
1738
+ if (obj1.arrayGetLength() == 4) {
1739
+ hasBBox = gTrue;
1740
+ xMin = obj1.arrayGet(0, &obj2)->getNum();
1741
+ obj2.free();
1742
+ yMin = obj1.arrayGet(1, &obj2)->getNum();
1743
+ obj2.free();
1744
+ xMax = obj1.arrayGet(2, &obj2)->getNum();
1745
+ obj2.free();
1746
+ yMax = obj1.arrayGet(3, &obj2)->getNum();
1747
+ obj2.free();
1748
+ } else {
1749
+ error(-1, "Bad BBox in shading dictionary");
1750
+ }
1751
+ }
1752
+ obj1.free();
1753
+
1754
+ return gTrue;
1755
+ }
1756
+
1757
+ //------------------------------------------------------------------------
1758
+ // GfxFunctionShading
1759
+ //------------------------------------------------------------------------
1760
+
1761
+ GfxFunctionShading::GfxFunctionShading(double x0A, double y0A,
1762
+ double x1A, double y1A,
1763
+ double *matrixA,
1764
+ Function **funcsA, int nFuncsA):
1765
+ GfxShading(1)
1766
+ {
1767
+ int i;
1768
+
1769
+ x0 = x0A;
1770
+ y0 = y0A;
1771
+ x1 = x1A;
1772
+ y1 = y1A;
1773
+ for (i = 0; i < 6; ++i) {
1774
+ matrix[i] = matrixA[i];
1775
+ }
1776
+ nFuncs = nFuncsA;
1777
+ for (i = 0; i < nFuncs; ++i) {
1778
+ funcs[i] = funcsA[i];
1779
+ }
1780
+ }
1781
+
1782
+ GfxFunctionShading::GfxFunctionShading(GfxFunctionShading *shading):
1783
+ GfxShading(shading)
1784
+ {
1785
+ int i;
1786
+
1787
+ x0 = shading->x0;
1788
+ y0 = shading->y0;
1789
+ x1 = shading->x1;
1790
+ y1 = shading->y1;
1791
+ for (i = 0; i < 6; ++i) {
1792
+ matrix[i] = shading->matrix[i];
1793
+ }
1794
+ nFuncs = shading->nFuncs;
1795
+ for (i = 0; i < nFuncs; ++i) {
1796
+ funcs[i] = shading->funcs[i]->copy();
1797
+ }
1798
+ }
1799
+
1800
+ GfxFunctionShading::~GfxFunctionShading() {
1801
+ int i;
1802
+
1803
+ for (i = 0; i < nFuncs; ++i) {
1804
+ delete funcs[i];
1805
+ }
1806
+ }
1807
+
1808
+ GfxFunctionShading *GfxFunctionShading::parse(Dict *dict) {
1809
+ GfxFunctionShading *shading;
1810
+ double x0A, y0A, x1A, y1A;
1811
+ double matrixA[6];
1812
+ Function *funcsA[gfxColorMaxComps];
1813
+ int nFuncsA;
1814
+ Object obj1, obj2;
1815
+ int i;
1816
+
1817
+ x0A = y0A = 0;
1818
+ x1A = y1A = 1;
1819
+ if (dict->lookup("Domain", &obj1)->isArray() &&
1820
+ obj1.arrayGetLength() == 4) {
1821
+ x0A = obj1.arrayGet(0, &obj2)->getNum();
1822
+ obj2.free();
1823
+ y0A = obj1.arrayGet(1, &obj2)->getNum();
1824
+ obj2.free();
1825
+ x1A = obj1.arrayGet(2, &obj2)->getNum();
1826
+ obj2.free();
1827
+ y1A = obj1.arrayGet(3, &obj2)->getNum();
1828
+ obj2.free();
1829
+ }
1830
+ obj1.free();
1831
+
1832
+ matrixA[0] = 1; matrixA[1] = 0;
1833
+ matrixA[2] = 0; matrixA[3] = 1;
1834
+ matrixA[4] = 0; matrixA[5] = 0;
1835
+ if (dict->lookup("Matrix", &obj1)->isArray() &&
1836
+ obj1.arrayGetLength() == 6) {
1837
+ matrixA[0] = obj1.arrayGet(0, &obj2)->getNum();
1838
+ obj2.free();
1839
+ matrixA[1] = obj1.arrayGet(1, &obj2)->getNum();
1840
+ obj2.free();
1841
+ matrixA[2] = obj1.arrayGet(2, &obj2)->getNum();
1842
+ obj2.free();
1843
+ matrixA[3] = obj1.arrayGet(3, &obj2)->getNum();
1844
+ obj2.free();
1845
+ matrixA[4] = obj1.arrayGet(4, &obj2)->getNum();
1846
+ obj2.free();
1847
+ matrixA[5] = obj1.arrayGet(5, &obj2)->getNum();
1848
+ obj2.free();
1849
+ }
1850
+ obj1.free();
1851
+
1852
+ dict->lookup("Function", &obj1);
1853
+ if (obj1.isArray()) {
1854
+ nFuncsA = obj1.arrayGetLength();
1855
+ if (nFuncsA > gfxColorMaxComps) {
1856
+ error(-1, "Invalid Function array in shading dictionary");
1857
+ goto err1;
1858
+ }
1859
+ for (i = 0; i < nFuncsA; ++i) {
1860
+ obj1.arrayGet(i, &obj2);
1861
+ if (!(funcsA[i] = Function::parse(&obj2))) {
1862
+ goto err2;
1863
+ }
1864
+ obj2.free();
1865
+ }
1866
+ } else {
1867
+ nFuncsA = 1;
1868
+ if (!(funcsA[0] = Function::parse(&obj1))) {
1869
+ goto err1;
1870
+ }
1871
+ }
1872
+ obj1.free();
1873
+
1874
+ shading = new GfxFunctionShading(x0A, y0A, x1A, y1A, matrixA,
1875
+ funcsA, nFuncsA);
1876
+ if (!shading->init(dict)) {
1877
+ delete shading;
1878
+ return NULL;
1879
+ }
1880
+ return shading;
1881
+
1882
+ err2:
1883
+ obj2.free();
1884
+ err1:
1885
+ obj1.free();
1886
+ return NULL;
1887
+ }
1888
+
1889
+ GfxShading *GfxFunctionShading::copy() {
1890
+ return new GfxFunctionShading(this);
1891
+ }
1892
+
1893
+ void GfxFunctionShading::getColor(double x, double y, GfxColor *color) {
1894
+ double in[2], out[gfxColorMaxComps];
1895
+ int i;
1896
+
1897
+ // NB: there can be one function with n outputs or n functions with
1898
+ // one output each (where n = number of color components)
1899
+ for (i = 0; i < gfxColorMaxComps; ++i) {
1900
+ out[i] = 0;
1901
+ }
1902
+ in[0] = x;
1903
+ in[1] = y;
1904
+ for (i = 0; i < nFuncs; ++i) {
1905
+ funcs[i]->transform(in, &out[i]);
1906
+ }
1907
+ for (i = 0; i < gfxColorMaxComps; ++i) {
1908
+ color->c[i] = dblToCol(out[i]);
1909
+ }
1910
+ }
1911
+
1912
+ //------------------------------------------------------------------------
1913
+ // GfxAxialShading
1914
+ //------------------------------------------------------------------------
1915
+
1916
+ GfxAxialShading::GfxAxialShading(double x0A, double y0A,
1917
+ double x1A, double y1A,
1918
+ double t0A, double t1A,
1919
+ Function **funcsA, int nFuncsA,
1920
+ GBool extend0A, GBool extend1A):
1921
+ GfxShading(2)
1922
+ {
1923
+ int i;
1924
+
1925
+ x0 = x0A;
1926
+ y0 = y0A;
1927
+ x1 = x1A;
1928
+ y1 = y1A;
1929
+ t0 = t0A;
1930
+ t1 = t1A;
1931
+ nFuncs = nFuncsA;
1932
+ for (i = 0; i < nFuncs; ++i) {
1933
+ funcs[i] = funcsA[i];
1934
+ }
1935
+ extend0 = extend0A;
1936
+ extend1 = extend1A;
1937
+ }
1938
+
1939
+ GfxAxialShading::GfxAxialShading(GfxAxialShading *shading):
1940
+ GfxShading(shading)
1941
+ {
1942
+ int i;
1943
+
1944
+ x0 = shading->x0;
1945
+ y0 = shading->y0;
1946
+ x1 = shading->x1;
1947
+ y1 = shading->y1;
1948
+ t0 = shading->t0;
1949
+ y1 = shading->t1;
1950
+ nFuncs = shading->nFuncs;
1951
+ for (i = 0; i < nFuncs; ++i) {
1952
+ funcs[i] = shading->funcs[i]->copy();
1953
+ }
1954
+ extend0 = shading->extend0;
1955
+ extend1 = shading->extend1;
1956
+ }
1957
+
1958
+ GfxAxialShading::~GfxAxialShading() {
1959
+ int i;
1960
+
1961
+ for (i = 0; i < nFuncs; ++i) {
1962
+ delete funcs[i];
1963
+ }
1964
+ }
1965
+
1966
+ GfxAxialShading *GfxAxialShading::parse(Dict *dict) {
1967
+ GfxAxialShading *shading;
1968
+ double x0A, y0A, x1A, y1A;
1969
+ double t0A, t1A;
1970
+ Function *funcsA[gfxColorMaxComps];
1971
+ int nFuncsA;
1972
+ GBool extend0A, extend1A;
1973
+ Object obj1, obj2;
1974
+ int i;
1975
+
1976
+ x0A = y0A = x1A = y1A = 0;
1977
+ if (dict->lookup("Coords", &obj1)->isArray() &&
1978
+ obj1.arrayGetLength() == 4) {
1979
+ x0A = obj1.arrayGet(0, &obj2)->getNum();
1980
+ obj2.free();
1981
+ y0A = obj1.arrayGet(1, &obj2)->getNum();
1982
+ obj2.free();
1983
+ x1A = obj1.arrayGet(2, &obj2)->getNum();
1984
+ obj2.free();
1985
+ y1A = obj1.arrayGet(3, &obj2)->getNum();
1986
+ obj2.free();
1987
+ } else {
1988
+ error(-1, "Missing or invalid Coords in shading dictionary");
1989
+ goto err1;
1990
+ }
1991
+ obj1.free();
1992
+
1993
+ t0A = 0;
1994
+ t1A = 1;
1995
+ if (dict->lookup("Domain", &obj1)->isArray() &&
1996
+ obj1.arrayGetLength() == 2) {
1997
+ t0A = obj1.arrayGet(0, &obj2)->getNum();
1998
+ obj2.free();
1999
+ t1A = obj1.arrayGet(1, &obj2)->getNum();
2000
+ obj2.free();
2001
+ }
2002
+ obj1.free();
2003
+
2004
+ dict->lookup("Function", &obj1);
2005
+ if (obj1.isArray()) {
2006
+ nFuncsA = obj1.arrayGetLength();
2007
+ if (nFuncsA > gfxColorMaxComps) {
2008
+ error(-1, "Invalid Function array in shading dictionary");
2009
+ goto err1;
2010
+ }
2011
+ for (i = 0; i < nFuncsA; ++i) {
2012
+ obj1.arrayGet(i, &obj2);
2013
+ if (!(funcsA[i] = Function::parse(&obj2))) {
2014
+ obj1.free();
2015
+ obj2.free();
2016
+ goto err1;
2017
+ }
2018
+ obj2.free();
2019
+ }
2020
+ } else {
2021
+ nFuncsA = 1;
2022
+ if (!(funcsA[0] = Function::parse(&obj1))) {
2023
+ obj1.free();
2024
+ goto err1;
2025
+ }
2026
+ }
2027
+ obj1.free();
2028
+
2029
+ extend0A = extend1A = gFalse;
2030
+ if (dict->lookup("Extend", &obj1)->isArray() &&
2031
+ obj1.arrayGetLength() == 2) {
2032
+ extend0A = obj1.arrayGet(0, &obj2)->getBool();
2033
+ obj2.free();
2034
+ extend1A = obj1.arrayGet(1, &obj2)->getBool();
2035
+ obj2.free();
2036
+ }
2037
+ obj1.free();
2038
+
2039
+ shading = new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A,
2040
+ funcsA, nFuncsA, extend0A, extend1A);
2041
+ if (!shading->init(dict)) {
2042
+ delete shading;
2043
+ return NULL;
2044
+ }
2045
+ return shading;
2046
+
2047
+ err1:
2048
+ return NULL;
2049
+ }
2050
+
2051
+ GfxShading *GfxAxialShading::copy() {
2052
+ return new GfxAxialShading(this);
2053
+ }
2054
+
2055
+ void GfxAxialShading::getColor(double t, GfxColor *color) {
2056
+ double out[gfxColorMaxComps];
2057
+ int i;
2058
+
2059
+ // NB: there can be one function with n outputs or n functions with
2060
+ // one output each (where n = number of color components)
2061
+ for (i = 0; i < gfxColorMaxComps; ++i) {
2062
+ out[i] = 0;
2063
+ }
2064
+ for (i = 0; i < nFuncs; ++i) {
2065
+ funcs[i]->transform(&t, &out[i]);
2066
+ }
2067
+ for (i = 0; i < gfxColorMaxComps; ++i) {
2068
+ color->c[i] = dblToCol(out[i]);
2069
+ }
2070
+ }
2071
+
2072
+ //------------------------------------------------------------------------
2073
+ // GfxRadialShading
2074
+ //------------------------------------------------------------------------
2075
+
2076
+ GfxRadialShading::GfxRadialShading(double x0A, double y0A, double r0A,
2077
+ double x1A, double y1A, double r1A,
2078
+ double t0A, double t1A,
2079
+ Function **funcsA, int nFuncsA,
2080
+ GBool extend0A, GBool extend1A):
2081
+ GfxShading(3)
2082
+ {
2083
+ int i;
2084
+
2085
+ x0 = x0A;
2086
+ y0 = y0A;
2087
+ r0 = r0A;
2088
+ x1 = x1A;
2089
+ y1 = y1A;
2090
+ r1 = r1A;
2091
+ t0 = t0A;
2092
+ t1 = t1A;
2093
+ nFuncs = nFuncsA;
2094
+ for (i = 0; i < nFuncs; ++i) {
2095
+ funcs[i] = funcsA[i];
2096
+ }
2097
+ extend0 = extend0A;
2098
+ extend1 = extend1A;
2099
+ }
2100
+
2101
+ GfxRadialShading::GfxRadialShading(GfxRadialShading *shading):
2102
+ GfxShading(shading)
2103
+ {
2104
+ int i;
2105
+
2106
+ x0 = shading->x0;
2107
+ y0 = shading->y0;
2108
+ r0 = shading->r0;
2109
+ x1 = shading->x1;
2110
+ y1 = shading->y1;
2111
+ r1 = shading->r1;
2112
+ t0 = shading->t0;
2113
+ y1 = shading->t1;
2114
+ nFuncs = shading->nFuncs;
2115
+ for (i = 0; i < nFuncs; ++i) {
2116
+ funcs[i] = shading->funcs[i]->copy();
2117
+ }
2118
+ extend0 = shading->extend0;
2119
+ extend1 = shading->extend1;
2120
+ }
2121
+
2122
+ GfxRadialShading::~GfxRadialShading() {
2123
+ int i;
2124
+
2125
+ for (i = 0; i < nFuncs; ++i) {
2126
+ delete funcs[i];
2127
+ }
2128
+ }
2129
+
2130
+ GfxRadialShading *GfxRadialShading::parse(Dict *dict) {
2131
+ GfxRadialShading *shading;
2132
+ double x0A, y0A, r0A, x1A, y1A, r1A;
2133
+ double t0A, t1A;
2134
+ Function *funcsA[gfxColorMaxComps];
2135
+ int nFuncsA;
2136
+ GBool extend0A, extend1A;
2137
+ Object obj1, obj2;
2138
+ int i;
2139
+
2140
+ x0A = y0A = r0A = x1A = y1A = r1A = 0;
2141
+ if (dict->lookup("Coords", &obj1)->isArray() &&
2142
+ obj1.arrayGetLength() == 6) {
2143
+ x0A = obj1.arrayGet(0, &obj2)->getNum();
2144
+ obj2.free();
2145
+ y0A = obj1.arrayGet(1, &obj2)->getNum();
2146
+ obj2.free();
2147
+ r0A = obj1.arrayGet(2, &obj2)->getNum();
2148
+ obj2.free();
2149
+ x1A = obj1.arrayGet(3, &obj2)->getNum();
2150
+ obj2.free();
2151
+ y1A = obj1.arrayGet(4, &obj2)->getNum();
2152
+ obj2.free();
2153
+ r1A = obj1.arrayGet(5, &obj2)->getNum();
2154
+ obj2.free();
2155
+ } else {
2156
+ error(-1, "Missing or invalid Coords in shading dictionary");
2157
+ goto err1;
2158
+ }
2159
+ obj1.free();
2160
+
2161
+ t0A = 0;
2162
+ t1A = 1;
2163
+ if (dict->lookup("Domain", &obj1)->isArray() &&
2164
+ obj1.arrayGetLength() == 2) {
2165
+ t0A = obj1.arrayGet(0, &obj2)->getNum();
2166
+ obj2.free();
2167
+ t1A = obj1.arrayGet(1, &obj2)->getNum();
2168
+ obj2.free();
2169
+ }
2170
+ obj1.free();
2171
+
2172
+ dict->lookup("Function", &obj1);
2173
+ if (obj1.isArray()) {
2174
+ nFuncsA = obj1.arrayGetLength();
2175
+ if (nFuncsA > gfxColorMaxComps) {
2176
+ error(-1, "Invalid Function array in shading dictionary");
2177
+ goto err1;
2178
+ }
2179
+ for (i = 0; i < nFuncsA; ++i) {
2180
+ obj1.arrayGet(i, &obj2);
2181
+ if (!(funcsA[i] = Function::parse(&obj2))) {
2182
+ obj1.free();
2183
+ obj2.free();
2184
+ goto err1;
2185
+ }
2186
+ obj2.free();
2187
+ }
2188
+ } else {
2189
+ nFuncsA = 1;
2190
+ if (!(funcsA[0] = Function::parse(&obj1))) {
2191
+ obj1.free();
2192
+ goto err1;
2193
+ }
2194
+ }
2195
+ obj1.free();
2196
+
2197
+ extend0A = extend1A = gFalse;
2198
+ if (dict->lookup("Extend", &obj1)->isArray() &&
2199
+ obj1.arrayGetLength() == 2) {
2200
+ extend0A = obj1.arrayGet(0, &obj2)->getBool();
2201
+ obj2.free();
2202
+ extend1A = obj1.arrayGet(1, &obj2)->getBool();
2203
+ obj2.free();
2204
+ }
2205
+ obj1.free();
2206
+
2207
+ shading = new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A,
2208
+ funcsA, nFuncsA, extend0A, extend1A);
2209
+ if (!shading->init(dict)) {
2210
+ delete shading;
2211
+ return NULL;
2212
+ }
2213
+ return shading;
2214
+
2215
+ err1:
2216
+ return NULL;
2217
+ }
2218
+
2219
+ GfxShading *GfxRadialShading::copy() {
2220
+ return new GfxRadialShading(this);
2221
+ }
2222
+
2223
+ void GfxRadialShading::getColor(double t, GfxColor *color) {
2224
+ double out[gfxColorMaxComps];
2225
+ int i;
2226
+
2227
+ // NB: there can be one function with n outputs or n functions with
2228
+ // one output each (where n = number of color components)
2229
+ for (i = 0; i < gfxColorMaxComps; ++i) {
2230
+ out[i] = 0;
2231
+ }
2232
+ for (i = 0; i < nFuncs; ++i) {
2233
+ funcs[i]->transform(&t, &out[i]);
2234
+ }
2235
+ for (i = 0; i < gfxColorMaxComps; ++i) {
2236
+ color->c[i] = dblToCol(out[i]);
2237
+ }
2238
+ }
2239
+
2240
+ //------------------------------------------------------------------------
2241
+ // GfxShadingBitBuf
2242
+ //------------------------------------------------------------------------
2243
+
2244
+ class GfxShadingBitBuf {
2245
+ public:
2246
+
2247
+ GfxShadingBitBuf(Stream *strA);
2248
+ ~GfxShadingBitBuf();
2249
+ GBool getBits(int n, Guint *val);
2250
+ void flushBits();
2251
+
2252
+ private:
2253
+
2254
+ Stream *str;
2255
+ int bitBuf;
2256
+ int nBits;
2257
+ };
2258
+
2259
+ GfxShadingBitBuf::GfxShadingBitBuf(Stream *strA) {
2260
+ str = strA;
2261
+ str->reset();
2262
+ bitBuf = 0;
2263
+ nBits = 0;
2264
+ }
2265
+
2266
+ GfxShadingBitBuf::~GfxShadingBitBuf() {
2267
+ str->close();
2268
+ }
2269
+
2270
+ GBool GfxShadingBitBuf::getBits(int n, Guint *val) {
2271
+ int x;
2272
+
2273
+ if (nBits >= n) {
2274
+ x = (bitBuf >> (nBits - n)) & ((1 << n) - 1);
2275
+ nBits -= n;
2276
+ } else {
2277
+ x = 0;
2278
+ if (nBits > 0) {
2279
+ x = bitBuf & ((1 << nBits) - 1);
2280
+ n -= nBits;
2281
+ nBits = 0;
2282
+ }
2283
+ while (n > 0) {
2284
+ if ((bitBuf = str->getChar()) == EOF) {
2285
+ nBits = 0;
2286
+ return gFalse;
2287
+ }
2288
+ if (n >= 8) {
2289
+ x = (x << 8) | bitBuf;
2290
+ n -= 8;
2291
+ } else {
2292
+ x = (x << n) | (bitBuf >> (8 - n));
2293
+ nBits = 8 - n;
2294
+ n = 0;
2295
+ }
2296
+ }
2297
+ }
2298
+ *val = x;
2299
+ return gTrue;
2300
+ }
2301
+
2302
+ void GfxShadingBitBuf::flushBits() {
2303
+ bitBuf = 0;
2304
+ nBits = 0;
2305
+ }
2306
+
2307
+ //------------------------------------------------------------------------
2308
+ // GfxGouraudTriangleShading
2309
+ //------------------------------------------------------------------------
2310
+
2311
+ GfxGouraudTriangleShading::GfxGouraudTriangleShading(
2312
+ int typeA,
2313
+ GfxGouraudVertex *verticesA, int nVerticesA,
2314
+ int (*trianglesA)[3], int nTrianglesA,
2315
+ Function **funcsA, int nFuncsA):
2316
+ GfxShading(typeA)
2317
+ {
2318
+ int i;
2319
+
2320
+ vertices = verticesA;
2321
+ nVertices = nVerticesA;
2322
+ triangles = trianglesA;
2323
+ nTriangles = nTrianglesA;
2324
+ nFuncs = nFuncsA;
2325
+ for (i = 0; i < nFuncs; ++i) {
2326
+ funcs[i] = funcsA[i];
2327
+ }
2328
+ }
2329
+
2330
+ GfxGouraudTriangleShading::GfxGouraudTriangleShading(
2331
+ GfxGouraudTriangleShading *shading):
2332
+ GfxShading(shading)
2333
+ {
2334
+ int i;
2335
+
2336
+ nVertices = shading->nVertices;
2337
+ vertices = (GfxGouraudVertex *)gmallocn(nVertices, sizeof(GfxGouraudVertex));
2338
+ memcpy(vertices, shading->vertices, nVertices * sizeof(GfxGouraudVertex));
2339
+ nTriangles = shading->nTriangles;
2340
+ triangles = (int (*)[3])gmallocn(nTriangles * 3, sizeof(int));
2341
+ memcpy(triangles, shading->triangles, nTriangles * 3 * sizeof(int));
2342
+ nFuncs = shading->nFuncs;
2343
+ for (i = 0; i < nFuncs; ++i) {
2344
+ funcs[i] = shading->funcs[i]->copy();
2345
+ }
2346
+ }
2347
+
2348
+ GfxGouraudTriangleShading::~GfxGouraudTriangleShading() {
2349
+ int i;
2350
+
2351
+ gfree(vertices);
2352
+ gfree(triangles);
2353
+ for (i = 0; i < nFuncs; ++i) {
2354
+ delete funcs[i];
2355
+ }
2356
+ }
2357
+
2358
+ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(int typeA,
2359
+ Dict *dict,
2360
+ Stream *str) {
2361
+ GfxGouraudTriangleShading *shading;
2362
+ Function *funcsA[gfxColorMaxComps];
2363
+ int nFuncsA;
2364
+ int coordBits, compBits, flagBits, vertsPerRow, nRows;
2365
+ double xMin, xMax, yMin, yMax;
2366
+ double cMin[gfxColorMaxComps], cMax[gfxColorMaxComps];
2367
+ double xMul, yMul;
2368
+ double cMul[gfxColorMaxComps];
2369
+ GfxGouraudVertex *verticesA;
2370
+ int (*trianglesA)[3];
2371
+ int nComps, nVerticesA, nTrianglesA, vertSize, triSize;
2372
+ Guint x, y, flag;
2373
+ Guint c[gfxColorMaxComps];
2374
+ GfxShadingBitBuf *bitBuf;
2375
+ Object obj1, obj2;
2376
+ int i, j, k, state;
2377
+
2378
+ if (dict->lookup("BitsPerCoordinate", &obj1)->isInt()) {
2379
+ coordBits = obj1.getInt();
2380
+ } else {
2381
+ error(-1, "Missing or invalid BitsPerCoordinate in shading dictionary");
2382
+ goto err2;
2383
+ }
2384
+ obj1.free();
2385
+ if (dict->lookup("BitsPerComponent", &obj1)->isInt()) {
2386
+ compBits = obj1.getInt();
2387
+ } else {
2388
+ error(-1, "Missing or invalid BitsPerComponent in shading dictionary");
2389
+ goto err2;
2390
+ }
2391
+ obj1.free();
2392
+ flagBits = vertsPerRow = 0; // make gcc happy
2393
+ if (typeA == 4) {
2394
+ if (dict->lookup("BitsPerFlag", &obj1)->isInt()) {
2395
+ flagBits = obj1.getInt();
2396
+ } else {
2397
+ error(-1, "Missing or invalid BitsPerFlag in shading dictionary");
2398
+ goto err2;
2399
+ }
2400
+ obj1.free();
2401
+ } else {
2402
+ if (dict->lookup("VerticesPerRow", &obj1)->isInt()) {
2403
+ vertsPerRow = obj1.getInt();
2404
+ } else {
2405
+ error(-1, "Missing or invalid VerticesPerRow in shading dictionary");
2406
+ goto err2;
2407
+ }
2408
+ obj1.free();
2409
+ }
2410
+ if (dict->lookup("Decode", &obj1)->isArray() &&
2411
+ obj1.arrayGetLength() >= 6) {
2412
+ xMin = obj1.arrayGet(0, &obj2)->getNum();
2413
+ obj2.free();
2414
+ xMax = obj1.arrayGet(1, &obj2)->getNum();
2415
+ obj2.free();
2416
+ xMul = (xMax - xMin) / (pow(2.0, coordBits) - 1);
2417
+ yMin = obj1.arrayGet(2, &obj2)->getNum();
2418
+ obj2.free();
2419
+ yMax = obj1.arrayGet(3, &obj2)->getNum();
2420
+ obj2.free();
2421
+ yMul = (yMax - yMin) / (pow(2.0, coordBits) - 1);
2422
+ for (i = 0; 5 + 2*i < obj1.arrayGetLength() && i < gfxColorMaxComps; ++i) {
2423
+ cMin[i] = obj1.arrayGet(4 + 2*i, &obj2)->getNum();
2424
+ obj2.free();
2425
+ cMax[i] = obj1.arrayGet(5 + 2*i, &obj2)->getNum();
2426
+ obj2.free();
2427
+ cMul[i] = (cMax[i] - cMin[i]) / (double)((1 << compBits) - 1);
2428
+ }
2429
+ nComps = i;
2430
+ } else {
2431
+ error(-1, "Missing or invalid Decode array in shading dictionary");
2432
+ goto err2;
2433
+ }
2434
+ obj1.free();
2435
+
2436
+ if (!dict->lookup("Function", &obj1)->isNull()) {
2437
+ if (obj1.isArray()) {
2438
+ nFuncsA = obj1.arrayGetLength();
2439
+ if (nFuncsA > gfxColorMaxComps) {
2440
+ error(-1, "Invalid Function array in shading dictionary");
2441
+ goto err1;
2442
+ }
2443
+ for (i = 0; i < nFuncsA; ++i) {
2444
+ obj1.arrayGet(i, &obj2);
2445
+ if (!(funcsA[i] = Function::parse(&obj2))) {
2446
+ obj1.free();
2447
+ obj2.free();
2448
+ goto err1;
2449
+ }
2450
+ obj2.free();
2451
+ }
2452
+ } else {
2453
+ nFuncsA = 1;
2454
+ if (!(funcsA[0] = Function::parse(&obj1))) {
2455
+ obj1.free();
2456
+ goto err1;
2457
+ }
2458
+ }
2459
+ } else {
2460
+ nFuncsA = 0;
2461
+ }
2462
+ obj1.free();
2463
+
2464
+ nVerticesA = nTrianglesA = 0;
2465
+ verticesA = NULL;
2466
+ trianglesA = NULL;
2467
+ vertSize = triSize = 0;
2468
+ state = 0;
2469
+ flag = 0; // make gcc happy
2470
+ bitBuf = new GfxShadingBitBuf(str);
2471
+ while (1) {
2472
+ if (typeA == 4) {
2473
+ if (!bitBuf->getBits(flagBits, &flag)) {
2474
+ break;
2475
+ }
2476
+ }
2477
+ if (!bitBuf->getBits(coordBits, &x) ||
2478
+ !bitBuf->getBits(coordBits, &y)) {
2479
+ break;
2480
+ }
2481
+ for (i = 0; i < nComps; ++i) {
2482
+ if (!bitBuf->getBits(compBits, &c[i])) {
2483
+ break;
2484
+ }
2485
+ }
2486
+ if (i < nComps) {
2487
+ break;
2488
+ }
2489
+ if (nVerticesA == vertSize) {
2490
+ vertSize = (vertSize == 0) ? 16 : 2 * vertSize;
2491
+ verticesA = (GfxGouraudVertex *)
2492
+ greallocn(verticesA, vertSize, sizeof(GfxGouraudVertex));
2493
+ }
2494
+ verticesA[nVerticesA].x = xMin + xMul * (double)x;
2495
+ verticesA[nVerticesA].y = yMin + yMul * (double)y;
2496
+ for (i = 0; i < nComps; ++i) {
2497
+ verticesA[nVerticesA].color.c[i] =
2498
+ dblToCol(cMin[i] + cMul[i] * (double)c[i]);
2499
+ }
2500
+ ++nVerticesA;
2501
+ bitBuf->flushBits();
2502
+ if (typeA == 4) {
2503
+ if (state == 0 || state == 1) {
2504
+ ++state;
2505
+ } else if (state == 2 || flag > 0) {
2506
+ if (nTrianglesA == triSize) {
2507
+ triSize = (triSize == 0) ? 16 : 2 * triSize;
2508
+ trianglesA = (int (*)[3])
2509
+ greallocn(trianglesA, triSize * 3, sizeof(int));
2510
+ }
2511
+ if (state == 2) {
2512
+ trianglesA[nTrianglesA][0] = nVerticesA - 3;
2513
+ trianglesA[nTrianglesA][1] = nVerticesA - 2;
2514
+ trianglesA[nTrianglesA][2] = nVerticesA - 1;
2515
+ ++state;
2516
+ } else if (flag == 1) {
2517
+ trianglesA[nTrianglesA][0] = trianglesA[nTrianglesA - 1][1];
2518
+ trianglesA[nTrianglesA][1] = trianglesA[nTrianglesA - 1][2];
2519
+ trianglesA[nTrianglesA][2] = nVerticesA - 1;
2520
+ } else { // flag == 2
2521
+ trianglesA[nTrianglesA][0] = trianglesA[nTrianglesA - 1][0];
2522
+ trianglesA[nTrianglesA][1] = trianglesA[nTrianglesA - 1][2];
2523
+ trianglesA[nTrianglesA][2] = nVerticesA - 1;
2524
+ }
2525
+ ++nTrianglesA;
2526
+ } else { // state == 3 && flag == 0
2527
+ state = 1;
2528
+ }
2529
+ }
2530
+ }
2531
+ delete bitBuf;
2532
+ if (typeA == 5) {
2533
+ nRows = nVerticesA / vertsPerRow;
2534
+ nTrianglesA = (nRows - 1) * 2 * (vertsPerRow - 1);
2535
+ trianglesA = (int (*)[3])gmallocn(nTrianglesA * 3, sizeof(int));
2536
+ k = 0;
2537
+ for (i = 0; i < nRows - 1; ++i) {
2538
+ for (j = 0; j < vertsPerRow - 1; ++j) {
2539
+ trianglesA[k][0] = i * vertsPerRow + j;
2540
+ trianglesA[k][1] = i * vertsPerRow + j+1;
2541
+ trianglesA[k][2] = (i+1) * vertsPerRow + j;
2542
+ ++k;
2543
+ trianglesA[k][0] = i * vertsPerRow + j+1;
2544
+ trianglesA[k][1] = (i+1) * vertsPerRow + j;
2545
+ trianglesA[k][2] = (i+1) * vertsPerRow + j+1;
2546
+ ++k;
2547
+ }
2548
+ }
2549
+ }
2550
+
2551
+ shading = new GfxGouraudTriangleShading(typeA, verticesA, nVerticesA,
2552
+ trianglesA, nTrianglesA,
2553
+ funcsA, nFuncsA);
2554
+ if (!shading->init(dict)) {
2555
+ delete shading;
2556
+ return NULL;
2557
+ }
2558
+ return shading;
2559
+
2560
+ err2:
2561
+ obj1.free();
2562
+ err1:
2563
+ return NULL;
2564
+ }
2565
+
2566
+ GfxShading *GfxGouraudTriangleShading::copy() {
2567
+ return new GfxGouraudTriangleShading(this);
2568
+ }
2569
+
2570
+ void GfxGouraudTriangleShading::getTriangle(
2571
+ int i,
2572
+ double *x0, double *y0, GfxColor *color0,
2573
+ double *x1, double *y1, GfxColor *color1,
2574
+ double *x2, double *y2, GfxColor *color2) {
2575
+ double in;
2576
+ double out[gfxColorMaxComps];
2577
+ int v, j;
2578
+
2579
+ v = triangles[i][0];
2580
+ *x0 = vertices[v].x;
2581
+ *y0 = vertices[v].y;
2582
+ if (nFuncs > 0) {
2583
+ in = colToDbl(vertices[v].color.c[0]);
2584
+ for (j = 0; j < nFuncs; ++j) {
2585
+ funcs[j]->transform(&in, &out[j]);
2586
+ }
2587
+ for (j = 0; j < gfxColorMaxComps; ++j) {
2588
+ color0->c[j] = dblToCol(out[j]);
2589
+ }
2590
+ } else {
2591
+ *color0 = vertices[v].color;
2592
+ }
2593
+ v = triangles[i][1];
2594
+ *x1 = vertices[v].x;
2595
+ *y1 = vertices[v].y;
2596
+ if (nFuncs > 0) {
2597
+ in = colToDbl(vertices[v].color.c[0]);
2598
+ for (j = 0; j < nFuncs; ++j) {
2599
+ funcs[j]->transform(&in, &out[j]);
2600
+ }
2601
+ for (j = 0; j < gfxColorMaxComps; ++j) {
2602
+ color1->c[j] = dblToCol(out[j]);
2603
+ }
2604
+ } else {
2605
+ *color1 = vertices[v].color;
2606
+ }
2607
+ v = triangles[i][2];
2608
+ *x2 = vertices[v].x;
2609
+ *y2 = vertices[v].y;
2610
+ if (nFuncs > 0) {
2611
+ in = colToDbl(vertices[v].color.c[0]);
2612
+ for (j = 0; j < nFuncs; ++j) {
2613
+ funcs[j]->transform(&in, &out[j]);
2614
+ }
2615
+ for (j = 0; j < gfxColorMaxComps; ++j) {
2616
+ color2->c[j] = dblToCol(out[j]);
2617
+ }
2618
+ } else {
2619
+ *color2 = vertices[v].color;
2620
+ }
2621
+ }
2622
+
2623
+ //------------------------------------------------------------------------
2624
+ // GfxPatchMeshShading
2625
+ //------------------------------------------------------------------------
2626
+
2627
+ GfxPatchMeshShading::GfxPatchMeshShading(int typeA,
2628
+ GfxPatch *patchesA, int nPatchesA,
2629
+ Function **funcsA, int nFuncsA):
2630
+ GfxShading(typeA)
2631
+ {
2632
+ int i;
2633
+
2634
+ patches = patchesA;
2635
+ nPatches = nPatchesA;
2636
+ nFuncs = nFuncsA;
2637
+ for (i = 0; i < nFuncs; ++i) {
2638
+ funcs[i] = funcsA[i];
2639
+ }
2640
+ }
2641
+
2642
+ GfxPatchMeshShading::GfxPatchMeshShading(GfxPatchMeshShading *shading):
2643
+ GfxShading(shading)
2644
+ {
2645
+ int i;
2646
+
2647
+ nPatches = shading->nPatches;
2648
+ patches = (GfxPatch *)gmallocn(nPatches, sizeof(GfxPatch));
2649
+ memcpy(patches, shading->patches, nPatches * sizeof(GfxPatch));
2650
+ nFuncs = shading->nFuncs;
2651
+ for (i = 0; i < nFuncs; ++i) {
2652
+ funcs[i] = shading->funcs[i]->copy();
2653
+ }
2654
+ }
2655
+
2656
+ GfxPatchMeshShading::~GfxPatchMeshShading() {
2657
+ int i;
2658
+
2659
+ gfree(patches);
2660
+ for (i = 0; i < nFuncs; ++i) {
2661
+ delete funcs[i];
2662
+ }
2663
+ }
2664
+
2665
+ GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict,
2666
+ Stream *str) {
2667
+ GfxPatchMeshShading *shading;
2668
+ Function *funcsA[gfxColorMaxComps];
2669
+ int nFuncsA;
2670
+ int coordBits, compBits, flagBits;
2671
+ double xMin, xMax, yMin, yMax;
2672
+ double cMin[gfxColorMaxComps], cMax[gfxColorMaxComps];
2673
+ double xMul, yMul;
2674
+ double cMul[gfxColorMaxComps];
2675
+ GfxPatch *patchesA, *p;
2676
+ int nComps, nPatchesA, patchesSize, nPts, nColors;
2677
+ Guint flag;
2678
+ double x[16], y[16];
2679
+ Guint xi, yi;
2680
+ GfxColorComp c[4][gfxColorMaxComps];
2681
+ Guint ci[4];
2682
+ GfxShadingBitBuf *bitBuf;
2683
+ Object obj1, obj2;
2684
+ int i, j;
2685
+
2686
+ if (dict->lookup("BitsPerCoordinate", &obj1)->isInt()) {
2687
+ coordBits = obj1.getInt();
2688
+ } else {
2689
+ error(-1, "Missing or invalid BitsPerCoordinate in shading dictionary");
2690
+ goto err2;
2691
+ }
2692
+ obj1.free();
2693
+ if (dict->lookup("BitsPerComponent", &obj1)->isInt()) {
2694
+ compBits = obj1.getInt();
2695
+ } else {
2696
+ error(-1, "Missing or invalid BitsPerComponent in shading dictionary");
2697
+ goto err2;
2698
+ }
2699
+ obj1.free();
2700
+ if (dict->lookup("BitsPerFlag", &obj1)->isInt()) {
2701
+ flagBits = obj1.getInt();
2702
+ } else {
2703
+ error(-1, "Missing or invalid BitsPerFlag in shading dictionary");
2704
+ goto err2;
2705
+ }
2706
+ obj1.free();
2707
+ if (dict->lookup("Decode", &obj1)->isArray() &&
2708
+ obj1.arrayGetLength() >= 6) {
2709
+ xMin = obj1.arrayGet(0, &obj2)->getNum();
2710
+ obj2.free();
2711
+ xMax = obj1.arrayGet(1, &obj2)->getNum();
2712
+ obj2.free();
2713
+ xMul = (xMax - xMin) / (pow(2.0, coordBits) - 1);
2714
+ yMin = obj1.arrayGet(2, &obj2)->getNum();
2715
+ obj2.free();
2716
+ yMax = obj1.arrayGet(3, &obj2)->getNum();
2717
+ obj2.free();
2718
+ yMul = (yMax - yMin) / (pow(2.0, coordBits) - 1);
2719
+ for (i = 0; 5 + 2*i < obj1.arrayGetLength() && i < gfxColorMaxComps; ++i) {
2720
+ cMin[i] = obj1.arrayGet(4 + 2*i, &obj2)->getNum();
2721
+ obj2.free();
2722
+ cMax[i] = obj1.arrayGet(5 + 2*i, &obj2)->getNum();
2723
+ obj2.free();
2724
+ cMul[i] = (cMax[i] - cMin[i]) / (double)((1 << compBits) - 1);
2725
+ }
2726
+ nComps = i;
2727
+ } else {
2728
+ error(-1, "Missing or invalid Decode array in shading dictionary");
2729
+ goto err2;
2730
+ }
2731
+ obj1.free();
2732
+
2733
+ if (!dict->lookup("Function", &obj1)->isNull()) {
2734
+ if (obj1.isArray()) {
2735
+ nFuncsA = obj1.arrayGetLength();
2736
+ if (nFuncsA > gfxColorMaxComps) {
2737
+ error(-1, "Invalid Function array in shading dictionary");
2738
+ goto err1;
2739
+ }
2740
+ for (i = 0; i < nFuncsA; ++i) {
2741
+ obj1.arrayGet(i, &obj2);
2742
+ if (!(funcsA[i] = Function::parse(&obj2))) {
2743
+ obj1.free();
2744
+ obj2.free();
2745
+ goto err1;
2746
+ }
2747
+ obj2.free();
2748
+ }
2749
+ } else {
2750
+ nFuncsA = 1;
2751
+ if (!(funcsA[0] = Function::parse(&obj1))) {
2752
+ obj1.free();
2753
+ goto err1;
2754
+ }
2755
+ }
2756
+ } else {
2757
+ nFuncsA = 0;
2758
+ }
2759
+ obj1.free();
2760
+
2761
+ nPatchesA = 0;
2762
+ patchesA = NULL;
2763
+ patchesSize = 0;
2764
+ bitBuf = new GfxShadingBitBuf(str);
2765
+ while (1) {
2766
+ if (!bitBuf->getBits(flagBits, &flag)) {
2767
+ break;
2768
+ }
2769
+ if (typeA == 6) {
2770
+ switch (flag) {
2771
+ case 0: nPts = 12; nColors = 4; break;
2772
+ case 1:
2773
+ case 2:
2774
+ case 3:
2775
+ default: nPts = 8; nColors = 2; break;
2776
+ }
2777
+ } else {
2778
+ switch (flag) {
2779
+ case 0: nPts = 16; nColors = 4; break;
2780
+ case 1:
2781
+ case 2:
2782
+ case 3:
2783
+ default: nPts = 12; nColors = 2; break;
2784
+ }
2785
+ }
2786
+ for (i = 0; i < nPts; ++i) {
2787
+ if (!bitBuf->getBits(coordBits, &xi) ||
2788
+ !bitBuf->getBits(coordBits, &yi)) {
2789
+ break;
2790
+ }
2791
+ x[i] = xMin + xMul * (double)xi;
2792
+ y[i] = yMin + yMul * (double)yi;
2793
+ }
2794
+ if (i < nPts) {
2795
+ break;
2796
+ }
2797
+ for (i = 0; i < nColors; ++i) {
2798
+ for (j = 0; j < nComps; ++j) {
2799
+ if (!bitBuf->getBits(compBits, &ci[j])) {
2800
+ break;
2801
+ }
2802
+ c[i][j] = dblToCol(cMin[j] + cMul[j] * (double)ci[j]);
2803
+ }
2804
+ if (j < nComps) {
2805
+ break;
2806
+ }
2807
+ }
2808
+ if (i < nColors) {
2809
+ break;
2810
+ }
2811
+ if (nPatchesA == patchesSize) {
2812
+ patchesSize = (patchesSize == 0) ? 16 : 2 * patchesSize;
2813
+ patchesA = (GfxPatch *)greallocn(patchesA,
2814
+ patchesSize, sizeof(GfxPatch));
2815
+ }
2816
+ p = &patchesA[nPatchesA];
2817
+ if (typeA == 6) {
2818
+ switch (flag) {
2819
+ case 0:
2820
+ p->x[0][0] = x[0];
2821
+ p->y[0][0] = y[0];
2822
+ p->x[0][1] = x[1];
2823
+ p->y[0][1] = y[1];
2824
+ p->x[0][2] = x[2];
2825
+ p->y[0][2] = y[2];
2826
+ p->x[0][3] = x[3];
2827
+ p->y[0][3] = y[3];
2828
+ p->x[1][3] = x[4];
2829
+ p->y[1][3] = y[4];
2830
+ p->x[2][3] = x[5];
2831
+ p->y[2][3] = y[5];
2832
+ p->x[3][3] = x[6];
2833
+ p->y[3][3] = y[6];
2834
+ p->x[3][2] = x[7];
2835
+ p->y[3][2] = y[7];
2836
+ p->x[3][1] = x[8];
2837
+ p->y[3][1] = y[8];
2838
+ p->x[3][0] = x[9];
2839
+ p->y[3][0] = y[9];
2840
+ p->x[2][0] = x[10];
2841
+ p->y[2][0] = y[10];
2842
+ p->x[1][0] = x[11];
2843
+ p->y[1][0] = y[11];
2844
+ for (j = 0; j < nComps; ++j) {
2845
+ p->color[0][0].c[j] = c[0][j];
2846
+ p->color[0][1].c[j] = c[1][j];
2847
+ p->color[1][1].c[j] = c[2][j];
2848
+ p->color[1][0].c[j] = c[3][j];
2849
+ }
2850
+ break;
2851
+ case 1:
2852
+ p->x[0][0] = patchesA[nPatchesA-1].x[0][3];
2853
+ p->y[0][0] = patchesA[nPatchesA-1].y[0][3];
2854
+ p->x[0][1] = patchesA[nPatchesA-1].x[1][3];
2855
+ p->y[0][1] = patchesA[nPatchesA-1].y[1][3];
2856
+ p->x[0][2] = patchesA[nPatchesA-1].x[2][3];
2857
+ p->y[0][2] = patchesA[nPatchesA-1].y[2][3];
2858
+ p->x[0][3] = patchesA[nPatchesA-1].x[3][3];
2859
+ p->y[0][3] = patchesA[nPatchesA-1].y[3][3];
2860
+ p->x[1][3] = x[0];
2861
+ p->y[1][3] = y[0];
2862
+ p->x[2][3] = x[1];
2863
+ p->y[2][3] = y[1];
2864
+ p->x[3][3] = x[2];
2865
+ p->y[3][3] = y[2];
2866
+ p->x[3][2] = x[3];
2867
+ p->y[3][2] = y[3];
2868
+ p->x[3][1] = x[4];
2869
+ p->y[3][1] = y[4];
2870
+ p->x[3][0] = x[5];
2871
+ p->y[3][0] = y[5];
2872
+ p->x[2][0] = x[6];
2873
+ p->y[2][0] = y[6];
2874
+ p->x[1][0] = x[7];
2875
+ p->y[1][0] = y[7];
2876
+ for (j = 0; j < nComps; ++j) {
2877
+ p->color[0][0].c[j] = patchesA[nPatchesA-1].color[0][1].c[j];
2878
+ p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][1].c[j];
2879
+ p->color[1][1].c[j] = c[0][j];
2880
+ p->color[1][0].c[j] = c[1][j];
2881
+ }
2882
+ break;
2883
+ case 2:
2884
+ p->x[0][0] = patchesA[nPatchesA-1].x[3][3];
2885
+ p->y[0][0] = patchesA[nPatchesA-1].y[3][3];
2886
+ p->x[0][1] = patchesA[nPatchesA-1].x[3][2];
2887
+ p->y[0][1] = patchesA[nPatchesA-1].y[3][2];
2888
+ p->x[0][2] = patchesA[nPatchesA-1].x[3][1];
2889
+ p->y[0][2] = patchesA[nPatchesA-1].y[3][1];
2890
+ p->x[0][3] = patchesA[nPatchesA-1].x[3][0];
2891
+ p->y[0][3] = patchesA[nPatchesA-1].y[3][0];
2892
+ p->x[1][3] = x[0];
2893
+ p->y[1][3] = y[0];
2894
+ p->x[2][3] = x[1];
2895
+ p->y[2][3] = y[1];
2896
+ p->x[3][3] = x[2];
2897
+ p->y[3][3] = y[2];
2898
+ p->x[3][2] = x[3];
2899
+ p->y[3][2] = y[3];
2900
+ p->x[3][1] = x[4];
2901
+ p->y[3][1] = y[4];
2902
+ p->x[3][0] = x[5];
2903
+ p->y[3][0] = y[5];
2904
+ p->x[2][0] = x[6];
2905
+ p->y[2][0] = y[6];
2906
+ p->x[1][0] = x[7];
2907
+ p->y[1][0] = y[7];
2908
+ for (j = 0; j < nComps; ++j) {
2909
+ p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][1].c[j];
2910
+ p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j];
2911
+ p->color[1][1].c[j] = c[0][j];
2912
+ p->color[1][0].c[j] = c[1][j];
2913
+ }
2914
+ break;
2915
+ case 3:
2916
+ p->x[0][0] = patchesA[nPatchesA-1].x[3][0];
2917
+ p->y[0][0] = patchesA[nPatchesA-1].y[3][0];
2918
+ p->x[0][1] = patchesA[nPatchesA-1].x[2][0];
2919
+ p->y[0][1] = patchesA[nPatchesA-1].y[2][0];
2920
+ p->x[0][2] = patchesA[nPatchesA-1].x[1][0];
2921
+ p->y[0][2] = patchesA[nPatchesA-1].y[1][0];
2922
+ p->x[0][3] = patchesA[nPatchesA-1].x[0][0];
2923
+ p->y[0][3] = patchesA[nPatchesA-1].y[0][0];
2924
+ p->x[1][3] = x[0];
2925
+ p->y[1][3] = y[0];
2926
+ p->x[2][3] = x[1];
2927
+ p->y[2][3] = y[1];
2928
+ p->x[3][3] = x[2];
2929
+ p->y[3][3] = y[2];
2930
+ p->x[3][2] = x[3];
2931
+ p->y[3][2] = y[3];
2932
+ p->x[3][1] = x[4];
2933
+ p->y[3][1] = y[4];
2934
+ p->x[3][0] = x[5];
2935
+ p->y[3][0] = y[5];
2936
+ p->x[2][0] = x[6];
2937
+ p->y[2][0] = y[6];
2938
+ p->x[1][0] = x[7];
2939
+ p->y[1][0] = y[7];
2940
+ for (j = 0; j < nComps; ++j) {
2941
+ p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j];
2942
+ p->color[0][1].c[j] = patchesA[nPatchesA-1].color[0][0].c[j];
2943
+ p->color[1][1].c[j] = c[0][j];
2944
+ p->color[1][0].c[j] = c[1][j];
2945
+ }
2946
+ break;
2947
+ }
2948
+ } else {
2949
+ switch (flag) {
2950
+ case 0:
2951
+ p->x[0][0] = x[0];
2952
+ p->y[0][0] = y[0];
2953
+ p->x[0][1] = x[1];
2954
+ p->y[0][1] = y[1];
2955
+ p->x[0][2] = x[2];
2956
+ p->y[0][2] = y[2];
2957
+ p->x[0][3] = x[3];
2958
+ p->y[0][3] = y[3];
2959
+ p->x[1][3] = x[4];
2960
+ p->y[1][3] = y[4];
2961
+ p->x[2][3] = x[5];
2962
+ p->y[2][3] = y[5];
2963
+ p->x[3][3] = x[6];
2964
+ p->y[3][3] = y[6];
2965
+ p->x[3][2] = x[7];
2966
+ p->y[3][2] = y[7];
2967
+ p->x[3][1] = x[8];
2968
+ p->y[3][1] = y[8];
2969
+ p->x[3][0] = x[9];
2970
+ p->y[3][0] = y[9];
2971
+ p->x[2][0] = x[10];
2972
+ p->y[2][0] = y[10];
2973
+ p->x[1][0] = x[11];
2974
+ p->y[1][0] = y[11];
2975
+ p->x[1][1] = x[12];
2976
+ p->y[1][1] = y[12];
2977
+ p->x[1][2] = x[13];
2978
+ p->y[1][2] = y[13];
2979
+ p->x[2][2] = x[14];
2980
+ p->y[2][2] = y[14];
2981
+ p->x[2][1] = x[15];
2982
+ p->y[2][1] = y[15];
2983
+ for (j = 0; j < nComps; ++j) {
2984
+ p->color[0][0].c[j] = c[0][j];
2985
+ p->color[0][1].c[j] = c[1][j];
2986
+ p->color[1][1].c[j] = c[2][j];
2987
+ p->color[1][0].c[j] = c[3][j];
2988
+ }
2989
+ break;
2990
+ case 1:
2991
+ p->x[0][0] = patchesA[nPatchesA-1].x[0][3];
2992
+ p->y[0][0] = patchesA[nPatchesA-1].y[0][3];
2993
+ p->x[0][1] = patchesA[nPatchesA-1].x[1][3];
2994
+ p->y[0][1] = patchesA[nPatchesA-1].y[1][3];
2995
+ p->x[0][2] = patchesA[nPatchesA-1].x[2][3];
2996
+ p->y[0][2] = patchesA[nPatchesA-1].y[2][3];
2997
+ p->x[0][3] = patchesA[nPatchesA-1].x[3][3];
2998
+ p->y[0][3] = patchesA[nPatchesA-1].y[3][3];
2999
+ p->x[1][3] = x[0];
3000
+ p->y[1][3] = y[0];
3001
+ p->x[2][3] = x[1];
3002
+ p->y[2][3] = y[1];
3003
+ p->x[3][3] = x[2];
3004
+ p->y[3][3] = y[2];
3005
+ p->x[3][2] = x[3];
3006
+ p->y[3][2] = y[3];
3007
+ p->x[3][1] = x[4];
3008
+ p->y[3][1] = y[4];
3009
+ p->x[3][0] = x[5];
3010
+ p->y[3][0] = y[5];
3011
+ p->x[2][0] = x[6];
3012
+ p->y[2][0] = y[6];
3013
+ p->x[1][0] = x[7];
3014
+ p->y[1][0] = y[7];
3015
+ p->x[1][1] = x[8];
3016
+ p->y[1][1] = y[8];
3017
+ p->x[1][2] = x[9];
3018
+ p->y[1][2] = y[9];
3019
+ p->x[2][2] = x[10];
3020
+ p->y[2][2] = y[10];
3021
+ p->x[2][1] = x[11];
3022
+ p->y[2][1] = y[11];
3023
+ for (j = 0; j < nComps; ++j) {
3024
+ p->color[0][0].c[j] = patchesA[nPatchesA-1].color[0][1].c[j];
3025
+ p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][1].c[j];
3026
+ p->color[1][1].c[j] = c[0][j];
3027
+ p->color[1][0].c[j] = c[1][j];
3028
+ }
3029
+ break;
3030
+ case 2:
3031
+ p->x[0][0] = patchesA[nPatchesA-1].x[3][3];
3032
+ p->y[0][0] = patchesA[nPatchesA-1].y[3][3];
3033
+ p->x[0][1] = patchesA[nPatchesA-1].x[3][2];
3034
+ p->y[0][1] = patchesA[nPatchesA-1].y[3][2];
3035
+ p->x[0][2] = patchesA[nPatchesA-1].x[3][1];
3036
+ p->y[0][2] = patchesA[nPatchesA-1].y[3][1];
3037
+ p->x[0][3] = patchesA[nPatchesA-1].x[3][0];
3038
+ p->y[0][3] = patchesA[nPatchesA-1].y[3][0];
3039
+ p->x[1][3] = x[0];
3040
+ p->y[1][3] = y[0];
3041
+ p->x[2][3] = x[1];
3042
+ p->y[2][3] = y[1];
3043
+ p->x[3][3] = x[2];
3044
+ p->y[3][3] = y[2];
3045
+ p->x[3][2] = x[3];
3046
+ p->y[3][2] = y[3];
3047
+ p->x[3][1] = x[4];
3048
+ p->y[3][1] = y[4];
3049
+ p->x[3][0] = x[5];
3050
+ p->y[3][0] = y[5];
3051
+ p->x[2][0] = x[6];
3052
+ p->y[2][0] = y[6];
3053
+ p->x[1][0] = x[7];
3054
+ p->y[1][0] = y[7];
3055
+ p->x[1][1] = x[8];
3056
+ p->y[1][1] = y[8];
3057
+ p->x[1][2] = x[9];
3058
+ p->y[1][2] = y[9];
3059
+ p->x[2][2] = x[10];
3060
+ p->y[2][2] = y[10];
3061
+ p->x[2][1] = x[11];
3062
+ p->y[2][1] = y[11];
3063
+ for (j = 0; j < nComps; ++j) {
3064
+ p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][1].c[j];
3065
+ p->color[0][1].c[j] = patchesA[nPatchesA-1].color[1][0].c[j];
3066
+ p->color[1][1].c[j] = c[0][j];
3067
+ p->color[1][0].c[j] = c[1][j];
3068
+ }
3069
+ break;
3070
+ case 3:
3071
+ p->x[0][0] = patchesA[nPatchesA-1].x[3][0];
3072
+ p->y[0][0] = patchesA[nPatchesA-1].y[3][0];
3073
+ p->x[0][1] = patchesA[nPatchesA-1].x[2][0];
3074
+ p->y[0][1] = patchesA[nPatchesA-1].y[2][0];
3075
+ p->x[0][2] = patchesA[nPatchesA-1].x[1][0];
3076
+ p->y[0][2] = patchesA[nPatchesA-1].y[1][0];
3077
+ p->x[0][3] = patchesA[nPatchesA-1].x[0][0];
3078
+ p->y[0][3] = patchesA[nPatchesA-1].y[0][0];
3079
+ p->x[1][3] = x[0];
3080
+ p->y[1][3] = y[0];
3081
+ p->x[2][3] = x[1];
3082
+ p->y[2][3] = y[1];
3083
+ p->x[3][3] = x[2];
3084
+ p->y[3][3] = y[2];
3085
+ p->x[3][2] = x[3];
3086
+ p->y[3][2] = y[3];
3087
+ p->x[3][1] = x[4];
3088
+ p->y[3][1] = y[4];
3089
+ p->x[3][0] = x[5];
3090
+ p->y[3][0] = y[5];
3091
+ p->x[2][0] = x[6];
3092
+ p->y[2][0] = y[6];
3093
+ p->x[1][0] = x[7];
3094
+ p->y[1][0] = y[7];
3095
+ p->x[1][1] = x[8];
3096
+ p->y[1][1] = y[8];
3097
+ p->x[1][2] = x[9];
3098
+ p->y[1][2] = y[9];
3099
+ p->x[2][2] = x[10];
3100
+ p->y[2][2] = y[10];
3101
+ p->x[2][1] = x[11];
3102
+ p->y[2][1] = y[11];
3103
+ for (j = 0; j < nComps; ++j) {
3104
+ p->color[0][0].c[j] = patchesA[nPatchesA-1].color[1][0].c[j];
3105
+ p->color[0][1].c[j] = patchesA[nPatchesA-1].color[0][0].c[j];
3106
+ p->color[1][1].c[j] = c[0][j];
3107
+ p->color[1][0].c[j] = c[1][j];
3108
+ }
3109
+ break;
3110
+ }
3111
+ }
3112
+ ++nPatchesA;
3113
+ bitBuf->flushBits();
3114
+ }
3115
+ delete bitBuf;
3116
+
3117
+ if (typeA == 6) {
3118
+ for (i = 0; i < nPatchesA; ++i) {
3119
+ p = &patchesA[i];
3120
+ p->x[1][1] = (-4 * p->x[0][0]
3121
+ +6 * (p->x[0][1] + p->x[1][0])
3122
+ -2 * (p->x[0][3] + p->x[3][0])
3123
+ +3 * (p->x[3][1] + p->x[1][3])
3124
+ - p->x[3][3]) / 9;
3125
+ p->y[1][1] = (-4 * p->y[0][0]
3126
+ +6 * (p->y[0][1] + p->y[1][0])
3127
+ -2 * (p->y[0][3] + p->y[3][0])
3128
+ +3 * (p->y[3][1] + p->y[1][3])
3129
+ - p->y[3][3]) / 9;
3130
+ p->x[1][2] = (-4 * p->x[0][3]
3131
+ +6 * (p->x[0][2] + p->x[1][3])
3132
+ -2 * (p->x[0][0] + p->x[3][3])
3133
+ +3 * (p->x[3][2] + p->x[1][0])
3134
+ - p->x[3][0]) / 9;
3135
+ p->y[1][2] = (-4 * p->y[0][3]
3136
+ +6 * (p->y[0][2] + p->y[1][3])
3137
+ -2 * (p->y[0][0] + p->y[3][3])
3138
+ +3 * (p->y[3][2] + p->y[1][0])
3139
+ - p->y[3][0]) / 9;
3140
+ p->x[2][1] = (-4 * p->x[3][0]
3141
+ +6 * (p->x[3][1] + p->x[2][0])
3142
+ -2 * (p->x[3][3] + p->x[0][0])
3143
+ +3 * (p->x[0][1] + p->x[2][3])
3144
+ - p->x[0][3]) / 9;
3145
+ p->y[2][1] = (-4 * p->y[3][0]
3146
+ +6 * (p->y[3][1] + p->y[2][0])
3147
+ -2 * (p->y[3][3] + p->y[0][0])
3148
+ +3 * (p->y[0][1] + p->y[2][3])
3149
+ - p->y[0][3]) / 9;
3150
+ p->x[2][2] = (-4 * p->x[3][3]
3151
+ +6 * (p->x[3][2] + p->x[2][3])
3152
+ -2 * (p->x[3][0] + p->x[0][3])
3153
+ +3 * (p->x[0][2] + p->x[2][0])
3154
+ - p->x[0][0]) / 9;
3155
+ p->y[2][2] = (-4 * p->y[3][3]
3156
+ +6 * (p->y[3][2] + p->y[2][3])
3157
+ -2 * (p->y[3][0] + p->y[0][3])
3158
+ +3 * (p->y[0][2] + p->y[2][0])
3159
+ - p->y[0][0]) / 9;
3160
+ }
3161
+ }
3162
+
3163
+ shading = new GfxPatchMeshShading(typeA, patchesA, nPatchesA,
3164
+ funcsA, nFuncsA);
3165
+ if (!shading->init(dict)) {
3166
+ delete shading;
3167
+ return NULL;
3168
+ }
3169
+ return shading;
3170
+
3171
+ err2:
3172
+ obj1.free();
3173
+ err1:
3174
+ return NULL;
3175
+ }
3176
+
3177
+ GfxShading *GfxPatchMeshShading::copy() {
3178
+ return new GfxPatchMeshShading(this);
3179
+ }
3180
+
3181
+ //------------------------------------------------------------------------
3182
+ // GfxImageColorMap
3183
+ //------------------------------------------------------------------------
3184
+
3185
+ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode,
3186
+ GfxColorSpace *colorSpaceA) {
3187
+ GfxIndexedColorSpace *indexedCS;
3188
+ GfxSeparationColorSpace *sepCS;
3189
+ int maxPixel, indexHigh;
3190
+ Guchar *lookup2;
3191
+ Function *sepFunc;
3192
+ Object obj;
3193
+ double x[gfxColorMaxComps];
3194
+ double y[gfxColorMaxComps];
3195
+ int i, j, k;
3196
+
3197
+ ok = gTrue;
3198
+
3199
+ // bits per component and color space
3200
+ bits = bitsA;
3201
+ maxPixel = (1 << bits) - 1;
3202
+ colorSpace = colorSpaceA;
3203
+
3204
+ // initialize
3205
+ for (k = 0; k < gfxColorMaxComps; ++k) {
3206
+ lookup[k] = NULL;
3207
+ }
3208
+
3209
+ // get decode map
3210
+ if (decode->isNull()) {
3211
+ nComps = colorSpace->getNComps();
3212
+ colorSpace->getDefaultRanges(decodeLow, decodeRange, maxPixel);
3213
+ } else if (decode->isArray()) {
3214
+ nComps = decode->arrayGetLength() / 2;
3215
+ if (nComps != colorSpace->getNComps()) {
3216
+ goto err1;
3217
+ }
3218
+ for (i = 0; i < nComps; ++i) {
3219
+ decode->arrayGet(2*i, &obj);
3220
+ if (!obj.isNum()) {
3221
+ goto err2;
3222
+ }
3223
+ decodeLow[i] = obj.getNum();
3224
+ obj.free();
3225
+ decode->arrayGet(2*i+1, &obj);
3226
+ if (!obj.isNum()) {
3227
+ goto err2;
3228
+ }
3229
+ decodeRange[i] = obj.getNum() - decodeLow[i];
3230
+ obj.free();
3231
+ }
3232
+ } else {
3233
+ goto err1;
3234
+ }
3235
+
3236
+ // Construct a lookup table -- this stores pre-computed decoded
3237
+ // values for each component, i.e., the result of applying the
3238
+ // decode mapping to each possible image pixel component value.
3239
+ //
3240
+ // Optimization: for Indexed and Separation color spaces (which have
3241
+ // only one component), we store color values in the lookup table
3242
+ // rather than component values.
3243
+ colorSpace2 = NULL;
3244
+ nComps2 = 0;
3245
+ if (colorSpace->getMode() == csIndexed) {
3246
+ // Note that indexHigh may not be the same as maxPixel --
3247
+ // Distiller will remove unused palette entries, resulting in
3248
+ // indexHigh < maxPixel.
3249
+ indexedCS = (GfxIndexedColorSpace *)colorSpace;
3250
+ colorSpace2 = indexedCS->getBase();
3251
+ indexHigh = indexedCS->getIndexHigh();
3252
+ nComps2 = colorSpace2->getNComps();
3253
+ lookup2 = indexedCS->getLookup();
3254
+ colorSpace2->getDefaultRanges(x, y, indexHigh);
3255
+ for (k = 0; k < nComps2; ++k) {
3256
+ lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
3257
+ sizeof(GfxColorComp));
3258
+ for (i = 0; i <= maxPixel; ++i) {
3259
+ j = (int)(decodeLow[0] + (i * decodeRange[0]) / maxPixel + 0.5);
3260
+ if (j < 0) {
3261
+ j = 0;
3262
+ } else if (j > indexHigh) {
3263
+ j = indexHigh;
3264
+ }
3265
+ lookup[k][i] =
3266
+ dblToCol(x[k] + (lookup2[j*nComps2 + k] / 255.0) * y[k]);
3267
+ }
3268
+ }
3269
+ } else if (colorSpace->getMode() == csSeparation) {
3270
+ sepCS = (GfxSeparationColorSpace *)colorSpace;
3271
+ colorSpace2 = sepCS->getAlt();
3272
+ nComps2 = colorSpace2->getNComps();
3273
+ sepFunc = sepCS->getFunc();
3274
+ for (k = 0; k < nComps2; ++k) {
3275
+ lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
3276
+ sizeof(GfxColorComp));
3277
+ for (i = 0; i <= maxPixel; ++i) {
3278
+ x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel;
3279
+ sepFunc->transform(x, y);
3280
+ lookup[k][i] = dblToCol(y[k]);
3281
+ }
3282
+ }
3283
+ } else {
3284
+ for (k = 0; k < nComps; ++k) {
3285
+ lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
3286
+ sizeof(GfxColorComp));
3287
+ for (i = 0; i <= maxPixel; ++i) {
3288
+ lookup[k][i] = dblToCol(decodeLow[k] +
3289
+ (i * decodeRange[k]) / maxPixel);
3290
+ }
3291
+ }
3292
+ }
3293
+
3294
+ return;
3295
+
3296
+ err2:
3297
+ obj.free();
3298
+ err1:
3299
+ ok = gFalse;
3300
+ }
3301
+
3302
+ GfxImageColorMap::GfxImageColorMap(GfxImageColorMap *colorMap) {
3303
+ int n, i, k;
3304
+
3305
+ colorSpace = colorMap->colorSpace->copy();
3306
+ bits = colorMap->bits;
3307
+ nComps = colorMap->nComps;
3308
+ nComps2 = colorMap->nComps2;
3309
+ colorSpace2 = NULL;
3310
+ for (k = 0; k < gfxColorMaxComps; ++k) {
3311
+ lookup[k] = NULL;
3312
+ }
3313
+ n = 1 << bits;
3314
+ if (colorSpace->getMode() == csIndexed) {
3315
+ colorSpace2 = ((GfxIndexedColorSpace *)colorSpace)->getBase();
3316
+ for (k = 0; k < nComps2; ++k) {
3317
+ lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
3318
+ memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp));
3319
+ }
3320
+ } else if (colorSpace->getMode() == csSeparation) {
3321
+ colorSpace2 = ((GfxSeparationColorSpace *)colorSpace)->getAlt();
3322
+ for (k = 0; k < nComps2; ++k) {
3323
+ lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
3324
+ memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp));
3325
+ }
3326
+ } else {
3327
+ for (k = 0; k < nComps; ++k) {
3328
+ lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
3329
+ memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp));
3330
+ }
3331
+ }
3332
+ for (i = 0; i < nComps; ++i) {
3333
+ decodeLow[i] = colorMap->decodeLow[i];
3334
+ decodeRange[i] = colorMap->decodeRange[i];
3335
+ }
3336
+ ok = gTrue;
3337
+ }
3338
+
3339
+ GfxImageColorMap::~GfxImageColorMap() {
3340
+ int i;
3341
+
3342
+ delete colorSpace;
3343
+ for (i = 0; i < gfxColorMaxComps; ++i) {
3344
+ gfree(lookup[i]);
3345
+ }
3346
+ }
3347
+
3348
+ void GfxImageColorMap::getGray(Guchar *x, GfxGray *gray) {
3349
+ GfxColor color;
3350
+ int i;
3351
+
3352
+ if (colorSpace2) {
3353
+ for (i = 0; i < nComps2; ++i) {
3354
+ color.c[i] = lookup[i][x[0]];
3355
+ }
3356
+ colorSpace2->getGray(&color, gray);
3357
+ } else {
3358
+ for (i = 0; i < nComps; ++i) {
3359
+ color.c[i] = lookup[i][x[i]];
3360
+ }
3361
+ colorSpace->getGray(&color, gray);
3362
+ }
3363
+ }
3364
+
3365
+ void GfxImageColorMap::getRGB(Guchar *x, GfxRGB *rgb) {
3366
+ GfxColor color;
3367
+ int i;
3368
+
3369
+ if (colorSpace2) {
3370
+ for (i = 0; i < nComps2; ++i) {
3371
+ color.c[i] = lookup[i][x[0]];
3372
+ }
3373
+ colorSpace2->getRGB(&color, rgb);
3374
+ } else {
3375
+ for (i = 0; i < nComps; ++i) {
3376
+ color.c[i] = lookup[i][x[i]];
3377
+ }
3378
+ colorSpace->getRGB(&color, rgb);
3379
+ }
3380
+ }
3381
+
3382
+ void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) {
3383
+ GfxColor color;
3384
+ int i;
3385
+
3386
+ if (colorSpace2) {
3387
+ for (i = 0; i < nComps2; ++i) {
3388
+ color.c[i] = lookup[i][x[0]];
3389
+ }
3390
+ colorSpace2->getCMYK(&color, cmyk);
3391
+ } else {
3392
+ for (i = 0; i < nComps; ++i) {
3393
+ color.c[i] = lookup[i][x[i]];
3394
+ }
3395
+ colorSpace->getCMYK(&color, cmyk);
3396
+ }
3397
+ }
3398
+
3399
+ void GfxImageColorMap::getColor(Guchar *x, GfxColor *color) {
3400
+ int maxPixel, i;
3401
+
3402
+ maxPixel = (1 << bits) - 1;
3403
+ for (i = 0; i < nComps; ++i) {
3404
+ color->c[i] = dblToCol(decodeLow[i] + (x[i] * decodeRange[i]) / maxPixel);
3405
+ }
3406
+ }
3407
+
3408
+ //------------------------------------------------------------------------
3409
+ // GfxSubpath and GfxPath
3410
+ //------------------------------------------------------------------------
3411
+
3412
+ GfxSubpath::GfxSubpath(double x1, double y1) {
3413
+ size = 16;
3414
+ x = (double *)gmallocn(size, sizeof(double));
3415
+ y = (double *)gmallocn(size, sizeof(double));
3416
+ curve = (GBool *)gmallocn(size, sizeof(GBool));
3417
+ n = 1;
3418
+ x[0] = x1;
3419
+ y[0] = y1;
3420
+ curve[0] = gFalse;
3421
+ closed = gFalse;
3422
+ }
3423
+
3424
+ GfxSubpath::~GfxSubpath() {
3425
+ gfree(x);
3426
+ gfree(y);
3427
+ gfree(curve);
3428
+ }
3429
+
3430
+ // Used for copy().
3431
+ GfxSubpath::GfxSubpath(GfxSubpath *subpath) {
3432
+ size = subpath->size;
3433
+ n = subpath->n;
3434
+ x = (double *)gmallocn(size, sizeof(double));
3435
+ y = (double *)gmallocn(size, sizeof(double));
3436
+ curve = (GBool *)gmallocn(size, sizeof(GBool));
3437
+ memcpy(x, subpath->x, n * sizeof(double));
3438
+ memcpy(y, subpath->y, n * sizeof(double));
3439
+ memcpy(curve, subpath->curve, n * sizeof(GBool));
3440
+ closed = subpath->closed;
3441
+ }
3442
+
3443
+ void GfxSubpath::lineTo(double x1, double y1) {
3444
+ if (n >= size) {
3445
+ size += 16;
3446
+ x = (double *)greallocn(x, size, sizeof(double));
3447
+ y = (double *)greallocn(y, size, sizeof(double));
3448
+ curve = (GBool *)greallocn(curve, size, sizeof(GBool));
3449
+ }
3450
+ x[n] = x1;
3451
+ y[n] = y1;
3452
+ curve[n] = gFalse;
3453
+ ++n;
3454
+ }
3455
+
3456
+ void GfxSubpath::curveTo(double x1, double y1, double x2, double y2,
3457
+ double x3, double y3) {
3458
+ if (n+3 > size) {
3459
+ size += 16;
3460
+ x = (double *)greallocn(x, size, sizeof(double));
3461
+ y = (double *)greallocn(y, size, sizeof(double));
3462
+ curve = (GBool *)greallocn(curve, size, sizeof(GBool));
3463
+ }
3464
+ x[n] = x1;
3465
+ y[n] = y1;
3466
+ x[n+1] = x2;
3467
+ y[n+1] = y2;
3468
+ x[n+2] = x3;
3469
+ y[n+2] = y3;
3470
+ curve[n] = curve[n+1] = gTrue;
3471
+ curve[n+2] = gFalse;
3472
+ n += 3;
3473
+ }
3474
+
3475
+ void GfxSubpath::close() {
3476
+ if (x[n-1] != x[0] || y[n-1] != y[0]) {
3477
+ lineTo(x[0], y[0]);
3478
+ }
3479
+ closed = gTrue;
3480
+ }
3481
+
3482
+ void GfxSubpath::offset(double dx, double dy) {
3483
+ int i;
3484
+
3485
+ for (i = 0; i < n; ++i) {
3486
+ x[i] += dx;
3487
+ y[i] += dy;
3488
+ }
3489
+ }
3490
+
3491
+ GfxPath::GfxPath() {
3492
+ justMoved = gFalse;
3493
+ size = 16;
3494
+ n = 0;
3495
+ firstX = firstY = 0;
3496
+ subpaths = (GfxSubpath **)gmallocn(size, sizeof(GfxSubpath *));
3497
+ }
3498
+
3499
+ GfxPath::~GfxPath() {
3500
+ int i;
3501
+
3502
+ for (i = 0; i < n; ++i)
3503
+ delete subpaths[i];
3504
+ gfree(subpaths);
3505
+ }
3506
+
3507
+ // Used for copy().
3508
+ GfxPath::GfxPath(GBool justMoved1, double firstX1, double firstY1,
3509
+ GfxSubpath **subpaths1, int n1, int size1) {
3510
+ int i;
3511
+
3512
+ justMoved = justMoved1;
3513
+ firstX = firstX1;
3514
+ firstY = firstY1;
3515
+ size = size1;
3516
+ n = n1;
3517
+ subpaths = (GfxSubpath **)gmallocn(size, sizeof(GfxSubpath *));
3518
+ for (i = 0; i < n; ++i)
3519
+ subpaths[i] = subpaths1[i]->copy();
3520
+ }
3521
+
3522
+ void GfxPath::moveTo(double x, double y) {
3523
+ justMoved = gTrue;
3524
+ firstX = x;
3525
+ firstY = y;
3526
+ }
3527
+
3528
+ void GfxPath::lineTo(double x, double y) {
3529
+ if (justMoved) {
3530
+ if (n >= size) {
3531
+ size += 16;
3532
+ subpaths = (GfxSubpath **)
3533
+ greallocn(subpaths, size, sizeof(GfxSubpath *));
3534
+ }
3535
+ subpaths[n] = new GfxSubpath(firstX, firstY);
3536
+ ++n;
3537
+ justMoved = gFalse;
3538
+ }
3539
+ subpaths[n-1]->lineTo(x, y);
3540
+ }
3541
+
3542
+ void GfxPath::curveTo(double x1, double y1, double x2, double y2,
3543
+ double x3, double y3) {
3544
+ if (justMoved) {
3545
+ if (n >= size) {
3546
+ size += 16;
3547
+ subpaths = (GfxSubpath **)
3548
+ greallocn(subpaths, size, sizeof(GfxSubpath *));
3549
+ }
3550
+ subpaths[n] = new GfxSubpath(firstX, firstY);
3551
+ ++n;
3552
+ justMoved = gFalse;
3553
+ }
3554
+ subpaths[n-1]->curveTo(x1, y1, x2, y2, x3, y3);
3555
+ }
3556
+
3557
+ void GfxPath::close() {
3558
+ // this is necessary to handle the pathological case of
3559
+ // moveto/closepath/clip, which defines an empty clipping region
3560
+ if (justMoved) {
3561
+ if (n >= size) {
3562
+ size += 16;
3563
+ subpaths = (GfxSubpath **)
3564
+ greallocn(subpaths, size, sizeof(GfxSubpath *));
3565
+ }
3566
+ subpaths[n] = new GfxSubpath(firstX, firstY);
3567
+ ++n;
3568
+ justMoved = gFalse;
3569
+ }
3570
+ subpaths[n-1]->close();
3571
+ }
3572
+
3573
+ void GfxPath::append(GfxPath *path) {
3574
+ int i;
3575
+
3576
+ if (n + path->n > size) {
3577
+ size = n + path->n;
3578
+ subpaths = (GfxSubpath **)
3579
+ greallocn(subpaths, size, sizeof(GfxSubpath *));
3580
+ }
3581
+ for (i = 0; i < path->n; ++i) {
3582
+ subpaths[n++] = path->subpaths[i]->copy();
3583
+ }
3584
+ justMoved = gFalse;
3585
+ }
3586
+
3587
+ void GfxPath::offset(double dx, double dy) {
3588
+ int i;
3589
+
3590
+ for (i = 0; i < n; ++i) {
3591
+ subpaths[i]->offset(dx, dy);
3592
+ }
3593
+ }
3594
+
3595
+ //------------------------------------------------------------------------
3596
+ // GfxState
3597
+ //------------------------------------------------------------------------
3598
+
3599
+ GfxState::GfxState(double hDPIA, double vDPIA, PDFRectangle *pageBox,
3600
+ int rotateA, GBool upsideDown) {
3601
+ double kx, ky;
3602
+
3603
+ hDPI = hDPIA;
3604
+ vDPI = vDPIA;
3605
+ rotate = rotateA;
3606
+ px1 = pageBox->x1;
3607
+ py1 = pageBox->y1;
3608
+ px2 = pageBox->x2;
3609
+ py2 = pageBox->y2;
3610
+ kx = hDPI / 72.0;
3611
+ ky = vDPI / 72.0;
3612
+ if (rotate == 90) {
3613
+ ctm[0] = 0;
3614
+ ctm[1] = upsideDown ? ky : -ky;
3615
+ ctm[2] = kx;
3616
+ ctm[3] = 0;
3617
+ ctm[4] = -kx * py1;
3618
+ ctm[5] = ky * (upsideDown ? -px1 : px2);
3619
+ pageWidth = kx * (py2 - py1);
3620
+ pageHeight = ky * (px2 - px1);
3621
+ } else if (rotate == 180) {
3622
+ ctm[0] = -kx;
3623
+ ctm[1] = 0;
3624
+ ctm[2] = 0;
3625
+ ctm[3] = upsideDown ? ky : -ky;
3626
+ ctm[4] = kx * px2;
3627
+ ctm[5] = ky * (upsideDown ? -py1 : py2);
3628
+ pageWidth = kx * (px2 - px1);
3629
+ pageHeight = ky * (py2 - py1);
3630
+ } else if (rotate == 270) {
3631
+ ctm[0] = 0;
3632
+ ctm[1] = upsideDown ? -ky : ky;
3633
+ ctm[2] = -kx;
3634
+ ctm[3] = 0;
3635
+ ctm[4] = kx * py2;
3636
+ ctm[5] = ky * (upsideDown ? px2 : -px1);
3637
+ pageWidth = kx * (py2 - py1);
3638
+ pageHeight = ky * (px2 - px1);
3639
+ } else {
3640
+ ctm[0] = kx;
3641
+ ctm[1] = 0;
3642
+ ctm[2] = 0;
3643
+ ctm[3] = upsideDown ? -ky : ky;
3644
+ ctm[4] = -kx * px1;
3645
+ ctm[5] = ky * (upsideDown ? py2 : -py1);
3646
+ pageWidth = kx * (px2 - px1);
3647
+ pageHeight = ky * (py2 - py1);
3648
+ }
3649
+
3650
+ fillColorSpace = new GfxDeviceGrayColorSpace();
3651
+ strokeColorSpace = new GfxDeviceGrayColorSpace();
3652
+ fillColor.c[0] = 0;
3653
+ strokeColor.c[0] = 0;
3654
+ fillPattern = NULL;
3655
+ strokePattern = NULL;
3656
+ blendMode = gfxBlendNormal;
3657
+ fillOpacity = 1;
3658
+ strokeOpacity = 1;
3659
+ fillOverprint = gFalse;
3660
+ strokeOverprint = gFalse;
3661
+ transfer[0] = transfer[1] = transfer[2] = transfer[3] = NULL;
3662
+
3663
+ lineWidth = 1;
3664
+ lineDash = NULL;
3665
+ lineDashLength = 0;
3666
+ lineDashStart = 0;
3667
+ flatness = 1;
3668
+ lineJoin = 0;
3669
+ lineCap = 0;
3670
+ miterLimit = 10;
3671
+ strokeAdjust = gFalse;
3672
+
3673
+ font = NULL;
3674
+ fontSize = 0;
3675
+ textMat[0] = 1; textMat[1] = 0;
3676
+ textMat[2] = 0; textMat[3] = 1;
3677
+ textMat[4] = 0; textMat[5] = 0;
3678
+ charSpace = 0;
3679
+ wordSpace = 0;
3680
+ horizScaling = 1;
3681
+ leading = 0;
3682
+ rise = 0;
3683
+ render = 0;
3684
+
3685
+ path = new GfxPath();
3686
+ curX = curY = 0;
3687
+ lineX = lineY = 0;
3688
+
3689
+ clipXMin = 0;
3690
+ clipYMin = 0;
3691
+ clipXMax = pageWidth;
3692
+ clipYMax = pageHeight;
3693
+
3694
+ saved = NULL;
3695
+ }
3696
+
3697
+ GfxState::~GfxState() {
3698
+ int i;
3699
+
3700
+ if (fillColorSpace) {
3701
+ delete fillColorSpace;
3702
+ }
3703
+ if (strokeColorSpace) {
3704
+ delete strokeColorSpace;
3705
+ }
3706
+ if (fillPattern) {
3707
+ delete fillPattern;
3708
+ }
3709
+ if (strokePattern) {
3710
+ delete strokePattern;
3711
+ }
3712
+ for (i = 0; i < 4; ++i) {
3713
+ if (transfer[i]) {
3714
+ delete transfer[i];
3715
+ }
3716
+ }
3717
+ gfree(lineDash);
3718
+ if (path) {
3719
+ // this gets set to NULL by restore()
3720
+ delete path;
3721
+ }
3722
+ if (saved) {
3723
+ delete saved;
3724
+ }
3725
+ }
3726
+
3727
+ // Used for copy();
3728
+ GfxState::GfxState(GfxState *state) {
3729
+ int i;
3730
+
3731
+ memcpy(this, state, sizeof(GfxState));
3732
+ if (fillColorSpace) {
3733
+ fillColorSpace = state->fillColorSpace->copy();
3734
+ }
3735
+ if (strokeColorSpace) {
3736
+ strokeColorSpace = state->strokeColorSpace->copy();
3737
+ }
3738
+ if (fillPattern) {
3739
+ fillPattern = state->fillPattern->copy();
3740
+ }
3741
+ if (strokePattern) {
3742
+ strokePattern = state->strokePattern->copy();
3743
+ }
3744
+ for (i = 0; i < 4; ++i) {
3745
+ if (transfer[i]) {
3746
+ transfer[i] = state->transfer[i]->copy();
3747
+ }
3748
+ }
3749
+ if (lineDashLength > 0) {
3750
+ lineDash = (double *)gmallocn(lineDashLength, sizeof(double));
3751
+ memcpy(lineDash, state->lineDash, lineDashLength * sizeof(double));
3752
+ }
3753
+ saved = NULL;
3754
+ }
3755
+
3756
+ void GfxState::setPath(GfxPath *pathA) {
3757
+ delete path;
3758
+ path = pathA;
3759
+ }
3760
+
3761
+ void GfxState::getUserClipBBox(double *xMin, double *yMin,
3762
+ double *xMax, double *yMax) {
3763
+ double ictm[6];
3764
+ double xMin1, yMin1, xMax1, yMax1, det, tx, ty;
3765
+
3766
+ // invert the CTM
3767
+ det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
3768
+ ictm[0] = ctm[3] * det;
3769
+ ictm[1] = -ctm[1] * det;
3770
+ ictm[2] = -ctm[2] * det;
3771
+ ictm[3] = ctm[0] * det;
3772
+ ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
3773
+ ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
3774
+
3775
+ // transform all four corners of the clip bbox; find the min and max
3776
+ // x and y values
3777
+ xMin1 = xMax1 = clipXMin * ictm[0] + clipYMin * ictm[2] + ictm[4];
3778
+ yMin1 = yMax1 = clipXMin * ictm[1] + clipYMin * ictm[3] + ictm[5];
3779
+ tx = clipXMin * ictm[0] + clipYMax * ictm[2] + ictm[4];
3780
+ ty = clipXMin * ictm[1] + clipYMax * ictm[3] + ictm[5];
3781
+ if (tx < xMin1) {
3782
+ xMin1 = tx;
3783
+ } else if (tx > xMax1) {
3784
+ xMax1 = tx;
3785
+ }
3786
+ if (ty < yMin1) {
3787
+ yMin1 = ty;
3788
+ } else if (ty > yMax1) {
3789
+ yMax1 = ty;
3790
+ }
3791
+ tx = clipXMax * ictm[0] + clipYMin * ictm[2] + ictm[4];
3792
+ ty = clipXMax * ictm[1] + clipYMin * ictm[3] + ictm[5];
3793
+ if (tx < xMin1) {
3794
+ xMin1 = tx;
3795
+ } else if (tx > xMax1) {
3796
+ xMax1 = tx;
3797
+ }
3798
+ if (ty < yMin1) {
3799
+ yMin1 = ty;
3800
+ } else if (ty > yMax1) {
3801
+ yMax1 = ty;
3802
+ }
3803
+ tx = clipXMax * ictm[0] + clipYMax * ictm[2] + ictm[4];
3804
+ ty = clipXMax * ictm[1] + clipYMax * ictm[3] + ictm[5];
3805
+ if (tx < xMin1) {
3806
+ xMin1 = tx;
3807
+ } else if (tx > xMax1) {
3808
+ xMax1 = tx;
3809
+ }
3810
+ if (ty < yMin1) {
3811
+ yMin1 = ty;
3812
+ } else if (ty > yMax1) {
3813
+ yMax1 = ty;
3814
+ }
3815
+
3816
+ *xMin = xMin1;
3817
+ *yMin = yMin1;
3818
+ *xMax = xMax1;
3819
+ *yMax = yMax1;
3820
+ }
3821
+
3822
+ double GfxState::transformWidth(double w) {
3823
+ double x, y;
3824
+
3825
+ x = ctm[0] + ctm[2];
3826
+ y = ctm[1] + ctm[3];
3827
+ return w * sqrt(0.5 * (x * x + y * y));
3828
+ }
3829
+
3830
+ double GfxState::getTransformedFontSize() {
3831
+ double x1, y1, x2, y2;
3832
+
3833
+ x1 = textMat[2] * fontSize;
3834
+ y1 = textMat[3] * fontSize;
3835
+ x2 = ctm[0] * x1 + ctm[2] * y1;
3836
+ y2 = ctm[1] * x1 + ctm[3] * y1;
3837
+ return sqrt(x2 * x2 + y2 * y2);
3838
+ }
3839
+
3840
+ void GfxState::getFontTransMat(double *m11, double *m12,
3841
+ double *m21, double *m22) {
3842
+ *m11 = (textMat[0] * ctm[0] + textMat[1] * ctm[2]) * fontSize;
3843
+ *m12 = (textMat[0] * ctm[1] + textMat[1] * ctm[3]) * fontSize;
3844
+ *m21 = (textMat[2] * ctm[0] + textMat[3] * ctm[2]) * fontSize;
3845
+ *m22 = (textMat[2] * ctm[1] + textMat[3] * ctm[3]) * fontSize;
3846
+ }
3847
+
3848
+ void GfxState::setCTM(double a, double b, double c,
3849
+ double d, double e, double f) {
3850
+ int i;
3851
+
3852
+ ctm[0] = a;
3853
+ ctm[1] = b;
3854
+ ctm[2] = c;
3855
+ ctm[3] = d;
3856
+ ctm[4] = e;
3857
+ ctm[5] = f;
3858
+
3859
+ // avoid FP exceptions on badly messed up PDF files
3860
+ for (i = 0; i < 6; ++i) {
3861
+ if (ctm[i] > 1e10) {
3862
+ ctm[i] = 1e10;
3863
+ } else if (ctm[i] < -1e10) {
3864
+ ctm[i] = -1e10;
3865
+ }
3866
+ }
3867
+ }
3868
+
3869
+ void GfxState::concatCTM(double a, double b, double c,
3870
+ double d, double e, double f) {
3871
+ double a1 = ctm[0];
3872
+ double b1 = ctm[1];
3873
+ double c1 = ctm[2];
3874
+ double d1 = ctm[3];
3875
+ int i;
3876
+
3877
+ ctm[0] = a * a1 + b * c1;
3878
+ ctm[1] = a * b1 + b * d1;
3879
+ ctm[2] = c * a1 + d * c1;
3880
+ ctm[3] = c * b1 + d * d1;
3881
+ ctm[4] = e * a1 + f * c1 + ctm[4];
3882
+ ctm[5] = e * b1 + f * d1 + ctm[5];
3883
+
3884
+ // avoid FP exceptions on badly messed up PDF files
3885
+ for (i = 0; i < 6; ++i) {
3886
+ if (ctm[i] > 1e10) {
3887
+ ctm[i] = 1e10;
3888
+ } else if (ctm[i] < -1e10) {
3889
+ ctm[i] = -1e10;
3890
+ }
3891
+ }
3892
+ }
3893
+
3894
+ void GfxState::shiftCTM(double tx, double ty) {
3895
+ ctm[4] += tx;
3896
+ ctm[5] += ty;
3897
+ clipXMin += tx;
3898
+ clipYMin += ty;
3899
+ clipXMax += tx;
3900
+ clipYMax += ty;
3901
+ }
3902
+
3903
+ void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) {
3904
+ if (fillColorSpace) {
3905
+ delete fillColorSpace;
3906
+ }
3907
+ fillColorSpace = colorSpace;
3908
+ }
3909
+
3910
+ void GfxState::setStrokeColorSpace(GfxColorSpace *colorSpace) {
3911
+ if (strokeColorSpace) {
3912
+ delete strokeColorSpace;
3913
+ }
3914
+ strokeColorSpace = colorSpace;
3915
+ }
3916
+
3917
+ void GfxState::setFillPattern(GfxPattern *pattern) {
3918
+ if (fillPattern) {
3919
+ delete fillPattern;
3920
+ }
3921
+ fillPattern = pattern;
3922
+ }
3923
+
3924
+ void GfxState::setStrokePattern(GfxPattern *pattern) {
3925
+ if (strokePattern) {
3926
+ delete strokePattern;
3927
+ }
3928
+ strokePattern = pattern;
3929
+ }
3930
+
3931
+ void GfxState::setTransfer(Function **funcs) {
3932
+ int i;
3933
+
3934
+ for (i = 0; i < 4; ++i) {
3935
+ if (transfer[i]) {
3936
+ delete transfer[i];
3937
+ }
3938
+ transfer[i] = funcs[i];
3939
+ }
3940
+ }
3941
+
3942
+ void GfxState::setLineDash(double *dash, int length, double start) {
3943
+ if (lineDash)
3944
+ gfree(lineDash);
3945
+ lineDash = dash;
3946
+ lineDashLength = length;
3947
+ lineDashStart = start;
3948
+ }
3949
+
3950
+ void GfxState::clearPath() {
3951
+ delete path;
3952
+ path = new GfxPath();
3953
+ }
3954
+
3955
+ void GfxState::clip() {
3956
+ double xMin, yMin, xMax, yMax, x, y;
3957
+ GfxSubpath *subpath;
3958
+ int i, j;
3959
+
3960
+ xMin = xMax = yMin = yMax = 0; // make gcc happy
3961
+ for (i = 0; i < path->getNumSubpaths(); ++i) {
3962
+ subpath = path->getSubpath(i);
3963
+ for (j = 0; j < subpath->getNumPoints(); ++j) {
3964
+ transform(subpath->getX(j), subpath->getY(j), &x, &y);
3965
+ if (i == 0 && j == 0) {
3966
+ xMin = xMax = x;
3967
+ yMin = yMax = y;
3968
+ } else {
3969
+ if (x < xMin) {
3970
+ xMin = x;
3971
+ } else if (x > xMax) {
3972
+ xMax = x;
3973
+ }
3974
+ if (y < yMin) {
3975
+ yMin = y;
3976
+ } else if (y > yMax) {
3977
+ yMax = y;
3978
+ }
3979
+ }
3980
+ }
3981
+ }
3982
+ if (xMin > clipXMin) {
3983
+ clipXMin = xMin;
3984
+ }
3985
+ if (yMin > clipYMin) {
3986
+ clipYMin = yMin;
3987
+ }
3988
+ if (xMax < clipXMax) {
3989
+ clipXMax = xMax;
3990
+ }
3991
+ if (yMax < clipYMax) {
3992
+ clipYMax = yMax;
3993
+ }
3994
+ }
3995
+
3996
+ void GfxState::clipToStrokePath() {
3997
+ double xMin, yMin, xMax, yMax, x, y, t0, t1;
3998
+ GfxSubpath *subpath;
3999
+ int i, j;
4000
+
4001
+ xMin = xMax = yMin = yMax = 0; // make gcc happy
4002
+ for (i = 0; i < path->getNumSubpaths(); ++i) {
4003
+ subpath = path->getSubpath(i);
4004
+ for (j = 0; j < subpath->getNumPoints(); ++j) {
4005
+ transform(subpath->getX(j), subpath->getY(j), &x, &y);
4006
+ if (i == 0 && j == 0) {
4007
+ xMin = xMax = x;
4008
+ yMin = yMax = y;
4009
+ } else {
4010
+ if (x < xMin) {
4011
+ xMin = x;
4012
+ } else if (x > xMax) {
4013
+ xMax = x;
4014
+ }
4015
+ if (y < yMin) {
4016
+ yMin = y;
4017
+ } else if (y > yMax) {
4018
+ yMax = y;
4019
+ }
4020
+ }
4021
+ }
4022
+ }
4023
+
4024
+ // allow for the line width
4025
+ //~ miter joins can extend farther than this
4026
+ t0 = fabs(ctm[0]);
4027
+ t1 = fabs(ctm[2]);
4028
+ if (t0 > t1) {
4029
+ xMin -= 0.5 * lineWidth * t0;
4030
+ xMax += 0.5 * lineWidth * t0;
4031
+ } else {
4032
+ xMin -= 0.5 * lineWidth * t1;
4033
+ xMax += 0.5 * lineWidth * t1;
4034
+ }
4035
+ t0 = fabs(ctm[0]);
4036
+ t1 = fabs(ctm[3]);
4037
+ if (t0 > t1) {
4038
+ yMin -= 0.5 * lineWidth * t0;
4039
+ yMax += 0.5 * lineWidth * t0;
4040
+ } else {
4041
+ yMin -= 0.5 * lineWidth * t1;
4042
+ yMax += 0.5 * lineWidth * t1;
4043
+ }
4044
+
4045
+ if (xMin > clipXMin) {
4046
+ clipXMin = xMin;
4047
+ }
4048
+ if (yMin > clipYMin) {
4049
+ clipYMin = yMin;
4050
+ }
4051
+ if (xMax < clipXMax) {
4052
+ clipXMax = xMax;
4053
+ }
4054
+ if (yMax < clipYMax) {
4055
+ clipYMax = yMax;
4056
+ }
4057
+ }
4058
+
4059
+ void GfxState::textShift(double tx, double ty) {
4060
+ double dx, dy;
4061
+
4062
+ textTransformDelta(tx, ty, &dx, &dy);
4063
+ curX += dx;
4064
+ curY += dy;
4065
+ }
4066
+
4067
+ void GfxState::shift(double dx, double dy) {
4068
+ curX += dx;
4069
+ curY += dy;
4070
+ }
4071
+
4072
+ GfxState *GfxState::save() {
4073
+ GfxState *newState;
4074
+
4075
+ newState = copy();
4076
+ newState->saved = this;
4077
+ return newState;
4078
+ }
4079
+
4080
+ GfxState *GfxState::restore() {
4081
+ GfxState *oldState;
4082
+
4083
+ if (saved) {
4084
+ oldState = saved;
4085
+
4086
+ // these attributes aren't saved/restored by the q/Q operators
4087
+ oldState->path = path;
4088
+ oldState->curX = curX;
4089
+ oldState->curY = curY;
4090
+ oldState->lineX = lineX;
4091
+ oldState->lineY = lineY;
4092
+
4093
+ path = NULL;
4094
+ saved = NULL;
4095
+ delete this;
4096
+
4097
+ } else {
4098
+ oldState = this;
4099
+ }
4100
+
4101
+ return oldState;
4102
+ }
4103
+
4104
+ GBool GfxState::parseBlendMode(Object *obj, GfxBlendMode *mode) {
4105
+ Object obj2;
4106
+ int i, j;
4107
+
4108
+ if (obj->isName()) {
4109
+ for (i = 0; i < nGfxBlendModeNames; ++i) {
4110
+ if (!strcmp(obj->getName(), gfxBlendModeNames[i].name)) {
4111
+ *mode = gfxBlendModeNames[i].mode;
4112
+ return gTrue;
4113
+ }
4114
+ }
4115
+ return gFalse;
4116
+ } else if (obj->isArray()) {
4117
+ for (i = 0; i < obj->arrayGetLength(); ++i) {
4118
+ obj->arrayGet(i, &obj2);
4119
+ if (!obj2.isName()) {
4120
+ obj2.free();
4121
+ return gFalse;
4122
+ }
4123
+ for (j = 0; j < nGfxBlendModeNames; ++j) {
4124
+ if (!strcmp(obj2.getName(), gfxBlendModeNames[j].name)) {
4125
+ obj2.free();
4126
+ *mode = gfxBlendModeNames[j].mode;
4127
+ return gTrue;
4128
+ }
4129
+ }
4130
+ obj2.free();
4131
+ }
4132
+ *mode = gfxBlendNormal;
4133
+ return gTrue;
4134
+ } else {
4135
+ return gFalse;
4136
+ }
4137
+ }