/* * Load CMap stream in PDF file */ pdf_cmap * pdf_load_embedded_cmap(pdf_document *doc, pdf_obj *stmobj) { fz_stream *file = NULL; pdf_cmap *cmap = NULL; pdf_cmap *usecmap; pdf_obj *wmode; pdf_obj *obj = NULL; fz_context *ctx = doc->ctx; int phase = 0; fz_var(phase); fz_var(obj); fz_var(file); fz_var(cmap); if (pdf_obj_marked(stmobj)) fz_throw(ctx, FZ_ERROR_GENERIC, "Recursion in embedded cmap"); if ((cmap = pdf_find_item(ctx, pdf_free_cmap_imp, stmobj)) != NULL) { return cmap; } fz_try(ctx) { file = pdf_open_stream(doc, pdf_to_num(stmobj), pdf_to_gen(stmobj)); phase = 1; cmap = pdf_load_cmap(ctx, file); phase = 2; fz_close(file); file = NULL; wmode = pdf_dict_gets(stmobj, "WMode"); if (pdf_is_int(wmode)) pdf_set_cmap_wmode(ctx, cmap, pdf_to_int(wmode)); obj = pdf_dict_gets(stmobj, "UseCMap"); if (pdf_is_name(obj)) { usecmap = pdf_load_system_cmap(ctx, pdf_to_name(obj)); pdf_set_usecmap(ctx, cmap, usecmap); pdf_drop_cmap(ctx, usecmap); } else if (pdf_is_indirect(obj)) { phase = 3; pdf_mark_obj(obj); usecmap = pdf_load_embedded_cmap(doc, obj); pdf_unmark_obj(obj); phase = 4; pdf_set_usecmap(ctx, cmap, usecmap); pdf_drop_cmap(ctx, usecmap); } pdf_store_item(ctx, stmobj, cmap, pdf_cmap_size(ctx, cmap)); } fz_catch(ctx) { if (file) fz_close(file); if (cmap) pdf_drop_cmap(ctx, cmap); if (phase < 1) fz_rethrow_message(ctx, "cannot open cmap stream (%d %d R)", pdf_to_num(stmobj), pdf_to_gen(stmobj)); else if (phase < 2) fz_rethrow_message(ctx, "cannot parse cmap stream (%d %d R)", pdf_to_num(stmobj), pdf_to_gen(stmobj)); else if (phase < 3) fz_rethrow_message(ctx, "cannot load system usecmap '%s'", pdf_to_name(obj)); else { if (phase == 3) pdf_unmark_obj(obj); fz_rethrow_message(ctx, "cannot load embedded usecmap (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj)); } } return cmap; }
int main(int argc, char **argv) { fz_context *ctx; fz_stream *fi; pdf_cmap *cmap; int k, m; int ns, nr; if (argc != 2) { fprintf(stderr, "usage: cmapclean input.cmap\n"); return 1; } ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); return 1; } fi = fz_open_file(ctx, argv[1]); cmap = pdf_load_cmap(ctx, fi); fz_close(fi); printf("begincmap\n"); printf("/CMapName /%s def\n", cmap->cmap_name); printf("/WMode %d def\n", cmap->wmode); if (cmap->usecmap_name[0]) printf("/%s usecmap\n", cmap->usecmap_name); if (cmap->codespace_len) { printf("begincodespacerange\n"); for (k = 0; k < cmap->codespace_len; k++) { if (cmap->codespace[k].n == 1) printf("<%02x><%02x>\n", cmap->codespace[k].low, cmap->codespace[k].high); else if (cmap->codespace[k].n == 2) printf("<%04x><%04x>\n", cmap->codespace[k].low, cmap->codespace[k].high); else if (cmap->codespace[k].n == 3) printf("<%06x><%06x>\n", cmap->codespace[k].low, cmap->codespace[k].high); else if (cmap->codespace[k].n == 4) printf("<%08x><%08x>\n", cmap->codespace[k].low, cmap->codespace[k].high); else printf("<%x><%x>\n", cmap->codespace[k].low, cmap->codespace[k].high); } printf("endcodespacerange\n"); } /* 16-bit ranges */ ns = nr = 0; for (k = 0; k < cmap->rlen; k++) if (cmap->ranges[k].high - cmap->ranges[k].low > 0) ++nr; else ++ns; if (ns) { printf("begincidchar\n"); for (k = 0; k < cmap->rlen; k++) { if (cmap->ranges[k].high - cmap->ranges[k].low == 0) { pc(cmap->ranges[k].low); printf("%u\n", cmap->ranges[k].out); } } printf("endcidchar\n"); } if (nr) { printf("begincidrange\n"); for (k = 0; k < cmap->rlen; k++) { if (cmap->ranges[k].high - cmap->ranges[k].low > 0) { pc(cmap->ranges[k].low); pc(cmap->ranges[k].high); printf("%u\n", cmap->ranges[k].out); } } printf("endcidrange\n"); } /* 32-bit ranges */ ns = nr = 0; for (k = 0; k < cmap->xlen; k++) if (cmap->xranges[k].high - cmap->xranges[k].low > 0) ++nr; else ++ns; if (ns) { printf("begincidchar\n"); for (k = 0; k < cmap->xlen; k++) { if (cmap->xranges[k].high - cmap->xranges[k].low == 0) { pc(cmap->xranges[k].low); printf("%u\n", cmap->xranges[k].out); } } printf("endcidchar\n"); } if (nr) { printf("begincidrange\n"); for (k = 0; k < cmap->xlen; k++) { if (cmap->xranges[k].high - cmap->xranges[k].low > 0) { pc(cmap->xranges[k].low); pc(cmap->xranges[k].high); printf("%u\n", cmap->xranges[k].out); } } printf("endcidrange\n"); } /* 1-to-many */ if (cmap->mlen > 0) { printf("beginbfchar\n"); for (k = 0; k < cmap->mlen; k++) { pc(cmap->mranges[k].low); printf("<"); for (m = 0; m < cmap->mranges[k].len; ++m) printf("%04x", cmap->mranges[k].out[m]); printf(">\n"); } printf("endbfchar\n"); } printf("endcmap\n"); fz_free_context(ctx); return 0; }
int main(int argc, char **argv) { pdf_cmap *cmap; fz_stream *fi; FILE *fo; char name[256]; char *realname; int i, k, m; fz_context *ctx; if (argc < 3) { fprintf(stderr, "usage: cmapdump output.c lots of cmap files\n"); return 1; } ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); return 1; } #undef fopen fo = fopen(argv[1], "wb"); if (!fo) { fprintf(stderr, "cmapdump: could not open output file '%s'\n", argv[1]); return 1; } fprintf(fo, "/* This is an automatically generated file. Do not edit. */\n"); for (i = 2; i < argc; i++) { realname = strrchr(argv[i], '/'); if (!realname) realname = strrchr(argv[i], '\\'); if (realname) realname ++; else realname = argv[i]; /* ignore VCS folders (such as .svn) */ if (*realname == '.') continue; if (strlen(realname) > (sizeof name - 1)) { fprintf(stderr, "cmapdump: file name too long\n"); if (fclose(fo)) { fprintf(stderr, "cmapdump: could not close output file '%s'\n", argv[1]); return 1; } return 1; } strcpy(name, realname); clean(name); fi = fz_open_file(ctx, argv[i]); cmap = pdf_load_cmap(ctx, fi); fz_drop_stream(ctx, fi); fprintf(fo, "\n/* %s */\n\n", cmap->cmap_name); if (cmap->rlen) { fprintf(fo, "static const pdf_range cmap_%s_ranges[] = {", name); for (k = 0; k < cmap->rlen; k++) { if (k % 4 == 0) fprintf(fo, "\n"); fprintf(fo, "{%uu,%uu,%uu},", cmap->ranges[k].low, cmap->ranges[k].high, cmap->ranges[k].out); } fprintf(fo, "\n};\n\n"); } if (cmap->xlen) { fprintf(fo, "static const pdf_xrange cmap_%s_xranges[] = {", name); for (k = 0; k < cmap->xlen; k++) { if (k % 4 == 0) fprintf(fo, "\n"); fprintf(fo, "{%uu,%uu,%uu},", cmap->xranges[k].low, cmap->xranges[k].high, cmap->xranges[k].out); } fprintf(fo, "\n};\n\n"); } if (cmap->mlen > 0) { fprintf(fo, "static const pdf_mrange cmap_%s_mranges[] = {", name); for (k = 0; k < cmap->mlen; k++) { fprintf(fo, "\n{%uu,%uu,{", cmap->mranges[k].low, cmap->mranges[k].len); for (m = 0; m < PDF_MRANGE_CAP; ++m) fprintf(fo, "%uu,", cmap->mranges[k].out[m]); fprintf(fo, "}},"); } fprintf(fo, "\n};\n\n"); } fprintf(fo, "static pdf_cmap cmap_%s = {\n", name); fprintf(fo, "\t{-1, pdf_drop_cmap_imp}, "); fprintf(fo, "\"%s\", ", cmap->cmap_name); fprintf(fo, "\"%s\", 0, ", cmap->usecmap_name); fprintf(fo, "%u, ", cmap->wmode); fprintf(fo, "%u,\n\t{ ", cmap->codespace_len); if (cmap->codespace_len == 0) { fprintf(fo, "{0,0,0},"); } for (k = 0; k < cmap->codespace_len; k++) { fprintf(fo, "{%u,%uu,%uu},", cmap->codespace[k].n, cmap->codespace[k].low, cmap->codespace[k].high); } fprintf(fo, " },\n"); if (cmap->rlen) fprintf(fo, "\t%u, %u, (pdf_range*) cmap_%s_ranges,\n", cmap->rlen, cmap->rlen, name); else fprintf(fo, "\t0, 0, NULL,\n"); if (cmap->xlen) fprintf(fo, "\t%u, %u, (pdf_xrange*) cmap_%s_xranges,\n", cmap->xlen, cmap->xlen, name); else fprintf(fo, "\t0, 0, NULL,\n"); if (cmap->mlen) fprintf(fo, "\t%u, %u, (pdf_mrange*) cmap_%s_mranges,\n", cmap->mlen, cmap->mlen, name); else fprintf(fo, "\t0, 0, NULL,\n"); fprintf(fo, "};\n"); if (getenv("verbose")) printf("\t{\"%s\",&cmap_%s},\n", cmap->cmap_name, name); pdf_drop_cmap(ctx, cmap); } if (fclose(fo)) { fprintf(stderr, "cmapdump: could not close output file '%s'\n", argv[1]); return 1; } fz_drop_context(ctx); return 0; }
int main(int argc, char **argv) { fz_context *ctx; fz_stream *fi; pdf_cmap *cmap; int k, m, n, i; struct cidrange *r; if (argc != 2) { fprintf(stderr, "usage: cmapclean input.cmap\n"); return 1; } ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); return 1; } fi = fz_open_file(ctx, argv[1]); cmap = pdf_load_cmap(ctx, fi); fz_close(fi); printf("begincmap\n"); printf("/CMapName /%s def\n", cmap->cmap_name); printf("/WMode %d def\n", cmap->wmode); if (cmap->usecmap_name[0]) printf("/%s usecmap\n", cmap->usecmap_name); if (cmap->codespace_len) { printf("begincodespacerange\n"); for (k = 0; k < cmap->codespace_len; k++) { if (cmap->codespace[k].n == 1) printf("<%02x> <%02x>\n", cmap->codespace[k].low, cmap->codespace[k].high); else if (cmap->codespace[k].n == 2) printf("<%04x> <%04x>\n", cmap->codespace[k].low, cmap->codespace[k].high); else if (cmap->codespace[k].n == 3) printf("<%06x> <%06x>\n", cmap->codespace[k].low, cmap->codespace[k].high); else if (cmap->codespace[k].n == 4) printf("<%08x> <%08x>\n", cmap->codespace[k].low, cmap->codespace[k].high); else printf("<%x> <%x>\n", cmap->codespace[k].low, cmap->codespace[k].high); } printf("endcodespacerange\n"); } n = cmap->rlen + cmap->xlen; r = malloc(n * sizeof *r); i = 0; for (k = 0; k < cmap->rlen; k++) { r[i].lo = cmap->ranges[k].low; r[i].hi = cmap->ranges[k].high; r[i].v = cmap->ranges[k].out; ++i; } for (k = 0; k < cmap->xlen; k++) { r[i].lo = cmap->xranges[k].low; r[i].hi = cmap->xranges[k].high; r[i].v = cmap->xranges[k].out; ++i; } qsort(r, n, sizeof *r, cmpcidrange); if (n) { printf("begincidchar\n"); for (i = 0; i < n; ++i) { for (k = r[i].lo, m = r[i].v; k <= r[i].hi; ++k, ++m) { pc(k); printf("%u\n", m); } } printf("endcidchar\n"); } if (cmap->mlen > 0) { printf("beginbfchar\n"); for (k = 0; k < cmap->mlen; k++) { pc(cmap->mranges[k].low); printf("<"); for (m = 0; m < cmap->mranges[k].len; ++m) printf("%04x", cmap->mranges[k].out[m]); printf(">\n"); } printf("endbfchar\n"); } printf("endcmap\n"); fz_free_context(ctx); return 0; }
int main(int argc, char **argv) { pdf_cmap *cmap; fz_stream *fi; FILE *fo; char name[256]; char *realname; int i, k; fz_context *ctx; if (argc < 3) { fprintf(stderr, "usage: cmapdump output.c lots of cmap files\n"); return 1; } ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); return 1; } fo = fopen(argv[1], "wb"); if (!fo) { fprintf(stderr, "cmapdump: could not open output file '%s'\n", argv[1]); return 1; } fprintf(fo, "/* This is an automatically generated file. Do not edit. */\n"); for (i = 2; i < argc; i++) { realname = strrchr(argv[i], '/'); if (!realname) realname = strrchr(argv[i], '\\'); if (realname) realname ++; else realname = argv[i]; if (strlen(realname) > (sizeof name - 1)) { fprintf(stderr, "cmapdump: file name too long\n"); return 1; } strcpy(name, realname); clean(name); fi = fz_open_file(ctx, argv[i]); fz_lock_stream(fi); cmap = pdf_load_cmap(ctx, fi); fz_close(fi); fprintf(fo, "\n/* %s */\n\n", cmap->cmap_name); fprintf(fo, "static const pdf_range cmap_%s_ranges[] = {", name); if (cmap->rlen == 0) { fprintf(fo, " {0,%d,0}", PDF_CMAP_RANGE); } for (k = 0; k < cmap->rlen; k++) { if (k % 4 == 0) fprintf(fo, "\n"); fprintf(fo, "{%d,%d,%d},", cmap->ranges[k].low, cmap->ranges[k].extent_flags, cmap->ranges[k].offset); } fprintf(fo, "\n};\n\n"); if (cmap->tlen == 0) { fprintf(fo, "static const unsigned short cmap_%s_table[] = { 0 };\n\n", name); } else { fprintf(fo, "static const unsigned short cmap_%s_table[%d] = {", name, cmap->tlen); for (k = 0; k < cmap->tlen; k++) { if (k % 12 == 0) fprintf(fo, "\n"); fprintf(fo, "%d,", cmap->table[k]); } fprintf(fo, "\n};\n\n"); } fprintf(fo, "static pdf_cmap cmap_%s = {\n", name); fprintf(fo, "\t{-1, pdf_free_cmap_imp}, "); fprintf(fo, "\"%s\", ", cmap->cmap_name); fprintf(fo, "\"%s\", 0, ", cmap->usecmap_name); fprintf(fo, "%d, ", cmap->wmode); fprintf(fo, "%d,\n\t{ ", cmap->codespace_len); if (cmap->codespace_len == 0) { fprintf(fo, "{0,0,0},"); } for (k = 0; k < cmap->codespace_len; k++) { fprintf(fo, "{%d,%d,%d},", cmap->codespace[k].n, cmap->codespace[k].low, cmap->codespace[k].high); } fprintf(fo, " },\n"); fprintf(fo, "\t%d, %d, (pdf_range*) cmap_%s_ranges,\n", cmap->rlen, cmap->rlen, name); fprintf(fo, "\t%d, %d, (unsigned short*) cmap_%s_table,\n", cmap->tlen, cmap->tlen, name); fprintf(fo, "};\n"); if (getenv("verbose")) printf("\t{\"%s\",&cmap_%s},\n", cmap->cmap_name, name); } if (fclose(fo)) { fprintf(stderr, "cmapdump: could not close output file '%s'\n", argv[1]); return 1; } fz_free_context(ctx); return 0; }
/* * Load CMap stream in PDF file */ pdf_cmap * pdf_load_embedded_cmap(fz_context *ctx, pdf_document *doc, pdf_obj *stmobj) { fz_stream *file = NULL; pdf_cmap *cmap = NULL; pdf_cmap *usecmap = NULL; pdf_obj *obj; fz_var(file); fz_var(cmap); fz_var(usecmap); if (pdf_obj_marked(ctx, stmobj)) fz_throw(ctx, FZ_ERROR_GENERIC, "Recursion in embedded cmap"); if ((cmap = pdf_find_item(ctx, pdf_drop_cmap_imp, stmobj)) != NULL) return cmap; fz_try(ctx) { file = pdf_open_stream(ctx, stmobj); cmap = pdf_load_cmap(ctx, file); obj = pdf_dict_get(ctx, stmobj, PDF_NAME_WMode); if (pdf_is_int(ctx, obj)) pdf_set_cmap_wmode(ctx, cmap, pdf_to_int(ctx, obj)); obj = pdf_dict_get(ctx, stmobj, PDF_NAME_UseCMap); if (pdf_is_name(ctx, obj)) { usecmap = pdf_load_system_cmap(ctx, pdf_to_name(ctx, obj)); pdf_set_usecmap(ctx, cmap, usecmap); } else if (pdf_is_indirect(ctx, obj)) { if (pdf_mark_obj(ctx, obj)) fz_throw(ctx, FZ_ERROR_GENERIC, "recursive CMap"); fz_try(ctx) usecmap = pdf_load_embedded_cmap(ctx, doc, obj); fz_always(ctx) pdf_unmark_obj(ctx, obj); fz_catch(ctx) fz_rethrow(ctx); pdf_set_usecmap(ctx, cmap, usecmap); } pdf_store_item(ctx, stmobj, cmap, pdf_cmap_size(ctx, cmap)); } fz_always(ctx) { fz_drop_stream(ctx, file); pdf_drop_cmap(ctx, usecmap); } fz_catch(ctx) { pdf_drop_cmap(ctx, cmap); fz_rethrow(ctx); } return cmap; }