cmapcleanx.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* cmapclean.c -- parse a CMap file and write it back out */
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "mupdf/pdf.h"
  5. struct cidrange {
  6. unsigned int lo, hi, v;
  7. };
  8. static int cmpcidrange(const void *va, const void *vb)
  9. {
  10. unsigned int a = ((const struct cidrange *)va)->lo;
  11. unsigned int b = ((const struct cidrange *)vb)->lo;
  12. return a < b ? -1 : a > b ? 1 : 0;
  13. }
  14. static void pc(unsigned int c)
  15. {
  16. if (c <= 0xff) printf("<%02x>", c);
  17. else if (c <= 0xffff) printf("<%04x>", c);
  18. else if (c <= 0xffffff) printf("<%06x>", c);
  19. else printf("<%010x>", c);
  20. }
  21. int
  22. main(int argc, char **argv)
  23. {
  24. fz_context *ctx;
  25. fz_stream *fi;
  26. pdf_cmap *cmap;
  27. int k, m, n, i;
  28. struct cidrange *r;
  29. if (argc != 2)
  30. {
  31. fprintf(stderr, "usage: cmapclean input.cmap\n");
  32. return 1;
  33. }
  34. ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
  35. if (!ctx)
  36. {
  37. fprintf(stderr, "cannot initialise context\n");
  38. return 1;
  39. }
  40. fi = fz_open_file(ctx, argv[1]);
  41. cmap = pdf_load_cmap(ctx, fi);
  42. fz_drop_stream(ctx, fi);
  43. printf("begincmap\n");
  44. printf("/CMapName /%s def\n", cmap->cmap_name);
  45. printf("/WMode %d def\n", cmap->wmode);
  46. if (cmap->usecmap_name[0])
  47. printf("/%s usecmap\n", cmap->usecmap_name);
  48. if (cmap->codespace_len)
  49. {
  50. printf("begincodespacerange\n");
  51. for (k = 0; k < cmap->codespace_len; k++)
  52. {
  53. if (cmap->codespace[k].n == 1)
  54. printf("<%02x> <%02x>\n", cmap->codespace[k].low, cmap->codespace[k].high);
  55. else if (cmap->codespace[k].n == 2)
  56. printf("<%04x> <%04x>\n", cmap->codespace[k].low, cmap->codespace[k].high);
  57. else if (cmap->codespace[k].n == 3)
  58. printf("<%06x> <%06x>\n", cmap->codespace[k].low, cmap->codespace[k].high);
  59. else if (cmap->codespace[k].n == 4)
  60. printf("<%08x> <%08x>\n", cmap->codespace[k].low, cmap->codespace[k].high);
  61. else
  62. printf("<%x> <%x>\n", cmap->codespace[k].low, cmap->codespace[k].high);
  63. }
  64. printf("endcodespacerange\n");
  65. }
  66. n = cmap->rlen + cmap->xlen;
  67. r = fz_malloc(ctx, n * sizeof *r);
  68. i = 0;
  69. for (k = 0; k < cmap->rlen; k++) {
  70. r[i].lo = cmap->ranges[k].low;
  71. r[i].hi = cmap->ranges[k].high;
  72. r[i].v = cmap->ranges[k].out;
  73. ++i;
  74. }
  75. for (k = 0; k < cmap->xlen; k++) {
  76. r[i].lo = cmap->xranges[k].low;
  77. r[i].hi = cmap->xranges[k].high;
  78. r[i].v = cmap->xranges[k].out;
  79. ++i;
  80. }
  81. qsort(r, n, sizeof *r, cmpcidrange);
  82. if (n)
  83. {
  84. printf("begincidchar\n");
  85. for (i = 0; i < n; ++i)
  86. {
  87. for (k = r[i].lo, m = r[i].v; k <= r[i].hi; ++k, ++m)
  88. {
  89. pc(k);
  90. printf("%u\n", m);
  91. }
  92. }
  93. printf("endcidchar\n");
  94. }
  95. #if 0
  96. if (cmap->mlen > 0)
  97. {
  98. printf("beginbfchar\n");
  99. for (k = 0; k < cmap->mlen; k++)
  100. {
  101. pc(cmap->mranges[k].low);
  102. printf("<");
  103. for (m = 0; m < cmap->mranges[k].len; ++m)
  104. printf("%04x", cmap->mranges[k].out[m]);
  105. printf(">\n");
  106. }
  107. printf("endbfchar\n");
  108. }
  109. #endif
  110. printf("endcmap\n");
  111. fz_drop_context(ctx);
  112. return 0;
  113. }