pdf_cmap_load.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "fitz-internal.h"
  2. #include "mupdf-internal.h"
  3. unsigned int
  4. pdf_cmap_size(fz_context *ctx, pdf_cmap *cmap)
  5. {
  6. if (cmap == NULL)
  7. return 0;
  8. if (cmap->storable.refs < 0)
  9. return 0;
  10. return cmap->rcap * sizeof(pdf_range) + cmap->tcap * sizeof(short) + pdf_cmap_size(ctx, cmap->usecmap);
  11. }
  12. /*
  13. * Load CMap stream in PDF file
  14. */
  15. pdf_cmap *
  16. pdf_load_embedded_cmap(pdf_document *xref, pdf_obj *stmobj)
  17. {
  18. fz_stream *file = NULL;
  19. pdf_cmap *cmap = NULL;
  20. pdf_cmap *usecmap;
  21. pdf_obj *wmode;
  22. pdf_obj *obj = NULL;
  23. fz_context *ctx = xref->ctx;
  24. int phase = 0;
  25. fz_var(phase);
  26. fz_var(obj);
  27. fz_var(file);
  28. fz_var(cmap);
  29. if (pdf_obj_marked(stmobj))
  30. fz_throw(ctx, "Recursion in embedded cmap");
  31. if ((cmap = pdf_find_item(ctx, pdf_free_cmap_imp, stmobj)))
  32. {
  33. return cmap;
  34. }
  35. fz_try(ctx)
  36. {
  37. file = pdf_open_stream(xref, pdf_to_num(stmobj), pdf_to_gen(stmobj));
  38. phase = 1;
  39. cmap = pdf_load_cmap(ctx, file);
  40. phase = 2;
  41. fz_close(file);
  42. file = NULL;
  43. wmode = pdf_dict_gets(stmobj, "WMode");
  44. if (pdf_is_int(wmode))
  45. pdf_set_cmap_wmode(ctx, cmap, pdf_to_int(wmode));
  46. obj = pdf_dict_gets(stmobj, "UseCMap");
  47. if (pdf_is_name(obj))
  48. {
  49. usecmap = pdf_load_system_cmap(ctx, pdf_to_name(obj));
  50. pdf_set_usecmap(ctx, cmap, usecmap);
  51. pdf_drop_cmap(ctx, usecmap);
  52. }
  53. else if (pdf_is_indirect(obj))
  54. {
  55. phase = 3;
  56. pdf_obj_mark(obj);
  57. usecmap = pdf_load_embedded_cmap(xref, obj);
  58. pdf_obj_unmark(obj);
  59. phase = 4;
  60. pdf_set_usecmap(ctx, cmap, usecmap);
  61. pdf_drop_cmap(ctx, usecmap);
  62. }
  63. pdf_store_item(ctx, stmobj, cmap, pdf_cmap_size(ctx, cmap));
  64. }
  65. fz_catch(ctx)
  66. {
  67. if (file)
  68. fz_close(file);
  69. if (cmap)
  70. pdf_drop_cmap(ctx, cmap);
  71. if (phase < 1)
  72. fz_throw(ctx, "cannot open cmap stream (%d %d R)", pdf_to_num(stmobj), pdf_to_gen(stmobj));
  73. else if (phase < 2)
  74. fz_throw(ctx, "cannot parse cmap stream (%d %d R)", pdf_to_num(stmobj), pdf_to_gen(stmobj));
  75. else if (phase < 3)
  76. fz_throw(ctx, "cannot load system usecmap '%s'", pdf_to_name(obj));
  77. else
  78. {
  79. if (phase == 3)
  80. pdf_obj_unmark(obj);
  81. fz_throw(ctx, "cannot load embedded usecmap (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj));
  82. }
  83. }
  84. return cmap;
  85. }
  86. /*
  87. * Create an Identity-* CMap (for both 1 and 2-byte encodings)
  88. */
  89. pdf_cmap *
  90. pdf_new_identity_cmap(fz_context *ctx, int wmode, int bytes)
  91. {
  92. pdf_cmap *cmap = pdf_new_cmap(ctx);
  93. fz_try(ctx)
  94. {
  95. sprintf(cmap->cmap_name, "Identity-%c", wmode ? 'V' : 'H');
  96. pdf_add_codespace(ctx, cmap, 0x0000, 0xffff, bytes);
  97. pdf_map_range_to_range(ctx, cmap, 0x0000, 0xffff, 0);
  98. pdf_sort_cmap(ctx, cmap);
  99. pdf_set_cmap_wmode(ctx, cmap, wmode);
  100. }
  101. fz_catch(ctx)
  102. {
  103. pdf_drop_cmap(ctx, cmap);
  104. fz_rethrow(ctx);
  105. }
  106. return cmap;
  107. }
  108. /*
  109. * Load predefined CMap from system.
  110. */
  111. pdf_cmap *
  112. pdf_load_system_cmap(fz_context *ctx, char *cmap_name)
  113. {
  114. pdf_cmap *usecmap;
  115. pdf_cmap *cmap;
  116. cmap = pdf_load_builtin_cmap(ctx, cmap_name);
  117. if (!cmap)
  118. fz_throw(ctx, "no builtin cmap file: %s", cmap_name);
  119. if (cmap->usecmap_name[0] && !cmap->usecmap)
  120. {
  121. usecmap = pdf_load_builtin_cmap(ctx, cmap->usecmap_name);
  122. if (!usecmap)
  123. fz_throw(ctx, "nu builtin cmap file: %s", cmap->usecmap_name);
  124. pdf_set_usecmap(ctx, cmap, usecmap);
  125. }
  126. return cmap;
  127. }