pdf-cmap-load.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. // Copyright (C) 2004-2024 Artifex Software, Inc.
  2. //
  3. // This file is part of MuPDF.
  4. //
  5. // MuPDF is free software: you can redistribute it and/or modify it under the
  6. // terms of the GNU Affero General Public License as published by the Free
  7. // Software Foundation, either version 3 of the License, or (at your option)
  8. // any later version.
  9. //
  10. // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
  11. // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. // details.
  14. //
  15. // You should have received a copy of the GNU Affero General Public License
  16. // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
  17. //
  18. // Alternative licensing terms are available from the licensor.
  19. // For commercial licensing, see <https://www.artifex.com/> or contact
  20. // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  21. // CA 94129, USA, for further information.
  22. #include "mupdf/fitz.h"
  23. #include "mupdf/pdf.h"
  24. #include "cmaps/TrueType-UCS2.h"
  25. #include <string.h>
  26. static pdf_cmap *
  27. pdf_load_embedded_cmap_imp(fz_context *ctx, pdf_document *doc, pdf_obj *stmobj, pdf_cycle_list *cycle_up)
  28. {
  29. pdf_cycle_list cycle;
  30. fz_stream *file = NULL;
  31. pdf_cmap *cmap = NULL;
  32. pdf_cmap *usecmap = NULL;
  33. pdf_obj *obj;
  34. fz_var(file);
  35. fz_var(cmap);
  36. fz_var(usecmap);
  37. if ((cmap = pdf_find_item(ctx, pdf_drop_cmap_imp, stmobj)) != NULL)
  38. return cmap;
  39. fz_try(ctx)
  40. {
  41. file = pdf_open_stream(ctx, stmobj);
  42. cmap = pdf_load_cmap(ctx, file);
  43. obj = pdf_dict_get(ctx, stmobj, PDF_NAME(WMode));
  44. if (pdf_is_int(ctx, obj))
  45. pdf_set_cmap_wmode(ctx, cmap, pdf_to_int(ctx, obj));
  46. obj = pdf_dict_get(ctx, stmobj, PDF_NAME(UseCMap));
  47. if (pdf_is_name(ctx, obj))
  48. {
  49. fz_try(ctx)
  50. {
  51. usecmap = pdf_load_system_cmap(ctx, pdf_to_name(ctx, obj));
  52. pdf_set_usecmap(ctx, cmap, usecmap);
  53. }
  54. fz_catch(ctx)
  55. {
  56. fz_rethrow_if(ctx, FZ_ERROR_SYSTEM);
  57. fz_report_error(ctx);
  58. fz_warn(ctx, "cannot load system CMap: %s", pdf_to_name(ctx, obj));
  59. }
  60. }
  61. else if (pdf_is_indirect(ctx, obj))
  62. {
  63. if (pdf_cycle(ctx, &cycle, cycle_up, obj))
  64. fz_throw(ctx, FZ_ERROR_FORMAT, "recursive CMap");
  65. usecmap = pdf_load_embedded_cmap_imp(ctx, doc, obj, &cycle);
  66. pdf_set_usecmap(ctx, cmap, usecmap);
  67. }
  68. else if (strlen(cmap->usecmap_name) > 0)
  69. {
  70. fz_try(ctx)
  71. {
  72. usecmap = pdf_load_system_cmap(ctx, cmap->usecmap_name);
  73. pdf_set_usecmap(ctx, cmap, usecmap);
  74. }
  75. fz_catch(ctx)
  76. {
  77. fz_rethrow_if(ctx, FZ_ERROR_SYSTEM);
  78. fz_report_error(ctx);
  79. fz_warn(ctx, "cannot load system CMap: %s", pdf_to_name(ctx, obj));
  80. }
  81. }
  82. pdf_store_item(ctx, stmobj, cmap, pdf_cmap_size(ctx, cmap));
  83. }
  84. fz_always(ctx)
  85. {
  86. fz_drop_stream(ctx, file);
  87. pdf_drop_cmap(ctx, usecmap);
  88. }
  89. fz_catch(ctx)
  90. {
  91. pdf_drop_cmap(ctx, cmap);
  92. fz_rethrow(ctx);
  93. }
  94. return cmap;
  95. }
  96. pdf_cmap *
  97. pdf_load_embedded_cmap(fz_context *ctx, pdf_document *doc, pdf_obj *stmobj)
  98. {
  99. return pdf_load_embedded_cmap_imp(ctx, doc, stmobj, NULL);
  100. }
  101. pdf_cmap *
  102. pdf_new_identity_cmap(fz_context *ctx, int wmode, int bytes)
  103. {
  104. pdf_cmap *cmap = pdf_new_cmap(ctx);
  105. fz_try(ctx)
  106. {
  107. unsigned int high = (1 << (bytes * 8)) - 1;
  108. if (wmode)
  109. fz_strlcpy(cmap->cmap_name, "Identity-V", sizeof cmap->cmap_name);
  110. else
  111. fz_strlcpy(cmap->cmap_name, "Identity-H", sizeof cmap->cmap_name);
  112. pdf_add_codespace(ctx, cmap, 0, high, bytes);
  113. pdf_map_range_to_range(ctx, cmap, 0, high, 0);
  114. pdf_sort_cmap(ctx, cmap);
  115. pdf_set_cmap_wmode(ctx, cmap, wmode);
  116. }
  117. fz_catch(ctx)
  118. {
  119. pdf_drop_cmap(ctx, cmap);
  120. fz_rethrow(ctx);
  121. }
  122. return cmap;
  123. }
  124. #ifdef NO_CJK
  125. pdf_cmap *
  126. pdf_load_builtin_cmap(fz_context *ctx, const char *name)
  127. {
  128. if (!strcmp(name, "Identity-H")) return pdf_new_identity_cmap(ctx, 0, 2);
  129. if (!strcmp(name, "Identity-V")) return pdf_new_identity_cmap(ctx, 1, 2);
  130. if (!strcmp(name, "TrueType-UCS2")) return &cmap_TrueType_UCS2;
  131. return NULL;
  132. }
  133. #else
  134. /* To regenerate this list: :r !bash scripts/runcmapdump.sh */
  135. #include "cmaps/83pv-RKSJ-H.h"
  136. #include "cmaps/90ms-RKSJ-H.h"
  137. #include "cmaps/90ms-RKSJ-V.h"
  138. #include "cmaps/90msp-RKSJ-H.h"
  139. #include "cmaps/90msp-RKSJ-V.h"
  140. #include "cmaps/90pv-RKSJ-H.h"
  141. #include "cmaps/Add-RKSJ-H.h"
  142. #include "cmaps/Add-RKSJ-V.h"
  143. #include "cmaps/Adobe-CNS1-UCS2.h"
  144. #include "cmaps/Adobe-GB1-UCS2.h"
  145. #include "cmaps/Adobe-Japan1-UCS2.h"
  146. #include "cmaps/Adobe-Korea1-UCS2.h"
  147. #include "cmaps/B5pc-H.h"
  148. #include "cmaps/B5pc-V.h"
  149. #include "cmaps/CNS-EUC-H.h"
  150. #include "cmaps/CNS-EUC-V.h"
  151. #include "cmaps/ETen-B5-H.h"
  152. #include "cmaps/ETen-B5-V.h"
  153. #include "cmaps/ETenms-B5-H.h"
  154. #include "cmaps/ETenms-B5-V.h"
  155. #include "cmaps/EUC-H.h"
  156. #include "cmaps/EUC-V.h"
  157. #include "cmaps/Ext-RKSJ-H.h"
  158. #include "cmaps/Ext-RKSJ-V.h"
  159. #include "cmaps/GB-EUC-H.h"
  160. #include "cmaps/GB-EUC-V.h"
  161. #include "cmaps/GBK-EUC-H.h"
  162. #include "cmaps/GBK-EUC-V.h"
  163. #include "cmaps/GBK-X.h"
  164. #include "cmaps/GBK2K-H.h"
  165. #include "cmaps/GBK2K-V.h"
  166. #include "cmaps/GBKp-EUC-H.h"
  167. #include "cmaps/GBKp-EUC-V.h"
  168. #include "cmaps/GBpc-EUC-H.h"
  169. #include "cmaps/GBpc-EUC-V.h"
  170. #include "cmaps/H.h"
  171. #include "cmaps/HKscs-B5-H.h"
  172. #include "cmaps/HKscs-B5-V.h"
  173. #include "cmaps/Identity-H.h"
  174. #include "cmaps/Identity-V.h"
  175. #include "cmaps/KSC-EUC-H.h"
  176. #include "cmaps/KSC-EUC-V.h"
  177. #include "cmaps/KSCms-UHC-H.h"
  178. #include "cmaps/KSCms-UHC-HW-H.h"
  179. #include "cmaps/KSCms-UHC-HW-V.h"
  180. #include "cmaps/KSCms-UHC-V.h"
  181. #include "cmaps/KSCpc-EUC-H.h"
  182. #include "cmaps/UniCNS-UCS2-H.h"
  183. #include "cmaps/UniCNS-UCS2-V.h"
  184. #include "cmaps/UniCNS-UTF16-H.h"
  185. #include "cmaps/UniCNS-UTF16-V.h"
  186. #include "cmaps/UniCNS-X.h"
  187. #include "cmaps/UniGB-UCS2-H.h"
  188. #include "cmaps/UniGB-UCS2-V.h"
  189. #include "cmaps/UniGB-UTF16-H.h"
  190. #include "cmaps/UniGB-UTF16-V.h"
  191. #include "cmaps/UniGB-X.h"
  192. #include "cmaps/UniJIS-UCS2-H.h"
  193. #include "cmaps/UniJIS-UCS2-HW-H.h"
  194. #include "cmaps/UniJIS-UCS2-HW-V.h"
  195. #include "cmaps/UniJIS-UCS2-V.h"
  196. #include "cmaps/UniJIS-UTF16-H.h"
  197. #include "cmaps/UniJIS-UTF16-V.h"
  198. #include "cmaps/UniJIS-X.h"
  199. #include "cmaps/UniKS-UCS2-H.h"
  200. #include "cmaps/UniKS-UCS2-V.h"
  201. #include "cmaps/UniKS-UTF16-H.h"
  202. #include "cmaps/UniKS-UTF16-V.h"
  203. #include "cmaps/UniKS-X.h"
  204. #include "cmaps/V.h"
  205. static pdf_cmap *table[] = {
  206. &cmap_83pv_RKSJ_H,
  207. &cmap_90ms_RKSJ_H,
  208. &cmap_90ms_RKSJ_V,
  209. &cmap_90msp_RKSJ_H,
  210. &cmap_90msp_RKSJ_V,
  211. &cmap_90pv_RKSJ_H,
  212. &cmap_Add_RKSJ_H,
  213. &cmap_Add_RKSJ_V,
  214. &cmap_Adobe_CNS1_UCS2,
  215. &cmap_Adobe_GB1_UCS2,
  216. &cmap_Adobe_Japan1_UCS2,
  217. &cmap_Adobe_Korea1_UCS2,
  218. &cmap_B5pc_H,
  219. &cmap_B5pc_V,
  220. &cmap_CNS_EUC_H,
  221. &cmap_CNS_EUC_V,
  222. &cmap_ETen_B5_H,
  223. &cmap_ETen_B5_V,
  224. &cmap_ETenms_B5_H,
  225. &cmap_ETenms_B5_V,
  226. &cmap_EUC_H,
  227. &cmap_EUC_V,
  228. &cmap_Ext_RKSJ_H,
  229. &cmap_Ext_RKSJ_V,
  230. &cmap_GB_EUC_H,
  231. &cmap_GB_EUC_V,
  232. &cmap_GBK_EUC_H,
  233. &cmap_GBK_EUC_V,
  234. &cmap_GBK_X,
  235. &cmap_GBK2K_H,
  236. &cmap_GBK2K_V,
  237. &cmap_GBKp_EUC_H,
  238. &cmap_GBKp_EUC_V,
  239. &cmap_GBpc_EUC_H,
  240. &cmap_GBpc_EUC_V,
  241. &cmap_H,
  242. &cmap_HKscs_B5_H,
  243. &cmap_HKscs_B5_V,
  244. &cmap_Identity_H,
  245. &cmap_Identity_V,
  246. &cmap_KSC_EUC_H,
  247. &cmap_KSC_EUC_V,
  248. &cmap_KSCms_UHC_H,
  249. &cmap_KSCms_UHC_HW_H,
  250. &cmap_KSCms_UHC_HW_V,
  251. &cmap_KSCms_UHC_V,
  252. &cmap_KSCpc_EUC_H,
  253. &cmap_TrueType_UCS2,
  254. &cmap_UniCNS_UCS2_H,
  255. &cmap_UniCNS_UCS2_V,
  256. &cmap_UniCNS_UTF16_H,
  257. &cmap_UniCNS_UTF16_V,
  258. &cmap_UniCNS_X,
  259. &cmap_UniGB_UCS2_H,
  260. &cmap_UniGB_UCS2_V,
  261. &cmap_UniGB_UTF16_H,
  262. &cmap_UniGB_UTF16_V,
  263. &cmap_UniGB_X,
  264. &cmap_UniJIS_UCS2_H,
  265. &cmap_UniJIS_UCS2_HW_H,
  266. &cmap_UniJIS_UCS2_HW_V,
  267. &cmap_UniJIS_UCS2_V,
  268. &cmap_UniJIS_UTF16_H,
  269. &cmap_UniJIS_UTF16_V,
  270. &cmap_UniJIS_X,
  271. &cmap_UniKS_UCS2_H,
  272. &cmap_UniKS_UCS2_V,
  273. &cmap_UniKS_UTF16_H,
  274. &cmap_UniKS_UTF16_V,
  275. &cmap_UniKS_X,
  276. &cmap_V,
  277. };
  278. pdf_cmap *
  279. pdf_load_builtin_cmap(fz_context *ctx, const char *name)
  280. {
  281. int r = nelem(table)-1;
  282. int l = 0;
  283. while (l <= r)
  284. {
  285. int m = (l + r) >> 1;
  286. int c = strcmp(name, table[m]->cmap_name);
  287. if (c < 0)
  288. r = m - 1;
  289. else if (c > 0)
  290. l = m + 1;
  291. else
  292. return table[m];
  293. }
  294. return NULL;
  295. }
  296. #endif
  297. pdf_cmap *
  298. pdf_load_system_cmap(fz_context *ctx, const char *cmap_name)
  299. {
  300. pdf_cmap *usecmap;
  301. pdf_cmap *cmap;
  302. cmap = pdf_load_builtin_cmap(ctx, cmap_name);
  303. if (!cmap)
  304. fz_throw(ctx, FZ_ERROR_FORMAT, "no builtin cmap file: %s", cmap_name);
  305. if (cmap->usecmap_name[0] && !cmap->usecmap)
  306. {
  307. usecmap = pdf_load_system_cmap(ctx, cmap->usecmap_name);
  308. if (!usecmap)
  309. fz_throw(ctx, FZ_ERROR_FORMAT, "no builtin cmap file: %s", cmap->usecmap_name);
  310. pdf_set_usecmap(ctx, cmap, usecmap);
  311. }
  312. return cmap;
  313. }