📄 pdf_cmap.c.svn-base
字号:
return fz_throw("expected integer"); dst = atoi(buf); error = pdf_maprangetorange(cmap, lo, hi, dst); if (error) return fz_rethrow(error, "cannot map cidrange"); }}static fz_error *parsecidchar(pdf_cmap *cmap, fz_stream *file){ fz_error *error; char buf[256]; pdf_token_e tok; int len; int src, dst; while (1) { error = lexcmap(&tok, file, buf, sizeof buf, &len); if (error) return fz_rethrow(error, "syntaxerror in cmap"); if (tok == TENDCIDCHAR) return fz_okay; else if (tok != PDF_TSTRING) return fz_throw("expected string or endcidchar"); src = codefromstring(buf, len); error = lexcmap(&tok, file, buf, sizeof buf, &len); if (error) return fz_rethrow(error, "syntaxerror in cmap"); if (tok != PDF_TINT) return fz_throw("expected integer"); dst = atoi(buf); error = pdf_maprangetorange(cmap, src, src, dst); if (error) return fz_rethrow(error, "cannot map cidchar"); }}static fz_error *parsebfrangearray(pdf_cmap *cmap, fz_stream *file, int lo, int hi){ fz_error *error; char buf[256]; pdf_token_e tok; int len; int dst[256]; int i; while (1) { error = lexcmap(&tok, file, buf, sizeof buf, &len); if (error) return fz_rethrow(error, "syntaxerror in cmap"); if (tok == PDF_TCARRAY) return fz_okay; /* Note: does not handle [ /Name /Name ... ] */ else if (tok != PDF_TSTRING) return fz_throw("expected string or ]"); if (len / 2) { for (i = 0; i < len / 2; i++) dst[i] = codefromstring(buf + i * 2, 2); error = pdf_maponetomany(cmap, lo, dst, len / 2); if (error) return fz_rethrow(error, "cannot map bfrange array"); } lo ++; }}static fz_error *parsebfrange(pdf_cmap *cmap, fz_stream *file){ fz_error *error; char buf[256]; pdf_token_e tok; int len; int lo, hi, dst; while (1) { error = lexcmap(&tok, file, buf, sizeof buf, &len); if (error) return fz_rethrow(error, "syntaxerror in cmap"); if (tok == TENDBFRANGE) return fz_okay; else if (tok != PDF_TSTRING) return fz_throw("expected string or endbfrange"); lo = codefromstring(buf, len); error = lexcmap(&tok, file, buf, sizeof buf, &len); if (error) return fz_rethrow(error, "syntaxerror in cmap"); if (tok != PDF_TSTRING) return fz_throw("expected string"); hi = codefromstring(buf, len); error = lexcmap(&tok, file, buf, sizeof buf, &len); if (error) return fz_rethrow(error, "syntaxerror in cmap"); if (tok == PDF_TSTRING) { if (len == 2) { dst = codefromstring(buf, len); error = pdf_maprangetorange(cmap, lo, hi, dst); if (error) return fz_rethrow(error, "cannot map bfrange"); } else { int dststr[256]; int i; if (len / 2) { for (i = 0; i < len / 2; i++) dststr[i] = codefromstring(buf + i * 2, 2); while (lo <= hi) { dststr[i-1] ++; error = pdf_maponetomany(cmap, lo, dststr, i); if (error) return fz_rethrow(error, "cannot map bfrange"); lo ++; } } } } else if (tok == PDF_TOARRAY) { error = parsebfrangearray(cmap, file, lo, hi); if (error) return fz_rethrow(error, "cannot map bfrange"); } else { return fz_throw("expected string or array or endbfrange"); } }}static fz_error *parsebfchar(pdf_cmap *cmap, fz_stream *file){ fz_error *error; char buf[256]; pdf_token_e tok; int len; int dst[256]; int src; int i; while (1) { error = lexcmap(&tok, file, buf, sizeof buf, &len); if (error) return fz_rethrow(error, "syntaxerror in cmap"); if (tok == TENDBFCHAR) return fz_okay; else if (tok != PDF_TSTRING) return fz_throw("expected string or endbfchar"); src = codefromstring(buf, len); error = lexcmap(&tok, file, buf, sizeof buf, &len); if (error) return fz_rethrow(error, "syntaxerror in cmap"); /* Note: does not handle /dstName */ if (tok != PDF_TSTRING) return fz_throw("expected string"); if (len / 2) { for (i = 0; i < len / 2; i++) dst[i] = codefromstring(buf + i * 2, 2); error = pdf_maponetomany(cmap, src, dst, i); if (error) return fz_rethrow(error, "cannot map bfchar"); } }}fz_error *pdf_parsecmap(pdf_cmap **cmapp, fz_stream *file){ fz_error *error; pdf_cmap *cmap; char key[64]; char buf[256]; pdf_token_e tok; int len; error = pdf_newcmap(&cmap); if (error) return fz_rethrow(error, "cannot create cmap"); strcpy(key, ".notdef"); while (1) { error = lexcmap(&tok, file, buf, sizeof buf, &len); if (error) { error = fz_rethrow(error, "syntaxerror in cmap"); goto cleanup; } if (tok == PDF_TEOF) break; else if (tok == PDF_TNAME) { if (!strcmp(buf, "CMapName")) { error = parsecmapname(cmap, file); if (error) { error = fz_rethrow(error, "syntaxerror in cmap after /CMapName"); goto cleanup; } } else if (!strcmp(buf, "WMode")) { error = parsewmode(cmap, file); if (error) { error = fz_rethrow(error, "syntaxerror in cmap after /WMode"); goto cleanup; } } else strlcpy(key, buf, sizeof key); } else if (tok == TUSECMAP) { strlcpy(cmap->usecmapname, key, sizeof(cmap->usecmapname)); } else if (tok == TBEGINCODESPACERANGE) { error = parsecodespacerange(cmap, file); if (error) { error = fz_rethrow(error, "syntaxerror in cmap codespacerange"); goto cleanup; } } else if (tok == TBEGINBFCHAR) { error = parsebfchar(cmap, file); if (error) { error = fz_rethrow(error, "syntaxerror in cmap bfchar"); goto cleanup; } } else if (tok == TBEGINCIDCHAR) { error = parsecidchar(cmap, file); if (error) { error = fz_rethrow(error, "syntaxerror in cmap cidchar"); goto cleanup; } } else if (tok == TBEGINBFRANGE) { error = parsebfrange(cmap, file); if (error) { error = fz_rethrow(error, "syntaxerror in cmap bfrange"); goto cleanup; } } else if (tok == TBEGINCIDRANGE) { error = parsecidrange(cmap, file); if (error) { error = fz_rethrow(error, "syntaxerror in cmap cidrange"); goto cleanup; } } /* ignore everything else */ } error = pdf_sortcmap(cmap); if (error) { error = fz_rethrow(error, "cannot sort cmap"); goto cleanup; } *cmapp = cmap; return fz_okay;cleanup: pdf_dropcmap(cmap); return error; /* already rethrown */}/* * Load CMap stream in PDF file */fz_error *pdf_loadembeddedcmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmref){ fz_error *error = fz_okay; fz_obj *stmobj = stmref; fz_stream *file; pdf_cmap *cmap = nil; pdf_cmap *usecmap; fz_obj *wmode; fz_obj *obj; if ((*cmapp = pdf_finditem(xref->store, PDF_KCMAP, stmref))) { pdf_keepcmap(*cmapp); return fz_okay; } pdf_logfont("load embedded cmap (%d %d R) {\n", fz_tonum(stmref), fz_togen(stmref)); error = pdf_resolve(&stmobj, xref); if (error) return fz_rethrow(error, "cannot resolve cmap object"); error = pdf_openstream(&file, xref, fz_tonum(stmref), fz_togen(stmref)); if (error) { error = fz_rethrow(error, "cannot open cmap stream"); goto cleanup; } error = pdf_parsecmap(&cmap, file); if (error) { error = fz_rethrow(error, "cannot parse cmap stream"); goto cleanup; } fz_dropstream(file); wmode = fz_dictgets(stmobj, "WMode"); if (fz_isint(wmode)) { pdf_logfont("wmode %d\n", wmode); pdf_setwmode(cmap, fz_toint(wmode)); } obj = fz_dictgets(stmobj, "UseCMap"); if (fz_isname(obj)) { pdf_logfont("usecmap /%s\n", fz_toname(obj)); error = pdf_loadsystemcmap(&usecmap, fz_toname(obj)); if (error) { error = fz_rethrow(error, "cannot load system usecmap '%s'", fz_toname(obj)); goto cleanup; } pdf_setusecmap(cmap, usecmap); pdf_dropcmap(usecmap); } else if (fz_isindirect(obj)) { pdf_logfont("usecmap (%d %d R)\n", fz_tonum(obj), fz_togen(obj)); error = pdf_loadembeddedcmap(&usecmap, xref, obj); if (error) { error = fz_rethrow(error, "cannot load embedded usecmap"); goto cleanup; } pdf_setusecmap(cmap, usecmap); pdf_dropcmap(usecmap); } pdf_logfont("}\n"); error = pdf_storeitem(xref->store, PDF_KCMAP, stmref, cmap); if (error) { error = fz_rethrow(error, "cannot store cmap resource"); goto cleanup; } fz_dropobj(stmobj); *cmapp = cmap; return fz_okay;cleanup: if (cmap) pdf_dropcmap(cmap); fz_dropobj(stmobj); return error; /* already rethrown */}#ifdef WIN32#define DIR_SEP_STR "\\"#else#define DIR_SEP_STR "/"#endif#include <ctype.h>static void filenamesanitze(char *name){ char *tmp = &(name[0]); while (*tmp) { *tmp = tolower(*tmp); if ('-' == *tmp) *tmp = '_'; ++tmp; }}static fz_error*pdf_dumpcmapasccode(pdf_cmap *cmap, char *name){ char filenamec[256]; char id[256]; char idupper[256]; char *tmp; int i, j; pdf_range *r; int *t; fz_stream *file; fz_error *error; strlcpy(filenamec, name, sizeof filenamec); strlcat(filenamec, ".c", sizeof filenamec); filenamesanitze(filenamec); strlcpy(id, name, sizeof id); filenamesanitze(id); strlcpy(idupper, name, sizeof idupper); tmp = &(idupper[0]); while (*tmp) { *tmp = toupper(*tmp); if ('-' == *tmp) *tmp = '_'; ++tmp; } error = fz_openwfile(&file, filenamec); if (error) { return fz_rethrow(error, "cannot open file '%s'", filenamec); } fz_print(file, "#ifdef USE_%s\n", idupper); fz_print(file, "\n"); fz_print(file, "#ifdef INCLUDE_CMAP_DATA\n"); fz_print(file, "\n"); /* generate table data */ t = cmap->table; if (t && cmap->tlen) { fz_print(file, "static const int g_cmap_%s_table[%d] = {\n", id, cmap->tlen); for (i = 0; i < cmap->tlen-1; i++) { fz_print(file, " %d, ", *t++); if (0 == ((i + 1) % 8)) fz_print(file, "\n"); } fz_print(file, " %d };\n\n", *t++); } /* generate ranges data */ r = cmap->ranges; if (r && cmap->rlen) { fz_print(file, "static const pdf_range g_cmap_%s_ranges[%d] = {\n", id, cmap->rlen); for (i = 0; i < cmap->rlen-1; i++) { fz_print(file, " {%d, %d, %d, %d},\n", r->low, r->high, r->flag, r->offset); ++r; } fz_print(file, " {%d, %d, %d, %d}\n};\n", r->low, r->high, r->flag, r->offset); } fz_print(file, "\n"); /* generate new function */ fz_print(file, "static fz_error *new_%s(pdf_cmap **out)\n", id); fz_print(file, "{\n"); fz_print(file, "\tfz_error *error;\n"); fz_print(file, "\tpdf_cmap *cmap;\n"); fz_print(file, "\terror = pdf_newcmap(&cmap);\n"); fz_print(file, "\tif (error)\n"); fz_print(file, "\t\treturn error;\n"); fz_print(file, "\tcmap->staticdata = 1;\n"); if (r && cmap->rlen) fz_print(file, "\tcmap->ranges = (pdf_range*)&g_cmap_%s_ranges[0];\n", id); else fz_print(file, "\tcmap->ranges = 0;\n"); if (t && cmap->tlen) fz_print(file, "\tcmap->table = (int*)&g_cmap_%s_table[0];\n", id); else fz_print(file, "\tcmap->table = 0;\n"); fz_print(file, "\tstrcpy(cmap->cmapname, \"%s\");\n", cmap->cmapname); fz_print(file, "\tstrcpy(cmap->usecmapname, \"%s\");\n", cmap->usecmapname); fz_print(file, "\tcmap->wmode = %d;\n", cmap->wmode); fz_print(file, "\tcmap->ncspace = %d;\n", cmap->ncspace); for (i = 0; i < cmap->ncspace; i++) { fz_print(file, "\tcmap->cspace[%d].n = %d;\n", i, cmap->cspace[i].n); for (j = 0; j < 4; j++) { fz_print(file, "\tcmap->cspace[%d].lo[%d] = %d;\n", i, j, (int)cmap->cspace[i].lo[j]); fz_print(file, "\tcmap->cspace[%d].hi[%d] = %d;\n", i, j, (int)cmap->cspace[i].hi[j]); } } fz_print(file, "\t\n"); fz_print(file, "\tcmap->rlen = %d;\n", cmap->rlen); fz_print(file, "\tcmap->rcap = %d;\n", cmap->rcap); fz_print(file, "\tcmap->tlen = %d;\n", cmap->tlen); fz_print(file, "\tcmap->tcap = %d;\n", cmap->tcap); fz_print(file, "\t*out = cmap;\n"); fz_print(file, "\n"); fz_print(file, "\treturn fz_okay;\n"); fz_print(file, "}\n"); fz_print(file, "\n"); /* generate part that constructs this cmap if name matches */ fz_print(file, "#else\n"); fz_print(file, "\n"); fz_print(file, "\tif (!strcmp(name, \"%s\"))\n", name); fz_print(file, "\t\treturn new_%s(cmapp);\n", id); fz_print(file, "\n"); fz_print(file, "#endif\n"); fz_print(file, "#endif\n"); fz_dropstream(file); return fz_okay;}#ifdef USE_STATIC_CMAPS#define USE_ADOBE_JAPAN1_UCS2#define USE_90MSP_RKSJ_H#define USE_GBK_EUC_H#define USE_ADOBE_GB1_UCS2#define USE_ADOBE_CNS1_UCS2#define USE_ADOBE_KOREA1_UCS2#define USE_ETEN_B5_H#define USE_ETENMS_B5_H#define USE_KSCMS_UHC_H#define USE_UNIJIS_UCS2_H#define USE_90MS_RKSJ_H#define INCLUDE_CMAP_DATA#include "adobe_japan1_ucs2.c"#include "90msp_rksj_h.c"#include "adobe_gb1_ucs2.c"#include "gbk_euc_h.c"#include "adobe_cns1_ucs2.c"#include "adobe_korea1_ucs2.c"#include "eten_b5_h.c"#include "etenms_b5_h.c"#include "kscms_uhc_h.c"#include "unijis_ucs2_h.c"#include "90ms_rksj_h.c"static fz_error *getstaticcmap(char *name, pdf_cmap **cmapp){#undef INCLUDE_CMAP_DATA#include "adobe_japan1_ucs2.c"#include "90msp_rksj_h.c"#include "adobe_gb1_ucs2.c"#include "gbk_euc_h.c"#include "adobe_cns1_ucs2.c"#include "adobe_korea1_ucs2.c"#include "eten_b5_h.c"#include "etenms_b5_h.c"#include "kscms_uhc_h.c"#include "unijis_ucs2_h.c"#include "90ms_rksj_h.c" return fz_okay;}#elsestatic fz_error *getstaticcmap(char *name, pdf_cmap **cmapp){ return fz_okay;}#endif/* * Load predefined CMap from system */fz_error *pdf_loadsystemcmap(pdf_cmap **cmapp, char *name){ fz_error *error = fz_okay; fz_stream *file; char *cmapdir; char *usecmapname; pdf_cmap *usecmap; pdf_cmap *cmap; char path[1024]; cmap = nil; file = nil; pdf_logfont("load system cmap %s {\n", name); error = getstaticcmap(name, &cmap); if (!error && cmap) { *cmapp = cmap; return fz_okay; } if (error) fz_droperror(error);#ifdef DUMP_STATIC_CMAPS printf("\nCMAP: filenamec='%s'\n", name);#endif cmapdir = getenv("CMAPDIR"); if (!cmapdir) return fz_throw("ioerror: CMAPDIR environment not set"); strlcpy(path, cmapdir, sizeof path); strlcat(path, DIR_SEP_STR, sizeof path); strlcat(path, name, sizeof path); error = fz_openrfile(&file, path); if (error) { error = fz_rethrow(error, "cannot open cmap file '%s'", name); goto cleanup; } error = pdf_parsecmap(&cmap, file); if (error) { error = fz_rethrow(error, "cannot parse cmap file"); goto cleanup; } fz_dropstream(file);#ifdef DUMP_STATIC_CMAPS pdf_dumpcmapasccode(cmap, name);#endif usecmapname = cmap->usecmapname; if (usecmapname[0]) { pdf_logfont("usecmap %s\n", usecmapname); error = pdf_loadsystemcmap(&usecmap, usecmapname); if (error) { error = fz_rethrow(error, "cannot load system usecmap '%s'", usecmapname); goto cleanup; } pdf_setusecmap(cmap, usecmap); pdf_dropcmap(usecmap); } pdf_logfont("}\n"); *cmapp = cmap; return fz_okay;cleanup: if (cmap) pdf_dropcmap(cmap); if (file) fz_dropstream(file); return error; /* already rethrown */}/* * Create an Identity-* CMap (for both 1 and 2-byte encodings) */fz_error *pdf_newidentitycmap(pdf_cmap **cmapp, int wmode, int bytes){ fz_error *error; pdf_cmap *cmap; error = pdf_newcmap(&cmap); if (error) return fz_rethrow(error, "cannot create cmap"); sprintf(cmap->cmapname, "Identity-%c", wmode ? 'V' : 'H'); error = pdf_addcodespace(cmap, 0x0000, 0xffff, bytes); if (error) { pdf_dropcmap(cmap); return fz_rethrow(error, "cannot add code space"); } error = pdf_maprangetorange(cmap, 0x0000, 0xffff, 0); if (error) { pdf_dropcmap(cmap); return fz_rethrow(error, "cannot map <0000> to <ffff>"); } error = pdf_sortcmap(cmap); if (error) { pdf_dropcmap(cmap); return fz_rethrow(error, "cannot sort cmap"); } pdf_setwmode(cmap, wmode); *cmapp = cmap; return fz_okay;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -