pdf2json 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. data/README.markdown +9 -0
  2. data/bin/.gitkeep +0 -0
  3. data/ext/extconf.rb +30 -0
  4. data/lib/pdf2json.rb +8 -0
  5. data/pdf2json-0.52-source/AUTHORS +24 -0
  6. data/pdf2json-0.52-source/CHANGES +11 -0
  7. data/pdf2json-0.52-source/Makefile +84 -0
  8. data/pdf2json-0.52-source/Makefile.in +84 -0
  9. data/pdf2json-0.52-source/aclocal.m4 +274 -0
  10. data/pdf2json-0.52-source/aconf-win32.h +86 -0
  11. data/pdf2json-0.52-source/aconf.h +42 -0
  12. data/pdf2json-0.52-source/aconf.h.in +41 -0
  13. data/pdf2json-0.52-source/autom4te.cache/output.0 +6908 -0
  14. data/pdf2json-0.52-source/autom4te.cache/requests +76 -0
  15. data/pdf2json-0.52-source/autom4te.cache/traces.0 +466 -0
  16. data/pdf2json-0.52-source/config.log +1259 -0
  17. data/pdf2json-0.52-source/config.status +1050 -0
  18. data/pdf2json-0.52-source/configure +6908 -0
  19. data/pdf2json-0.52-source/configure.ac +93 -0
  20. data/pdf2json-0.52-source/doc/pdffonts.1 +130 -0
  21. data/pdf2json-0.52-source/doc/pdffonts.cat +107 -0
  22. data/pdf2json-0.52-source/doc/pdffonts.hlp +117 -0
  23. data/pdf2json-0.52-source/doc/pdfimages.1 +102 -0
  24. data/pdf2json-0.52-source/doc/pdfimages.cat +92 -0
  25. data/pdf2json-0.52-source/doc/pdfimages.hlp +101 -0
  26. data/pdf2json-0.52-source/doc/pdfinfo.1 +158 -0
  27. data/pdf2json-0.52-source/doc/pdfinfo.cat +119 -0
  28. data/pdf2json-0.52-source/doc/pdfinfo.hlp +129 -0
  29. data/pdf2json-0.52-source/doc/pdftoppm.1 +115 -0
  30. data/pdf2json-0.52-source/doc/pdftoppm.cat +105 -0
  31. data/pdf2json-0.52-source/doc/pdftoppm.hlp +114 -0
  32. data/pdf2json-0.52-source/doc/pdftops.1 +229 -0
  33. data/pdf2json-0.52-source/doc/pdftops.cat +221 -0
  34. data/pdf2json-0.52-source/doc/pdftops.hlp +231 -0
  35. data/pdf2json-0.52-source/doc/pdftotext.1 +137 -0
  36. data/pdf2json-0.52-source/doc/pdftotext.cat +120 -0
  37. data/pdf2json-0.52-source/doc/pdftotext.hlp +133 -0
  38. data/pdf2json-0.52-source/doc/sample-xpdfrc +91 -0
  39. data/pdf2json-0.52-source/doc/xpdf.1 +513 -0
  40. data/pdf2json-0.52-source/doc/xpdf.cat +476 -0
  41. data/pdf2json-0.52-source/doc/xpdf.hlp +489 -0
  42. data/pdf2json-0.52-source/doc/xpdfrc.5 +480 -0
  43. data/pdf2json-0.52-source/doc/xpdfrc.cat +474 -0
  44. data/pdf2json-0.52-source/doc/xpdfrc.hlp +479 -0
  45. data/pdf2json-0.52-source/fofi/.DS_Store +0 -0
  46. data/pdf2json-0.52-source/fofi/FoFiBase.cc +156 -0
  47. data/pdf2json-0.52-source/fofi/FoFiBase.h +57 -0
  48. data/pdf2json-0.52-source/fofi/FoFiBase.o +0 -0
  49. data/pdf2json-0.52-source/fofi/FoFiEncodings.cc +994 -0
  50. data/pdf2json-0.52-source/fofi/FoFiEncodings.h +36 -0
  51. data/pdf2json-0.52-source/fofi/FoFiEncodings.o +0 -0
  52. data/pdf2json-0.52-source/fofi/FoFiTrueType.cc +2027 -0
  53. data/pdf2json-0.52-source/fofi/FoFiTrueType.h +174 -0
  54. data/pdf2json-0.52-source/fofi/FoFiTrueType.o +0 -0
  55. data/pdf2json-0.52-source/fofi/FoFiType1.cc +252 -0
  56. data/pdf2json-0.52-source/fofi/FoFiType1.h +59 -0
  57. data/pdf2json-0.52-source/fofi/FoFiType1.o +0 -0
  58. data/pdf2json-0.52-source/fofi/FoFiType1C.cc +2603 -0
  59. data/pdf2json-0.52-source/fofi/FoFiType1C.h +233 -0
  60. data/pdf2json-0.52-source/fofi/FoFiType1C.o +0 -0
  61. data/pdf2json-0.52-source/fofi/Makefile +70 -0
  62. data/pdf2json-0.52-source/fofi/Makefile.dep +0 -0
  63. data/pdf2json-0.52-source/fofi/Makefile.in +70 -0
  64. data/pdf2json-0.52-source/fofi/libfofi.a +0 -0
  65. data/pdf2json-0.52-source/fofi/vms_make.com +0 -0
  66. data/pdf2json-0.52-source/freetype.win32/.DS_Store +0 -0
  67. data/pdf2json-0.52-source/freetype.win32/include/.DS_Store +0 -0
  68. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftconfig.h +528 -0
  69. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftheader.h +780 -0
  70. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftmodule.h +32 -0
  71. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftoption.h +733 -0
  72. data/pdf2json-0.52-source/freetype.win32/include/freetype/config/ftstdlib.h +173 -0
  73. data/pdf2json-0.52-source/freetype.win32/include/freetype/freetype.h +3919 -0
  74. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftadvanc.h +179 -0
  75. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbbox.h +94 -0
  76. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbdf.h +209 -0
  77. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftbitmap.h +227 -0
  78. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcache.h +1128 -0
  79. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftchapters.h +103 -0
  80. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftcid.h +166 -0
  81. data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrdef.h +244 -0
  82. data/pdf2json-0.52-source/freetype.win32/include/freetype/fterrors.h +206 -0
  83. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgasp.h +120 -0
  84. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftglyph.h +613 -0
  85. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgxval.h +358 -0
  86. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftgzip.h +102 -0
  87. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftimage.h +1313 -0
  88. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftincrem.h +353 -0
  89. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlcdfil.h +213 -0
  90. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlist.h +277 -0
  91. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftlzw.h +99 -0
  92. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmac.h +274 -0
  93. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmm.h +378 -0
  94. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmodapi.h +483 -0
  95. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftmoderr.h +155 -0
  96. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftotval.h +203 -0
  97. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftoutln.h +537 -0
  98. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftpfr.h +172 -0
  99. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftrender.h +230 -0
  100. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsizes.h +159 -0
  101. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsnames.h +200 -0
  102. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftstroke.h +716 -0
  103. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsynth.h +80 -0
  104. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftsystem.h +347 -0
  105. data/pdf2json-0.52-source/freetype.win32/include/freetype/fttrigon.h +350 -0
  106. data/pdf2json-0.52-source/freetype.win32/include/freetype/fttypes.h +588 -0
  107. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftwinfnt.h +274 -0
  108. data/pdf2json-0.52-source/freetype.win32/include/freetype/ftxf86.h +83 -0
  109. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/autohint.h +231 -0
  110. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftcalc.h +179 -0
  111. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdebug.h +250 -0
  112. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftdriver.h +422 -0
  113. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftgloadr.h +168 -0
  114. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftmemory.h +380 -0
  115. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftobjs.h +1428 -0
  116. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftpic.h +67 -0
  117. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftrfork.h +196 -0
  118. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftserv.h +620 -0
  119. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftstream.h +539 -0
  120. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/fttrace.h +139 -0
  121. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/ftvalid.h +150 -0
  122. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/internal.h +51 -0
  123. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pcftypes.h +56 -0
  124. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/psaux.h +873 -0
  125. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/pshints.h +712 -0
  126. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svbdf.h +77 -0
  127. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svcid.h +83 -0
  128. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgldict.h +82 -0
  129. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svgxval.h +72 -0
  130. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svkern.h +51 -0
  131. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svmm.h +104 -0
  132. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svotval.h +55 -0
  133. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpfr.h +66 -0
  134. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpostnm.h +79 -0
  135. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpscmap.h +164 -0
  136. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svpsinfo.h +92 -0
  137. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svsfnt.h +102 -0
  138. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttcmap.h +106 -0
  139. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svtteng.h +53 -0
  140. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svttglyf.h +67 -0
  141. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svwinfnt.h +50 -0
  142. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/services/svxf86nm.h +55 -0
  143. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/sfnt.h +897 -0
  144. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/t1types.h +270 -0
  145. data/pdf2json-0.52-source/freetype.win32/include/freetype/internal/tttypes.h +1543 -0
  146. data/pdf2json-0.52-source/freetype.win32/include/freetype/t1tables.h +504 -0
  147. data/pdf2json-0.52-source/freetype.win32/include/freetype/ttnameid.h +1247 -0
  148. data/pdf2json-0.52-source/freetype.win32/include/freetype/tttables.h +759 -0
  149. data/pdf2json-0.52-source/freetype.win32/include/freetype/tttags.h +107 -0
  150. data/pdf2json-0.52-source/freetype.win32/include/freetype/ttunpat.h +59 -0
  151. data/pdf2json-0.52-source/freetype.win32/include/ft2build.h +39 -0
  152. data/pdf2json-0.52-source/freetype.win32/lib/freetype_a.lib +0 -0
  153. data/pdf2json-0.52-source/goo/.DS_Store +0 -0
  154. data/pdf2json-0.52-source/goo/FixedPoint.cc +118 -0
  155. data/pdf2json-0.52-source/goo/FixedPoint.h +155 -0
  156. data/pdf2json-0.52-source/goo/FixedPoint.o +0 -0
  157. data/pdf2json-0.52-source/goo/GHash.cc +380 -0
  158. data/pdf2json-0.52-source/goo/GHash.h +78 -0
  159. data/pdf2json-0.52-source/goo/GHash.o +0 -0
  160. data/pdf2json-0.52-source/goo/GList.cc +97 -0
  161. data/pdf2json-0.52-source/goo/GList.h +96 -0
  162. data/pdf2json-0.52-source/goo/GList.o +0 -0
  163. data/pdf2json-0.52-source/goo/GMutex.h +49 -0
  164. data/pdf2json-0.52-source/goo/GString.cc +724 -0
  165. data/pdf2json-0.52-source/goo/GString.cc.fixed +718 -0
  166. data/pdf2json-0.52-source/goo/GString.h +136 -0
  167. data/pdf2json-0.52-source/goo/GString.o +0 -0
  168. data/pdf2json-0.52-source/goo/ImgWriter.o +0 -0
  169. data/pdf2json-0.52-source/goo/JpegWriter.o +0 -0
  170. data/pdf2json-0.52-source/goo/Makefile +72 -0
  171. data/pdf2json-0.52-source/goo/Makefile.dep +0 -0
  172. data/pdf2json-0.52-source/goo/Makefile.in +72 -0
  173. data/pdf2json-0.52-source/goo/PNGWriter.o +0 -0
  174. data/pdf2json-0.52-source/goo/gfile.cc +731 -0
  175. data/pdf2json-0.52-source/goo/gfile.h +138 -0
  176. data/pdf2json-0.52-source/goo/gfile.o +0 -0
  177. data/pdf2json-0.52-source/goo/gmem.cc +264 -0
  178. data/pdf2json-0.52-source/goo/gmem.h +79 -0
  179. data/pdf2json-0.52-source/goo/gmem.o +0 -0
  180. data/pdf2json-0.52-source/goo/gmempp.cc +32 -0
  181. data/pdf2json-0.52-source/goo/gmempp.o +0 -0
  182. data/pdf2json-0.52-source/goo/gtypes.h +29 -0
  183. data/pdf2json-0.52-source/goo/libGoo.a +0 -0
  184. data/pdf2json-0.52-source/goo/parseargs.c +190 -0
  185. data/pdf2json-0.52-source/goo/parseargs.h +71 -0
  186. data/pdf2json-0.52-source/goo/parseargs.o +0 -0
  187. data/pdf2json-0.52-source/goo/vms_directory.c +214 -0
  188. data/pdf2json-0.52-source/goo/vms_dirent.h +67 -0
  189. data/pdf2json-0.52-source/goo/vms_make.com +82 -0
  190. data/pdf2json-0.52-source/goo/vms_sys_dirent.h +54 -0
  191. data/pdf2json-0.52-source/goo/vms_unix_time.h +102 -0
  192. data/pdf2json-0.52-source/goo/vms_unix_times.c +42 -0
  193. data/pdf2json-0.52-source/goo/vms_unlink.c +22 -0
  194. data/pdf2json-0.52-source/ms_make.bat +199 -0
  195. data/pdf2json-0.52-source/splash/.DS_Store +0 -0
  196. data/pdf2json-0.52-source/splash/Makefile +103 -0
  197. data/pdf2json-0.52-source/splash/Makefile.dep +0 -0
  198. data/pdf2json-0.52-source/splash/Makefile.in +103 -0
  199. data/pdf2json-0.52-source/splash/Splash.cc +3310 -0
  200. data/pdf2json-0.52-source/splash/Splash.h +293 -0
  201. data/pdf2json-0.52-source/splash/Splash.o +0 -0
  202. data/pdf2json-0.52-source/splash/SplashBitmap.cc +188 -0
  203. data/pdf2json-0.52-source/splash/SplashBitmap.h +64 -0
  204. data/pdf2json-0.52-source/splash/SplashBitmap.o +0 -0
  205. data/pdf2json-0.52-source/splash/SplashClip.cc +382 -0
  206. data/pdf2json-0.52-source/splash/SplashClip.h +107 -0
  207. data/pdf2json-0.52-source/splash/SplashClip.o +0 -0
  208. data/pdf2json-0.52-source/splash/SplashErrorCodes.h +32 -0
  209. data/pdf2json-0.52-source/splash/SplashFTFont.cc +357 -0
  210. data/pdf2json-0.52-source/splash/SplashFTFont.h +58 -0
  211. data/pdf2json-0.52-source/splash/SplashFTFont.o +0 -0
  212. data/pdf2json-0.52-source/splash/SplashFTFontEngine.cc +179 -0
  213. data/pdf2json-0.52-source/splash/SplashFTFontEngine.h +65 -0
  214. data/pdf2json-0.52-source/splash/SplashFTFontEngine.o +0 -0
  215. data/pdf2json-0.52-source/splash/SplashFTFontFile.cc +114 -0
  216. data/pdf2json-0.52-source/splash/SplashFTFontFile.h +73 -0
  217. data/pdf2json-0.52-source/splash/SplashFTFontFile.o +0 -0
  218. data/pdf2json-0.52-source/splash/SplashFont.cc +176 -0
  219. data/pdf2json-0.52-source/splash/SplashFont.h +104 -0
  220. data/pdf2json-0.52-source/splash/SplashFont.o +0 -0
  221. data/pdf2json-0.52-source/splash/SplashFontEngine.cc +317 -0
  222. data/pdf2json-0.52-source/splash/SplashFontEngine.h +91 -0
  223. data/pdf2json-0.52-source/splash/SplashFontEngine.o +0 -0
  224. data/pdf2json-0.52-source/splash/SplashFontFile.cc +55 -0
  225. data/pdf2json-0.52-source/splash/SplashFontFile.h +60 -0
  226. data/pdf2json-0.52-source/splash/SplashFontFile.o +0 -0
  227. data/pdf2json-0.52-source/splash/SplashFontFileID.cc +23 -0
  228. data/pdf2json-0.52-source/splash/SplashFontFileID.h +30 -0
  229. data/pdf2json-0.52-source/splash/SplashFontFileID.o +0 -0
  230. data/pdf2json-0.52-source/splash/SplashGlyphBitmap.h +26 -0
  231. data/pdf2json-0.52-source/splash/SplashMath.h +89 -0
  232. data/pdf2json-0.52-source/splash/SplashPath.cc +184 -0
  233. data/pdf2json-0.52-source/splash/SplashPath.h +121 -0
  234. data/pdf2json-0.52-source/splash/SplashPath.o +0 -0
  235. data/pdf2json-0.52-source/splash/SplashPattern.cc +40 -0
  236. data/pdf2json-0.52-source/splash/SplashPattern.h +65 -0
  237. data/pdf2json-0.52-source/splash/SplashPattern.o +0 -0
  238. data/pdf2json-0.52-source/splash/SplashScreen.cc +383 -0
  239. data/pdf2json-0.52-source/splash/SplashScreen.h +56 -0
  240. data/pdf2json-0.52-source/splash/SplashScreen.o +0 -0
  241. data/pdf2json-0.52-source/splash/SplashState.cc +165 -0
  242. data/pdf2json-0.52-source/splash/SplashState.h +103 -0
  243. data/pdf2json-0.52-source/splash/SplashState.o +0 -0
  244. data/pdf2json-0.52-source/splash/SplashT1Font.cc +287 -0
  245. data/pdf2json-0.52-source/splash/SplashT1Font.h +57 -0
  246. data/pdf2json-0.52-source/splash/SplashT1Font.o +0 -0
  247. data/pdf2json-0.52-source/splash/SplashT1FontEngine.cc +124 -0
  248. data/pdf2json-0.52-source/splash/SplashT1FontEngine.h +53 -0
  249. data/pdf2json-0.52-source/splash/SplashT1FontEngine.o +0 -0
  250. data/pdf2json-0.52-source/splash/SplashT1FontFile.cc +97 -0
  251. data/pdf2json-0.52-source/splash/SplashT1FontFile.h +58 -0
  252. data/pdf2json-0.52-source/splash/SplashT1FontFile.o +0 -0
  253. data/pdf2json-0.52-source/splash/SplashTypes.h +132 -0
  254. data/pdf2json-0.52-source/splash/SplashXPath.cc +438 -0
  255. data/pdf2json-0.52-source/splash/SplashXPath.h +100 -0
  256. data/pdf2json-0.52-source/splash/SplashXPath.o +0 -0
  257. data/pdf2json-0.52-source/splash/SplashXPathScanner.cc +428 -0
  258. data/pdf2json-0.52-source/splash/SplashXPathScanner.h +87 -0
  259. data/pdf2json-0.52-source/splash/SplashXPathScanner.o +0 -0
  260. data/pdf2json-0.52-source/splash/libsplash.a +0 -0
  261. data/pdf2json-0.52-source/splash/vms_make.com +0 -0
  262. data/pdf2json-0.52-source/src/.DS_Store +0 -0
  263. data/pdf2json-0.52-source/src/GVector.h +101 -0
  264. data/pdf2json-0.52-source/src/ImgOutputDev.cc +1243 -0
  265. data/pdf2json-0.52-source/src/ImgOutputDev.h +307 -0
  266. data/pdf2json-0.52-source/src/ImgOutputDev.o +0 -0
  267. data/pdf2json-0.52-source/src/Makefile +68 -0
  268. data/pdf2json-0.52-source/src/Makefile.in +68 -0
  269. data/pdf2json-0.52-source/src/XmlFonts.cc +367 -0
  270. data/pdf2json-0.52-source/src/XmlFonts.h +91 -0
  271. data/pdf2json-0.52-source/src/XmlFonts.o +0 -0
  272. data/pdf2json-0.52-source/src/XmlLinks.cc +101 -0
  273. data/pdf2json-0.52-source/src/XmlLinks.h +54 -0
  274. data/pdf2json-0.52-source/src/XmlLinks.o +0 -0
  275. data/pdf2json-0.52-source/src/pdf2json +0 -0
  276. data/pdf2json-0.52-source/src/pdf2json.cc +343 -0
  277. data/pdf2json-0.52-source/src/pdf2json.o +0 -0
  278. data/pdf2json-0.52-source/src/pdf2xml.dtd +22 -0
  279. data/pdf2json-0.52-source/src/pdf2xmljson.dtd +9 -0
  280. data/pdf2json-0.52-source/xpdf/.DS_Store +0 -0
  281. data/pdf2json-0.52-source/xpdf/Annot.cc +1556 -0
  282. data/pdf2json-0.52-source/xpdf/Annot.h +142 -0
  283. data/pdf2json-0.52-source/xpdf/Annot.o +0 -0
  284. data/pdf2json-0.52-source/xpdf/Array.cc +73 -0
  285. data/pdf2json-0.52-source/xpdf/Array.h +58 -0
  286. data/pdf2json-0.52-source/xpdf/Array.o +0 -0
  287. data/pdf2json-0.52-source/xpdf/BuiltinFont.cc +65 -0
  288. data/pdf2json-0.52-source/xpdf/BuiltinFont.h +57 -0
  289. data/pdf2json-0.52-source/xpdf/BuiltinFont.o +0 -0
  290. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.cc +4284 -0
  291. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.h +23 -0
  292. data/pdf2json-0.52-source/xpdf/BuiltinFontTables.o +0 -0
  293. data/pdf2json-0.52-source/xpdf/CMap.cc +408 -0
  294. data/pdf2json-0.52-source/xpdf/CMap.h +102 -0
  295. data/pdf2json-0.52-source/xpdf/CMap.o +0 -0
  296. data/pdf2json-0.52-source/xpdf/Catalog.cc +374 -0
  297. data/pdf2json-0.52-source/xpdf/Catalog.h +97 -0
  298. data/pdf2json-0.52-source/xpdf/Catalog.o +0 -0
  299. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.cc +540 -0
  300. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.h +117 -0
  301. data/pdf2json-0.52-source/xpdf/CharCodeToUnicode.o +0 -0
  302. data/pdf2json-0.52-source/xpdf/CharTypes.h +24 -0
  303. data/pdf2json-0.52-source/xpdf/CompactFontTables.h +464 -0
  304. data/pdf2json-0.52-source/xpdf/CoreOutputDev.cc +61 -0
  305. data/pdf2json-0.52-source/xpdf/CoreOutputDev.h +61 -0
  306. data/pdf2json-0.52-source/xpdf/Decrypt.cc +776 -0
  307. data/pdf2json-0.52-source/xpdf/Decrypt.h +95 -0
  308. data/pdf2json-0.52-source/xpdf/Decrypt.o +0 -0
  309. data/pdf2json-0.52-source/xpdf/Dict.cc +95 -0
  310. data/pdf2json-0.52-source/xpdf/Dict.h +77 -0
  311. data/pdf2json-0.52-source/xpdf/Dict.o +0 -0
  312. data/pdf2json-0.52-source/xpdf/Error.cc +38 -0
  313. data/pdf2json-0.52-source/xpdf/Error.h +23 -0
  314. data/pdf2json-0.52-source/xpdf/Error.o +0 -0
  315. data/pdf2json-0.52-source/xpdf/ErrorCodes.h +36 -0
  316. data/pdf2json-0.52-source/xpdf/FontEncodingTables.cc +1824 -0
  317. data/pdf2json-0.52-source/xpdf/FontEncodingTables.h +20 -0
  318. data/pdf2json-0.52-source/xpdf/FontEncodingTables.o +0 -0
  319. data/pdf2json-0.52-source/xpdf/Function.cc +1573 -0
  320. data/pdf2json-0.52-source/xpdf/Function.h +229 -0
  321. data/pdf2json-0.52-source/xpdf/Function.o +0 -0
  322. data/pdf2json-0.52-source/xpdf/Gfx.cc +4187 -0
  323. data/pdf2json-0.52-source/xpdf/Gfx.h +312 -0
  324. data/pdf2json-0.52-source/xpdf/Gfx.o +0 -0
  325. data/pdf2json-0.52-source/xpdf/GfxFont.cc +1568 -0
  326. data/pdf2json-0.52-source/xpdf/GfxFont.h +320 -0
  327. data/pdf2json-0.52-source/xpdf/GfxFont.o +0 -0
  328. data/pdf2json-0.52-source/xpdf/GfxState.cc +4137 -0
  329. data/pdf2json-0.52-source/xpdf/GfxState.h +1244 -0
  330. data/pdf2json-0.52-source/xpdf/GfxState.o +0 -0
  331. data/pdf2json-0.52-source/xpdf/GlobalParams.cc +2924 -0
  332. data/pdf2json-0.52-source/xpdf/GlobalParams.cc.old +2908 -0
  333. data/pdf2json-0.52-source/xpdf/GlobalParams.h +466 -0
  334. data/pdf2json-0.52-source/xpdf/GlobalParams.h.old +463 -0
  335. data/pdf2json-0.52-source/xpdf/GlobalParams.o +0 -0
  336. data/pdf2json-0.52-source/xpdf/ImageOutputDev.cc +195 -0
  337. data/pdf2json-0.52-source/xpdf/ImageOutputDev.h +76 -0
  338. data/pdf2json-0.52-source/xpdf/ImageOutputDev.o +0 -0
  339. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.cc +322 -0
  340. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.h +109 -0
  341. data/pdf2json-0.52-source/xpdf/JArithmeticDecoder.o +0 -0
  342. data/pdf2json-0.52-source/xpdf/JBIG2Stream.cc +3413 -0
  343. data/pdf2json-0.52-source/xpdf/JBIG2Stream.h +145 -0
  344. data/pdf2json-0.52-source/xpdf/JBIG2Stream.o +0 -0
  345. data/pdf2json-0.52-source/xpdf/JPXStream.cc +3144 -0
  346. data/pdf2json-0.52-source/xpdf/JPXStream.h +351 -0
  347. data/pdf2json-0.52-source/xpdf/JPXStream.o +0 -0
  348. data/pdf2json-0.52-source/xpdf/Lexer.cc +485 -0
  349. data/pdf2json-0.52-source/xpdf/Lexer.h +80 -0
  350. data/pdf2json-0.52-source/xpdf/Lexer.o +0 -0
  351. data/pdf2json-0.52-source/xpdf/Link.cc +806 -0
  352. data/pdf2json-0.52-source/xpdf/Link.cc.old +784 -0
  353. data/pdf2json-0.52-source/xpdf/Link.h +415 -0
  354. data/pdf2json-0.52-source/xpdf/Link.h.old +369 -0
  355. data/pdf2json-0.52-source/xpdf/Link.o +0 -0
  356. data/pdf2json-0.52-source/xpdf/Makefile +232 -0
  357. data/pdf2json-0.52-source/xpdf/Makefile.dep +0 -0
  358. data/pdf2json-0.52-source/xpdf/Makefile.in +232 -0
  359. data/pdf2json-0.52-source/xpdf/NameToCharCode.cc +116 -0
  360. data/pdf2json-0.52-source/xpdf/NameToCharCode.h +42 -0
  361. data/pdf2json-0.52-source/xpdf/NameToCharCode.o +0 -0
  362. data/pdf2json-0.52-source/xpdf/NameToUnicodeTable.h +1097 -0
  363. data/pdf2json-0.52-source/xpdf/Object.cc +231 -0
  364. data/pdf2json-0.52-source/xpdf/Object.h +303 -0
  365. data/pdf2json-0.52-source/xpdf/Object.o +0 -0
  366. data/pdf2json-0.52-source/xpdf/Outline.cc +151 -0
  367. data/pdf2json-0.52-source/xpdf/Outline.h +76 -0
  368. data/pdf2json-0.52-source/xpdf/Outline.o +0 -0
  369. data/pdf2json-0.52-source/xpdf/OutputDev.cc +131 -0
  370. data/pdf2json-0.52-source/xpdf/OutputDev.h +253 -0
  371. data/pdf2json-0.52-source/xpdf/OutputDev.o +0 -0
  372. data/pdf2json-0.52-source/xpdf/PDFCore.cc +2044 -0
  373. data/pdf2json-0.52-source/xpdf/PDFCore.h +321 -0
  374. data/pdf2json-0.52-source/xpdf/PDFDoc.cc +404 -0
  375. data/pdf2json-0.52-source/xpdf/PDFDoc.h +183 -0
  376. data/pdf2json-0.52-source/xpdf/PDFDoc.o +0 -0
  377. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.cc +44 -0
  378. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.h +16 -0
  379. data/pdf2json-0.52-source/xpdf/PDFDocEncoding.o +0 -0
  380. data/pdf2json-0.52-source/xpdf/PSOutputDev.cc +6224 -0
  381. data/pdf2json-0.52-source/xpdf/PSOutputDev.h +395 -0
  382. data/pdf2json-0.52-source/xpdf/PSOutputDev.o +0 -0
  383. data/pdf2json-0.52-source/xpdf/PSTokenizer.cc +135 -0
  384. data/pdf2json-0.52-source/xpdf/PSTokenizer.h +41 -0
  385. data/pdf2json-0.52-source/xpdf/PSTokenizer.o +0 -0
  386. data/pdf2json-0.52-source/xpdf/Page.cc +454 -0
  387. data/pdf2json-0.52-source/xpdf/Page.h +187 -0
  388. data/pdf2json-0.52-source/xpdf/Page.o +0 -0
  389. data/pdf2json-0.52-source/xpdf/Parser.cc +227 -0
  390. data/pdf2json-0.52-source/xpdf/Parser.h +59 -0
  391. data/pdf2json-0.52-source/xpdf/Parser.o +0 -0
  392. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.cc +257 -0
  393. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.h +130 -0
  394. data/pdf2json-0.52-source/xpdf/PreScanOutputDev.o +0 -0
  395. data/pdf2json-0.52-source/xpdf/SecurityHandler.cc +390 -0
  396. data/pdf2json-0.52-source/xpdf/SecurityHandler.h +160 -0
  397. data/pdf2json-0.52-source/xpdf/SecurityHandler.o +0 -0
  398. data/pdf2json-0.52-source/xpdf/SplashOutputDev.cc +2845 -0
  399. data/pdf2json-0.52-source/xpdf/SplashOutputDev.h +247 -0
  400. data/pdf2json-0.52-source/xpdf/SplashOutputDev.o +0 -0
  401. data/pdf2json-0.52-source/xpdf/Stream-CCITT.h +459 -0
  402. data/pdf2json-0.52-source/xpdf/Stream.cc +4627 -0
  403. data/pdf2json-0.52-source/xpdf/Stream.h +858 -0
  404. data/pdf2json-0.52-source/xpdf/Stream.o +0 -0
  405. data/pdf2json-0.52-source/xpdf/TextOutputDev.cc +4090 -0
  406. data/pdf2json-0.52-source/xpdf/TextOutputDev.h +661 -0
  407. data/pdf2json-0.52-source/xpdf/TextOutputDev.o +0 -0
  408. data/pdf2json-0.52-source/xpdf/UTF8.h +56 -0
  409. data/pdf2json-0.52-source/xpdf/UnicodeMap.cc +302 -0
  410. data/pdf2json-0.52-source/xpdf/UnicodeMap.cc.old +293 -0
  411. data/pdf2json-0.52-source/xpdf/UnicodeMap.h +135 -0
  412. data/pdf2json-0.52-source/xpdf/UnicodeMap.h.old +123 -0
  413. data/pdf2json-0.52-source/xpdf/UnicodeMap.o +0 -0
  414. data/pdf2json-0.52-source/xpdf/UnicodeMapTables.h +361 -0
  415. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.cc +949 -0
  416. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.h +20 -0
  417. data/pdf2json-0.52-source/xpdf/UnicodeTypeTable.o +0 -0
  418. data/pdf2json-0.52-source/xpdf/XPDFApp.cc +447 -0
  419. data/pdf2json-0.52-source/xpdf/XPDFApp.h +114 -0
  420. data/pdf2json-0.52-source/xpdf/XPDFCore.cc +1655 -0
  421. data/pdf2json-0.52-source/xpdf/XPDFCore.h +251 -0
  422. data/pdf2json-0.52-source/xpdf/XPDFTree.cc +931 -0
  423. data/pdf2json-0.52-source/xpdf/XPDFTree.h +45 -0
  424. data/pdf2json-0.52-source/xpdf/XPDFTreeP.h +87 -0
  425. data/pdf2json-0.52-source/xpdf/XPDFViewer.cc +3488 -0
  426. data/pdf2json-0.52-source/xpdf/XPDFViewer.h +352 -0
  427. data/pdf2json-0.52-source/xpdf/XRef.cc +896 -0
  428. data/pdf2json-0.52-source/xpdf/XRef.h +133 -0
  429. data/pdf2json-0.52-source/xpdf/XRef.o +0 -0
  430. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.cc +262 -0
  431. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.h +341 -0
  432. data/pdf2json-0.52-source/xpdf/XpdfPluginAPI.o +0 -0
  433. data/pdf2json-0.52-source/xpdf/about-text.h +48 -0
  434. data/pdf2json-0.52-source/xpdf/about.xbm +6 -0
  435. data/pdf2json-0.52-source/xpdf/backArrow.xbm +6 -0
  436. data/pdf2json-0.52-source/xpdf/backArrowDis.xbm +6 -0
  437. data/pdf2json-0.52-source/xpdf/config.h +112 -0
  438. data/pdf2json-0.52-source/xpdf/dblLeftArrow.xbm +6 -0
  439. data/pdf2json-0.52-source/xpdf/dblLeftArrowDis.xbm +6 -0
  440. data/pdf2json-0.52-source/xpdf/dblRightArrow.xbm +6 -0
  441. data/pdf2json-0.52-source/xpdf/dblRightArrowDis.xbm +6 -0
  442. data/pdf2json-0.52-source/xpdf/find.xbm +6 -0
  443. data/pdf2json-0.52-source/xpdf/findDis.xbm +6 -0
  444. data/pdf2json-0.52-source/xpdf/forwardArrow.xbm +6 -0
  445. data/pdf2json-0.52-source/xpdf/forwardArrowDis.xbm +6 -0
  446. data/pdf2json-0.52-source/xpdf/leftArrow.xbm +5 -0
  447. data/pdf2json-0.52-source/xpdf/leftArrowDis.xbm +5 -0
  448. data/pdf2json-0.52-source/xpdf/libXpdf.a +0 -0
  449. data/pdf2json-0.52-source/xpdf/pdffonts +0 -0
  450. data/pdf2json-0.52-source/xpdf/pdffonts.cc +298 -0
  451. data/pdf2json-0.52-source/xpdf/pdffonts.o +0 -0
  452. data/pdf2json-0.52-source/xpdf/pdfimages +0 -0
  453. data/pdf2json-0.52-source/xpdf/pdfimages.cc +155 -0
  454. data/pdf2json-0.52-source/xpdf/pdfimages.o +0 -0
  455. data/pdf2json-0.52-source/xpdf/pdfinfo +0 -0
  456. data/pdf2json-0.52-source/xpdf/pdfinfo.cc +387 -0
  457. data/pdf2json-0.52-source/xpdf/pdfinfo.o +0 -0
  458. data/pdf2json-0.52-source/xpdf/pdftoppm.cc +203 -0
  459. data/pdf2json-0.52-source/xpdf/pdftops +0 -0
  460. data/pdf2json-0.52-source/xpdf/pdftops.cc +344 -0
  461. data/pdf2json-0.52-source/xpdf/pdftops.o +0 -0
  462. data/pdf2json-0.52-source/xpdf/pdftotext +0 -0
  463. data/pdf2json-0.52-source/xpdf/pdftotext.cc +333 -0
  464. data/pdf2json-0.52-source/xpdf/pdftotext.o +0 -0
  465. data/pdf2json-0.52-source/xpdf/print.xbm +6 -0
  466. data/pdf2json-0.52-source/xpdf/printDis.xbm +6 -0
  467. data/pdf2json-0.52-source/xpdf/rightArrow.xbm +5 -0
  468. data/pdf2json-0.52-source/xpdf/rightArrowDis.xbm +5 -0
  469. data/pdf2json-0.52-source/xpdf/vms_make.com +129 -0
  470. data/pdf2json-0.52-source/xpdf/xpdf.cc +344 -0
  471. data/pdf2json-0.52-source/xpdf/xpdfIcon.xpm +62 -0
  472. data/pdf2json.gemspec +29 -0
  473. metadata +518 -0
@@ -0,0 +1,36 @@
1
+ //========================================================================
2
+ //
3
+ // FoFiEncodings.h
4
+ //
5
+ // Copyright 1999-2003 Glyph & Cog, LLC
6
+ //
7
+ //========================================================================
8
+
9
+ #ifndef FOFIENCODINGS_H
10
+ #define FOFIENCODINGS_H
11
+
12
+ #include <aconf.h>
13
+
14
+ #ifdef USE_GCC_PRAGMAS
15
+ #pragma interface
16
+ #endif
17
+
18
+ #include "gtypes.h"
19
+
20
+ //------------------------------------------------------------------------
21
+ // Type 1 and 1C font data
22
+ //------------------------------------------------------------------------
23
+
24
+ extern char *fofiType1StandardEncoding[256];
25
+ extern char *fofiType1ExpertEncoding[256];
26
+
27
+ //------------------------------------------------------------------------
28
+ // Type 1C font data
29
+ //------------------------------------------------------------------------
30
+
31
+ extern char *fofiType1CStdStrings[391];
32
+ extern Gushort fofiType1CISOAdobeCharset[229];
33
+ extern Gushort fofiType1CExpertCharset[166];
34
+ extern Gushort fofiType1CExpertSubsetCharset[87];
35
+
36
+ #endif
@@ -0,0 +1,2027 @@
1
+ //========================================================================
2
+ //
3
+ // FoFiTrueType.cc
4
+ //
5
+ // Copyright 1999-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 <string.h>
17
+ #include "gtypes.h"
18
+ #include "gmem.h"
19
+ #include "GString.h"
20
+ #include "GHash.h"
21
+ #include "FoFiType1C.h"
22
+ #include "FoFiTrueType.h"
23
+
24
+ //
25
+ // Terminology
26
+ // -----------
27
+ //
28
+ // character code = number used as an element of a text string
29
+ //
30
+ // character name = glyph name = name for a particular glyph within a
31
+ // font
32
+ //
33
+ // glyph index = GID = position (within some internal table in the font)
34
+ // where the instructions to draw a particular glyph are
35
+ // stored
36
+ //
37
+ // Type 1 fonts
38
+ // ------------
39
+ //
40
+ // Type 1 fonts contain:
41
+ //
42
+ // Encoding: array of glyph names, maps char codes to glyph names
43
+ //
44
+ // Encoding[charCode] = charName
45
+ //
46
+ // CharStrings: dictionary of instructions, keyed by character names,
47
+ // maps character name to glyph data
48
+ //
49
+ // CharStrings[charName] = glyphData
50
+ //
51
+ // TrueType fonts
52
+ // --------------
53
+ //
54
+ // TrueType fonts contain:
55
+ //
56
+ // 'cmap' table: mapping from character code to glyph index; there may
57
+ // be multiple cmaps in a TrueType font
58
+ //
59
+ // cmap[charCode] = gid
60
+ //
61
+ // 'post' table: mapping from glyph index to glyph name
62
+ //
63
+ // post[gid] = glyphName
64
+ //
65
+ // Type 42 fonts
66
+ // -------------
67
+ //
68
+ // Type 42 fonts contain:
69
+ //
70
+ // Encoding: array of glyph names, maps char codes to glyph names
71
+ //
72
+ // Encoding[charCode] = charName
73
+ //
74
+ // CharStrings: dictionary of glyph indexes, keyed by character names,
75
+ // maps character name to glyph index
76
+ //
77
+ // CharStrings[charName] = gid
78
+ //
79
+
80
+ //------------------------------------------------------------------------
81
+
82
+ #define ttcfTag 0x74746366
83
+
84
+ //------------------------------------------------------------------------
85
+
86
+ struct TrueTypeTable {
87
+ Guint tag;
88
+ Guint checksum;
89
+ int offset;
90
+ int origOffset;
91
+ int len;
92
+ };
93
+
94
+ struct TrueTypeCmap {
95
+ int platform;
96
+ int encoding;
97
+ int offset;
98
+ int len;
99
+ int fmt;
100
+ };
101
+
102
+ struct TrueTypeLoca {
103
+ int idx;
104
+ int origOffset;
105
+ int newOffset;
106
+ int len;
107
+ };
108
+
109
+ #define cmapTag 0x636d6170
110
+ #define glyfTag 0x676c7966
111
+ #define headTag 0x68656164
112
+ #define hheaTag 0x68686561
113
+ #define hmtxTag 0x686d7478
114
+ #define locaTag 0x6c6f6361
115
+ #define nameTag 0x6e616d65
116
+ #define os2Tag 0x4f532f32
117
+ #define postTag 0x706f7374
118
+
119
+ static int cmpTrueTypeLocaOffset(const void *p1, const void *p2) {
120
+ TrueTypeLoca *loca1 = (TrueTypeLoca *)p1;
121
+ TrueTypeLoca *loca2 = (TrueTypeLoca *)p2;
122
+
123
+ if (loca1->origOffset == loca2->origOffset) {
124
+ return loca1->idx - loca2->idx;
125
+ }
126
+ return loca1->origOffset - loca2->origOffset;
127
+ }
128
+
129
+ static int cmpTrueTypeLocaIdx(const void *p1, const void *p2) {
130
+ TrueTypeLoca *loca1 = (TrueTypeLoca *)p1;
131
+ TrueTypeLoca *loca2 = (TrueTypeLoca *)p2;
132
+
133
+ return loca1->idx - loca2->idx;
134
+ }
135
+
136
+ static int cmpTrueTypeTableTag(const void *p1, const void *p2) {
137
+ TrueTypeTable *tab1 = (TrueTypeTable *)p1;
138
+ TrueTypeTable *tab2 = (TrueTypeTable *)p2;
139
+
140
+ return (int)tab1->tag - (int)tab2->tag;
141
+ }
142
+
143
+ //------------------------------------------------------------------------
144
+
145
+ struct T42Table {
146
+ char *tag; // 4-byte tag
147
+ GBool required; // required by the TrueType spec?
148
+ };
149
+
150
+ // TrueType tables to be embedded in Type 42 fonts.
151
+ // NB: the table names must be in alphabetical order here.
152
+ #define nT42Tables 11
153
+ static T42Table t42Tables[nT42Tables] = {
154
+ { "cvt ", gTrue },
155
+ { "fpgm", gTrue },
156
+ { "glyf", gTrue },
157
+ { "head", gTrue },
158
+ { "hhea", gTrue },
159
+ { "hmtx", gTrue },
160
+ { "loca", gTrue },
161
+ { "maxp", gTrue },
162
+ { "prep", gTrue },
163
+ { "vhea", gFalse },
164
+ { "vmtx", gFalse }
165
+ };
166
+ #define t42HeadTable 3
167
+ #define t42LocaTable 6
168
+ #define t42GlyfTable 2
169
+ #define t42VheaTable 9
170
+ #define t42VmtxTable 10
171
+
172
+ //------------------------------------------------------------------------
173
+
174
+ // Glyph names in some arbitrary standard order that Apple uses for
175
+ // their TrueType fonts.
176
+ static char *macGlyphNames[258] = {
177
+ ".notdef", "null", "CR", "space",
178
+ "exclam", "quotedbl", "numbersign", "dollar",
179
+ "percent", "ampersand", "quotesingle", "parenleft",
180
+ "parenright", "asterisk", "plus", "comma",
181
+ "hyphen", "period", "slash", "zero",
182
+ "one", "two", "three", "four",
183
+ "five", "six", "seven", "eight",
184
+ "nine", "colon", "semicolon", "less",
185
+ "equal", "greater", "question", "at",
186
+ "A", "B", "C", "D",
187
+ "E", "F", "G", "H",
188
+ "I", "J", "K", "L",
189
+ "M", "N", "O", "P",
190
+ "Q", "R", "S", "T",
191
+ "U", "V", "W", "X",
192
+ "Y", "Z", "bracketleft", "backslash",
193
+ "bracketright", "asciicircum", "underscore", "grave",
194
+ "a", "b", "c", "d",
195
+ "e", "f", "g", "h",
196
+ "i", "j", "k", "l",
197
+ "m", "n", "o", "p",
198
+ "q", "r", "s", "t",
199
+ "u", "v", "w", "x",
200
+ "y", "z", "braceleft", "bar",
201
+ "braceright", "asciitilde", "Adieresis", "Aring",
202
+ "Ccedilla", "Eacute", "Ntilde", "Odieresis",
203
+ "Udieresis", "aacute", "agrave", "acircumflex",
204
+ "adieresis", "atilde", "aring", "ccedilla",
205
+ "eacute", "egrave", "ecircumflex", "edieresis",
206
+ "iacute", "igrave", "icircumflex", "idieresis",
207
+ "ntilde", "oacute", "ograve", "ocircumflex",
208
+ "odieresis", "otilde", "uacute", "ugrave",
209
+ "ucircumflex", "udieresis", "dagger", "degree",
210
+ "cent", "sterling", "section", "bullet",
211
+ "paragraph", "germandbls", "registered", "copyright",
212
+ "trademark", "acute", "dieresis", "notequal",
213
+ "AE", "Oslash", "infinity", "plusminus",
214
+ "lessequal", "greaterequal", "yen", "mu1",
215
+ "partialdiff", "summation", "product", "pi",
216
+ "integral", "ordfeminine", "ordmasculine", "Ohm",
217
+ "ae", "oslash", "questiondown", "exclamdown",
218
+ "logicalnot", "radical", "florin", "approxequal",
219
+ "increment", "guillemotleft", "guillemotright", "ellipsis",
220
+ "nbspace", "Agrave", "Atilde", "Otilde",
221
+ "OE", "oe", "endash", "emdash",
222
+ "quotedblleft", "quotedblright", "quoteleft", "quoteright",
223
+ "divide", "lozenge", "ydieresis", "Ydieresis",
224
+ "fraction", "currency", "guilsinglleft", "guilsinglright",
225
+ "fi", "fl", "daggerdbl", "periodcentered",
226
+ "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex",
227
+ "Ecircumflex", "Aacute", "Edieresis", "Egrave",
228
+ "Iacute", "Icircumflex", "Idieresis", "Igrave",
229
+ "Oacute", "Ocircumflex", "applelogo", "Ograve",
230
+ "Uacute", "Ucircumflex", "Ugrave", "dotlessi",
231
+ "circumflex", "tilde", "overscore", "breve",
232
+ "dotaccent", "ring", "cedilla", "hungarumlaut",
233
+ "ogonek", "caron", "Lslash", "lslash",
234
+ "Scaron", "scaron", "Zcaron", "zcaron",
235
+ "brokenbar", "Eth", "eth", "Yacute",
236
+ "yacute", "Thorn", "thorn", "minus",
237
+ "multiply", "onesuperior", "twosuperior", "threesuperior",
238
+ "onehalf", "onequarter", "threequarters", "franc",
239
+ "Gbreve", "gbreve", "Idot", "Scedilla",
240
+ "scedilla", "Cacute", "cacute", "Ccaron",
241
+ "ccaron", "dmacron"
242
+ };
243
+
244
+ //------------------------------------------------------------------------
245
+ // FoFiTrueType
246
+ //------------------------------------------------------------------------
247
+
248
+ FoFiTrueType *FoFiTrueType::make(char *fileA, int lenA) {
249
+ FoFiTrueType *ff;
250
+
251
+ ff = new FoFiTrueType(fileA, lenA, gFalse);
252
+ if (!ff->parsedOk) {
253
+ delete ff;
254
+ return NULL;
255
+ }
256
+ return ff;
257
+ }
258
+
259
+ FoFiTrueType *FoFiTrueType::load(char *fileName) {
260
+ FoFiTrueType *ff;
261
+ char *fileA;
262
+ int lenA;
263
+
264
+ if (!(fileA = FoFiBase::readFile(fileName, &lenA))) {
265
+ return NULL;
266
+ }
267
+ ff = new FoFiTrueType(fileA, lenA, gTrue);
268
+ if (!ff->parsedOk) {
269
+ delete ff;
270
+ return NULL;
271
+ }
272
+ return ff;
273
+ }
274
+
275
+ FoFiTrueType::FoFiTrueType(char *fileA, int lenA, GBool freeFileDataA):
276
+ FoFiBase(fileA, lenA, freeFileDataA)
277
+ {
278
+ tables = NULL;
279
+ nTables = 0;
280
+ cmaps = NULL;
281
+ nCmaps = 0;
282
+ nameToGID = NULL;
283
+ parsedOk = gFalse;
284
+
285
+ parse();
286
+ }
287
+
288
+ FoFiTrueType::~FoFiTrueType() {
289
+ gfree(tables);
290
+ gfree(cmaps);
291
+ if (nameToGID) {
292
+ delete nameToGID;
293
+ }
294
+ }
295
+
296
+ int FoFiTrueType::getNumCmaps() {
297
+ return nCmaps;
298
+ }
299
+
300
+ int FoFiTrueType::getCmapPlatform(int i) {
301
+ return cmaps[i].platform;
302
+ }
303
+
304
+ int FoFiTrueType::getCmapEncoding(int i) {
305
+ return cmaps[i].encoding;
306
+ }
307
+
308
+ int FoFiTrueType::findCmap(int platform, int encoding) {
309
+ int i;
310
+
311
+ for (i = 0; i < nCmaps; ++i) {
312
+ if (cmaps[i].platform == platform && cmaps[i].encoding == encoding) {
313
+ return i;
314
+ }
315
+ }
316
+ return -1;
317
+ }
318
+
319
+ Gushort FoFiTrueType::mapCodeToGID(int i, int c) {
320
+ Gushort gid;
321
+ int segCnt, segEnd, segStart, segDelta, segOffset;
322
+ int cmapFirst, cmapLen;
323
+ int pos, a, b, m;
324
+ GBool ok;
325
+
326
+ if (i < 0 || i >= nCmaps) {
327
+ return 0;
328
+ }
329
+ ok = gTrue;
330
+ pos = cmaps[i].offset;
331
+ switch (cmaps[i].fmt) {
332
+ case 0:
333
+ if (c < 0 || c >= cmaps[i].len - 6) {
334
+ return 0;
335
+ }
336
+ gid = getU8(cmaps[i].offset + 6 + c, &ok);
337
+ break;
338
+ case 4:
339
+ segCnt = getU16BE(pos + 6, &ok) / 2;
340
+ a = -1;
341
+ b = segCnt - 1;
342
+ segEnd = getU16BE(pos + 14 + 2*b, &ok);
343
+ if (c > segEnd) {
344
+ // malformed font -- the TrueType spec requires the last segEnd
345
+ // to be 0xffff
346
+ return 0;
347
+ }
348
+ // invariant: seg[a].end < code <= seg[b].end
349
+ while (b - a > 1 && ok) {
350
+ m = (a + b) / 2;
351
+ segEnd = getU16BE(pos + 14 + 2*m, &ok);
352
+ if (segEnd < c) {
353
+ a = m;
354
+ } else {
355
+ b = m;
356
+ }
357
+ }
358
+ segStart = getU16BE(pos + 16 + 2*segCnt + 2*b, &ok);
359
+ segDelta = getU16BE(pos + 16 + 4*segCnt + 2*b, &ok);
360
+ segOffset = getU16BE(pos + 16 + 6*segCnt + 2*b, &ok);
361
+ if (c < segStart) {
362
+ return 0;
363
+ }
364
+ if (segOffset == 0) {
365
+ gid = (c + segDelta) & 0xffff;
366
+ } else {
367
+ gid = getU16BE(pos + 16 + 6*segCnt + 2*b +
368
+ segOffset + 2 * (c - segStart), &ok);
369
+ if (gid != 0) {
370
+ gid = (gid + segDelta) & 0xffff;
371
+ }
372
+ }
373
+ break;
374
+ case 6:
375
+ cmapFirst = getU16BE(pos + 6, &ok);
376
+ cmapLen = getU16BE(pos + 8, &ok);
377
+ if (c < cmapFirst || c >= cmapFirst + cmapLen) {
378
+ return 0;
379
+ }
380
+ gid = getU16BE(pos + 10 + 2 * (c - cmapFirst), &ok);
381
+ break;
382
+ default:
383
+ return 0;
384
+ }
385
+ if (!ok) {
386
+ return 0;
387
+ }
388
+ return gid;
389
+ }
390
+
391
+ int FoFiTrueType::mapNameToGID(char *name) {
392
+ if (!nameToGID) {
393
+ return 0;
394
+ }
395
+ return nameToGID->lookupInt(name);
396
+ }
397
+
398
+ Gushort *FoFiTrueType::getCIDToGIDMap(int *nCIDs) {
399
+ FoFiType1C *ff;
400
+ Gushort *map;
401
+ int i;
402
+
403
+ *nCIDs = 0;
404
+ if (!openTypeCFF) {
405
+ return NULL;
406
+ }
407
+ i = seekTable("CFF ");
408
+ if (!checkRegion(tables[i].offset, tables[i].len)) {
409
+ return NULL;
410
+ }
411
+ if (!(ff = FoFiType1C::make((char *)file + tables[i].offset,
412
+ tables[i].len))) {
413
+ return NULL;
414
+ }
415
+ map = ff->getCIDToGIDMap(nCIDs);
416
+ delete ff;
417
+ return map;
418
+ }
419
+
420
+ int FoFiTrueType::getEmbeddingRights() {
421
+ int i, fsType;
422
+ GBool ok;
423
+
424
+ if ((i = seekTable("OS/2")) < 0) {
425
+ return 4;
426
+ }
427
+ ok = gTrue;
428
+ fsType = getU16BE(tables[i].offset + 8, &ok);
429
+ if (!ok) {
430
+ return 4;
431
+ }
432
+ if (fsType & 0x0008) {
433
+ return 2;
434
+ }
435
+ if (fsType & 0x0004) {
436
+ return 1;
437
+ }
438
+ if (fsType & 0x0002) {
439
+ return 0;
440
+ }
441
+ return 3;
442
+ }
443
+
444
+ void FoFiTrueType::convertToType42(char *psName, char **encoding,
445
+ Gushort *codeToGID,
446
+ FoFiOutputFunc outputFunc,
447
+ void *outputStream) {
448
+ GString *buf;
449
+ GBool ok;
450
+
451
+ if (openTypeCFF) {
452
+ return;
453
+ }
454
+
455
+ // write the header
456
+ ok = gTrue;
457
+ buf = GString::format("%!PS-TrueTypeFont-{0:2g}\n",
458
+ (double)getS32BE(0, &ok) / 65536.0);
459
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
460
+ delete buf;
461
+
462
+ // begin the font dictionary
463
+ (*outputFunc)(outputStream, "10 dict begin\n", 14);
464
+ (*outputFunc)(outputStream, "/FontName /", 11);
465
+ (*outputFunc)(outputStream, psName, strlen(psName));
466
+ (*outputFunc)(outputStream, " def\n", 5);
467
+ (*outputFunc)(outputStream, "/FontType 42 def\n", 17);
468
+ (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
469
+ buf = GString::format("/FontBBox [{0:d} {1:d} {2:d} {3:d}] def\n",
470
+ bbox[0], bbox[1], bbox[2], bbox[3]);
471
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
472
+ delete buf;
473
+ (*outputFunc)(outputStream, "/PaintType 0 def\n", 17);
474
+
475
+ // write the guts of the dictionary
476
+ cvtEncoding(encoding, outputFunc, outputStream);
477
+ cvtCharStrings(encoding, codeToGID, outputFunc, outputStream);
478
+ cvtSfnts(outputFunc, outputStream, NULL, gFalse);
479
+
480
+ // end the dictionary and define the font
481
+ (*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40);
482
+ }
483
+
484
+ void FoFiTrueType::convertToType1(char *psName, char **newEncoding,
485
+ GBool ascii, FoFiOutputFunc outputFunc,
486
+ void *outputStream) {
487
+ FoFiType1C *ff;
488
+ int i;
489
+
490
+ if (!openTypeCFF) {
491
+ return;
492
+ }
493
+ i = seekTable("CFF ");
494
+ if (!checkRegion(tables[i].offset, tables[i].len)) {
495
+ return;
496
+ }
497
+ if (!(ff = FoFiType1C::make((char *)file + tables[i].offset,
498
+ tables[i].len))) {
499
+ return;
500
+ }
501
+ ff->convertToType1(psName, newEncoding, ascii, outputFunc, outputStream);
502
+ delete ff;
503
+ }
504
+
505
+ void FoFiTrueType::convertToCIDType2(char *psName,
506
+ Gushort *cidMap, int nCIDs,
507
+ GBool needVerticalMetrics,
508
+ FoFiOutputFunc outputFunc,
509
+ void *outputStream) {
510
+ GString *buf;
511
+ Gushort cid;
512
+ GBool ok;
513
+ int i, j, k;
514
+
515
+ if (openTypeCFF) {
516
+ return;
517
+ }
518
+
519
+ // write the header
520
+ ok = gTrue;
521
+ buf = GString::format("%!PS-TrueTypeFont-{0:2g}\n",
522
+ (double)getS32BE(0, &ok) / 65536.0);
523
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
524
+ delete buf;
525
+
526
+ // begin the font dictionary
527
+ (*outputFunc)(outputStream, "20 dict begin\n", 14);
528
+ (*outputFunc)(outputStream, "/CIDFontName /", 14);
529
+ (*outputFunc)(outputStream, psName, strlen(psName));
530
+ (*outputFunc)(outputStream, " def\n", 5);
531
+ (*outputFunc)(outputStream, "/CIDFontType 2 def\n", 19);
532
+ (*outputFunc)(outputStream, "/FontType 42 def\n", 17);
533
+ (*outputFunc)(outputStream, "/CIDSystemInfo 3 dict dup begin\n", 32);
534
+ (*outputFunc)(outputStream, " /Registry (Adobe) def\n", 24);
535
+ (*outputFunc)(outputStream, " /Ordering (Identity) def\n", 27);
536
+ (*outputFunc)(outputStream, " /Supplement 0 def\n", 20);
537
+ (*outputFunc)(outputStream, " end def\n", 10);
538
+ (*outputFunc)(outputStream, "/GDBytes 2 def\n", 15);
539
+ if (cidMap) {
540
+ buf = GString::format("/CIDCount {0:d} def\n", nCIDs);
541
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
542
+ delete buf;
543
+ if (nCIDs > 32767) {
544
+ (*outputFunc)(outputStream, "/CIDMap [", 9);
545
+ for (i = 0; i < nCIDs; i += 32768 - 16) {
546
+ (*outputFunc)(outputStream, "<\n", 2);
547
+ for (j = 0; j < 32768 - 16 && i+j < nCIDs; j += 16) {
548
+ (*outputFunc)(outputStream, " ", 2);
549
+ for (k = 0; k < 16 && i+j+k < nCIDs; ++k) {
550
+ cid = cidMap[i+j+k];
551
+ buf = GString::format("{0:02x}{1:02x}",
552
+ (cid >> 8) & 0xff, cid & 0xff);
553
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
554
+ delete buf;
555
+ }
556
+ (*outputFunc)(outputStream, "\n", 1);
557
+ }
558
+ (*outputFunc)(outputStream, " >", 3);
559
+ }
560
+ (*outputFunc)(outputStream, "\n", 1);
561
+ (*outputFunc)(outputStream, "] def\n", 6);
562
+ } else {
563
+ (*outputFunc)(outputStream, "/CIDMap <\n", 10);
564
+ for (i = 0; i < nCIDs; i += 16) {
565
+ (*outputFunc)(outputStream, " ", 2);
566
+ for (j = 0; j < 16 && i+j < nCIDs; ++j) {
567
+ cid = cidMap[i+j];
568
+ buf = GString::format("{0:02x}{1:02x}",
569
+ (cid >> 8) & 0xff, cid & 0xff);
570
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
571
+ delete buf;
572
+ }
573
+ (*outputFunc)(outputStream, "\n", 1);
574
+ }
575
+ (*outputFunc)(outputStream, "> def\n", 6);
576
+ }
577
+ } else {
578
+ // direct mapping - just fill the string(s) with s[i]=i
579
+ buf = GString::format("/CIDCount {0:d} def\n", nGlyphs);
580
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
581
+ delete buf;
582
+ if (nGlyphs > 32767) {
583
+ (*outputFunc)(outputStream, "/CIDMap [\n", 10);
584
+ for (i = 0; i < nGlyphs; i += 32767) {
585
+ j = nGlyphs - i < 32767 ? nGlyphs - i : 32767;
586
+ buf = GString::format(" {0:d} string 0 1 {1:d} {{\n", 2 * j, j - 1);
587
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
588
+ delete buf;
589
+ buf = GString::format(" 2 copy dup 2 mul exch {0:d} add -8 bitshift put\n",
590
+ i);
591
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
592
+ delete buf;
593
+ buf = GString::format(" 1 index exch dup 2 mul 1 add exch {0:d} add"
594
+ " 255 and put\n", i);
595
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
596
+ delete buf;
597
+ (*outputFunc)(outputStream, " } for\n", 8);
598
+ }
599
+ (*outputFunc)(outputStream, "] def\n", 6);
600
+ } else {
601
+ buf = GString::format("/CIDMap {0:d} string\n", 2 * nGlyphs);
602
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
603
+ delete buf;
604
+ buf = GString::format(" 0 1 {0:d} {{\n", nGlyphs - 1);
605
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
606
+ delete buf;
607
+ (*outputFunc)(outputStream,
608
+ " 2 copy dup 2 mul exch -8 bitshift put\n", 42);
609
+ (*outputFunc)(outputStream,
610
+ " 1 index exch dup 2 mul 1 add exch 255 and put\n", 50);
611
+ (*outputFunc)(outputStream, " } for\n", 8);
612
+ (*outputFunc)(outputStream, "def\n", 4);
613
+ }
614
+ }
615
+ (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
616
+ buf = GString::format("/FontBBox [{0:d} {1:d} {2:d} {3:d}] def\n",
617
+ bbox[0], bbox[1], bbox[2], bbox[3]);
618
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
619
+ delete buf;
620
+ (*outputFunc)(outputStream, "/PaintType 0 def\n", 17);
621
+ (*outputFunc)(outputStream, "/Encoding [] readonly def\n", 26);
622
+ (*outputFunc)(outputStream, "/CharStrings 1 dict dup begin\n", 30);
623
+ (*outputFunc)(outputStream, " /.notdef 0 def\n", 17);
624
+ (*outputFunc)(outputStream, " end readonly def\n", 19);
625
+
626
+ // write the guts of the dictionary
627
+ cvtSfnts(outputFunc, outputStream, NULL, needVerticalMetrics);
628
+
629
+ // end the dictionary and define the font
630
+ (*outputFunc)(outputStream,
631
+ "CIDFontName currentdict end /CIDFont defineresource pop\n",
632
+ 56);
633
+ }
634
+
635
+ void FoFiTrueType::convertToCIDType0(char *psName,
636
+ FoFiOutputFunc outputFunc,
637
+ void *outputStream) {
638
+ FoFiType1C *ff;
639
+ int i;
640
+
641
+ if (!openTypeCFF) {
642
+ return;
643
+ }
644
+ i = seekTable("CFF ");
645
+ if (!checkRegion(tables[i].offset, tables[i].len)) {
646
+ return;
647
+ }
648
+ if (!(ff = FoFiType1C::make((char *)file + tables[i].offset,
649
+ tables[i].len))) {
650
+ return;
651
+ }
652
+ ff->convertToCIDType0(psName, outputFunc, outputStream);
653
+ delete ff;
654
+ }
655
+
656
+ void FoFiTrueType::convertToType0(char *psName, Gushort *cidMap, int nCIDs,
657
+ GBool needVerticalMetrics,
658
+ FoFiOutputFunc outputFunc,
659
+ void *outputStream) {
660
+ GString *buf;
661
+ GString *sfntsName;
662
+ int n, i, j;
663
+
664
+ if (openTypeCFF) {
665
+ return;
666
+ }
667
+
668
+ // write the Type 42 sfnts array
669
+ sfntsName = (new GString(psName))->append("_sfnts");
670
+ cvtSfnts(outputFunc, outputStream, sfntsName, needVerticalMetrics);
671
+ delete sfntsName;
672
+
673
+ // write the descendant Type 42 fonts
674
+ n = cidMap ? nCIDs : nGlyphs;
675
+ for (i = 0; i < n; i += 256) {
676
+ (*outputFunc)(outputStream, "10 dict begin\n", 14);
677
+ (*outputFunc)(outputStream, "/FontName /", 11);
678
+ (*outputFunc)(outputStream, psName, strlen(psName));
679
+ buf = GString::format("_{0:02x} def\n", i >> 8);
680
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
681
+ delete buf;
682
+ (*outputFunc)(outputStream, "/FontType 42 def\n", 17);
683
+ (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
684
+ buf = GString::format("/FontBBox [{0:d} {1:d} {2:d} {3:d}] def\n",
685
+ bbox[0], bbox[1], bbox[2], bbox[3]);
686
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
687
+ delete buf;
688
+ (*outputFunc)(outputStream, "/PaintType 0 def\n", 17);
689
+ (*outputFunc)(outputStream, "/sfnts ", 7);
690
+ (*outputFunc)(outputStream, psName, strlen(psName));
691
+ (*outputFunc)(outputStream, "_sfnts def\n", 11);
692
+ (*outputFunc)(outputStream, "/Encoding 256 array\n", 20);
693
+ for (j = 0; j < 256 && i+j < n; ++j) {
694
+ buf = GString::format("dup {0:d} /c{1:02x} put\n", j, j);
695
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
696
+ delete buf;
697
+ }
698
+ (*outputFunc)(outputStream, "readonly def\n", 13);
699
+ (*outputFunc)(outputStream, "/CharStrings 257 dict dup begin\n", 32);
700
+ (*outputFunc)(outputStream, "/.notdef 0 def\n", 15);
701
+ for (j = 0; j < 256 && i+j < n; ++j) {
702
+ buf = GString::format("/c{0:02x} {1:d} def\n",
703
+ j, cidMap ? cidMap[i+j] : i+j);
704
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
705
+ delete buf;
706
+ }
707
+ (*outputFunc)(outputStream, "end readonly def\n", 17);
708
+ (*outputFunc)(outputStream,
709
+ "FontName currentdict end definefont pop\n", 40);
710
+ }
711
+
712
+ // write the Type 0 parent font
713
+ (*outputFunc)(outputStream, "16 dict begin\n", 14);
714
+ (*outputFunc)(outputStream, "/FontName /", 11);
715
+ (*outputFunc)(outputStream, psName, strlen(psName));
716
+ (*outputFunc)(outputStream, " def\n", 5);
717
+ (*outputFunc)(outputStream, "/FontType 0 def\n", 16);
718
+ (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
719
+ (*outputFunc)(outputStream, "/FMapType 2 def\n", 16);
720
+ (*outputFunc)(outputStream, "/Encoding [\n", 12);
721
+ for (i = 0; i < n; i += 256) {
722
+ buf = GString::format("{0:d}\n", i >> 8);
723
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
724
+ delete buf;
725
+ }
726
+ (*outputFunc)(outputStream, "] def\n", 6);
727
+ (*outputFunc)(outputStream, "/FDepVector [\n", 14);
728
+ for (i = 0; i < n; i += 256) {
729
+ (*outputFunc)(outputStream, "/", 1);
730
+ (*outputFunc)(outputStream, psName, strlen(psName));
731
+ buf = GString::format("_{0:02x} findfont\n", i >> 8);
732
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
733
+ delete buf;
734
+ }
735
+ (*outputFunc)(outputStream, "] def\n", 6);
736
+ (*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40);
737
+ }
738
+
739
+ void FoFiTrueType::convertToType0(char *psName,
740
+ FoFiOutputFunc outputFunc,
741
+ void *outputStream) {
742
+ FoFiType1C *ff;
743
+ int i;
744
+
745
+ if (!openTypeCFF) {
746
+ return;
747
+ }
748
+ i = seekTable("CFF ");
749
+ if (!checkRegion(tables[i].offset, tables[i].len)) {
750
+ return;
751
+ }
752
+ if (!(ff = FoFiType1C::make((char *)file + tables[i].offset,
753
+ tables[i].len))) {
754
+ return;
755
+ }
756
+ ff->convertToType0(psName, outputFunc, outputStream);
757
+ delete ff;
758
+ }
759
+
760
+ void FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc,
761
+ void *outputStream, char *name,
762
+ Gushort *codeToGID) {
763
+ // this substitute cmap table maps char codes 0000-ffff directly to
764
+ // glyphs 0000-ffff
765
+ static char cmapTab[36] = {
766
+ 0, 0, // table version number
767
+ 0, 1, // number of encoding tables
768
+ 0, 1, // platform ID
769
+ 0, 0, // encoding ID
770
+ 0, 0, 0, 12, // offset of subtable
771
+ 0, 4, // subtable format
772
+ 0, 24, // subtable length
773
+ 0, 0, // subtable version
774
+ 0, 2, // segment count * 2
775
+ 0, 2, // 2 * 2 ^ floor(log2(segCount))
776
+ 0, 0, // floor(log2(segCount))
777
+ 0, 0, // 2*segCount - 2*2^floor(log2(segCount))
778
+ (char)0xff, (char)0xff, // endCount[0]
779
+ 0, 0, // reserved
780
+ 0, 0, // startCount[0]
781
+ 0, 0, // idDelta[0]
782
+ 0, 0 // pad to a mulitple of four bytes
783
+ };
784
+ static char nameTab[8] = {
785
+ 0, 0, // format
786
+ 0, 0, // number of name records
787
+ 0, 6, // offset to start of string storage
788
+ 0, 0 // pad to multiple of four bytes
789
+ };
790
+ static char postTab[32] = {
791
+ 0, 1, 0, 0, // format
792
+ 0, 0, 0, 0, // italic angle
793
+ 0, 0, // underline position
794
+ 0, 0, // underline thickness
795
+ 0, 0, 0, 0, // fixed pitch
796
+ 0, 0, 0, 0, // min Type 42 memory
797
+ 0, 0, 0, 0, // max Type 42 memory
798
+ 0, 0, 0, 0, // min Type 1 memory
799
+ 0, 0, 0, 0 // max Type 1 memory
800
+ };
801
+ static char os2Tab[86] = {
802
+ 0, 1, // version
803
+ 0, 1, // xAvgCharWidth
804
+ 0, 0, // usWeightClass
805
+ 0, 0, // usWidthClass
806
+ 0, 0, // fsType
807
+ 0, 0, // ySubscriptXSize
808
+ 0, 0, // ySubscriptYSize
809
+ 0, 0, // ySubscriptXOffset
810
+ 0, 0, // ySubscriptYOffset
811
+ 0, 0, // ySuperscriptXSize
812
+ 0, 0, // ySuperscriptYSize
813
+ 0, 0, // ySuperscriptXOffset
814
+ 0, 0, // ySuperscriptYOffset
815
+ 0, 0, // yStrikeoutSize
816
+ 0, 0, // yStrikeoutPosition
817
+ 0, 0, // sFamilyClass
818
+ 0, 0, 0, 0, 0, // panose
819
+ 0, 0, 0, 0, 0,
820
+ 0, 0, 0, 0, // ulUnicodeRange1
821
+ 0, 0, 0, 0, // ulUnicodeRange2
822
+ 0, 0, 0, 0, // ulUnicodeRange3
823
+ 0, 0, 0, 0, // ulUnicodeRange4
824
+ 0, 0, 0, 0, // achVendID
825
+ 0, 0, // fsSelection
826
+ 0, 0, // usFirstCharIndex
827
+ 0, 0, // usLastCharIndex
828
+ 0, 0, // sTypoAscender
829
+ 0, 0, // sTypoDescender
830
+ 0, 0, // sTypoLineGap
831
+ 0, 0, // usWinAscent
832
+ 0, 0, // usWinDescent
833
+ 0, 0, 0, 0, // ulCodePageRange1
834
+ 0, 0, 0, 0 // ulCodePageRange2
835
+ };
836
+ GBool missingCmap, missingName, missingPost, missingOS2;
837
+ GBool unsortedLoca, badCmapLen, abbrevHMTX;
838
+ int nZeroLengthTables;
839
+ int nHMetrics, advWidth, lsb;
840
+ TrueTypeLoca *locaTable;
841
+ TrueTypeTable *newTables;
842
+ char *newNameTab, *newCmapTab, *newHHEATab, *newHMTXTab;
843
+ int nNewTables, cmapIdx, cmapLen, glyfLen, newNameLen, newCmapLen, next;
844
+ int newHHEALen, newHMTXLen;
845
+ Guint locaChecksum, glyfChecksum, fileChecksum;
846
+ char *tableDir;
847
+ char locaBuf[4], checksumBuf[4];
848
+ GBool ok;
849
+ Guint t;
850
+ int pos, i, j, k, n;
851
+
852
+ if (openTypeCFF) {
853
+ return;
854
+ }
855
+
856
+ // check for missing tables
857
+ // (Note: if the OS/2 table is missing, the Microsoft PCL5 driver
858
+ // will embed a PCL TrueType font with the pitch field set to zero,
859
+ // which apparently causes divide-by-zero errors. As far as I can
860
+ // tell, the only important field in the OS/2 table is
861
+ // xAvgCharWidth.)
862
+ missingCmap = (cmapIdx = seekTable("cmap")) < 0;
863
+ missingName = seekTable("name") < 0;
864
+ missingPost = seekTable("post") < 0;
865
+ missingOS2 = seekTable("OS/2") < 0;
866
+
867
+ // read the loca table, check to see if it's sorted
868
+ locaTable = (TrueTypeLoca *)gmallocn(nGlyphs + 1, sizeof(TrueTypeLoca));
869
+ unsortedLoca = gFalse;
870
+ i = seekTable("loca");
871
+ pos = tables[i].offset;
872
+ ok = gTrue;
873
+ for (i = 0; i <= nGlyphs; ++i) {
874
+ if (locaFmt) {
875
+ locaTable[i].origOffset = (int)getU32BE(pos + i*4, &ok);
876
+ } else {
877
+ locaTable[i].origOffset = 2 * getU16BE(pos + i*2, &ok);
878
+ }
879
+ if (i > 0 && locaTable[i].origOffset < locaTable[i-1].origOffset) {
880
+ unsortedLoca = gTrue;
881
+ }
882
+ // glyph descriptions must be at least 12 bytes long (nContours,
883
+ // xMin, yMin, xMax, yMax, instructionLength - two bytes each);
884
+ // invalid glyph descriptions (even if they're never used) make
885
+ // Windows choke, so we work around that problem here (ideally,
886
+ // this would parse the glyph descriptions in the glyf table and
887
+ // remove any that were invalid, but this quick test is a decent
888
+ // start)
889
+ if (i > 0 &&
890
+ locaTable[i].origOffset - locaTable[i-1].origOffset > 0 &&
891
+ locaTable[i].origOffset - locaTable[i-1].origOffset < 12) {
892
+ locaTable[i-1].origOffset = locaTable[i].origOffset;
893
+ unsortedLoca = gTrue;
894
+ }
895
+ locaTable[i].idx = i;
896
+ }
897
+
898
+ // check for zero-length tables
899
+ nZeroLengthTables = 0;
900
+ for (i = 0; i < nTables; ++i) {
901
+ if (tables[i].len == 0) {
902
+ ++nZeroLengthTables;
903
+ }
904
+ }
905
+
906
+ // check for an incorrect cmap table length
907
+ badCmapLen = gFalse;
908
+ cmapLen = 0; // make gcc happy
909
+ if (!missingCmap) {
910
+ cmapLen = cmaps[0].offset + cmaps[0].len;
911
+ for (i = 1; i < nCmaps; ++i) {
912
+ if (cmaps[i].offset + cmaps[i].len > cmapLen) {
913
+ cmapLen = cmaps[i].offset + cmaps[i].len;
914
+ }
915
+ }
916
+ cmapLen -= tables[cmapIdx].offset;
917
+ if (cmapLen > tables[cmapIdx].len) {
918
+ badCmapLen = gTrue;
919
+ }
920
+ }
921
+
922
+ // check for an abbreviated hmtx table (this is completely legal,
923
+ // but confuses the Microsoft PCL5 printer driver, which generates
924
+ // embedded fonts with the pitch field set to zero)
925
+ i = seekTable("hhea");
926
+ nHMetrics = getU16BE(tables[i].offset + 34, &ok);
927
+ abbrevHMTX = nHMetrics < nGlyphs;
928
+
929
+ // if nothing is broken, just write the TTF file as is
930
+ if (!missingCmap && !missingName && !missingPost && !missingOS2 &&
931
+ !unsortedLoca && !badCmapLen && !abbrevHMTX && nZeroLengthTables == 0 &&
932
+ !name && !codeToGID) {
933
+ (*outputFunc)(outputStream, (char *)file, len);
934
+ goto done1;
935
+ }
936
+
937
+ // sort the 'loca' table: some (non-compliant) fonts have
938
+ // out-of-order loca tables; in order to correctly handle the case
939
+ // where (compliant) fonts have empty entries in the middle of the
940
+ // table, cmpTrueTypeLocaOffset uses offset as its primary sort key,
941
+ // and idx as its secondary key (ensuring that adjacent entries with
942
+ // the same pos value remain in the same order)
943
+ glyfLen = 0; // make gcc happy
944
+ if (unsortedLoca) {
945
+ qsort(locaTable, nGlyphs + 1, sizeof(TrueTypeLoca),
946
+ &cmpTrueTypeLocaOffset);
947
+ for (i = 0; i < nGlyphs; ++i) {
948
+ locaTable[i].len = locaTable[i+1].origOffset - locaTable[i].origOffset;
949
+ }
950
+ locaTable[nGlyphs].len = 0;
951
+ qsort(locaTable, nGlyphs + 1, sizeof(TrueTypeLoca),
952
+ &cmpTrueTypeLocaIdx);
953
+ pos = 0;
954
+ for (i = 0; i <= nGlyphs; ++i) {
955
+ locaTable[i].newOffset = pos;
956
+ pos += locaTable[i].len;
957
+ if (pos & 3) {
958
+ pos += 4 - (pos & 3);
959
+ }
960
+ }
961
+ glyfLen = pos;
962
+ }
963
+
964
+ // compute checksums for the loca and glyf tables
965
+ locaChecksum = glyfChecksum = 0;
966
+ if (unsortedLoca) {
967
+ if (locaFmt) {
968
+ for (j = 0; j <= nGlyphs; ++j) {
969
+ locaChecksum += locaTable[j].newOffset;
970
+ }
971
+ } else {
972
+ for (j = 0; j <= nGlyphs; j += 2) {
973
+ locaChecksum += locaTable[j].newOffset << 16;
974
+ if (j + 1 <= nGlyphs) {
975
+ locaChecksum += locaTable[j+1].newOffset;
976
+ }
977
+ }
978
+ }
979
+ pos = tables[seekTable("glyf")].offset;
980
+ for (j = 0; j < nGlyphs; ++j) {
981
+ n = locaTable[j].len;
982
+ if (n > 0) {
983
+ k = locaTable[j].origOffset;
984
+ if (checkRegion(pos + k, n)) {
985
+ glyfChecksum += computeTableChecksum(file + pos + k, n);
986
+ }
987
+ }
988
+ }
989
+ }
990
+
991
+ // construct the new name table
992
+ if (name) {
993
+ n = strlen(name);
994
+ newNameLen = (6 + 4*12 + 2 * (3*n + 7) + 3) & ~3;
995
+ newNameTab = (char *)gmalloc(newNameLen);
996
+ memset(newNameTab, 0, newNameLen);
997
+ newNameTab[0] = 0; // format selector
998
+ newNameTab[1] = 0;
999
+ newNameTab[2] = 0; // number of name records
1000
+ newNameTab[3] = 4;
1001
+ newNameTab[4] = 0; // offset to start of string storage
1002
+ newNameTab[5] = 6 + 4*12;
1003
+ next = 0;
1004
+ for (i = 0; i < 4; ++i) {
1005
+ newNameTab[6 + i*12 + 0] = 0; // platform ID = Microsoft
1006
+ newNameTab[6 + i*12 + 1] = 3;
1007
+ newNameTab[6 + i*12 + 2] = 0; // encoding ID = Unicode
1008
+ newNameTab[6 + i*12 + 3] = 1;
1009
+ newNameTab[6 + i*12 + 4] = 0x04; // language ID = American English
1010
+ newNameTab[6 + i*12 + 5] = 0x09;
1011
+ newNameTab[6 + i*12 + 6] = 0; // name ID
1012
+ newNameTab[6 + i*12 + 7] = i + 1;
1013
+ newNameTab[6 + i*12 + 8] = i+1 == 2 ? 0 : ((2*n) >> 8); // string length
1014
+ newNameTab[6 + i*12 + 9] = i+1 == 2 ? 14 : ((2*n) & 0xff);
1015
+ newNameTab[6 + i*12 + 10] = next >> 8; // string offset
1016
+ newNameTab[6 + i*12 + 11] = next & 0xff;
1017
+ if (i+1 == 2) {
1018
+ memcpy(newNameTab + 6 + 4*12 + next, "\0R\0e\0g\0u\0l\0a\0r", 14);
1019
+ next += 14;
1020
+ } else {
1021
+ for (j = 0; j < n; ++j) {
1022
+ newNameTab[6 + 4*12 + next + 2*j] = 0;
1023
+ newNameTab[6 + 4*12 + next + 2*j + 1] = name[j];
1024
+ }
1025
+ next += 2*n;
1026
+ }
1027
+ }
1028
+ } else {
1029
+ newNameLen = 0;
1030
+ newNameTab = NULL;
1031
+ }
1032
+
1033
+ // construct the new cmap table
1034
+ if (codeToGID) {
1035
+ newCmapLen = 44 + 256 * 2;
1036
+ newCmapTab = (char *)gmalloc(newCmapLen);
1037
+ newCmapTab[0] = 0; // table version number = 0
1038
+ newCmapTab[1] = 0;
1039
+ newCmapTab[2] = 0; // number of encoding tables = 1
1040
+ newCmapTab[3] = 1;
1041
+ newCmapTab[4] = 0; // platform ID = Microsoft
1042
+ newCmapTab[5] = 3;
1043
+ newCmapTab[6] = 0; // encoding ID = Unicode
1044
+ newCmapTab[7] = 1;
1045
+ newCmapTab[8] = 0; // offset of subtable
1046
+ newCmapTab[9] = 0;
1047
+ newCmapTab[10] = 0;
1048
+ newCmapTab[11] = 12;
1049
+ newCmapTab[12] = 0; // subtable format = 4
1050
+ newCmapTab[13] = 4;
1051
+ newCmapTab[14] = 0x02; // subtable length
1052
+ newCmapTab[15] = 0x20;
1053
+ newCmapTab[16] = 0; // subtable version = 0
1054
+ newCmapTab[17] = 0;
1055
+ newCmapTab[18] = 0; // segment count * 2
1056
+ newCmapTab[19] = 4;
1057
+ newCmapTab[20] = 0; // 2 * 2 ^ floor(log2(segCount))
1058
+ newCmapTab[21] = 4;
1059
+ newCmapTab[22] = 0; // floor(log2(segCount))
1060
+ newCmapTab[23] = 1;
1061
+ newCmapTab[24] = 0; // 2*segCount - 2*2^floor(log2(segCount))
1062
+ newCmapTab[25] = 0;
1063
+ newCmapTab[26] = 0x00; // endCount[0]
1064
+ newCmapTab[27] = (char)0xff;
1065
+ newCmapTab[28] = (char)0xff; // endCount[1]
1066
+ newCmapTab[29] = (char)0xff;
1067
+ newCmapTab[30] = 0; // reserved
1068
+ newCmapTab[31] = 0;
1069
+ newCmapTab[32] = 0x00; // startCount[0]
1070
+ newCmapTab[33] = 0x00;
1071
+ newCmapTab[34] = (char)0xff; // startCount[1]
1072
+ newCmapTab[35] = (char)0xff;
1073
+ newCmapTab[36] = 0; // idDelta[0]
1074
+ newCmapTab[37] = 0;
1075
+ newCmapTab[38] = 0; // idDelta[1]
1076
+ newCmapTab[39] = 1;
1077
+ newCmapTab[40] = 0; // idRangeOffset[0]
1078
+ newCmapTab[41] = 4;
1079
+ newCmapTab[42] = 0; // idRangeOffset[1]
1080
+ newCmapTab[43] = 0;
1081
+ for (i = 0; i < 256; ++i) {
1082
+ newCmapTab[44 + 2*i] = codeToGID[i] >> 8;
1083
+ newCmapTab[44 + 2*i + 1] = codeToGID[i] & 0xff;
1084
+ }
1085
+ } else {
1086
+ newCmapLen = 0;
1087
+ newCmapTab = NULL;
1088
+ }
1089
+
1090
+ // generate the new hmtx table and the updated hhea table
1091
+ if (abbrevHMTX) {
1092
+ i = seekTable("hhea");
1093
+ pos = tables[i].offset;
1094
+ newHHEALen = 36;
1095
+ newHHEATab = (char *)gmalloc(newHHEALen);
1096
+ for (i = 0; i < newHHEALen; ++i) {
1097
+ newHHEATab[i] = getU8(pos++, &ok);
1098
+ }
1099
+ newHHEATab[34] = nGlyphs >> 8;
1100
+ newHHEATab[35] = nGlyphs & 0xff;
1101
+ i = seekTable("hmtx");
1102
+ pos = tables[i].offset;
1103
+ newHMTXLen = 4 * nGlyphs;
1104
+ newHMTXTab = (char *)gmalloc(newHMTXLen);
1105
+ advWidth = 0;
1106
+ for (i = 0; i < nHMetrics; ++i) {
1107
+ advWidth = getU16BE(pos, &ok);
1108
+ lsb = getU16BE(pos + 2, &ok);
1109
+ pos += 4;
1110
+ newHMTXTab[4*i ] = advWidth >> 8;
1111
+ newHMTXTab[4*i + 1] = advWidth & 0xff;
1112
+ newHMTXTab[4*i + 2] = lsb >> 8;
1113
+ newHMTXTab[4*i + 3] = lsb & 0xff;
1114
+ }
1115
+ for (; i < nGlyphs; ++i) {
1116
+ lsb = getU16BE(pos, &ok);
1117
+ pos += 2;
1118
+ newHMTXTab[4*i ] = advWidth >> 8;
1119
+ newHMTXTab[4*i + 1] = advWidth & 0xff;
1120
+ newHMTXTab[4*i + 2] = lsb >> 8;
1121
+ newHMTXTab[4*i + 3] = lsb & 0xff;
1122
+ }
1123
+ } else {
1124
+ newHHEATab = newHMTXTab = NULL;
1125
+ newHHEALen = newHMTXLen = 0; // make gcc happy
1126
+ }
1127
+
1128
+ // construct the new table directory:
1129
+ // - keep all original tables with non-zero length
1130
+ // - fix the cmap table's length, if necessary
1131
+ // - add missing tables
1132
+ // - sort the table by tag
1133
+ // - compute new table positions, including 4-byte alignment
1134
+ // - (re)compute table checksums
1135
+ nNewTables = nTables - nZeroLengthTables +
1136
+ (missingCmap ? 1 : 0) + (missingName ? 1 : 0) +
1137
+ (missingPost ? 1 : 0) + (missingOS2 ? 1 : 0);
1138
+ newTables = (TrueTypeTable *)gmallocn(nNewTables, sizeof(TrueTypeTable));
1139
+ j = 0;
1140
+ for (i = 0; i < nTables; ++i) {
1141
+ if (tables[i].len > 0) {
1142
+ newTables[j] = tables[i];
1143
+ newTables[j].origOffset = tables[i].offset;
1144
+ if (checkRegion(tables[i].offset, newTables[i].len)) {
1145
+ newTables[j].checksum =
1146
+ computeTableChecksum(file + tables[i].offset, tables[i].len);
1147
+ if (tables[i].tag == headTag) {
1148
+ // don't include the file checksum
1149
+ newTables[j].checksum -= getU32BE(tables[i].offset + 8, &ok);
1150
+ }
1151
+ }
1152
+ if (newTables[j].tag == cmapTag && codeToGID) {
1153
+ newTables[j].len = newCmapLen;
1154
+ newTables[j].checksum = computeTableChecksum((Guchar *)newCmapTab,
1155
+ newCmapLen);
1156
+ } else if (newTables[j].tag == cmapTag && badCmapLen) {
1157
+ newTables[j].len = cmapLen;
1158
+ } else if (newTables[j].tag == locaTag && unsortedLoca) {
1159
+ newTables[j].len = (nGlyphs + 1) * (locaFmt ? 4 : 2);
1160
+ newTables[j].checksum = locaChecksum;
1161
+ } else if (newTables[j].tag == glyfTag && unsortedLoca) {
1162
+ newTables[j].len = glyfLen;
1163
+ newTables[j].checksum = glyfChecksum;
1164
+ } else if (newTables[j].tag == nameTag && name) {
1165
+ newTables[j].len = newNameLen;
1166
+ newTables[j].checksum = computeTableChecksum((Guchar *)newNameTab,
1167
+ newNameLen);
1168
+ } else if (newTables[j].tag == hheaTag && abbrevHMTX) {
1169
+ newTables[j].len = newHHEALen;
1170
+ newTables[j].checksum = computeTableChecksum((Guchar *)newHHEATab,
1171
+ newHHEALen);
1172
+ } else if (newTables[j].tag == hmtxTag && abbrevHMTX) {
1173
+ newTables[j].len = newHMTXLen;
1174
+ newTables[j].checksum = computeTableChecksum((Guchar *)newHMTXTab,
1175
+ newHMTXLen);
1176
+ }
1177
+ ++j;
1178
+ }
1179
+ }
1180
+ if (missingCmap) {
1181
+ newTables[j].tag = cmapTag;
1182
+ if (codeToGID) {
1183
+ newTables[j].checksum = computeTableChecksum((Guchar *)newCmapTab,
1184
+ newCmapLen);
1185
+ newTables[j].len = newCmapLen;
1186
+ } else {
1187
+ newTables[j].checksum = computeTableChecksum((Guchar *)cmapTab,
1188
+ sizeof(cmapTab));
1189
+ newTables[j].len = sizeof(cmapTab);
1190
+ }
1191
+ ++j;
1192
+ }
1193
+ if (missingName) {
1194
+ newTables[j].tag = nameTag;
1195
+ if (name) {
1196
+ newTables[j].checksum = computeTableChecksum((Guchar *)newNameTab,
1197
+ newNameLen);
1198
+ newTables[j].len = newNameLen;
1199
+ } else {
1200
+ newTables[j].checksum = computeTableChecksum((Guchar *)nameTab,
1201
+ sizeof(nameTab));
1202
+ newTables[j].len = sizeof(nameTab);
1203
+ }
1204
+ ++j;
1205
+ }
1206
+ if (missingPost) {
1207
+ newTables[j].tag = postTag;
1208
+ newTables[j].checksum = computeTableChecksum((Guchar *)postTab,
1209
+ sizeof(postTab));
1210
+ newTables[j].len = sizeof(postTab);
1211
+ ++j;
1212
+ }
1213
+ if (missingOS2) {
1214
+ newTables[j].tag = os2Tag;
1215
+ newTables[j].checksum = computeTableChecksum((Guchar *)os2Tab,
1216
+ sizeof(os2Tab));
1217
+ newTables[j].len = sizeof(os2Tab);
1218
+ ++j;
1219
+ }
1220
+ qsort(newTables, nNewTables, sizeof(TrueTypeTable),
1221
+ &cmpTrueTypeTableTag);
1222
+ pos = 12 + nNewTables * 16;
1223
+ for (i = 0; i < nNewTables; ++i) {
1224
+ newTables[i].offset = pos;
1225
+ pos += newTables[i].len;
1226
+ if (pos & 3) {
1227
+ pos += 4 - (pos & 3);
1228
+ }
1229
+ }
1230
+
1231
+ // write the table directory
1232
+ tableDir = (char *)gmalloc(12 + nNewTables * 16);
1233
+ tableDir[0] = 0x00; // sfnt version
1234
+ tableDir[1] = 0x01;
1235
+ tableDir[2] = 0x00;
1236
+ tableDir[3] = 0x00;
1237
+ tableDir[4] = (char)((nNewTables >> 8) & 0xff); // numTables
1238
+ tableDir[5] = (char)(nNewTables & 0xff);
1239
+ for (i = -1, t = (Guint)nNewTables; t; ++i, t >>= 1) ;
1240
+ t = 1 << (4 + i);
1241
+ tableDir[6] = (char)((t >> 8) & 0xff); // searchRange
1242
+ tableDir[7] = (char)(t & 0xff);
1243
+ tableDir[8] = (char)((i >> 8) & 0xff); // entrySelector
1244
+ tableDir[9] = (char)(i & 0xff);
1245
+ t = nNewTables * 16 - t;
1246
+ tableDir[10] = (char)((t >> 8) & 0xff); // rangeShift
1247
+ tableDir[11] = (char)(t & 0xff);
1248
+ pos = 12;
1249
+ for (i = 0; i < nNewTables; ++i) {
1250
+ tableDir[pos ] = (char)(newTables[i].tag >> 24);
1251
+ tableDir[pos+ 1] = (char)(newTables[i].tag >> 16);
1252
+ tableDir[pos+ 2] = (char)(newTables[i].tag >> 8);
1253
+ tableDir[pos+ 3] = (char) newTables[i].tag;
1254
+ tableDir[pos+ 4] = (char)(newTables[i].checksum >> 24);
1255
+ tableDir[pos+ 5] = (char)(newTables[i].checksum >> 16);
1256
+ tableDir[pos+ 6] = (char)(newTables[i].checksum >> 8);
1257
+ tableDir[pos+ 7] = (char) newTables[i].checksum;
1258
+ tableDir[pos+ 8] = (char)(newTables[i].offset >> 24);
1259
+ tableDir[pos+ 9] = (char)(newTables[i].offset >> 16);
1260
+ tableDir[pos+10] = (char)(newTables[i].offset >> 8);
1261
+ tableDir[pos+11] = (char) newTables[i].offset;
1262
+ tableDir[pos+12] = (char)(newTables[i].len >> 24);
1263
+ tableDir[pos+13] = (char)(newTables[i].len >> 16);
1264
+ tableDir[pos+14] = (char)(newTables[i].len >> 8);
1265
+ tableDir[pos+15] = (char) newTables[i].len;
1266
+ pos += 16;
1267
+ }
1268
+ (*outputFunc)(outputStream, tableDir, 12 + nNewTables * 16);
1269
+
1270
+ // compute the file checksum
1271
+ fileChecksum = computeTableChecksum((Guchar *)tableDir,
1272
+ 12 + nNewTables * 16);
1273
+ for (i = 0; i < nNewTables; ++i) {
1274
+ fileChecksum += newTables[i].checksum;
1275
+ }
1276
+ fileChecksum = 0xb1b0afba - fileChecksum;
1277
+
1278
+ // write the tables
1279
+ for (i = 0; i < nNewTables; ++i) {
1280
+ if (newTables[i].tag == headTag) {
1281
+ if (checkRegion(newTables[i].origOffset, newTables[i].len)) {
1282
+ (*outputFunc)(outputStream, (char *)file + newTables[i].origOffset, 8);
1283
+ checksumBuf[0] = fileChecksum >> 24;
1284
+ checksumBuf[1] = fileChecksum >> 16;
1285
+ checksumBuf[2] = fileChecksum >> 8;
1286
+ checksumBuf[3] = fileChecksum;
1287
+ (*outputFunc)(outputStream, checksumBuf, 4);
1288
+ (*outputFunc)(outputStream,
1289
+ (char *)file + newTables[i].origOffset + 12,
1290
+ newTables[i].len - 12);
1291
+ } else {
1292
+ for (j = 0; j < newTables[i].len; ++j) {
1293
+ (*outputFunc)(outputStream, "\0", 1);
1294
+ }
1295
+ }
1296
+ } else if (newTables[i].tag == cmapTag && codeToGID) {
1297
+ (*outputFunc)(outputStream, newCmapTab, newTables[i].len);
1298
+ } else if (newTables[i].tag == cmapTag && missingCmap) {
1299
+ (*outputFunc)(outputStream, cmapTab, newTables[i].len);
1300
+ } else if (newTables[i].tag == nameTag && name) {
1301
+ (*outputFunc)(outputStream, newNameTab, newTables[i].len);
1302
+ } else if (newTables[i].tag == nameTag && missingName) {
1303
+ (*outputFunc)(outputStream, nameTab, newTables[i].len);
1304
+ } else if (newTables[i].tag == postTag && missingPost) {
1305
+ (*outputFunc)(outputStream, postTab, newTables[i].len);
1306
+ } else if (newTables[i].tag == os2Tag && missingOS2) {
1307
+ (*outputFunc)(outputStream, os2Tab, newTables[i].len);
1308
+ } else if (newTables[i].tag == hheaTag && abbrevHMTX) {
1309
+ (*outputFunc)(outputStream, newHHEATab, newTables[i].len);
1310
+ } else if (newTables[i].tag == hmtxTag && abbrevHMTX) {
1311
+ (*outputFunc)(outputStream, newHMTXTab, newTables[i].len);
1312
+ } else if (newTables[i].tag == locaTag && unsortedLoca) {
1313
+ for (j = 0; j <= nGlyphs; ++j) {
1314
+ if (locaFmt) {
1315
+ locaBuf[0] = (char)(locaTable[j].newOffset >> 24);
1316
+ locaBuf[1] = (char)(locaTable[j].newOffset >> 16);
1317
+ locaBuf[2] = (char)(locaTable[j].newOffset >> 8);
1318
+ locaBuf[3] = (char) locaTable[j].newOffset;
1319
+ (*outputFunc)(outputStream, locaBuf, 4);
1320
+ } else {
1321
+ locaBuf[0] = (char)(locaTable[j].newOffset >> 9);
1322
+ locaBuf[1] = (char)(locaTable[j].newOffset >> 1);
1323
+ (*outputFunc)(outputStream, locaBuf, 2);
1324
+ }
1325
+ }
1326
+ } else if (newTables[i].tag == glyfTag && unsortedLoca) {
1327
+ pos = tables[seekTable("glyf")].offset;
1328
+ for (j = 0; j < nGlyphs; ++j) {
1329
+ n = locaTable[j].len;
1330
+ if (n > 0) {
1331
+ k = locaTable[j].origOffset;
1332
+ if (checkRegion(pos + k, n)) {
1333
+ (*outputFunc)(outputStream, (char *)file + pos + k, n);
1334
+ } else {
1335
+ for (k = 0; k < n; ++k) {
1336
+ (*outputFunc)(outputStream, "\0", 1);
1337
+ }
1338
+ }
1339
+ if ((k = locaTable[j].len & 3)) {
1340
+ (*outputFunc)(outputStream, "\0\0\0\0", 4 - k);
1341
+ }
1342
+ }
1343
+ }
1344
+ } else {
1345
+ if (checkRegion(newTables[i].origOffset, newTables[i].len)) {
1346
+ (*outputFunc)(outputStream, (char *)file + newTables[i].origOffset,
1347
+ newTables[i].len);
1348
+ } else {
1349
+ for (j = 0; j < newTables[i].len; ++j) {
1350
+ (*outputFunc)(outputStream, "\0", 1);
1351
+ }
1352
+ }
1353
+ }
1354
+ if (newTables[i].len & 3) {
1355
+ (*outputFunc)(outputStream, "\0\0\0", 4 - (newTables[i].len & 3));
1356
+ }
1357
+ }
1358
+
1359
+ gfree(newHMTXTab);
1360
+ gfree(newHHEATab);
1361
+ gfree(newCmapTab);
1362
+ gfree(newNameTab);
1363
+ gfree(tableDir);
1364
+ gfree(newTables);
1365
+ done1:
1366
+ gfree(locaTable);
1367
+ }
1368
+
1369
+ void FoFiTrueType::cvtEncoding(char **encoding,
1370
+ FoFiOutputFunc outputFunc,
1371
+ void *outputStream) {
1372
+ char *name;
1373
+ GString *buf;
1374
+ int i;
1375
+
1376
+ (*outputFunc)(outputStream, "/Encoding 256 array\n", 20);
1377
+ if (encoding) {
1378
+ for (i = 0; i < 256; ++i) {
1379
+ if (!(name = encoding[i])) {
1380
+ name = ".notdef";
1381
+ }
1382
+ buf = GString::format("dup {0:d} /", i);
1383
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
1384
+ delete buf;
1385
+ (*outputFunc)(outputStream, name, strlen(name));
1386
+ (*outputFunc)(outputStream, " put\n", 5);
1387
+ }
1388
+ } else {
1389
+ for (i = 0; i < 256; ++i) {
1390
+ buf = GString::format("dup {0:d} /c{1:02x} put\n", i, i);
1391
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
1392
+ delete buf;
1393
+ }
1394
+ }
1395
+ (*outputFunc)(outputStream, "readonly def\n", 13);
1396
+ }
1397
+
1398
+ void FoFiTrueType::cvtCharStrings(char **encoding,
1399
+ Gushort *codeToGID,
1400
+ FoFiOutputFunc outputFunc,
1401
+ void *outputStream) {
1402
+ char *name;
1403
+ GString *buf;
1404
+ char buf2[16];
1405
+ int i, k;
1406
+
1407
+ // always define '.notdef'
1408
+ (*outputFunc)(outputStream, "/CharStrings 256 dict dup begin\n", 32);
1409
+ (*outputFunc)(outputStream, "/.notdef 0 def\n", 15);
1410
+
1411
+ // if there's no 'cmap' table, punt
1412
+ if (nCmaps == 0) {
1413
+ goto err;
1414
+ }
1415
+
1416
+ // map char name to glyph index:
1417
+ // 1. use encoding to map name to char code
1418
+ // 2. use codeToGID to map char code to glyph index
1419
+ // N.B. We do this in reverse order because font subsets can have
1420
+ // weird encodings that use the same character name twice, and
1421
+ // the first definition is probably the one we want.
1422
+ k = 0; // make gcc happy
1423
+ for (i = 255; i >= 0; --i) {
1424
+ if (encoding) {
1425
+ name = encoding[i];
1426
+ } else {
1427
+ sprintf(buf2, "c%02x", i);
1428
+ name = buf2;
1429
+ }
1430
+ if (name && strcmp(name, ".notdef")) {
1431
+ k = codeToGID[i];
1432
+ // note: Distiller (maybe Adobe's PS interpreter in general)
1433
+ // doesn't like TrueType fonts that have CharStrings entries
1434
+ // which point to nonexistent glyphs, hence the (k < nGlyphs)
1435
+ // test
1436
+ if (k > 0 && k < nGlyphs) {
1437
+ (*outputFunc)(outputStream, "/", 1);
1438
+ (*outputFunc)(outputStream, name, strlen(name));
1439
+ buf = GString::format(" {0:d} def\n", k);
1440
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
1441
+ delete buf;
1442
+ }
1443
+ }
1444
+ }
1445
+
1446
+ err:
1447
+ (*outputFunc)(outputStream, "end readonly def\n", 17);
1448
+ }
1449
+
1450
+ void FoFiTrueType::cvtSfnts(FoFiOutputFunc outputFunc,
1451
+ void *outputStream, GString *name,
1452
+ GBool needVerticalMetrics) {
1453
+ Guchar headData[54];
1454
+ TrueTypeLoca *locaTable;
1455
+ Guchar *locaData;
1456
+ TrueTypeTable newTables[nT42Tables];
1457
+ Guchar tableDir[12 + nT42Tables*16];
1458
+ GBool ok;
1459
+ Guint checksum;
1460
+ int nNewTables;
1461
+ int length, pos, glyfPos, i, j, k;
1462
+ Guchar vheaTab[36] = {
1463
+ 0, 1, 0, 0, // table version number
1464
+ 0, 0, // ascent
1465
+ 0, 0, // descent
1466
+ 0, 0, // reserved
1467
+ 0, 0, // max advance height
1468
+ 0, 0, // min top side bearing
1469
+ 0, 0, // min bottom side bearing
1470
+ 0, 0, // y max extent
1471
+ 0, 0, // caret slope rise
1472
+ 0, 1, // caret slope run
1473
+ 0, 0, // caret offset
1474
+ 0, 0, // reserved
1475
+ 0, 0, // reserved
1476
+ 0, 0, // reserved
1477
+ 0, 0, // reserved
1478
+ 0, 0, // metric data format
1479
+ 0, 1 // number of advance heights in vmtx table
1480
+ };
1481
+ Guchar *vmtxTab;
1482
+ GBool needVhea, needVmtx;
1483
+ int advance;
1484
+
1485
+ // construct the 'head' table, zero out the font checksum
1486
+ i = seekTable("head");
1487
+ pos = tables[i].offset;
1488
+ if (!checkRegion(pos, 54)) {
1489
+ return;
1490
+ }
1491
+ memcpy(headData, file + pos, 54);
1492
+ headData[8] = headData[9] = headData[10] = headData[11] = (Guchar)0;
1493
+
1494
+ // read the original 'loca' table, pad entries out to 4 bytes, and
1495
+ // sort it into proper order -- some (non-compliant) fonts have
1496
+ // out-of-order loca tables; in order to correctly handle the case
1497
+ // where (compliant) fonts have empty entries in the middle of the
1498
+ // table, cmpTrueTypeLocaPos uses offset as its primary sort key,
1499
+ // and idx as its secondary key (ensuring that adjacent entries with
1500
+ // the same pos value remain in the same order)
1501
+ locaTable = (TrueTypeLoca *)gmallocn(nGlyphs + 1, sizeof(TrueTypeLoca));
1502
+ i = seekTable("loca");
1503
+ pos = tables[i].offset;
1504
+ ok = gTrue;
1505
+ for (i = 0; i <= nGlyphs; ++i) {
1506
+ locaTable[i].idx = i;
1507
+ if (locaFmt) {
1508
+ locaTable[i].origOffset = (int)getU32BE(pos + i*4, &ok);
1509
+ } else {
1510
+ locaTable[i].origOffset = 2 * getU16BE(pos + i*2, &ok);
1511
+ }
1512
+ }
1513
+ qsort(locaTable, nGlyphs + 1, sizeof(TrueTypeLoca),
1514
+ &cmpTrueTypeLocaOffset);
1515
+ for (i = 0; i < nGlyphs; ++i) {
1516
+ locaTable[i].len = locaTable[i+1].origOffset - locaTable[i].origOffset;
1517
+ }
1518
+ locaTable[nGlyphs].len = 0;
1519
+ qsort(locaTable, nGlyphs + 1, sizeof(TrueTypeLoca),
1520
+ &cmpTrueTypeLocaIdx);
1521
+ pos = 0;
1522
+ for (i = 0; i <= nGlyphs; ++i) {
1523
+ locaTable[i].newOffset = pos;
1524
+ pos += locaTable[i].len;
1525
+ if (pos & 3) {
1526
+ pos += 4 - (pos & 3);
1527
+ }
1528
+ }
1529
+
1530
+ // construct the new 'loca' table
1531
+ locaData = (Guchar *)gmallocn(nGlyphs + 1, (locaFmt ? 4 : 2));
1532
+ for (i = 0; i <= nGlyphs; ++i) {
1533
+ pos = locaTable[i].newOffset;
1534
+ if (locaFmt) {
1535
+ locaData[4*i ] = (Guchar)(pos >> 24);
1536
+ locaData[4*i+1] = (Guchar)(pos >> 16);
1537
+ locaData[4*i+2] = (Guchar)(pos >> 8);
1538
+ locaData[4*i+3] = (Guchar) pos;
1539
+ } else {
1540
+ locaData[2*i ] = (Guchar)(pos >> 9);
1541
+ locaData[2*i+1] = (Guchar)(pos >> 1);
1542
+ }
1543
+ }
1544
+
1545
+ // count the number of tables
1546
+ nNewTables = 0;
1547
+ for (i = 0; i < nT42Tables; ++i) {
1548
+ if (t42Tables[i].required ||
1549
+ seekTable(t42Tables[i].tag) >= 0) {
1550
+ ++nNewTables;
1551
+ }
1552
+ }
1553
+ vmtxTab = NULL; // make gcc happy
1554
+ advance = 0; // make gcc happy
1555
+ if (needVerticalMetrics) {
1556
+ needVhea = seekTable("vhea") < 0;
1557
+ needVmtx = seekTable("vmtx") < 0;
1558
+ if (needVhea || needVmtx) {
1559
+ i = seekTable("head");
1560
+ advance = getU16BE(tables[i].offset + 18, &ok); // units per em
1561
+ if (needVhea) {
1562
+ ++nNewTables;
1563
+ }
1564
+ if (needVmtx) {
1565
+ ++nNewTables;
1566
+ }
1567
+ }
1568
+ }
1569
+
1570
+ // construct the new table headers, including table checksums
1571
+ // (pad each table out to a multiple of 4 bytes)
1572
+ pos = 12 + nNewTables*16;
1573
+ k = 0;
1574
+ for (i = 0; i < nT42Tables; ++i) {
1575
+ length = -1;
1576
+ checksum = 0; // make gcc happy
1577
+ if (i == t42HeadTable) {
1578
+ length = 54;
1579
+ checksum = computeTableChecksum(headData, 54);
1580
+ } else if (i == t42LocaTable) {
1581
+ length = (nGlyphs + 1) * (locaFmt ? 4 : 2);
1582
+ checksum = computeTableChecksum(locaData, length);
1583
+ } else if (i == t42GlyfTable) {
1584
+ length = 0;
1585
+ checksum = 0;
1586
+ glyfPos = tables[seekTable("glyf")].offset;
1587
+ for (j = 0; j < nGlyphs; ++j) {
1588
+ length += locaTable[j].len;
1589
+ if (length & 3) {
1590
+ length += 4 - (length & 3);
1591
+ }
1592
+ if (checkRegion(glyfPos + locaTable[j].origOffset, locaTable[j].len)) {
1593
+ checksum +=
1594
+ computeTableChecksum(file + glyfPos + locaTable[j].origOffset,
1595
+ locaTable[j].len);
1596
+ }
1597
+ }
1598
+ } else {
1599
+ if ((j = seekTable(t42Tables[i].tag)) >= 0) {
1600
+ length = tables[j].len;
1601
+ if (checkRegion(tables[j].offset, length)) {
1602
+ checksum = computeTableChecksum(file + tables[j].offset, length);
1603
+ }
1604
+ } else if (needVerticalMetrics && i == t42VheaTable) {
1605
+ vheaTab[10] = advance / 256; // max advance height
1606
+ vheaTab[11] = advance % 256;
1607
+ length = sizeof(vheaTab);
1608
+ checksum = computeTableChecksum(vheaTab, length);
1609
+ } else if (needVerticalMetrics && i == t42VmtxTable) {
1610
+ length = 4 + (nGlyphs - 1) * 4;
1611
+ vmtxTab = (Guchar *)gmalloc(length);
1612
+ vmtxTab[0] = advance / 256;
1613
+ vmtxTab[1] = advance % 256;
1614
+ for (j = 2; j < length; j += 2) {
1615
+ vmtxTab[j] = 0;
1616
+ vmtxTab[j+1] = 0;
1617
+ }
1618
+ checksum = computeTableChecksum(vmtxTab, length);
1619
+ } else if (t42Tables[i].required) {
1620
+ //~ error(-1, "Embedded TrueType font is missing a required table ('%s')",
1621
+ //~ t42Tables[i].tag);
1622
+ length = 0;
1623
+ checksum = 0;
1624
+ }
1625
+ }
1626
+ if (length >= 0) {
1627
+ newTables[k].tag = ((t42Tables[i].tag[0] & 0xff) << 24) |
1628
+ ((t42Tables[i].tag[1] & 0xff) << 16) |
1629
+ ((t42Tables[i].tag[2] & 0xff) << 8) |
1630
+ (t42Tables[i].tag[3] & 0xff);
1631
+ newTables[k].checksum = checksum;
1632
+ newTables[k].offset = pos;
1633
+ newTables[k].len = length;
1634
+ pos += length;
1635
+ if (pos & 3) {
1636
+ pos += 4 - (length & 3);
1637
+ }
1638
+ ++k;
1639
+ }
1640
+ }
1641
+
1642
+ // construct the table directory
1643
+ tableDir[0] = 0x00; // sfnt version
1644
+ tableDir[1] = 0x01;
1645
+ tableDir[2] = 0x00;
1646
+ tableDir[3] = 0x00;
1647
+ tableDir[4] = 0; // numTables
1648
+ tableDir[5] = nNewTables;
1649
+ tableDir[6] = 0; // searchRange
1650
+ tableDir[7] = (Guchar)128;
1651
+ tableDir[8] = 0; // entrySelector
1652
+ tableDir[9] = 3;
1653
+ tableDir[10] = 0; // rangeShift
1654
+ tableDir[11] = (Guchar)(16 * nNewTables - 128);
1655
+ pos = 12;
1656
+ for (i = 0; i < nNewTables; ++i) {
1657
+ tableDir[pos ] = (Guchar)(newTables[i].tag >> 24);
1658
+ tableDir[pos+ 1] = (Guchar)(newTables[i].tag >> 16);
1659
+ tableDir[pos+ 2] = (Guchar)(newTables[i].tag >> 8);
1660
+ tableDir[pos+ 3] = (Guchar) newTables[i].tag;
1661
+ tableDir[pos+ 4] = (Guchar)(newTables[i].checksum >> 24);
1662
+ tableDir[pos+ 5] = (Guchar)(newTables[i].checksum >> 16);
1663
+ tableDir[pos+ 6] = (Guchar)(newTables[i].checksum >> 8);
1664
+ tableDir[pos+ 7] = (Guchar) newTables[i].checksum;
1665
+ tableDir[pos+ 8] = (Guchar)(newTables[i].offset >> 24);
1666
+ tableDir[pos+ 9] = (Guchar)(newTables[i].offset >> 16);
1667
+ tableDir[pos+10] = (Guchar)(newTables[i].offset >> 8);
1668
+ tableDir[pos+11] = (Guchar) newTables[i].offset;
1669
+ tableDir[pos+12] = (Guchar)(newTables[i].len >> 24);
1670
+ tableDir[pos+13] = (Guchar)(newTables[i].len >> 16);
1671
+ tableDir[pos+14] = (Guchar)(newTables[i].len >> 8);
1672
+ tableDir[pos+15] = (Guchar) newTables[i].len;
1673
+ pos += 16;
1674
+ }
1675
+
1676
+ // compute the font checksum and store it in the head table
1677
+ checksum = computeTableChecksum(tableDir, 12 + nNewTables*16);
1678
+ for (i = 0; i < nNewTables; ++i) {
1679
+ checksum += newTables[i].checksum;
1680
+ }
1681
+ checksum = 0xb1b0afba - checksum; // because the TrueType spec says so
1682
+ headData[ 8] = (Guchar)(checksum >> 24);
1683
+ headData[ 9] = (Guchar)(checksum >> 16);
1684
+ headData[10] = (Guchar)(checksum >> 8);
1685
+ headData[11] = (Guchar) checksum;
1686
+
1687
+ // start the sfnts array
1688
+ if (name) {
1689
+ (*outputFunc)(outputStream, "/", 1);
1690
+ (*outputFunc)(outputStream, name->getCString(), name->getLength());
1691
+ (*outputFunc)(outputStream, " [\n", 3);
1692
+ } else {
1693
+ (*outputFunc)(outputStream, "/sfnts [\n", 9);
1694
+ }
1695
+
1696
+ // write the table directory
1697
+ dumpString(tableDir, 12 + nNewTables*16, outputFunc, outputStream);
1698
+
1699
+ // write the tables
1700
+ for (i = 0; i < nNewTables; ++i) {
1701
+ if (i == t42HeadTable) {
1702
+ dumpString(headData, 54, outputFunc, outputStream);
1703
+ } else if (i == t42LocaTable) {
1704
+ length = (nGlyphs + 1) * (locaFmt ? 4 : 2);
1705
+ dumpString(locaData, length, outputFunc, outputStream);
1706
+ } else if (i == t42GlyfTable) {
1707
+ glyfPos = tables[seekTable("glyf")].offset;
1708
+ for (j = 0; j < nGlyphs; ++j) {
1709
+ if (locaTable[j].len > 0 &&
1710
+ checkRegion(glyfPos + locaTable[j].origOffset, locaTable[j].len)) {
1711
+ dumpString(file + glyfPos + locaTable[j].origOffset,
1712
+ locaTable[j].len, outputFunc, outputStream);
1713
+ }
1714
+ }
1715
+ } else {
1716
+ // length == 0 means the table is missing and the error was
1717
+ // already reported during the construction of the table
1718
+ // headers
1719
+ if ((length = newTables[i].len) > 0) {
1720
+ if ((j = seekTable(t42Tables[i].tag)) >= 0 &&
1721
+ checkRegion(tables[j].offset, tables[j].len)) {
1722
+ dumpString(file + tables[j].offset, tables[j].len,
1723
+ outputFunc, outputStream);
1724
+ } else if (needVerticalMetrics && i == t42VheaTable) {
1725
+ dumpString(vheaTab, length, outputFunc, outputStream);
1726
+ } else if (needVerticalMetrics && i == t42VmtxTable) {
1727
+ dumpString(vmtxTab, length, outputFunc, outputStream);
1728
+ gfree(vmtxTab);
1729
+ }
1730
+ }
1731
+ }
1732
+ }
1733
+
1734
+ // end the sfnts array
1735
+ (*outputFunc)(outputStream, "] def\n", 6);
1736
+
1737
+ gfree(locaData);
1738
+ gfree(locaTable);
1739
+ }
1740
+
1741
+ void FoFiTrueType::dumpString(Guchar *s, int length,
1742
+ FoFiOutputFunc outputFunc,
1743
+ void *outputStream) {
1744
+ GString *buf;
1745
+ int pad, i, j;
1746
+
1747
+ (*outputFunc)(outputStream, "<", 1);
1748
+ for (i = 0; i < length; i += 32) {
1749
+ for (j = 0; j < 32 && i+j < length; ++j) {
1750
+ buf = GString::format("{0:02x}", s[i+j] & 0xff);
1751
+ (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
1752
+ delete buf;
1753
+ }
1754
+ if (i % (65536 - 32) == 65536 - 64) {
1755
+ (*outputFunc)(outputStream, ">\n<", 3);
1756
+ } else if (i+32 < length) {
1757
+ (*outputFunc)(outputStream, "\n", 1);
1758
+ }
1759
+ }
1760
+ if (length & 3) {
1761
+ pad = 4 - (length & 3);
1762
+ for (i = 0; i < pad; ++i) {
1763
+ (*outputFunc)(outputStream, "00", 2);
1764
+ }
1765
+ }
1766
+ // add an extra zero byte because the Adobe Type 42 spec says so
1767
+ (*outputFunc)(outputStream, "00>\n", 4);
1768
+ }
1769
+
1770
+ Guint FoFiTrueType::computeTableChecksum(Guchar *data, int length) {
1771
+ Guint checksum, word;
1772
+ int i;
1773
+
1774
+ checksum = 0;
1775
+ for (i = 0; i+3 < length; i += 4) {
1776
+ word = ((data[i ] & 0xff) << 24) +
1777
+ ((data[i+1] & 0xff) << 16) +
1778
+ ((data[i+2] & 0xff) << 8) +
1779
+ (data[i+3] & 0xff);
1780
+ checksum += word;
1781
+ }
1782
+ if (length & 3) {
1783
+ word = 0;
1784
+ i = length & ~3;
1785
+ switch (length & 3) {
1786
+ case 3:
1787
+ word |= (data[i+2] & 0xff) << 8;
1788
+ case 2:
1789
+ word |= (data[i+1] & 0xff) << 16;
1790
+ case 1:
1791
+ word |= (data[i ] & 0xff) << 24;
1792
+ break;
1793
+ }
1794
+ checksum += word;
1795
+ }
1796
+ return checksum;
1797
+ }
1798
+
1799
+ void FoFiTrueType::parse() {
1800
+ Guint topTag;
1801
+ int pos, ver, i, j;
1802
+
1803
+ parsedOk = gTrue;
1804
+
1805
+ // look for a collection (TTC)
1806
+ topTag = getU32BE(0, &parsedOk);
1807
+ if (!parsedOk) {
1808
+ return;
1809
+ }
1810
+ if (topTag == ttcfTag) {
1811
+ pos = getU32BE(12, &parsedOk);
1812
+ if (!parsedOk) {
1813
+ return;
1814
+ }
1815
+ } else {
1816
+ pos = 0;
1817
+ }
1818
+
1819
+ // check the sfnt version
1820
+ ver = getU32BE(pos, &parsedOk);
1821
+ if (!parsedOk) {
1822
+ return;
1823
+ }
1824
+ openTypeCFF = ver == 0x4f54544f; // 'OTTO'
1825
+
1826
+ // read the table directory
1827
+ nTables = getU16BE(pos + 4, &parsedOk);
1828
+ if (!parsedOk) {
1829
+ return;
1830
+ }
1831
+ tables = (TrueTypeTable *)gmallocn(nTables, sizeof(TrueTypeTable));
1832
+ pos += 12;
1833
+ for (i = 0; i < nTables; ++i) {
1834
+ tables[i].tag = getU32BE(pos, &parsedOk);
1835
+ tables[i].checksum = getU32BE(pos + 4, &parsedOk);
1836
+ tables[i].offset = (int)getU32BE(pos + 8, &parsedOk);
1837
+ tables[i].len = (int)getU32BE(pos + 12, &parsedOk);
1838
+ if (tables[i].offset + tables[i].len < tables[i].offset ||
1839
+ tables[i].offset + tables[i].len > len) {
1840
+ parsedOk = gFalse;
1841
+ }
1842
+ pos += 16;
1843
+ }
1844
+ if (!parsedOk) {
1845
+ return;
1846
+ }
1847
+
1848
+ // check for tables that are required by both the TrueType spec and
1849
+ // the Type 42 spec
1850
+ if (seekTable("head") < 0 ||
1851
+ seekTable("hhea") < 0 ||
1852
+ seekTable("maxp") < 0 ||
1853
+ seekTable("hmtx") < 0 ||
1854
+ (!openTypeCFF && seekTable("loca") < 0) ||
1855
+ (!openTypeCFF && seekTable("glyf") < 0) ||
1856
+ (openTypeCFF && seekTable("CFF ") < 0)) {
1857
+ parsedOk = gFalse;
1858
+ return;
1859
+ }
1860
+
1861
+ // read the cmaps
1862
+ if ((i = seekTable("cmap")) >= 0) {
1863
+ pos = tables[i].offset + 2;
1864
+ nCmaps = getU16BE(pos, &parsedOk);
1865
+ pos += 2;
1866
+ if (!parsedOk) {
1867
+ return;
1868
+ }
1869
+ cmaps = (TrueTypeCmap *)gmallocn(nCmaps, sizeof(TrueTypeCmap));
1870
+ for (j = 0; j < nCmaps; ++j) {
1871
+ cmaps[j].platform = getU16BE(pos, &parsedOk);
1872
+ cmaps[j].encoding = getU16BE(pos + 2, &parsedOk);
1873
+ cmaps[j].offset = tables[i].offset + getU32BE(pos + 4, &parsedOk);
1874
+ pos += 8;
1875
+ cmaps[j].fmt = getU16BE(cmaps[j].offset, &parsedOk);
1876
+ cmaps[j].len = getU16BE(cmaps[j].offset + 2, &parsedOk);
1877
+ }
1878
+ if (!parsedOk) {
1879
+ return;
1880
+ }
1881
+ } else {
1882
+ nCmaps = 0;
1883
+ }
1884
+
1885
+ // get the number of glyphs from the maxp table
1886
+ i = seekTable("maxp");
1887
+ nGlyphs = getU16BE(tables[i].offset + 4, &parsedOk);
1888
+ if (!parsedOk) {
1889
+ return;
1890
+ }
1891
+
1892
+ // get the bbox and loca table format from the head table
1893
+ i = seekTable("head");
1894
+ bbox[0] = getS16BE(tables[i].offset + 36, &parsedOk);
1895
+ bbox[1] = getS16BE(tables[i].offset + 38, &parsedOk);
1896
+ bbox[2] = getS16BE(tables[i].offset + 40, &parsedOk);
1897
+ bbox[3] = getS16BE(tables[i].offset + 42, &parsedOk);
1898
+ locaFmt = getS16BE(tables[i].offset + 50, &parsedOk);
1899
+ if (!parsedOk) {
1900
+ return;
1901
+ }
1902
+
1903
+ // make sure the loca table is sane (correct length and entries are
1904
+ // in bounds)
1905
+ if (!openTypeCFF) {
1906
+ i = seekTable("loca");
1907
+ if (tables[i].len < 0) {
1908
+ parsedOk = gFalse;
1909
+ return;
1910
+ }
1911
+ if (tables[i].len < (nGlyphs + 1) * (locaFmt ? 4 : 2)) {
1912
+ nGlyphs = tables[i].len / (locaFmt ? 4 : 2) - 1;
1913
+ }
1914
+ for (j = 0; j <= nGlyphs; ++j) {
1915
+ if (locaFmt) {
1916
+ pos = (int)getU32BE(tables[i].offset + j*4, &parsedOk);
1917
+ } else {
1918
+ pos = getU16BE(tables[i].offset + j*2, &parsedOk);
1919
+ }
1920
+ if (pos < 0 || pos > len) {
1921
+ parsedOk = gFalse;
1922
+ }
1923
+ }
1924
+ if (!parsedOk) {
1925
+ return;
1926
+ }
1927
+ }
1928
+
1929
+ // read the post table
1930
+ readPostTable();
1931
+ }
1932
+
1933
+ void FoFiTrueType::readPostTable() {
1934
+ GString *name;
1935
+ int tablePos, postFmt, stringIdx, stringPos;
1936
+ GBool ok;
1937
+ int i, j, n, m;
1938
+
1939
+ ok = gTrue;
1940
+ if ((i = seekTable("post")) < 0) {
1941
+ return;
1942
+ }
1943
+ tablePos = tables[i].offset;
1944
+ postFmt = getU32BE(tablePos, &ok);
1945
+ if (!ok) {
1946
+ goto err;
1947
+ }
1948
+ if (postFmt == 0x00010000) {
1949
+ nameToGID = new GHash(gTrue);
1950
+ for (i = 0; i < 258; ++i) {
1951
+ nameToGID->add(new GString(macGlyphNames[i]), i);
1952
+ }
1953
+ } else if (postFmt == 0x00020000) {
1954
+ nameToGID = new GHash(gTrue);
1955
+ n = getU16BE(tablePos + 32, &ok);
1956
+ if (!ok) {
1957
+ goto err;
1958
+ }
1959
+ if (n > nGlyphs) {
1960
+ n = nGlyphs;
1961
+ }
1962
+ stringIdx = 0;
1963
+ stringPos = tablePos + 34 + 2*n;
1964
+ for (i = 0; i < n; ++i) {
1965
+ j = getU16BE(tablePos + 34 + 2*i, &ok);
1966
+ if (j < 258) {
1967
+ nameToGID->removeInt(macGlyphNames[j]);
1968
+ nameToGID->add(new GString(macGlyphNames[j]), i);
1969
+ } else {
1970
+ j -= 258;
1971
+ if (j != stringIdx) {
1972
+ for (stringIdx = 0, stringPos = tablePos + 34 + 2*n;
1973
+ stringIdx < j;
1974
+ ++stringIdx, stringPos += 1 + getU8(stringPos, &ok)) ;
1975
+ if (!ok) {
1976
+ goto err;
1977
+ }
1978
+ }
1979
+ m = getU8(stringPos, &ok);
1980
+ if (!ok || !checkRegion(stringPos + 1, m)) {
1981
+ goto err;
1982
+ }
1983
+ name = new GString((char *)&file[stringPos + 1], m);
1984
+ nameToGID->removeInt(name);
1985
+ nameToGID->add(name, i);
1986
+ ++stringIdx;
1987
+ stringPos += 1 + m;
1988
+ }
1989
+ }
1990
+ } else if (postFmt == 0x00028000) {
1991
+ nameToGID = new GHash(gTrue);
1992
+ for (i = 0; i < nGlyphs; ++i) {
1993
+ j = getU8(tablePos + 32 + i, &ok);
1994
+ if (!ok) {
1995
+ goto err;
1996
+ }
1997
+ if (j < 258) {
1998
+ nameToGID->removeInt(macGlyphNames[j]);
1999
+ nameToGID->add(new GString(macGlyphNames[j]), i);
2000
+ }
2001
+ }
2002
+ }
2003
+
2004
+ return;
2005
+
2006
+ err:
2007
+ if (nameToGID) {
2008
+ delete nameToGID;
2009
+ nameToGID = NULL;
2010
+ }
2011
+ }
2012
+
2013
+ int FoFiTrueType::seekTable(char *tag) {
2014
+ Guint tagI;
2015
+ int i;
2016
+
2017
+ tagI = ((tag[0] & 0xff) << 24) |
2018
+ ((tag[1] & 0xff) << 16) |
2019
+ ((tag[2] & 0xff) << 8) |
2020
+ (tag[3] & 0xff);
2021
+ for (i = 0; i < nTables; ++i) {
2022
+ if (tables[i].tag == tagI) {
2023
+ return i;
2024
+ }
2025
+ }
2026
+ return -1;
2027
+ }