pdf2json 0.1.0

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