pdf2json 0.1.0

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