diff options
author | Tor Andersson <tor@ghostscript.com> | 2009-02-28 16:26:56 +0100 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2009-02-28 16:26:56 +0100 |
commit | de55e619b33ef2e59fdabdb060add37b2da76aa4 (patch) | |
tree | 3965a5cacc03356113066b68b59c45076c3b4b1d /cmapdump.c | |
parent | f744dace3f0f91b8505979bf244453c9ec713b4b (diff) | |
download | mupdf-de55e619b33ef2e59fdabdb060add37b2da76aa4.tar.xz |
Pre-compile the standard CMaps into c-structs instead of parsing them at runtime.
Diffstat (limited to 'cmapdump.c')
-rw-r--r-- | cmapdump.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/cmapdump.c b/cmapdump.c new file mode 100644 index 00000000..f6c5cb2e --- /dev/null +++ b/cmapdump.c @@ -0,0 +1,160 @@ +/* cmapdump.c -- parse a CMap file and dump it as a c-struct */ + +#include <stdio.h> +#include <string.h> + +#include "fitz.h" +#include "mupdf.h" + +#include "mupdf/pdf_lex.c" +#include "mupdf/pdf_cmap.c" +#include "mupdf/pdf_cmap_parse.c" + +char * +flagtoname(int flag) +{ + switch (flag) + { + case PDF_CMAP_SINGLE: return "PDF_CMAP_SINGLE,"; + case PDF_CMAP_RANGE: return "PDF_CMAP_RANGE, "; + case PDF_CMAP_TABLE: return "PDF_CMAP_TABLE, "; + case PDF_CMAP_MULTI: return "PDF_CMAP_MULTI, "; + } + return "-1,"; +} + +void +clean(char *p) +{ + while (*p) + { + if ((*p == '/') || (*p == '.') || (*p == '\\') || (*p == '-')) + *p = '_'; + p ++; + } +} + +int +main(int argc, char **argv) +{ + pdf_cmap *cmap; + fz_error *error; + fz_stream *fi; + FILE *fo; + char name[256]; + char *realname; + char *p; + int i, k; + + if (argc < 3) + { + fprintf(stderr, "usage: cmapdump output.c lots of cmap files\n"); + return 1; + } + + fo = fopen(argv[1], "wb"); + if (!fo) + { + fprintf(stderr, "cmapdump: could not open output file\n"); + return 1; + } + + fprintf(fo, "#include \"fitz.h\"\n"); + fprintf(fo, "#include \"mupdf.h\"\n"); + fprintf(fo, "\n"); + + for (i = 2; i < argc; i++) + { + realname = strrchr(argv[i], '/'); + if (!realname) + realname = strrchr(argv[i], '\\'); + if (realname) + realname ++; + else + realname = argv[i]; + + strcpy(name, realname); + p = name; + while (*p) + { + if ((*p == '/') || (*p == '.') || (*p == '\\') || (*p == '-')) + *p = '_'; + p ++; + } + + error = fz_openrfile(&fi, argv[i]); + if (error) + { + fprintf(stderr, "cmapdump: could not open input file %s\n", argv[i]); + fz_printerror(error); + return 1; + } + + error = pdf_parsecmap(&cmap, fi); + if (error) + { + fprintf(stderr, "cmapdump: could not parse input cmap %s\n", argv[i]); + fz_printerror(error); + return 1; + } + + fprintf(fo, "/*\n * %s\n */\n\n", cmap->cmapname); + + fprintf(fo, "static const pdf_range pdf_cmap_%s_ranges[%d] =\n{\n", + name, cmap->rlen); + for (k = 0; k < cmap->rlen; k++) + { + fprintf(fo, " { 0x%04x, 0x%04x, %s %d },\n", + cmap->ranges[k].low, cmap->ranges[k].high, + flagtoname(cmap->ranges[k].flag), + cmap->ranges[k].offset); + } + fprintf(fo, "};\n\n"); + + if (cmap->tlen == 0) + { + fprintf(fo, "static const int pdf_cmap_%s_table[1] = { 0 };\n\n", name); + } + else + { + fprintf(fo, "static const int pdf_cmap_%s_table[%d] =\n{", + name, cmap->tlen); + for (k = 0; k < cmap->tlen; k++) + { + if (k % 8 == 0) + fprintf(fo, "\n "); + fprintf(fo, "%d, ", cmap->table[k]); + } + fprintf(fo, "\n};\n\n"); + } + + fprintf(fo, "pdf_cmap pdf_cmap_%s =\n", name); + fprintf(fo, "{\n"); + fprintf(fo, " -1, "); + fprintf(fo, "\"%s\", ", cmap->cmapname); + fprintf(fo, "\"%s\", 0, ", cmap->usecmapname); + fprintf(fo, "%d,\n", cmap->wmode); + + fprintf(fo, " %d, /* codespace table */\n", cmap->ncspace); + fprintf(fo, " {\n"); + for (k = 0; k < cmap->ncspace; k++) + { + fprintf(fo, "\t{ %d, 0x%04x, 0x%04x },\n", + cmap->cspace[k].n, cmap->cspace[k].lo, cmap->cspace[k].hi); + } + fprintf(fo, " },\n"); + + fprintf(fo, " %d, %d, (pdf_range*) pdf_cmap_%s_ranges,\n", + cmap->rlen, cmap->rlen, name); + + fprintf(fo, " %d, %d, (int*) pdf_cmap_%s_table,\n", + cmap->tlen, cmap->tlen, name); + + fprintf(fo, "};\n\n"); + + fz_dropstream(fi); + } + + return 0; +} + |