pdf2json 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. data/README.markdown +9 -0
  2. data/bin/.gitkeep +0 -0
  3. data/ext/extconf.rb +30 -0
  4. data/lib/pdf2json.rb +8 -0
  5. data/pdf2json-0.52-source/AUTHORS +24 -0
  6. data/pdf2json-0.52-source/CHANGES +11 -0
  7. data/pdf2json-0.52-source/Makefile +84 -0
  8. data/pdf2json-0.52-source/Makefile.in +84 -0
  9. data/pdf2json-0.52-source/aclocal.m4 +274 -0
  10. data/pdf2json-0.52-source/aconf-win32.h +86 -0
  11. data/pdf2json-0.52-source/aconf.h +42 -0
  12. data/pdf2json-0.52-source/aconf.h.in +41 -0
  13. data/pdf2json-0.52-source/autom4te.cache/output.0 +6908 -0
  14. data/pdf2json-0.52-source/autom4te.cache/requests +76 -0
  15. data/pdf2json-0.52-source/autom4te.cache/traces.0 +466 -0
  16. data/pdf2json-0.52-source/config.log +1259 -0
  17. data/pdf2json-0.52-source/config.status +1050 -0
  18. data/pdf2json-0.52-source/configure +6908 -0
  19. data/pdf2json-0.52-source/configure.ac +93 -0
  20. data/pdf2json-0.52-source/doc/pdffonts.1 +130 -0
  21. data/pdf2json-0.52-source/doc/pdffonts.cat +107 -0
  22. data/pdf2json-0.52-source/doc/pdffonts.hlp +117 -0
  23. data/pdf2json-0.52-source/doc/pdfimages.1 +102 -0
  24. data/pdf2json-0.52-source/doc/pdfimages.cat +92 -0
  25. data/pdf2json-0.52-source/doc/pdfimages.hlp +101 -0
  26. data/pdf2json-0.52-source/doc/pdfinfo.1 +158 -0
  27. data/pdf2json-0.52-source/doc/pdfinfo.cat +119 -0
  28. data/pdf2json-0.52-source/doc/pdfinfo.hlp +129 -0
  29. data/pdf2json-0.52-source/doc/pdftoppm.1 +115 -0
  30. data/pdf2json-0.52-source/doc/pdftoppm.cat +105 -0
  31. data/pdf2json-0.52-source/doc/pdftoppm.hlp +114 -0
  32. data/pdf2json-0.52-source/doc/pdftops.1 +229 -0
  33. data/pdf2json-0.52-source/doc/pdftops.cat +221 -0
  34. data/pdf2json-0.52-source/doc/pdftops.hlp +231 -0
  35. data/pdf2json-0.52-source/doc/pdftotext.1 +137 -0
  36. data/pdf2json-0.52-source/doc/pdftotext.cat +120 -0
  37. data/pdf2json-0.52-source/doc/pdftotext.hlp +133 -0
  38. data/pdf2json-0.52-source/doc/sample-xpdfrc +91 -0
  39. data/pdf2json-0.52-source/doc/xpdf.1 +513 -0
  40. data/pdf2json-0.52-source/doc/xpdf.cat +476 -0
  41. data/pdf2json-0.52-source/doc/xpdf.hlp +489 -0
  42. data/pdf2json-0.52-source/doc/xpdfrc.5 +480 -0
  43. data/pdf2json-0.52-source/doc/xpdfrc.cat +474 -0
  44. data/pdf2json-0.52-source/doc/xpdfrc.hlp +479 -0
  45. data/pdf2json-0.52-source/fofi/.DS_Store +0 -0
  46. data/pdf2json-0.52-source/fofi/FoFiBase.cc +156 -0
  47. data/pdf2json-0.52-source/fofi/FoFiBase.h +57 -0
  48. data/pdf2json-0.52-source/fofi/FoFiBase.o +0 -0
  49. data/pdf2json-0.52-source/fofi/FoFiEncodings.cc +994 -0
  50. data/pdf2json-0.52-source/fofi/FoFiEncodings.h +36 -0
  51. data/pdf2json-0.52-source/fofi/FoFiEncodings.o +0 -0
  52. data/pdf2json-0.52-source/fofi/FoFiTrueType.cc +2027 -0
  53. data/pdf2json-0.52-source/fofi/FoFiTrueType.h +174 -0
  54. data/pdf2json-0.52-source/fofi/FoFiTrueType.o +0 -0
  55. data/pdf2json-0.52-source/fofi/FoFiType1.cc +252 -0
  56. data/pdf2json-0.52-source/fofi/FoFiType1.h +59 -0
  57. data/pdf2json-0.52-source/fofi/FoFiType1.o +0 -0
  58. data/pdf2json-0.52-source/fofi/FoFiType1C.cc +2603 -0
  59. data/pdf2json-0.52-source/fofi/FoFiType1C.h +233 -0
  60. data/pdf2json-0.52-source/fofi/FoFiType1C.o +0 -0
  61. data/pdf2json-0.52-source/fofi/Makefile +70 -0
  62. data/pdf2json-0.52-source/fofi/Makefile.dep +0 -0
  63. data/pdf2json-0.52-source/fofi/Makefile.in +70 -0
  64. data/pdf2json-0.52-source/fofi/libfofi.a +0 -0
  65. data/pdf2json-0.52-source/fofi/vms_make.com +0 -0
  66. data/pdf2json-0.52-source/freetype.win32/.DS_Store +0 -0
  67. data/pdf2json-0.52-source/freetype.win32/include/.DS_Store +0 -0
  68. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftconfig.h +528 -0
  69. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftheader.h +780 -0
  70. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftmodule.h +32 -0
  71. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftoption.h +733 -0
  72. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftstdlib.h +173 -0
  73. data/pdf2json-0.52-source/freetype.win32/include/freetype/freetype.h +3919 -0
  74. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftadvanc.h +179 -0
  75. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbbox.h +94 -0
  76. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbdf.h +209 -0
  77. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbitmap.h +227 -0
  78. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcache.h +1128 -0
  79. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftchapters.h +103 -0
  80. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcid.h +166 -0
  81. data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrdef.h +244 -0
  82. data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrors.h +206 -0
  83. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgasp.h +120 -0
  84. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftglyph.h +613 -0
  85. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgxval.h +358 -0
  86. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgzip.h +102 -0
  87. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftimage.h +1313 -0
  88. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftincrem.h +353 -0
  89. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlcdfil.h +213 -0
  90. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlist.h +277 -0
  91. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlzw.h +99 -0
  92. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmac.h +274 -0
  93. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmm.h +378 -0
  94. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmodapi.h +483 -0
  95. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmoderr.h +155 -0
  96. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftotval.h +203 -0
  97. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftoutln.h +537 -0
  98. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftpfr.h +172 -0
  99. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftrender.h +230 -0
  100. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsizes.h +159 -0
  101. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsnames.h +200 -0
  102. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftstroke.h +716 -0
  103. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsynth.h +80 -0
  104. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsystem.h +347 -0
  105. data/pdf2json-0.52-source/freetype.win32/include/freetype/fttrigon.h +350 -0
  106. data/pdf2json-0.52-source/freetype.win32/include/freetype/fttypes.h +588 -0
  107. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftwinfnt.h +274 -0
  108. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftxf86.h +83 -0
  109. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/autohint.h +231 -0
  110. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftcalc.h +179 -0
  111. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdebug.h +250 -0
  112. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdriver.h +422 -0
  113. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftgloadr.h +168 -0
  114. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftmemory.h +380 -0
  115. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftobjs.h +1428 -0
  116. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftpic.h +67 -0
  117. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftrfork.h +196 -0
  118. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftserv.h +620 -0
  119. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftstream.h +539 -0
  120. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/fttrace.h +139 -0
  121. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftvalid.h +150 -0
  122. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/internal.h +51 -0
  123. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pcftypes.h +56 -0
  124. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/psaux.h +873 -0
  125. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pshints.h +712 -0
  126. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svbdf.h +77 -0
  127. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svcid.h +83 -0
  128. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgldict.h +82 -0
  129. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgxval.h +72 -0
  130. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svkern.h +51 -0
  131. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svmm.h +104 -0
  132. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svotval.h +55 -0
  133. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpfr.h +66 -0
  134. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpostnm.h +79 -0
  135. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpscmap.h +164 -0
  136. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpsinfo.h +92 -0
  137. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svsfnt.h +102 -0
  138. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttcmap.h +106 -0
  139. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svtteng.h +53 -0
  140. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttglyf.h +67 -0
  141. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svwinfnt.h +50 -0
  142. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svxf86nm.h +55 -0
  143. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/sfnt.h +897 -0
  144. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/t1types.h +270 -0
  145. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/tttypes.h +1543 -0
  146. data/pdf2json-0.52-source/freetype.win32/include/freetype/t1tables.h +504 -0
  147. data/pdf2json-0.52-source/freetype.win32/include/freetype/ttnameid.h +1247 -0
  148. data/pdf2json-0.52-source/freetype.win32/include/freetype/tttables.h +759 -0
  149. data/pdf2json-0.52-source/freetype.win32/include/freetype/tttags.h +107 -0
  150. data/pdf2json-0.52-source/freetype.win32/include/freetype/ttunpat.h +59 -0
  151. data/pdf2json-0.52-source/freetype.win32/include/ft2build.h +39 -0
  152. data/pdf2json-0.52-source/freetype.win32/lib/freetype_a.lib +0 -0
  153. data/pdf2json-0.52-source/goo/.DS_Store +0 -0
  154. data/pdf2json-0.52-source/goo/FixedPoint.cc +118 -0
  155. data/pdf2json-0.52-source/goo/FixedPoint.h +155 -0
  156. data/pdf2json-0.52-source/goo/FixedPoint.o +0 -0
  157. data/pdf2json-0.52-source/goo/GHash.cc +380 -0
  158. data/pdf2json-0.52-source/goo/GHash.h +78 -0
  159. data/pdf2json-0.52-source/goo/GHash.o +0 -0
  160. data/pdf2json-0.52-source/goo/GList.cc +97 -0
  161. data/pdf2json-0.52-source/goo/GList.h +96 -0
  162. data/pdf2json-0.52-source/goo/GList.o +0 -0
  163. data/pdf2json-0.52-source/goo/GMutex.h +49 -0
  164. data/pdf2json-0.52-source/goo/GString.cc +724 -0
  165. data/pdf2json-0.52-source/goo/GString.cc.fixed +718 -0
  166. data/pdf2json-0.52-source/goo/GString.h +136 -0
  167. data/pdf2json-0.52-source/goo/GString.o +0 -0
  168. data/pdf2json-0.52-source/goo/ImgWriter.o +0 -0
  169. data/pdf2json-0.52-source/goo/JpegWriter.o +0 -0
  170. data/pdf2json-0.52-source/goo/Makefile +72 -0
  171. data/pdf2json-0.52-source/goo/Makefile.dep +0 -0
  172. data/pdf2json-0.52-source/goo/Makefile.in +72 -0
  173. data/pdf2json-0.52-source/goo/PNGWriter.o +0 -0
  174. data/pdf2json-0.52-source/goo/gfile.cc +731 -0
  175. data/pdf2json-0.52-source/goo/gfile.h +138 -0
  176. data/pdf2json-0.52-source/goo/gfile.o +0 -0
  177. data/pdf2json-0.52-source/goo/gmem.cc +264 -0
  178. data/pdf2json-0.52-source/goo/gmem.h +79 -0
  179. data/pdf2json-0.52-source/goo/gmem.o +0 -0
  180. data/pdf2json-0.52-source/goo/gmempp.cc +32 -0
  181. data/pdf2json-0.52-source/goo/gmempp.o +0 -0
  182. data/pdf2json-0.52-source/goo/gtypes.h +29 -0
  183. data/pdf2json-0.52-source/goo/libGoo.a +0 -0
  184. data/pdf2json-0.52-source/goo/parseargs.c +190 -0
  185. data/pdf2json-0.52-source/goo/parseargs.h +71 -0
  186. data/pdf2json-0.52-source/goo/parseargs.o +0 -0
  187. data/pdf2json-0.52-source/goo/vms_directory.c +214 -0
  188. data/pdf2json-0.52-source/goo/vms_dirent.h +67 -0
  189. data/pdf2json-0.52-source/goo/vms_make.com +82 -0
  190. data/pdf2json-0.52-source/goo/vms_sys_dirent.h +54 -0
  191. data/pdf2json-0.52-source/goo/vms_unix_time.h +102 -0
  192. data/pdf2json-0.52-source/goo/vms_unix_times.c +42 -0
  193. data/pdf2json-0.52-source/goo/vms_unlink.c +22 -0
  194. data/pdf2json-0.52-source/ms_make.bat +199 -0
  195. data/pdf2json-0.52-source/splash/.DS_Store +0 -0
  196. data/pdf2json-0.52-source/splash/Makefile +103 -0
  197. data/pdf2json-0.52-source/splash/Makefile.dep +0 -0
  198. data/pdf2json-0.52-source/splash/Makefile.in +103 -0
  199. data/pdf2json-0.52-source/splash/Splash.cc +3310 -0
  200. data/pdf2json-0.52-source/splash/Splash.h +293 -0
  201. data/pdf2json-0.52-source/splash/Splash.o +0 -0
  202. data/pdf2json-0.52-source/splash/SplashBitmap.cc +188 -0
  203. data/pdf2json-0.52-source/splash/SplashBitmap.h +64 -0
  204. data/pdf2json-0.52-source/splash/SplashBitmap.o +0 -0
  205. data/pdf2json-0.52-source/splash/SplashClip.cc +382 -0
  206. data/pdf2json-0.52-source/splash/SplashClip.h +107 -0
  207. data/pdf2json-0.52-source/splash/SplashClip.o +0 -0
  208. data/pdf2json-0.52-source/splash/SplashErrorCodes.h +32 -0
  209. data/pdf2json-0.52-source/splash/SplashFTFont.cc +357 -0
  210. data/pdf2json-0.52-source/splash/SplashFTFont.h +58 -0
  211. data/pdf2json-0.52-source/splash/SplashFTFont.o +0 -0
  212. data/pdf2json-0.52-source/splash/SplashFTFontEngine.cc +179 -0
  213. data/pdf2json-0.52-source/splash/SplashFTFontEngine.h +65 -0
  214. data/pdf2json-0.52-source/splash/SplashFTFontEngine.o +0 -0
  215. data/pdf2json-0.52-source/splash/SplashFTFontFile.cc +114 -0
  216. data/pdf2json-0.52-source/splash/SplashFTFontFile.h +73 -0
  217. data/pdf2json-0.52-source/splash/SplashFTFontFile.o +0 -0
  218. data/pdf2json-0.52-source/splash/SplashFont.cc +176 -0
  219. data/pdf2json-0.52-source/splash/SplashFont.h +104 -0
  220. data/pdf2json-0.52-source/splash/SplashFont.o +0 -0
  221. data/pdf2json-0.52-source/splash/SplashFontEngine.cc +317 -0
  222. data/pdf2json-0.52-source/splash/SplashFontEngine.h +91 -0
  223. data/pdf2json-0.52-source/splash/SplashFontEngine.o +0 -0
  224. data/pdf2json-0.52-source/splash/SplashFontFile.cc +55 -0
  225. data/pdf2json-0.52-source/splash/SplashFontFile.h +60 -0
  226. data/pdf2json-0.52-source/splash/SplashFontFile.o +0 -0
  227. data/pdf2json-0.52-source/splash/SplashFontFileID.cc +23 -0
  228. data/pdf2json-0.52-source/splash/SplashFontFileID.h +30 -0
  229. data/pdf2json-0.52-source/splash/SplashFontFileID.o +0 -0
  230. data/pdf2json-0.52-source/splash/SplashGlyphBitmap.h +26 -0
  231. data/pdf2json-0.52-source/splash/SplashMath.h +89 -0
  232. data/pdf2json-0.52-source/splash/SplashPath.cc +184 -0
  233. data/pdf2json-0.52-source/splash/SplashPath.h +121 -0
  234. data/pdf2json-0.52-source/splash/SplashPath.o +0 -0
  235. data/pdf2json-0.52-source/splash/SplashPattern.cc +40 -0
  236. data/pdf2json-0.52-source/splash/SplashPattern.h +65 -0
  237. data/pdf2json-0.52-source/splash/SplashPattern.o +0 -0
  238. data/pdf2json-0.52-source/splash/SplashScreen.cc +383 -0
  239. data/pdf2json-0.52-source/splash/SplashScreen.h +56 -0
  240. data/pdf2json-0.52-source/splash/SplashScreen.o +0 -0
  241. data/pdf2json-0.52-source/splash/SplashState.cc +165 -0
  242. data/pdf2json-0.52-source/splash/SplashState.h +103 -0
  243. data/pdf2json-0.52-source/splash/SplashState.o +0 -0
  244. data/pdf2json-0.52-source/splash/SplashT1Font.cc +287 -0
  245. data/pdf2json-0.52-source/splash/SplashT1Font.h +57 -0
  246. data/pdf2json-0.52-source/splash/SplashT1Font.o +0 -0
  247. data/pdf2json-0.52-source/splash/SplashT1FontEngine.cc +124 -0
  248. data/pdf2json-0.52-source/splash/SplashT1FontEngine.h +53 -0
  249. data/pdf2json-0.52-source/splash/SplashT1FontEngine.o +0 -0
  250. data/pdf2json-0.52-source/splash/SplashT1FontFile.cc +97 -0
  251. data/pdf2json-0.52-source/splash/SplashT1FontFile.h +58 -0
  252. data/pdf2json-0.52-source/splash/SplashT1FontFile.o +0 -0
  253. data/pdf2json-0.52-source/splash/SplashTypes.h +132 -0
  254. data/pdf2json-0.52-source/splash/SplashXPath.cc +438 -0
  255. data/pdf2json-0.52-source/splash/SplashXPath.h +100 -0
  256. data/pdf2json-0.52-source/splash/SplashXPath.o +0 -0
  257. data/pdf2json-0.52-source/splash/SplashXPathScanner.cc +428 -0
  258. data/pdf2json-0.52-source/splash/SplashXPathScanner.h +87 -0
  259. data/pdf2json-0.52-source/splash/SplashXPathScanner.o +0 -0
  260. data/pdf2json-0.52-source/splash/libsplash.a +0 -0
  261. data/pdf2json-0.52-source/splash/vms_make.com +0 -0
  262. data/pdf2json-0.52-source/src/.DS_Store +0 -0
  263. data/pdf2json-0.52-source/src/GVector.h +101 -0
  264. data/pdf2json-0.52-source/src/ImgOutputDev.cc +1243 -0
  265. data/pdf2json-0.52-source/src/ImgOutputDev.h +307 -0
  266. data/pdf2json-0.52-source/src/ImgOutputDev.o +0 -0
  267. data/pdf2json-0.52-source/src/Makefile +68 -0
  268. data/pdf2json-0.52-source/src/Makefile.in +68 -0
  269. data/pdf2json-0.52-source/src/XmlFonts.cc +367 -0
  270. data/pdf2json-0.52-source/src/XmlFonts.h +91 -0
  271. data/pdf2json-0.52-source/src/XmlFonts.o +0 -0
  272. data/pdf2json-0.52-source/src/XmlLinks.cc +101 -0
  273. data/pdf2json-0.52-source/src/XmlLinks.h +54 -0
  274. data/pdf2json-0.52-source/src/XmlLinks.o +0 -0
  275. data/pdf2json-0.52-source/src/pdf2json +0 -0
  276. data/pdf2json-0.52-source/src/pdf2json.cc +343 -0
  277. data/pdf2json-0.52-source/src/pdf2json.o +0 -0
  278. data/pdf2json-0.52-source/src/pdf2xml.dtd +22 -0
  279. data/pdf2json-0.52-source/src/pdf2xmljson.dtd +9 -0
  280. data/pdf2json-0.52-source/xpdf/.DS_Store +0 -0
  281. data/pdf2json-0.52-source/xpdf/Annot.cc +1556 -0
  282. data/pdf2json-0.52-source/xpdf/Annot.h +142 -0
  283. data/pdf2json-0.52-source/xpdf/Annot.o +0 -0
  284. data/pdf2json-0.52-source/xpdf/Array.cc +73 -0
  285. data/pdf2json-0.52-source/xpdf/Array.h +58 -0
  286. data/pdf2json-0.52-source/xpdf/Array.o +0 -0
  287. data/pdf2json-0.52-source/xpdf/BuiltinFont.cc +65 -0
  288. data/pdf2json-0.52-source/xpdf/BuiltinFont.h +57 -0
  289. data/pdf2json-0.52-source/xpdf/BuiltinFont.o +0 -0
  290. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.cc +4284 -0
  291. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.h +23 -0
  292. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.o +0 -0
  293. data/pdf2json-0.52-source/xpdf/CMap.cc +408 -0
  294. data/pdf2json-0.52-source/xpdf/CMap.h +102 -0
  295. data/pdf2json-0.52-source/xpdf/CMap.o +0 -0
  296. data/pdf2json-0.52-source/xpdf/Catalog.cc +374 -0
  297. data/pdf2json-0.52-source/xpdf/Catalog.h +97 -0
  298. data/pdf2json-0.52-source/xpdf/Catalog.o +0 -0
  299. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.cc +540 -0
  300. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.h +117 -0
  301. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.o +0 -0
  302. data/pdf2json-0.52-source/xpdf/CharTypes.h +24 -0
  303. data/pdf2json-0.52-source/xpdf/CompactFontTables.h +464 -0
  304. data/pdf2json-0.52-source/xpdf/CoreOutputDev.cc +61 -0
  305. data/pdf2json-0.52-source/xpdf/CoreOutputDev.h +61 -0
  306. data/pdf2json-0.52-source/xpdf/Decrypt.cc +776 -0
  307. data/pdf2json-0.52-source/xpdf/Decrypt.h +95 -0
  308. data/pdf2json-0.52-source/xpdf/Decrypt.o +0 -0
  309. data/pdf2json-0.52-source/xpdf/Dict.cc +95 -0
  310. data/pdf2json-0.52-source/xpdf/Dict.h +77 -0
  311. data/pdf2json-0.52-source/xpdf/Dict.o +0 -0
  312. data/pdf2json-0.52-source/xpdf/Error.cc +38 -0
  313. data/pdf2json-0.52-source/xpdf/Error.h +23 -0
  314. data/pdf2json-0.52-source/xpdf/Error.o +0 -0
  315. data/pdf2json-0.52-source/xpdf/ErrorCodes.h +36 -0
  316. data/pdf2json-0.52-source/xpdf/FontEncodingTables.cc +1824 -0
  317. data/pdf2json-0.52-source/xpdf/FontEncodingTables.h +20 -0
  318. data/pdf2json-0.52-source/xpdf/FontEncodingTables.o +0 -0
  319. data/pdf2json-0.52-source/xpdf/Function.cc +1573 -0
  320. data/pdf2json-0.52-source/xpdf/Function.h +229 -0
  321. data/pdf2json-0.52-source/xpdf/Function.o +0 -0
  322. data/pdf2json-0.52-source/xpdf/Gfx.cc +4187 -0
  323. data/pdf2json-0.52-source/xpdf/Gfx.h +312 -0
  324. data/pdf2json-0.52-source/xpdf/Gfx.o +0 -0
  325. data/pdf2json-0.52-source/xpdf/GfxFont.cc +1568 -0
  326. data/pdf2json-0.52-source/xpdf/GfxFont.h +320 -0
  327. data/pdf2json-0.52-source/xpdf/GfxFont.o +0 -0
  328. data/pdf2json-0.52-source/xpdf/GfxState.cc +4137 -0
  329. data/pdf2json-0.52-source/xpdf/GfxState.h +1244 -0
  330. data/pdf2json-0.52-source/xpdf/GfxState.o +0 -0
  331. data/pdf2json-0.52-source/xpdf/GlobalParams.cc +2924 -0
  332. data/pdf2json-0.52-source/xpdf/GlobalParams.cc.old +2908 -0
  333. data/pdf2json-0.52-source/xpdf/GlobalParams.h +466 -0
  334. data/pdf2json-0.52-source/xpdf/GlobalParams.h.old +463 -0
  335. data/pdf2json-0.52-source/xpdf/GlobalParams.o +0 -0
  336. data/pdf2json-0.52-source/xpdf/ImageOutputDev.cc +195 -0
  337. data/pdf2json-0.52-source/xpdf/ImageOutputDev.h +76 -0
  338. data/pdf2json-0.52-source/xpdf/ImageOutputDev.o +0 -0
  339. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.cc +322 -0
  340. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.h +109 -0
  341. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.o +0 -0
  342. data/pdf2json-0.52-source/xpdf/JBIG2Stream.cc +3413 -0
  343. data/pdf2json-0.52-source/xpdf/JBIG2Stream.h +145 -0
  344. data/pdf2json-0.52-source/xpdf/JBIG2Stream.o +0 -0
  345. data/pdf2json-0.52-source/xpdf/JPXStream.cc +3144 -0
  346. data/pdf2json-0.52-source/xpdf/JPXStream.h +351 -0
  347. data/pdf2json-0.52-source/xpdf/JPXStream.o +0 -0
  348. data/pdf2json-0.52-source/xpdf/Lexer.cc +485 -0
  349. data/pdf2json-0.52-source/xpdf/Lexer.h +80 -0
  350. data/pdf2json-0.52-source/xpdf/Lexer.o +0 -0
  351. data/pdf2json-0.52-source/xpdf/Link.cc +806 -0
  352. data/pdf2json-0.52-source/xpdf/Link.cc.old +784 -0
  353. data/pdf2json-0.52-source/xpdf/Link.h +415 -0
  354. data/pdf2json-0.52-source/xpdf/Link.h.old +369 -0
  355. data/pdf2json-0.52-source/xpdf/Link.o +0 -0
  356. data/pdf2json-0.52-source/xpdf/Makefile +232 -0
  357. data/pdf2json-0.52-source/xpdf/Makefile.dep +0 -0
  358. data/pdf2json-0.52-source/xpdf/Makefile.in +232 -0
  359. data/pdf2json-0.52-source/xpdf/NameToCharCode.cc +116 -0
  360. data/pdf2json-0.52-source/xpdf/NameToCharCode.h +42 -0
  361. data/pdf2json-0.52-source/xpdf/NameToCharCode.o +0 -0
  362. data/pdf2json-0.52-source/xpdf/NameToUnicodeTable.h +1097 -0
  363. data/pdf2json-0.52-source/xpdf/Object.cc +231 -0
  364. data/pdf2json-0.52-source/xpdf/Object.h +303 -0
  365. data/pdf2json-0.52-source/xpdf/Object.o +0 -0
  366. data/pdf2json-0.52-source/xpdf/Outline.cc +151 -0
  367. data/pdf2json-0.52-source/xpdf/Outline.h +76 -0
  368. data/pdf2json-0.52-source/xpdf/Outline.o +0 -0
  369. data/pdf2json-0.52-source/xpdf/OutputDev.cc +131 -0
  370. data/pdf2json-0.52-source/xpdf/OutputDev.h +253 -0
  371. data/pdf2json-0.52-source/xpdf/OutputDev.o +0 -0
  372. data/pdf2json-0.52-source/xpdf/PDFCore.cc +2044 -0
  373. data/pdf2json-0.52-source/xpdf/PDFCore.h +321 -0
  374. data/pdf2json-0.52-source/xpdf/PDFDoc.cc +404 -0
  375. data/pdf2json-0.52-source/xpdf/PDFDoc.h +183 -0
  376. data/pdf2json-0.52-source/xpdf/PDFDoc.o +0 -0
  377. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.cc +44 -0
  378. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.h +16 -0
  379. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.o +0 -0
  380. data/pdf2json-0.52-source/xpdf/PSOutputDev.cc +6224 -0
  381. data/pdf2json-0.52-source/xpdf/PSOutputDev.h +395 -0
  382. data/pdf2json-0.52-source/xpdf/PSOutputDev.o +0 -0
  383. data/pdf2json-0.52-source/xpdf/PSTokenizer.cc +135 -0
  384. data/pdf2json-0.52-source/xpdf/PSTokenizer.h +41 -0
  385. data/pdf2json-0.52-source/xpdf/PSTokenizer.o +0 -0
  386. data/pdf2json-0.52-source/xpdf/Page.cc +454 -0
  387. data/pdf2json-0.52-source/xpdf/Page.h +187 -0
  388. data/pdf2json-0.52-source/xpdf/Page.o +0 -0
  389. data/pdf2json-0.52-source/xpdf/Parser.cc +227 -0
  390. data/pdf2json-0.52-source/xpdf/Parser.h +59 -0
  391. data/pdf2json-0.52-source/xpdf/Parser.o +0 -0
  392. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.cc +257 -0
  393. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.h +130 -0
  394. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.o +0 -0
  395. data/pdf2json-0.52-source/xpdf/SecurityHandler.cc +390 -0
  396. data/pdf2json-0.52-source/xpdf/SecurityHandler.h +160 -0
  397. data/pdf2json-0.52-source/xpdf/SecurityHandler.o +0 -0
  398. data/pdf2json-0.52-source/xpdf/SplashOutputDev.cc +2845 -0
  399. data/pdf2json-0.52-source/xpdf/SplashOutputDev.h +247 -0
  400. data/pdf2json-0.52-source/xpdf/SplashOutputDev.o +0 -0
  401. data/pdf2json-0.52-source/xpdf/Stream-CCITT.h +459 -0
  402. data/pdf2json-0.52-source/xpdf/Stream.cc +4627 -0
  403. data/pdf2json-0.52-source/xpdf/Stream.h +858 -0
  404. data/pdf2json-0.52-source/xpdf/Stream.o +0 -0
  405. data/pdf2json-0.52-source/xpdf/TextOutputDev.cc +4090 -0
  406. data/pdf2json-0.52-source/xpdf/TextOutputDev.h +661 -0
  407. data/pdf2json-0.52-source/xpdf/TextOutputDev.o +0 -0
  408. data/pdf2json-0.52-source/xpdf/UTF8.h +56 -0
  409. data/pdf2json-0.52-source/xpdf/UnicodeMap.cc +302 -0
  410. data/pdf2json-0.52-source/xpdf/UnicodeMap.cc.old +293 -0
  411. data/pdf2json-0.52-source/xpdf/UnicodeMap.h +135 -0
  412. data/pdf2json-0.52-source/xpdf/UnicodeMap.h.old +123 -0
  413. data/pdf2json-0.52-source/xpdf/UnicodeMap.o +0 -0
  414. data/pdf2json-0.52-source/xpdf/UnicodeMapTables.h +361 -0
  415. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.cc +949 -0
  416. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.h +20 -0
  417. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.o +0 -0
  418. data/pdf2json-0.52-source/xpdf/XPDFApp.cc +447 -0
  419. data/pdf2json-0.52-source/xpdf/XPDFApp.h +114 -0
  420. data/pdf2json-0.52-source/xpdf/XPDFCore.cc +1655 -0
  421. data/pdf2json-0.52-source/xpdf/XPDFCore.h +251 -0
  422. data/pdf2json-0.52-source/xpdf/XPDFTree.cc +931 -0
  423. data/pdf2json-0.52-source/xpdf/XPDFTree.h +45 -0
  424. data/pdf2json-0.52-source/xpdf/XPDFTreeP.h +87 -0
  425. data/pdf2json-0.52-source/xpdf/XPDFViewer.cc +3488 -0
  426. data/pdf2json-0.52-source/xpdf/XPDFViewer.h +352 -0
  427. data/pdf2json-0.52-source/xpdf/XRef.cc +896 -0
  428. data/pdf2json-0.52-source/xpdf/XRef.h +133 -0
  429. data/pdf2json-0.52-source/xpdf/XRef.o +0 -0
  430. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.cc +262 -0
  431. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.h +341 -0
  432. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.o +0 -0
  433. data/pdf2json-0.52-source/xpdf/about-text.h +48 -0
  434. data/pdf2json-0.52-source/xpdf/about.xbm +6 -0
  435. data/pdf2json-0.52-source/xpdf/backArrow.xbm +6 -0
  436. data/pdf2json-0.52-source/xpdf/backArrowDis.xbm +6 -0
  437. data/pdf2json-0.52-source/xpdf/config.h +112 -0
  438. data/pdf2json-0.52-source/xpdf/dblLeftArrow.xbm +6 -0
  439. data/pdf2json-0.52-source/xpdf/dblLeftArrowDis.xbm +6 -0
  440. data/pdf2json-0.52-source/xpdf/dblRightArrow.xbm +6 -0
  441. data/pdf2json-0.52-source/xpdf/dblRightArrowDis.xbm +6 -0
  442. data/pdf2json-0.52-source/xpdf/find.xbm +6 -0
  443. data/pdf2json-0.52-source/xpdf/findDis.xbm +6 -0
  444. data/pdf2json-0.52-source/xpdf/forwardArrow.xbm +6 -0
  445. data/pdf2json-0.52-source/xpdf/forwardArrowDis.xbm +6 -0
  446. data/pdf2json-0.52-source/xpdf/leftArrow.xbm +5 -0
  447. data/pdf2json-0.52-source/xpdf/leftArrowDis.xbm +5 -0
  448. data/pdf2json-0.52-source/xpdf/libXpdf.a +0 -0
  449. data/pdf2json-0.52-source/xpdf/pdffonts +0 -0
  450. data/pdf2json-0.52-source/xpdf/pdffonts.cc +298 -0
  451. data/pdf2json-0.52-source/xpdf/pdffonts.o +0 -0
  452. data/pdf2json-0.52-source/xpdf/pdfimages +0 -0
  453. data/pdf2json-0.52-source/xpdf/pdfimages.cc +155 -0
  454. data/pdf2json-0.52-source/xpdf/pdfimages.o +0 -0
  455. data/pdf2json-0.52-source/xpdf/pdfinfo +0 -0
  456. data/pdf2json-0.52-source/xpdf/pdfinfo.cc +387 -0
  457. data/pdf2json-0.52-source/xpdf/pdfinfo.o +0 -0
  458. data/pdf2json-0.52-source/xpdf/pdftoppm.cc +203 -0
  459. data/pdf2json-0.52-source/xpdf/pdftops +0 -0
  460. data/pdf2json-0.52-source/xpdf/pdftops.cc +344 -0
  461. data/pdf2json-0.52-source/xpdf/pdftops.o +0 -0
  462. data/pdf2json-0.52-source/xpdf/pdftotext +0 -0
  463. data/pdf2json-0.52-source/xpdf/pdftotext.cc +333 -0
  464. data/pdf2json-0.52-source/xpdf/pdftotext.o +0 -0
  465. data/pdf2json-0.52-source/xpdf/print.xbm +6 -0
  466. data/pdf2json-0.52-source/xpdf/printDis.xbm +6 -0
  467. data/pdf2json-0.52-source/xpdf/rightArrow.xbm +5 -0
  468. data/pdf2json-0.52-source/xpdf/rightArrowDis.xbm +5 -0
  469. data/pdf2json-0.52-source/xpdf/vms_make.com +129 -0
  470. data/pdf2json-0.52-source/xpdf/xpdf.cc +344 -0
  471. data/pdf2json-0.52-source/xpdf/xpdfIcon.xpm +62 -0
  472. data/pdf2json.gemspec +29 -0
  473. metadata +518 -0
Binary file
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!ELEMENT pdf2xml (page*)>
3
+ <!ELEMENT page (text*)>
4
+ <!ELEMENT text (#PCDATA)>
5
+
6
+ <!ATTLIST page
7
+ width CDATA #REQUIRED
8
+ height CDATA #REQUIRED
9
+ number CDATA #REQUIRED
10
+ >
11
+
12
+ <!ATTLIST text
13
+ top CDATA #REQUIRED
14
+ left CDATA #REQUIRED
15
+ width CDATA #REQUIRED
16
+ height CDATA #REQUIRED
17
+ color CDATA #REQUIRED
18
+ bgcolor CDATA #IMPLIED
19
+ family CDATA #REQUIRED
20
+ face CDATA #REQUIRED
21
+ size CDATA #REQUIRED
22
+ >
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!ELEMENT pdf2xmljson (page*)>
3
+ <!ELEMENT page (text*)>
4
+
5
+ <!ATTLIST page
6
+ width CDATA #REQUIRED
7
+ height CDATA #REQUIRED
8
+ number CDATA #REQUIRED
9
+ >
Binary file
@@ -0,0 +1,1556 @@
1
+ //========================================================================
2
+ //
3
+ // Annot.cc
4
+ //
5
+ // Copyright 2000-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 <stdlib.h>
16
+ #include <math.h>
17
+ #include "gmem.h"
18
+ #include "GList.h"
19
+ #include "Error.h"
20
+ #include "Object.h"
21
+ #include "Catalog.h"
22
+ #include "Gfx.h"
23
+ #include "GfxFont.h"
24
+ #include "Lexer.h"
25
+ #include "Annot.h"
26
+
27
+ //------------------------------------------------------------------------
28
+
29
+ #define annotFlagHidden 0x0002
30
+ #define annotFlagPrint 0x0004
31
+ #define annotFlagNoView 0x0020
32
+
33
+ #define fieldFlagReadOnly 0x00000001
34
+ #define fieldFlagRequired 0x00000002
35
+ #define fieldFlagNoExport 0x00000004
36
+ #define fieldFlagMultiline 0x00001000
37
+ #define fieldFlagPassword 0x00002000
38
+ #define fieldFlagNoToggleToOff 0x00004000
39
+ #define fieldFlagRadio 0x00008000
40
+ #define fieldFlagPushbutton 0x00010000
41
+ #define fieldFlagCombo 0x00020000
42
+ #define fieldFlagEdit 0x00040000
43
+ #define fieldFlagSort 0x00080000
44
+ #define fieldFlagFileSelect 0x00100000
45
+ #define fieldFlagMultiSelect 0x00200000
46
+ #define fieldFlagDoNotSpellCheck 0x00400000
47
+ #define fieldFlagDoNotScroll 0x00800000
48
+ #define fieldFlagComb 0x01000000
49
+ #define fieldFlagRichText 0x02000000
50
+ #define fieldFlagRadiosInUnison 0x02000000
51
+ #define fieldFlagCommitOnSelChange 0x04000000
52
+
53
+ #define fieldQuadLeft 0
54
+ #define fieldQuadCenter 1
55
+ #define fieldQuadRight 2
56
+
57
+ // distance of Bezier control point from center for circle approximation
58
+ // = (4 * (sqrt(2) - 1) / 3) * r
59
+ #define bezierCircle 0.55228475
60
+
61
+ //------------------------------------------------------------------------
62
+ // AnnotBorderStyle
63
+ //------------------------------------------------------------------------
64
+
65
+ AnnotBorderStyle::AnnotBorderStyle(AnnotBorderType typeA, double widthA,
66
+ double *dashA, int dashLengthA,
67
+ double rA, double gA, double bA) {
68
+ type = typeA;
69
+ width = widthA;
70
+ dash = dashA;
71
+ dashLength = dashLengthA;
72
+ r = rA;
73
+ g = gA;
74
+ b = bA;
75
+ }
76
+
77
+ AnnotBorderStyle::~AnnotBorderStyle() {
78
+ if (dash) {
79
+ gfree(dash);
80
+ }
81
+ }
82
+
83
+ //------------------------------------------------------------------------
84
+ // Annot
85
+ //------------------------------------------------------------------------
86
+
87
+ Annot::Annot(XRef *xrefA, Dict *acroForm, Dict *dict, Ref *refA) {
88
+ Object apObj, asObj, obj1, obj2, obj3;
89
+ AnnotBorderType borderType;
90
+ double borderWidth;
91
+ double *borderDash;
92
+ int borderDashLength;
93
+ double borderR, borderG, borderB;
94
+ double t;
95
+ int i;
96
+
97
+ ok = gTrue;
98
+ xref = xrefA;
99
+ ref = *refA;
100
+ type = NULL;
101
+ appearBuf = NULL;
102
+ borderStyle = NULL;
103
+
104
+ //----- parse the type
105
+
106
+ if (dict->lookup("Subtype", &obj1)->isName()) {
107
+ type = new GString(obj1.getName());
108
+ }
109
+ obj1.free();
110
+
111
+ //----- parse the rectangle
112
+
113
+ if (dict->lookup("Rect", &obj1)->isArray() &&
114
+ obj1.arrayGetLength() == 4) {
115
+ xMin = yMin = xMax = yMax = 0;
116
+ if (obj1.arrayGet(0, &obj2)->isNum()) {
117
+ xMin = obj2.getNum();
118
+ }
119
+ obj2.free();
120
+ if (obj1.arrayGet(1, &obj2)->isNum()) {
121
+ yMin = obj2.getNum();
122
+ }
123
+ obj2.free();
124
+ if (obj1.arrayGet(2, &obj2)->isNum()) {
125
+ xMax = obj2.getNum();
126
+ }
127
+ obj2.free();
128
+ if (obj1.arrayGet(3, &obj2)->isNum()) {
129
+ yMax = obj2.getNum();
130
+ }
131
+ obj2.free();
132
+ if (xMin > xMax) {
133
+ t = xMin; xMin = xMax; xMax = t;
134
+ }
135
+ if (yMin > yMax) {
136
+ t = yMin; yMin = yMax; yMax = t;
137
+ }
138
+ } else {
139
+ error(-1, "Bad bounding box for annotation");
140
+ ok = gFalse;
141
+ }
142
+ obj1.free();
143
+
144
+ //----- parse the flags
145
+
146
+ if (dict->lookup("F", &obj1)->isInt()) {
147
+ flags = obj1.getInt();
148
+ } else {
149
+ flags = 0;
150
+ }
151
+ obj1.free();
152
+
153
+ //----- parse the border style
154
+
155
+ borderType = annotBorderSolid;
156
+ borderWidth = 1;
157
+ borderDash = NULL;
158
+ borderDashLength = 0;
159
+ borderR = 0;
160
+ borderG = 0;
161
+ borderB = 1;
162
+ if (dict->lookup("BS", &obj1)->isDict()) {
163
+ if (obj1.dictLookup("S", &obj2)->isName()) {
164
+ if (obj2.isName("S")) {
165
+ borderType = annotBorderSolid;
166
+ } else if (obj2.isName("D")) {
167
+ borderType = annotBorderDashed;
168
+ } else if (obj2.isName("B")) {
169
+ borderType = annotBorderBeveled;
170
+ } else if (obj2.isName("I")) {
171
+ borderType = annotBorderInset;
172
+ } else if (obj2.isName("U")) {
173
+ borderType = annotBorderUnderlined;
174
+ }
175
+ }
176
+ obj2.free();
177
+ if (obj1.dictLookup("W", &obj2)->isNum()) {
178
+ borderWidth = obj2.getNum();
179
+ }
180
+ obj2.free();
181
+ if (obj1.dictLookup("D", &obj2)->isArray()) {
182
+ borderDashLength = obj2.arrayGetLength();
183
+ borderDash = (double *)gmallocn(borderDashLength, sizeof(double));
184
+ for (i = 0; i < borderDashLength; ++i) {
185
+ if (obj2.arrayGet(i, &obj3)->isNum()) {
186
+ borderDash[i] = obj3.getNum();
187
+ } else {
188
+ borderDash[i] = 1;
189
+ }
190
+ obj3.free();
191
+ }
192
+ }
193
+ obj2.free();
194
+ } else {
195
+ obj1.free();
196
+ if (dict->lookup("Border", &obj1)->isArray()) {
197
+ if (obj1.arrayGetLength() >= 3) {
198
+ if (obj1.arrayGet(2, &obj2)->isNum()) {
199
+ borderWidth = obj2.getNum();
200
+ }
201
+ obj2.free();
202
+ if (obj1.arrayGetLength() >= 4) {
203
+ if (obj1.arrayGet(3, &obj2)->isArray()) {
204
+ borderType = annotBorderDashed;
205
+ borderDashLength = obj2.arrayGetLength();
206
+ borderDash = (double *)gmallocn(borderDashLength, sizeof(double));
207
+ for (i = 0; i < borderDashLength; ++i) {
208
+ if (obj2.arrayGet(i, &obj3)->isNum()) {
209
+ borderDash[i] = obj3.getNum();
210
+ } else {
211
+ borderDash[i] = 1;
212
+ }
213
+ obj3.free();
214
+ }
215
+ } else {
216
+ // Adobe draws no border at all if the last element is of
217
+ // the wrong type.
218
+ borderWidth = 0;
219
+ }
220
+ obj2.free();
221
+ }
222
+ }
223
+ }
224
+ }
225
+ obj1.free();
226
+ if (dict->lookup("C", &obj1)->isArray() && obj1.arrayGetLength() == 3) {
227
+ if (obj1.arrayGet(0, &obj2)->isNum()) {
228
+ borderR = obj2.getNum();
229
+ }
230
+ obj1.free();
231
+ if (obj1.arrayGet(1, &obj2)->isNum()) {
232
+ borderG = obj2.getNum();
233
+ }
234
+ obj1.free();
235
+ if (obj1.arrayGet(2, &obj2)->isNum()) {
236
+ borderB = obj2.getNum();
237
+ }
238
+ obj1.free();
239
+ }
240
+ obj1.free();
241
+ borderStyle = new AnnotBorderStyle(borderType, borderWidth,
242
+ borderDash, borderDashLength,
243
+ borderR, borderG, borderB);
244
+
245
+ //----- get the annotation appearance
246
+
247
+ if (dict->lookup("AP", &apObj)->isDict()) {
248
+ if (dict->lookup("AS", &asObj)->isName()) {
249
+ if (apObj.dictLookup("N", &obj1)->isDict()) {
250
+ if (obj1.dictLookupNF(asObj.getName(), &obj2)->isRef()) {
251
+ obj2.copy(&appearance);
252
+ ok = gTrue;
253
+ } else {
254
+ obj2.free();
255
+ if (obj1.dictLookupNF("Off", &obj2)->isRef()) {
256
+ obj2.copy(&appearance);
257
+ }
258
+ }
259
+ obj2.free();
260
+ }
261
+ obj1.free();
262
+ } else {
263
+ if (apObj.dictLookupNF("N", &obj1)->isRef()) {
264
+ obj1.copy(&appearance);
265
+ }
266
+ obj1.free();
267
+ }
268
+ asObj.free();
269
+ }
270
+ apObj.free();
271
+ }
272
+
273
+ Annot::~Annot() {
274
+ if (type) {
275
+ delete type;
276
+ }
277
+ appearance.free();
278
+ if (appearBuf) {
279
+ delete appearBuf;
280
+ }
281
+ if (borderStyle) {
282
+ delete borderStyle;
283
+ }
284
+ }
285
+
286
+ void Annot::generateFieldAppearance(Dict *field, Dict *annot, Dict *acroForm) {
287
+ Object mkObj, ftObj, appearDict, drObj, obj1, obj2, obj3;
288
+ Dict *mkDict;
289
+ MemStream *appearStream;
290
+ GfxFontDict *fontDict;
291
+ GBool hasCaption;
292
+ double w, dx, dy, r;
293
+ double *dash;
294
+ GString *caption, *da;
295
+ GString **text;
296
+ GBool *selection;
297
+ int dashLength, ff, quadding, comb, nOptions, topIdx, i, j;
298
+
299
+ // must be a Widget annotation
300
+ if (type->cmp("Widget")) {
301
+ return;
302
+ }
303
+
304
+ appearBuf = new GString();
305
+
306
+ // get the appearance characteristics (MK) dictionary
307
+ if (annot->lookup("MK", &mkObj)->isDict()) {
308
+ mkDict = mkObj.getDict();
309
+ } else {
310
+ mkDict = NULL;
311
+ }
312
+
313
+ // draw the background
314
+ if (mkDict) {
315
+ if (mkDict->lookup("BG", &obj1)->isArray() &&
316
+ obj1.arrayGetLength() > 0) {
317
+ setColor(obj1.getArray(), gTrue, 0);
318
+ appearBuf->appendf("0 0 {0:.2f} {1:.2f} re f\n",
319
+ xMax - xMin, yMax - yMin);
320
+ }
321
+ obj1.free();
322
+ }
323
+
324
+ // get the field type
325
+ fieldLookup(field, "FT", &ftObj);
326
+
327
+ // get the field flags (Ff) value
328
+ if (fieldLookup(field, "Ff", &obj1)->isInt()) {
329
+ ff = obj1.getInt();
330
+ } else {
331
+ ff = 0;
332
+ }
333
+ obj1.free();
334
+
335
+ // draw the border
336
+ if (mkDict) {
337
+ w = borderStyle->getWidth();
338
+ if (w > 0) {
339
+ mkDict->lookup("BC", &obj1);
340
+ if (!(obj1.isArray() && obj1.arrayGetLength() > 0)) {
341
+ mkDict->lookup("BG", &obj1);
342
+ }
343
+ if (obj1.isArray() && obj1.arrayGetLength() > 0) {
344
+ dx = xMax - xMin;
345
+ dy = yMax - yMin;
346
+
347
+ // radio buttons with no caption have a round border
348
+ hasCaption = mkDict->lookup("CA", &obj2)->isString();
349
+ obj2.free();
350
+ if (ftObj.isName("Btn") && (ff & fieldFlagRadio) && !hasCaption) {
351
+ r = 0.5 * (dx < dy ? dx : dy);
352
+ switch (borderStyle->getType()) {
353
+ case annotBorderDashed:
354
+ appearBuf->append("[");
355
+ borderStyle->getDash(&dash, &dashLength);
356
+ for (i = 0; i < dashLength; ++i) {
357
+ appearBuf->appendf(" {0:.2f}", dash[i]);
358
+ }
359
+ appearBuf->append("] 0 d\n");
360
+ // fall through to the solid case
361
+ case annotBorderSolid:
362
+ case annotBorderUnderlined:
363
+ appearBuf->appendf("{0:.2f} w\n", w);
364
+ setColor(obj1.getArray(), gFalse, 0);
365
+ drawCircle(0.5 * dx, 0.5 * dy, r - 0.5 * w, gFalse);
366
+ break;
367
+ case annotBorderBeveled:
368
+ case annotBorderInset:
369
+ appearBuf->appendf("{0:.2f} w\n", 0.5 * w);
370
+ setColor(obj1.getArray(), gFalse, 0);
371
+ drawCircle(0.5 * dx, 0.5 * dy, r - 0.25 * w, gFalse);
372
+ setColor(obj1.getArray(), gFalse,
373
+ borderStyle->getType() == annotBorderBeveled ? 1 : -1);
374
+ drawCircleTopLeft(0.5 * dx, 0.5 * dy, r - 0.75 * w);
375
+ setColor(obj1.getArray(), gFalse,
376
+ borderStyle->getType() == annotBorderBeveled ? -1 : 1);
377
+ drawCircleBottomRight(0.5 * dx, 0.5 * dy, r - 0.75 * w);
378
+ break;
379
+ }
380
+
381
+ } else {
382
+ switch (borderStyle->getType()) {
383
+ case annotBorderDashed:
384
+ appearBuf->append("[");
385
+ borderStyle->getDash(&dash, &dashLength);
386
+ for (i = 0; i < dashLength; ++i) {
387
+ appearBuf->appendf(" {0:.2f}", dash[i]);
388
+ }
389
+ appearBuf->append("] 0 d\n");
390
+ // fall through to the solid case
391
+ case annotBorderSolid:
392
+ appearBuf->appendf("{0:.2f} w\n", w);
393
+ setColor(obj1.getArray(), gFalse, 0);
394
+ appearBuf->appendf("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re s\n",
395
+ 0.5 * w, dx - w, dy - w);
396
+ break;
397
+ case annotBorderBeveled:
398
+ case annotBorderInset:
399
+ setColor(obj1.getArray(), gTrue,
400
+ borderStyle->getType() == annotBorderBeveled ? 1 : -1);
401
+ appearBuf->append("0 0 m\n");
402
+ appearBuf->appendf("0 {0:.2f} l\n", dy);
403
+ appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx, dy);
404
+ appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx - w, dy - w);
405
+ appearBuf->appendf("{0:.2f} {1:.2f} l\n", w, dy - w);
406
+ appearBuf->appendf("{0:.2f} {0:.2f} l\n", w);
407
+ appearBuf->append("f\n");
408
+ setColor(obj1.getArray(), gTrue,
409
+ borderStyle->getType() == annotBorderBeveled ? -1 : 1);
410
+ appearBuf->append("0 0 m\n");
411
+ appearBuf->appendf("{0:.2f} 0 l\n", dx);
412
+ appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx, dy);
413
+ appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx - w, dy - w);
414
+ appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx - w, w);
415
+ appearBuf->appendf("{0:.2f} {0:.2f} l\n", w);
416
+ appearBuf->append("f\n");
417
+ break;
418
+ case annotBorderUnderlined:
419
+ appearBuf->appendf("{0:.2f} w\n", w);
420
+ setColor(obj1.getArray(), gFalse, 0);
421
+ appearBuf->appendf("0 0 m {0:.2f} 0 l s\n", dx);
422
+ break;
423
+ }
424
+
425
+ // clip to the inside of the border
426
+ appearBuf->appendf("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re W n\n",
427
+ w, dx - 2 * w, dy - 2 * w);
428
+ }
429
+ }
430
+ obj1.free();
431
+ }
432
+ }
433
+
434
+ // get the resource dictionary
435
+ acroForm->lookup("DR", &drObj);
436
+
437
+ // build the font dictionary
438
+ if (drObj.isDict() && drObj.dictLookup("Font", &obj1)->isDict()) {
439
+ fontDict = new GfxFontDict(xref, NULL, obj1.getDict());
440
+ } else {
441
+ fontDict = NULL;
442
+ }
443
+ obj1.free();
444
+
445
+ // get the default appearance string
446
+ if (fieldLookup(field, "DA", &obj1)->isNull()) {
447
+ obj1.free();
448
+ acroForm->lookup("DA", &obj1);
449
+ }
450
+ if (obj1.isString()) {
451
+ da = obj1.getString()->copy();
452
+ } else {
453
+ da = NULL;
454
+ }
455
+ obj1.free();
456
+
457
+ // draw the field contents
458
+ if (ftObj.isName("Btn")) {
459
+ caption = NULL;
460
+ if (mkDict) {
461
+ if (mkDict->lookup("CA", &obj1)->isString()) {
462
+ caption = obj1.getString()->copy();
463
+ }
464
+ obj1.free();
465
+ }
466
+ // radio button
467
+ if (ff & fieldFlagRadio) {
468
+ //~ Acrobat doesn't draw a caption if there is no AP dict (?)
469
+ if (fieldLookup(field, "V", &obj1)->isName()) {
470
+ if (annot->lookup("AS", &obj2)->isName(obj1.getName())) {
471
+ if (caption) {
472
+ drawText(caption, da, fontDict, gFalse, 0, fieldQuadCenter,
473
+ gFalse, gTrue);
474
+ } else {
475
+ if (mkDict) {
476
+ if (mkDict->lookup("BC", &obj3)->isArray() &&
477
+ obj3.arrayGetLength() > 0) {
478
+ dx = xMax - xMin;
479
+ dy = yMax - yMin;
480
+ setColor(obj3.getArray(), gTrue, 0);
481
+ drawCircle(0.5 * dx, 0.5 * dy, 0.2 * (dx < dy ? dx : dy),
482
+ gTrue);
483
+ }
484
+ obj3.free();
485
+ }
486
+ }
487
+ }
488
+ obj2.free();
489
+ }
490
+ obj1.free();
491
+ // pushbutton
492
+ } else if (ff & fieldFlagPushbutton) {
493
+ if (caption) {
494
+ drawText(caption, da, fontDict, gFalse, 0, fieldQuadCenter,
495
+ gFalse, gFalse);
496
+ }
497
+ // checkbox
498
+ } else {
499
+ // According to the PDF spec the off state must be named "Off",
500
+ // and the on state can be named anything, but Acrobat apparently
501
+ // looks for "Yes" and treats anything else as off.
502
+ if (fieldLookup(field, "V", &obj1)->isName("Yes")) {
503
+ if (!caption) {
504
+ caption = new GString("3"); // ZapfDingbats checkmark
505
+ }
506
+ drawText(caption, da, fontDict, gFalse, 0, fieldQuadCenter,
507
+ gFalse, gTrue);
508
+ }
509
+ obj1.free();
510
+ }
511
+ if (caption) {
512
+ delete caption;
513
+ }
514
+ } else if (ftObj.isName("Tx")) {
515
+ //~ value strings can be Unicode
516
+ if (fieldLookup(field, "V", &obj1)->isString()) {
517
+ if (fieldLookup(field, "Q", &obj2)->isInt()) {
518
+ quadding = obj2.getInt();
519
+ } else {
520
+ quadding = fieldQuadLeft;
521
+ }
522
+ obj2.free();
523
+ comb = 0;
524
+ if (ff & fieldFlagComb) {
525
+ if (fieldLookup(field, "MaxLen", &obj2)->isInt()) {
526
+ comb = obj2.getInt();
527
+ }
528
+ obj2.free();
529
+ }
530
+ drawText(obj1.getString(), da, fontDict,
531
+ ff & fieldFlagMultiline, comb, quadding, gTrue, gFalse);
532
+ }
533
+ obj1.free();
534
+ } else if (ftObj.isName("Ch")) {
535
+ //~ value/option strings can be Unicode
536
+ if (fieldLookup(field, "Q", &obj1)->isInt()) {
537
+ quadding = obj1.getInt();
538
+ } else {
539
+ quadding = fieldQuadLeft;
540
+ }
541
+ obj1.free();
542
+ // combo box
543
+ if (ff & fieldFlagCombo) {
544
+ if (fieldLookup(field, "V", &obj1)->isString()) {
545
+ drawText(obj1.getString(), da, fontDict,
546
+ gFalse, 0, quadding, gTrue, gFalse);
547
+ //~ Acrobat draws a popup icon on the right side
548
+ }
549
+ obj1.free();
550
+ // list box
551
+ } else {
552
+ if (field->lookup("Opt", &obj1)->isArray()) {
553
+ nOptions = obj1.arrayGetLength();
554
+ // get the option text
555
+ text = (GString **)gmallocn(nOptions, sizeof(GString *));
556
+ for (i = 0; i < nOptions; ++i) {
557
+ text[i] = NULL;
558
+ obj1.arrayGet(i, &obj2);
559
+ if (obj2.isString()) {
560
+ text[i] = obj2.getString()->copy();
561
+ } else if (obj2.isArray() && obj2.arrayGetLength() == 2) {
562
+ if (obj2.arrayGet(1, &obj3)->isString()) {
563
+ text[i] = obj3.getString()->copy();
564
+ }
565
+ obj3.free();
566
+ }
567
+ obj2.free();
568
+ if (!text[i]) {
569
+ text[i] = new GString();
570
+ }
571
+ }
572
+ // get the selected option(s)
573
+ selection = (GBool *)gmallocn(nOptions, sizeof(GBool));
574
+ //~ need to use the I field in addition to the V field
575
+ fieldLookup(field, "V", &obj2);
576
+ for (i = 0; i < nOptions; ++i) {
577
+ selection[i] = gFalse;
578
+ if (obj2.isString()) {
579
+ if (!obj2.getString()->cmp(text[i])) {
580
+ selection[i] = gTrue;
581
+ }
582
+ } else if (obj2.isArray()) {
583
+ for (j = 0; j < obj2.arrayGetLength(); ++j) {
584
+ if (obj2.arrayGet(j, &obj3)->isString() &&
585
+ !obj3.getString()->cmp(text[i])) {
586
+ selection[i] = gTrue;
587
+ }
588
+ obj3.free();
589
+ }
590
+ }
591
+ }
592
+ obj2.free();
593
+ // get the top index
594
+ if (field->lookup("TI", &obj2)->isInt()) {
595
+ topIdx = obj2.getInt();
596
+ } else {
597
+ topIdx = 0;
598
+ }
599
+ obj2.free();
600
+ // draw the text
601
+ drawListBox(text, selection, nOptions, topIdx, da, fontDict, quadding);
602
+ for (i = 0; i < nOptions; ++i) {
603
+ delete text[i];
604
+ }
605
+ gfree(text);
606
+ gfree(selection);
607
+ }
608
+ obj1.free();
609
+ }
610
+ } else if (ftObj.isName("Sig")) {
611
+ //~unimp
612
+ } else {
613
+ error(-1, "Unknown field type");
614
+ }
615
+
616
+ if (da) {
617
+ delete da;
618
+ }
619
+
620
+ // build the appearance stream dictionary
621
+ appearDict.initDict(xref);
622
+ appearDict.dictAdd(copyString("Length"),
623
+ obj1.initInt(appearBuf->getLength()));
624
+ appearDict.dictAdd(copyString("Subtype"), obj1.initName("Form"));
625
+ obj1.initArray(xref);
626
+ obj1.arrayAdd(obj2.initReal(0));
627
+ obj1.arrayAdd(obj2.initReal(0));
628
+ obj1.arrayAdd(obj2.initReal(xMax - xMin));
629
+ obj1.arrayAdd(obj2.initReal(yMax - yMin));
630
+ appearDict.dictAdd(copyString("BBox"), &obj1);
631
+
632
+ // set the resource dictionary
633
+ if (drObj.isDict()) {
634
+ appearDict.dictAdd(copyString("Resources"), drObj.copy(&obj1));
635
+ }
636
+ drObj.free();
637
+
638
+ // build the appearance stream
639
+ appearStream = new MemStream(appearBuf->getCString(), 0,
640
+ appearBuf->getLength(), &appearDict);
641
+ appearance.free();
642
+ appearance.initStream(appearStream);
643
+
644
+ if (fontDict) {
645
+ delete fontDict;
646
+ }
647
+ ftObj.free();
648
+ mkObj.free();
649
+ }
650
+
651
+ // Set the current fill or stroke color, based on <a> (which should
652
+ // have 1, 3, or 4 elements). If <adjust> is +1, color is brightened;
653
+ // if <adjust> is -1, color is darkened; otherwise color is not
654
+ // modified.
655
+ void Annot::setColor(Array *a, GBool fill, int adjust) {
656
+ Object obj1;
657
+ double color[4];
658
+ int nComps, i;
659
+
660
+ nComps = a->getLength();
661
+ if (nComps > 4) {
662
+ nComps = 4;
663
+ }
664
+ for (i = 0; i < nComps && i < 4; ++i) {
665
+ if (a->get(i, &obj1)->isNum()) {
666
+ color[i] = obj1.getNum();
667
+ } else {
668
+ color[i] = 0;
669
+ }
670
+ obj1.free();
671
+ }
672
+ if (nComps == 4) {
673
+ adjust = -adjust;
674
+ }
675
+ if (adjust > 0) {
676
+ for (i = 0; i < nComps; ++i) {
677
+ color[i] = 0.5 * color[i] + 0.5;
678
+ }
679
+ } else if (adjust < 0) {
680
+ for (i = 0; i < nComps; ++i) {
681
+ color[i] = 0.5 * color[i];
682
+ }
683
+ }
684
+ if (nComps == 4) {
685
+ appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:c}\n",
686
+ color[0], color[1], color[2], color[3],
687
+ fill ? 'k' : 'K');
688
+ } else if (nComps == 3) {
689
+ appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:s}\n",
690
+ color[0], color[1], color[2],
691
+ fill ? "rg" : "RG");
692
+ } else {
693
+ appearBuf->appendf("{0:.2f} {1:c}\n",
694
+ color[0],
695
+ fill ? 'g' : 'G');
696
+ }
697
+ }
698
+
699
+ // Draw the variable text or caption for a field.
700
+ void Annot::drawText(GString *text, GString *da, GfxFontDict *fontDict,
701
+ GBool multiline, int comb, int quadding,
702
+ GBool txField, GBool forceZapfDingbats) {
703
+ GList *daToks;
704
+ GString *tok;
705
+ GfxFont *font;
706
+ double fontSize, fontSize2, border, x, xPrev, y, w, w2, wMax;
707
+ int tfPos, tmPos, i, j, k, c;
708
+
709
+ //~ if there is no MK entry, this should use the existing content stream,
710
+ //~ and only replace the marked content portion of it
711
+ //~ (this is only relevant for Tx fields)
712
+
713
+ // parse the default appearance string
714
+ tfPos = tmPos = -1;
715
+ if (da) {
716
+ daToks = new GList();
717
+ i = 0;
718
+ while (i < da->getLength()) {
719
+ while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {
720
+ ++i;
721
+ }
722
+ if (i < da->getLength()) {
723
+ for (j = i + 1;
724
+ j < da->getLength() && !Lexer::isSpace(da->getChar(j));
725
+ ++j) ;
726
+ daToks->append(new GString(da, i, j - i));
727
+ i = j;
728
+ }
729
+ }
730
+ for (i = 2; i < daToks->getLength(); ++i) {
731
+ if (i >= 2 && !((GString *)daToks->get(i))->cmp("Tf")) {
732
+ tfPos = i - 2;
733
+ } else if (i >= 6 && !((GString *)daToks->get(i))->cmp("Tm")) {
734
+ tmPos = i - 6;
735
+ }
736
+ }
737
+ } else {
738
+ daToks = NULL;
739
+ }
740
+
741
+ // force ZapfDingbats
742
+ //~ this should create the font if needed (?)
743
+ if (forceZapfDingbats) {
744
+ if (tfPos >= 0) {
745
+ tok = (GString *)daToks->get(tfPos);
746
+ if (tok->cmp("/ZaDb")) {
747
+ tok->clear();
748
+ tok->append("/ZaDb");
749
+ }
750
+ }
751
+ }
752
+
753
+ // get the font and font size
754
+ font = NULL;
755
+ fontSize = 0;
756
+ if (tfPos >= 0) {
757
+ tok = (GString *)daToks->get(tfPos);
758
+ if (tok->getLength() >= 1 && tok->getChar(0) == '/') {
759
+ if (!fontDict || !(font = fontDict->lookup(tok->getCString() + 1))) {
760
+ error(-1, "Unknown font in field's DA string");
761
+ }
762
+ } else {
763
+ error(-1, "Invalid font name in 'Tf' operator in field's DA string");
764
+ }
765
+ tok = (GString *)daToks->get(tfPos + 1);
766
+ fontSize = atof(tok->getCString());
767
+ } else {
768
+ error(-1, "Missing 'Tf' operator in field's DA string");
769
+ }
770
+
771
+ // get the border width
772
+ border = borderStyle->getWidth();
773
+
774
+ // setup
775
+ if (txField) {
776
+ appearBuf->append("/Tx BMC\n");
777
+ }
778
+ appearBuf->append("q\n");
779
+ appearBuf->append("BT\n");
780
+
781
+ // multi-line text
782
+ if (multiline) {
783
+ // note: the comb flag is ignored in multiline mode
784
+
785
+ wMax = xMax - xMin - 2 * border - 4;
786
+
787
+ // compute font autosize
788
+ if (fontSize == 0) {
789
+ for (fontSize = 20; fontSize > 1; --fontSize) {
790
+ y = yMax - yMin;
791
+ w2 = 0;
792
+ i = 0;
793
+ while (i < text->getLength()) {
794
+ getNextLine(text, i, font, fontSize, wMax, &j, &w, &k);
795
+ if (w > w2) {
796
+ w2 = w;
797
+ }
798
+ i = k;
799
+ y -= fontSize;
800
+ }
801
+ // approximate the descender for the last line
802
+ if (y >= 0.33 * fontSize) {
803
+ break;
804
+ }
805
+ }
806
+ if (tfPos >= 0) {
807
+ tok = (GString *)daToks->get(tfPos + 1);
808
+ tok->clear();
809
+ tok->appendf("{0:.2f}", fontSize);
810
+ }
811
+ }
812
+
813
+ // starting y coordinate
814
+ // (note: each line of text starts with a Td operator that moves
815
+ // down a line)
816
+ y = yMax - yMin;
817
+
818
+ // set the font matrix
819
+ if (tmPos >= 0) {
820
+ tok = (GString *)daToks->get(tmPos + 4);
821
+ tok->clear();
822
+ tok->append('0');
823
+ tok = (GString *)daToks->get(tmPos + 5);
824
+ tok->clear();
825
+ tok->appendf("{0:.2f}", y);
826
+ }
827
+
828
+ // write the DA string
829
+ if (daToks) {
830
+ for (i = 0; i < daToks->getLength(); ++i) {
831
+ appearBuf->append((GString *)daToks->get(i))->append(' ');
832
+ }
833
+ }
834
+
835
+ // write the font matrix (if not part of the DA string)
836
+ if (tmPos < 0) {
837
+ appearBuf->appendf("1 0 0 1 0 {0:.2f} Tm\n", y);
838
+ }
839
+
840
+ // write a series of lines of text
841
+ i = 0;
842
+ xPrev = 0;
843
+ while (i < text->getLength()) {
844
+
845
+ getNextLine(text, i, font, fontSize, wMax, &j, &w, &k);
846
+
847
+ // compute text start position
848
+ switch (quadding) {
849
+ case fieldQuadLeft:
850
+ default:
851
+ x = border + 2;
852
+ break;
853
+ case fieldQuadCenter:
854
+ x = (xMax - xMin - w) / 2;
855
+ break;
856
+ case fieldQuadRight:
857
+ x = xMax - xMin - border - 2 - w;
858
+ break;
859
+ }
860
+
861
+ // draw the line
862
+ appearBuf->appendf("{0:.2f} {1:.2f} Td\n", x - xPrev, -fontSize);
863
+ appearBuf->append('(');
864
+ for (; i < j; ++i) {
865
+ c = text->getChar(i) & 0xff;
866
+ if (c == '(' || c == ')' || c == '\\') {
867
+ appearBuf->append('\\');
868
+ appearBuf->append(c);
869
+ } else if (c < 0x20 || c >= 0x80) {
870
+ appearBuf->appendf("\\{0:03o}", c);
871
+ } else {
872
+ appearBuf->append(c);
873
+ }
874
+ }
875
+ appearBuf->append(") Tj\n");
876
+
877
+ // next line
878
+ i = k;
879
+ xPrev = x;
880
+ }
881
+
882
+ // single-line text
883
+ } else {
884
+ //~ replace newlines with spaces? - what does Acrobat do?
885
+
886
+ // comb formatting
887
+ if (comb > 0) {
888
+
889
+ // compute comb spacing
890
+ w = (xMax - xMin - 2 * border) / comb;
891
+
892
+ // compute font autosize
893
+ if (fontSize == 0) {
894
+ fontSize = yMax - yMin - 2 * border;
895
+ if (w < fontSize) {
896
+ fontSize = w;
897
+ }
898
+ fontSize = floor(fontSize);
899
+ if (tfPos >= 0) {
900
+ tok = (GString *)daToks->get(tfPos + 1);
901
+ tok->clear();
902
+ tok->appendf("{0:.2f}", fontSize);
903
+ }
904
+ }
905
+
906
+ // compute text start position
907
+ switch (quadding) {
908
+ case fieldQuadLeft:
909
+ default:
910
+ x = border + 2;
911
+ break;
912
+ case fieldQuadCenter:
913
+ x = border + 2 + 0.5 * (comb - text->getLength()) * w;
914
+ break;
915
+ case fieldQuadRight:
916
+ x = border + 2 + (comb - text->getLength()) * w;
917
+ break;
918
+ }
919
+ y = 0.5 * (yMax - yMin) - 0.4 * fontSize;
920
+
921
+ // set the font matrix
922
+ if (tmPos >= 0) {
923
+ tok = (GString *)daToks->get(tmPos + 4);
924
+ tok->clear();
925
+ tok->appendf("{0:.2f}", x);
926
+ tok = (GString *)daToks->get(tmPos + 5);
927
+ tok->clear();
928
+ tok->appendf("{0:.2f}", y);
929
+ }
930
+
931
+ // write the DA string
932
+ if (daToks) {
933
+ for (i = 0; i < daToks->getLength(); ++i) {
934
+ appearBuf->append((GString *)daToks->get(i))->append(' ');
935
+ }
936
+ }
937
+
938
+ // write the font matrix (if not part of the DA string)
939
+ if (tmPos < 0) {
940
+ appearBuf->appendf("1 0 0 1 {0:.2f} {1:.2f} Tm\n", x, y);
941
+ }
942
+
943
+ // write the text string
944
+ //~ this should center (instead of left-justify) each character within
945
+ //~ its comb cell
946
+ for (i = 0; i < text->getLength(); ++i) {
947
+ if (i > 0) {
948
+ appearBuf->appendf("{0:.2f} 0 Td\n", w);
949
+ }
950
+ appearBuf->append('(');
951
+ c = text->getChar(i) & 0xff;
952
+ if (c == '(' || c == ')' || c == '\\') {
953
+ appearBuf->append('\\');
954
+ appearBuf->append(c);
955
+ } else if (c < 0x20 || c >= 0x80) {
956
+ appearBuf->appendf("{0:.2f} 0 Td\n", w);
957
+ } else {
958
+ appearBuf->append(c);
959
+ }
960
+ appearBuf->append(") Tj\n");
961
+ }
962
+
963
+ // regular (non-comb) formatting
964
+ } else {
965
+
966
+ // compute string width
967
+ if (font && !font->isCIDFont()) {
968
+ w = 0;
969
+ for (i = 0; i < text->getLength(); ++i) {
970
+ w += ((Gfx8BitFont *)font)->getWidth(text->getChar(i));
971
+ }
972
+ } else {
973
+ // otherwise, make a crude estimate
974
+ w = text->getLength() * 0.5;
975
+ }
976
+
977
+ // compute font autosize
978
+ if (fontSize == 0) {
979
+ fontSize = yMax - yMin - 2 * border;
980
+ fontSize2 = (xMax - xMin - 4 - 2 * border) / w;
981
+ if (fontSize2 < fontSize) {
982
+ fontSize = fontSize2;
983
+ }
984
+ fontSize = floor(fontSize);
985
+ if (tfPos >= 0) {
986
+ tok = (GString *)daToks->get(tfPos + 1);
987
+ tok->clear();
988
+ tok->appendf("{0:.2f}", fontSize);
989
+ }
990
+ }
991
+
992
+ // compute text start position
993
+ w *= fontSize;
994
+ switch (quadding) {
995
+ case fieldQuadLeft:
996
+ default:
997
+ x = border + 2;
998
+ break;
999
+ case fieldQuadCenter:
1000
+ x = (xMax - xMin - w) / 2;
1001
+ break;
1002
+ case fieldQuadRight:
1003
+ x = xMax - xMin - border - 2 - w;
1004
+ break;
1005
+ }
1006
+ y = 0.5 * (yMax - yMin) - 0.4 * fontSize;
1007
+
1008
+ // set the font matrix
1009
+ if (tmPos >= 0) {
1010
+ tok = (GString *)daToks->get(tmPos + 4);
1011
+ tok->clear();
1012
+ tok->appendf("{0:.2f}", x);
1013
+ tok = (GString *)daToks->get(tmPos + 5);
1014
+ tok->clear();
1015
+ tok->appendf("{0:.2f}", y);
1016
+ }
1017
+
1018
+ // write the DA string
1019
+ if (daToks) {
1020
+ for (i = 0; i < daToks->getLength(); ++i) {
1021
+ appearBuf->append((GString *)daToks->get(i))->append(' ');
1022
+ }
1023
+ }
1024
+
1025
+ // write the font matrix (if not part of the DA string)
1026
+ if (tmPos < 0) {
1027
+ appearBuf->appendf("1 0 0 1 {0:.2f} {1:.2f} Tm\n", x, y);
1028
+ }
1029
+
1030
+ // write the text string
1031
+ appearBuf->append('(');
1032
+ for (i = 0; i < text->getLength(); ++i) {
1033
+ c = text->getChar(i) & 0xff;
1034
+ if (c == '(' || c == ')' || c == '\\') {
1035
+ appearBuf->append('\\');
1036
+ appearBuf->append(c);
1037
+ } else if (c < 0x20 || c >= 0x80) {
1038
+ appearBuf->appendf("\\{0:03o}", c);
1039
+ } else {
1040
+ appearBuf->append(c);
1041
+ }
1042
+ }
1043
+ appearBuf->append(") Tj\n");
1044
+ }
1045
+ }
1046
+
1047
+ // cleanup
1048
+ appearBuf->append("ET\n");
1049
+ appearBuf->append("Q\n");
1050
+ if (txField) {
1051
+ appearBuf->append("EMC\n");
1052
+ }
1053
+
1054
+ if (daToks) {
1055
+ deleteGList(daToks, GString);
1056
+ }
1057
+ }
1058
+
1059
+ // Draw the variable text or caption for a field.
1060
+ void Annot::drawListBox(GString **text, GBool *selection,
1061
+ int nOptions, int topIdx,
1062
+ GString *da, GfxFontDict *fontDict, GBool quadding) {
1063
+ GList *daToks;
1064
+ GString *tok;
1065
+ GfxFont *font;
1066
+ double fontSize, fontSize2, border, x, y, w, wMax;
1067
+ int tfPos, tmPos, i, j, c;
1068
+
1069
+ //~ if there is no MK entry, this should use the existing content stream,
1070
+ //~ and only replace the marked content portion of it
1071
+ //~ (this is only relevant for Tx fields)
1072
+
1073
+ // parse the default appearance string
1074
+ tfPos = tmPos = -1;
1075
+ if (da) {
1076
+ daToks = new GList();
1077
+ i = 0;
1078
+ while (i < da->getLength()) {
1079
+ while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {
1080
+ ++i;
1081
+ }
1082
+ if (i < da->getLength()) {
1083
+ for (j = i + 1;
1084
+ j < da->getLength() && !Lexer::isSpace(da->getChar(j));
1085
+ ++j) ;
1086
+ daToks->append(new GString(da, i, j - i));
1087
+ i = j;
1088
+ }
1089
+ }
1090
+ for (i = 2; i < daToks->getLength(); ++i) {
1091
+ if (i >= 2 && !((GString *)daToks->get(i))->cmp("Tf")) {
1092
+ tfPos = i - 2;
1093
+ } else if (i >= 6 && !((GString *)daToks->get(i))->cmp("Tm")) {
1094
+ tmPos = i - 6;
1095
+ }
1096
+ }
1097
+ } else {
1098
+ daToks = NULL;
1099
+ }
1100
+
1101
+ // get the font and font size
1102
+ font = NULL;
1103
+ fontSize = 0;
1104
+ if (tfPos >= 0) {
1105
+ tok = (GString *)daToks->get(tfPos);
1106
+ if (tok->getLength() >= 1 && tok->getChar(0) == '/') {
1107
+ if (!fontDict || !(font = fontDict->lookup(tok->getCString() + 1))) {
1108
+ error(-1, "Unknown font in field's DA string");
1109
+ }
1110
+ } else {
1111
+ error(-1, "Invalid font name in 'Tf' operator in field's DA string");
1112
+ }
1113
+ tok = (GString *)daToks->get(tfPos + 1);
1114
+ fontSize = atof(tok->getCString());
1115
+ } else {
1116
+ error(-1, "Missing 'Tf' operator in field's DA string");
1117
+ }
1118
+
1119
+ // get the border width
1120
+ border = borderStyle->getWidth();
1121
+
1122
+ // compute font autosize
1123
+ if (fontSize == 0) {
1124
+ wMax = 0;
1125
+ for (i = 0; i < nOptions; ++i) {
1126
+ if (font && !font->isCIDFont()) {
1127
+ w = 0;
1128
+ for (j = 0; j < text[i]->getLength(); ++j) {
1129
+ w += ((Gfx8BitFont *)font)->getWidth(text[i]->getChar(j));
1130
+ }
1131
+ } else {
1132
+ // otherwise, make a crude estimate
1133
+ w = text[i]->getLength() * 0.5;
1134
+ }
1135
+ if (w > wMax) {
1136
+ wMax = w;
1137
+ }
1138
+ }
1139
+ fontSize = yMax - yMin - 2 * border;
1140
+ fontSize2 = (xMax - xMin - 4 - 2 * border) / wMax;
1141
+ if (fontSize2 < fontSize) {
1142
+ fontSize = fontSize2;
1143
+ }
1144
+ fontSize = floor(fontSize);
1145
+ if (tfPos >= 0) {
1146
+ tok = (GString *)daToks->get(tfPos + 1);
1147
+ tok->clear();
1148
+ tok->appendf("{0:.2f}", fontSize);
1149
+ }
1150
+ }
1151
+
1152
+ // draw the text
1153
+ y = yMax - yMin - 1.1 * fontSize;
1154
+ for (i = topIdx; i < nOptions; ++i) {
1155
+
1156
+ // setup
1157
+ appearBuf->append("q\n");
1158
+
1159
+ // draw the background if selected
1160
+ if (selection[i]) {
1161
+ appearBuf->append("0 g f\n");
1162
+ appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} re f\n",
1163
+ border,
1164
+ y - 0.2 * fontSize,
1165
+ xMax - xMin - 2 * border,
1166
+ 1.1 * fontSize);
1167
+ }
1168
+
1169
+ // setup
1170
+ appearBuf->append("BT\n");
1171
+
1172
+ // compute string width
1173
+ if (font && !font->isCIDFont()) {
1174
+ w = 0;
1175
+ for (j = 0; j < text[i]->getLength(); ++j) {
1176
+ w += ((Gfx8BitFont *)font)->getWidth(text[i]->getChar(j));
1177
+ }
1178
+ } else {
1179
+ // otherwise, make a crude estimate
1180
+ w = text[i]->getLength() * 0.5;
1181
+ }
1182
+
1183
+ // compute text start position
1184
+ w *= fontSize;
1185
+ switch (quadding) {
1186
+ case fieldQuadLeft:
1187
+ default:
1188
+ x = border + 2;
1189
+ break;
1190
+ case fieldQuadCenter:
1191
+ x = (xMax - xMin - w) / 2;
1192
+ break;
1193
+ case fieldQuadRight:
1194
+ x = xMax - xMin - border - 2 - w;
1195
+ break;
1196
+ }
1197
+
1198
+ // set the font matrix
1199
+ if (tmPos >= 0) {
1200
+ tok = (GString *)daToks->get(tmPos + 4);
1201
+ tok->clear();
1202
+ tok->appendf("{0:.2f}", x);
1203
+ tok = (GString *)daToks->get(tmPos + 5);
1204
+ tok->clear();
1205
+ tok->appendf("{0:.2f}", y);
1206
+ }
1207
+
1208
+ // write the DA string
1209
+ if (daToks) {
1210
+ for (j = 0; j < daToks->getLength(); ++j) {
1211
+ appearBuf->append((GString *)daToks->get(j))->append(' ');
1212
+ }
1213
+ }
1214
+
1215
+ // write the font matrix (if not part of the DA string)
1216
+ if (tmPos < 0) {
1217
+ appearBuf->appendf("1 0 0 1 {0:.2f} {1:.2f} Tm\n", x, y);
1218
+ }
1219
+
1220
+ // change the text color if selected
1221
+ if (selection[i]) {
1222
+ appearBuf->append("1 g\n");
1223
+ }
1224
+
1225
+ // write the text string
1226
+ appearBuf->append('(');
1227
+ for (j = 0; j < text[i]->getLength(); ++j) {
1228
+ c = text[i]->getChar(j) & 0xff;
1229
+ if (c == '(' || c == ')' || c == '\\') {
1230
+ appearBuf->append('\\');
1231
+ appearBuf->append(c);
1232
+ } else if (c < 0x20 || c >= 0x80) {
1233
+ appearBuf->appendf("\\{0:03o}", c);
1234
+ } else {
1235
+ appearBuf->append(c);
1236
+ }
1237
+ }
1238
+ appearBuf->append(") Tj\n");
1239
+
1240
+ // cleanup
1241
+ appearBuf->append("ET\n");
1242
+ appearBuf->append("Q\n");
1243
+
1244
+ // next line
1245
+ y -= 1.1 * fontSize;
1246
+ }
1247
+
1248
+ if (daToks) {
1249
+ deleteGList(daToks, GString);
1250
+ }
1251
+ }
1252
+
1253
+ // Figure out how much text will fit on the next line. Returns:
1254
+ // *end = one past the last character to be included
1255
+ // *width = width of the characters start .. end-1
1256
+ // *next = index of first character on the following line
1257
+ void Annot::getNextLine(GString *text, int start,
1258
+ GfxFont *font, double fontSize, double wMax,
1259
+ int *end, double *width, int *next) {
1260
+ double w, dw;
1261
+ int j, k, c;
1262
+
1263
+ // figure out how much text will fit on the line
1264
+ //~ what does Adobe do with tabs?
1265
+ w = 0;
1266
+ for (j = start; j < text->getLength() && w <= wMax; ++j) {
1267
+ c = text->getChar(j) & 0xff;
1268
+ if (c == 0x0a || c == 0x0d) {
1269
+ break;
1270
+ }
1271
+ if (font && !font->isCIDFont()) {
1272
+ dw = ((Gfx8BitFont *)font)->getWidth(c) * fontSize;
1273
+ } else {
1274
+ // otherwise, make a crude estimate
1275
+ dw = 0.5 * fontSize;
1276
+ }
1277
+ w += dw;
1278
+ }
1279
+ if (w > wMax) {
1280
+ for (k = j; k > start && text->getChar(k-1) != ' '; --k) ;
1281
+ for (; k > start && text->getChar(k-1) == ' '; --k) ;
1282
+ if (k > start) {
1283
+ j = k;
1284
+ }
1285
+ if (j == start) {
1286
+ // handle the pathological case where the first character is
1287
+ // too wide to fit on the line all by itself
1288
+ j = start + 1;
1289
+ }
1290
+ }
1291
+ *end = j;
1292
+
1293
+ // compute the width
1294
+ w = 0;
1295
+ for (k = start; k < j; ++k) {
1296
+ if (font && !font->isCIDFont()) {
1297
+ dw = ((Gfx8BitFont *)font)->getWidth(text->getChar(k)) * fontSize;
1298
+ } else {
1299
+ // otherwise, make a crude estimate
1300
+ dw = 0.5 * fontSize;
1301
+ }
1302
+ w += dw;
1303
+ }
1304
+ *width = w;
1305
+
1306
+ // next line
1307
+ while (j < text->getLength() && text->getChar(j) == ' ') {
1308
+ ++j;
1309
+ }
1310
+ if (j < text->getLength() && text->getChar(j) == 0x0d) {
1311
+ ++j;
1312
+ }
1313
+ if (j < text->getLength() && text->getChar(j) == 0x0a) {
1314
+ ++j;
1315
+ }
1316
+ *next = j;
1317
+ }
1318
+
1319
+ // Draw an (approximate) circle of radius <r> centered at (<cx>, <cy>).
1320
+ // If <fill> is true, the circle is filled; otherwise it is stroked.
1321
+ void Annot::drawCircle(double cx, double cy, double r, GBool fill) {
1322
+ appearBuf->appendf("{0:.2f} {1:.2f} m\n",
1323
+ cx + r, cy);
1324
+ appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
1325
+ cx + r, cy + bezierCircle * r,
1326
+ cx + bezierCircle * r, cy + r,
1327
+ cx, cy + r);
1328
+ appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
1329
+ cx - bezierCircle * r, cy + r,
1330
+ cx - r, cy + bezierCircle * r,
1331
+ cx - r, cy);
1332
+ appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
1333
+ cx - r, cy - bezierCircle * r,
1334
+ cx - bezierCircle * r, cy - r,
1335
+ cx, cy - r);
1336
+ appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
1337
+ cx + bezierCircle * r, cy - r,
1338
+ cx + r, cy - bezierCircle * r,
1339
+ cx + r, cy);
1340
+ appearBuf->append(fill ? "f\n" : "s\n");
1341
+ }
1342
+
1343
+ // Draw the top-left half of an (approximate) circle of radius <r>
1344
+ // centered at (<cx>, <cy>).
1345
+ void Annot::drawCircleTopLeft(double cx, double cy, double r) {
1346
+ double r2;
1347
+
1348
+ r2 = r / sqrt(2.0);
1349
+ appearBuf->appendf("{0:.2f} {1:.2f} m\n",
1350
+ cx + r2, cy + r2);
1351
+ appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
1352
+ cx + (1 - bezierCircle) * r2,
1353
+ cy + (1 + bezierCircle) * r2,
1354
+ cx - (1 - bezierCircle) * r2,
1355
+ cy + (1 + bezierCircle) * r2,
1356
+ cx - r2,
1357
+ cy + r2);
1358
+ appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
1359
+ cx - (1 + bezierCircle) * r2,
1360
+ cy + (1 - bezierCircle) * r2,
1361
+ cx - (1 + bezierCircle) * r2,
1362
+ cy - (1 - bezierCircle) * r2,
1363
+ cx - r2,
1364
+ cy - r2);
1365
+ appearBuf->append("S\n");
1366
+ }
1367
+
1368
+ // Draw the bottom-right half of an (approximate) circle of radius <r>
1369
+ // centered at (<cx>, <cy>).
1370
+ void Annot::drawCircleBottomRight(double cx, double cy, double r) {
1371
+ double r2;
1372
+
1373
+ r2 = r / sqrt(2.0);
1374
+ appearBuf->appendf("{0:.2f} {1:.2f} m\n",
1375
+ cx - r2, cy - r2);
1376
+ appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
1377
+ cx - (1 - bezierCircle) * r2,
1378
+ cy - (1 + bezierCircle) * r2,
1379
+ cx + (1 - bezierCircle) * r2,
1380
+ cy - (1 + bezierCircle) * r2,
1381
+ cx + r2,
1382
+ cy - r2);
1383
+ appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
1384
+ cx + (1 + bezierCircle) * r2,
1385
+ cy - (1 - bezierCircle) * r2,
1386
+ cx + (1 + bezierCircle) * r2,
1387
+ cy + (1 - bezierCircle) * r2,
1388
+ cx + r2,
1389
+ cy + r2);
1390
+ appearBuf->append("S\n");
1391
+ }
1392
+
1393
+ // Look up an inheritable field dictionary entry.
1394
+ Object *Annot::fieldLookup(Dict *field, char *key, Object *obj) {
1395
+ Dict *dict;
1396
+ Object parent;
1397
+
1398
+ dict = field;
1399
+ if (!dict->lookup(key, obj)->isNull()) {
1400
+ return obj;
1401
+ }
1402
+ obj->free();
1403
+ if (dict->lookup("Parent", &parent)->isDict()) {
1404
+ fieldLookup(parent.getDict(), key, obj);
1405
+ } else {
1406
+ obj->initNull();
1407
+ }
1408
+ parent.free();
1409
+ return obj;
1410
+ }
1411
+
1412
+ void Annot::draw(Gfx *gfx, GBool printing) {
1413
+ Object obj;
1414
+ GBool isLink;
1415
+
1416
+ // check the flags
1417
+ if ((flags & annotFlagHidden) ||
1418
+ (printing && !(flags & annotFlagPrint)) ||
1419
+ (!printing && (flags & annotFlagNoView))) {
1420
+ return;
1421
+ }
1422
+
1423
+ // draw the appearance stream
1424
+ isLink = type && !type->cmp("Link");
1425
+ appearance.fetch(xref, &obj);
1426
+ gfx->drawAnnot(&obj, isLink ? borderStyle : (AnnotBorderStyle *)NULL,
1427
+ xMin, yMin, xMax, yMax);
1428
+ obj.free();
1429
+ }
1430
+
1431
+ //------------------------------------------------------------------------
1432
+ // Annots
1433
+ //------------------------------------------------------------------------
1434
+
1435
+ Annots::Annots(XRef *xref, Catalog *catalog, Object *annotsObj) {
1436
+ Dict *acroForm;
1437
+ Annot *annot;
1438
+ Object obj1;
1439
+ Ref ref;
1440
+ int size;
1441
+ int i;
1442
+
1443
+ annots = NULL;
1444
+ size = 0;
1445
+ nAnnots = 0;
1446
+
1447
+ acroForm = catalog->getAcroForm()->isDict() ?
1448
+ catalog->getAcroForm()->getDict() : NULL;
1449
+ if (annotsObj->isArray()) {
1450
+ for (i = 0; i < annotsObj->arrayGetLength(); ++i) {
1451
+ if (annotsObj->arrayGetNF(i, &obj1)->isRef()) {
1452
+ ref = obj1.getRef();
1453
+ obj1.free();
1454
+ annotsObj->arrayGet(i, &obj1);
1455
+ } else {
1456
+ ref.num = ref.gen = -1;
1457
+ }
1458
+ if (obj1.isDict()) {
1459
+ annot = new Annot(xref, acroForm, obj1.getDict(), &ref);
1460
+ if (annot->isOk()) {
1461
+ if (nAnnots >= size) {
1462
+ size += 16;
1463
+ annots = (Annot **)greallocn(annots, size, sizeof(Annot *));
1464
+ }
1465
+ annots[nAnnots++] = annot;
1466
+ } else {
1467
+ delete annot;
1468
+ }
1469
+ }
1470
+ obj1.free();
1471
+ }
1472
+ }
1473
+ }
1474
+
1475
+ Annots::~Annots() {
1476
+ int i;
1477
+
1478
+ for (i = 0; i < nAnnots; ++i) {
1479
+ delete annots[i];
1480
+ }
1481
+ gfree(annots);
1482
+ }
1483
+
1484
+ void Annots::generateAppearances(Dict *acroForm) {
1485
+ Object obj1, obj2;
1486
+ Ref ref;
1487
+ int i;
1488
+
1489
+ if (acroForm->lookup("Fields", &obj1)->isArray()) {
1490
+ for (i = 0; i < obj1.arrayGetLength(); ++i) {
1491
+ if (obj1.arrayGetNF(i, &obj2)->isRef()) {
1492
+ ref = obj2.getRef();
1493
+ obj2.free();
1494
+ obj1.arrayGet(i, &obj2);
1495
+ } else {
1496
+ ref.num = ref.gen = -1;
1497
+ }
1498
+ if (obj2.isDict()) {
1499
+ scanFieldAppearances(obj2.getDict(), &ref, NULL, acroForm);
1500
+ }
1501
+ obj2.free();
1502
+ }
1503
+ }
1504
+ obj1.free();
1505
+ }
1506
+
1507
+ void Annots::scanFieldAppearances(Dict *node, Ref *ref, Dict *parent,
1508
+ Dict *acroForm) {
1509
+ Annot *annot;
1510
+ Object obj1, obj2;
1511
+ Ref ref2;
1512
+ int i;
1513
+
1514
+ // non-terminal node: scan the children
1515
+ if (node->lookup("Kids", &obj1)->isArray()) {
1516
+ for (i = 0; i < obj1.arrayGetLength(); ++i) {
1517
+ if (obj1.arrayGetNF(i, &obj2)->isRef()) {
1518
+ ref2 = obj2.getRef();
1519
+ obj2.free();
1520
+ obj1.arrayGet(i, &obj2);
1521
+ } else {
1522
+ ref2.num = ref2.gen = -1;
1523
+ }
1524
+ if (obj2.isDict()) {
1525
+ scanFieldAppearances(obj2.getDict(), &ref2, node, acroForm);
1526
+ }
1527
+ obj2.free();
1528
+ }
1529
+ obj1.free();
1530
+ return;
1531
+ }
1532
+ obj1.free();
1533
+
1534
+ // terminal node: this is either a combined annot/field dict, or an
1535
+ // annot dict whose parent is a field
1536
+ if ((annot = findAnnot(ref))) {
1537
+ node->lookupNF("Parent", &obj1);
1538
+ if (!parent || !obj1.isNull()) {
1539
+ annot->generateFieldAppearance(node, node, acroForm);
1540
+ } else {
1541
+ annot->generateFieldAppearance(parent, node, acroForm);
1542
+ }
1543
+ obj1.free();
1544
+ }
1545
+ }
1546
+
1547
+ Annot *Annots::findAnnot(Ref *ref) {
1548
+ int i;
1549
+
1550
+ for (i = 0; i < nAnnots; ++i) {
1551
+ if (annots[i]->match(ref)) {
1552
+ return annots[i];
1553
+ }
1554
+ }
1555
+ return NULL;
1556
+ }