📄 tfmtodit.cc
字号:
goto eof; if (!skip(n, fp)) goto eof; for (;;) { int op = getc(fp); if (op == EOF) goto eof; if (op == post) break; if ((op >= paint_0 && op <= paint_0 + 63) || (op >= new_row_0 && op <= new_row_0 + 164)) continue; switch (op) { case no_op: case eoc: case skip0: break; case paint1: case skip1: if (!skip(1, fp)) goto eof; break; case paint1 + 1: case skip1 + 1: if (!skip(2, fp)) goto eof; break; case paint1 + 2: case skip1 + 2: if (!skip(3, fp)) goto eof; break; case boc: { int code; if (!sread4(&code, fp)) goto eof; if (pending_adjustment) { pending_adjustment = 0; left[code & 0377] = left_adj; right[code & 0377] = right_adj; } if (!skip(20, fp)) goto eof; break; } case boc1: { int code = getc(fp); if (code == EOF) goto eof; if (pending_adjustment) { pending_adjustment = 0; left[code] = left_adj; right[code] = right_adj; } if (!skip(4, fp)) goto eof; break; } case xxx1: { int len = getc(fp); if (len == EOF) goto eof; char buf[256]; if (fread(buf, 1, len, fp) != len) goto eof; if (len == 10 /* strlen("adjustment") */ && memcmp(buf, "adjustment", len) == 0) { int c = getc(fp); if (c != yyy) { if (c != EOF) ungetc(c, fp); break; } if (!sread4(&left_adj, fp)) goto eof; c = getc(fp); if (c != yyy) { if (c != EOF) ungetc(c, fp); break; } if (!sread4(&right_adj, fp)) goto eof; got_an_adjustment = 1; pending_adjustment = 1; } break; } case xxx1 + 1: if (!uread2(&n, fp) || !skip(n, fp)) goto eof; break; case xxx1 + 2: if (!uread3(&n, fp) || !skip(n, fp)) goto eof; break; case xxx1 + 3: if (!sread4(&n, fp) || !skip(n, fp)) goto eof; break; case yyy: if (!skip(4, fp)) goto eof; break; default: fatal("unrecognized opcode `%1'", op); break; } } if (!got_an_adjustment) warning("no adjustment specials found in gf file"); return 1; eof: error("unexpected end of file"); return 0;}int gf::sread4(int *p, FILE *fp){ *p = getc(fp); if (*p >= 128) *p -= 256; *p <<= 8; *p |= getc(fp); *p <<= 8; *p |= getc(fp); *p <<= 8; *p |= getc(fp); return !ferror(fp) && !feof(fp);}int gf::uread3(int *p, FILE *fp){ *p = getc(fp); *p <<= 8; *p |= getc(fp); *p <<= 8; *p |= getc(fp); return !ferror(fp) && !feof(fp);}int gf::uread2(int *p, FILE *fp){ *p = getc(fp); *p <<= 8; *p |= getc(fp); return !ferror(fp) && !feof(fp);}int gf::skip(int n, FILE *fp){ while (--n >= 0) if (getc(fp) == EOF) return 0; return 1;}struct char_list { char *ch; char_list *next; char_list(const char *, char_list * = 0);};char_list::char_list(const char *s, char_list *p) : ch(strsave(s)), next(p){}int read_map(const char *file, char_list **table){ errno = 0; FILE *fp = fopen(file, "r"); if (!fp) { error("can't open `%1': %2", file, strerror(errno)); return 0; } for (int i = 0; i < 256; i++) table[i] = 0; char buf[512]; int lineno = 0; while (fgets(buf, int(sizeof(buf)), fp)) { lineno++; char *ptr = buf; while (csspace(*ptr)) ptr++; if (*ptr == '\0' || *ptr == '#') continue; ptr = strtok(ptr, " \n\t"); if (!ptr) continue; int n; if (sscanf(ptr, "%d", &n) != 1) { error("%1:%2: bad map file", file, lineno); fclose(fp); return 0; } if (n < 0 || n > 255) { error("%1:%2: code out of range", file, lineno); fclose(fp); return 0; } ptr = strtok(0, " \n\t"); if (!ptr) { error("%1:%2: missing names", file, lineno); fclose(fp); return 0; } for (; ptr; ptr = strtok(0, " \n\t")) table[n] = new char_list(ptr, table[n]); } fclose(fp); return 1;}/* Every character that can participate in a ligature appears in thelig_chars table. `ch' gives the full-name of the character, `name'gives the groff name of the character, `i' gives its index inthe encoding, which is filled in later (-1 if it does not appear). */struct { const char *ch; int i;} lig_chars[] = { "f", -1, "i", -1, "l", -1, "ff", -1, "fi", -1, "fl", -1, "Fi", -1, "Fl", -1,};// Indices into lig_chars[].enum { CH_f, CH_i, CH_l, CH_ff, CH_fi, CH_fl, CH_ffi, CH_ffl };// Each possible ligature appears in this table.struct { unsigned char c1, c2, res; const char *ch;} lig_table[] = { CH_f, CH_f, CH_ff, "ff", CH_f, CH_i, CH_fi, "fi", CH_f, CH_l, CH_fl, "fl", CH_ff, CH_i, CH_ffi, "ffi", CH_ff, CH_l, CH_ffl, "ffl", };static void usage(); int main(int argc, char **argv){ program_name = argv[0]; int special_flag = 0; int skewchar = -1; int opt; const char *gf_file = 0; while ((opt = getopt(argc, argv, "svg:k:")) != EOF) switch (opt) { case 'g': gf_file = optarg; break; case 's': special_flag = 1; break; case 'k': { char *ptr; long n = strtol(optarg, &ptr, 0); if ((n == 0 && ptr == optarg) || *ptr != '\0' || n < 0 || n > UCHAR_MAX) error("invalid skewchar"); else skewchar = (int)n; break; } case 'v': { extern const char *version_string; fprintf(stderr, "tfmtodit version %s\n", version_string); fflush(stderr); break; } case '?': usage(); break; case EOF: assert(0); } if (argc - optind != 3) usage(); gf g; if (gf_file) { if (!g.load(gf_file)) return 1; } const char *tfm_file = argv[optind]; const char *map_file = argv[optind + 1]; const char *font_file = argv[optind + 2]; tfm t; if (!t.load(tfm_file)) return 1; char_list *table[256]; if (!read_map(map_file, table)) return 1; errno = 0; if (!freopen(font_file, "w", stdout)) { error("can't open `%1' for writing: %2", font_file, strerror(errno)); return 1; } printf("name %s\n", font_file); if (special_flag) fputs("special\n", stdout); char *internal_name = strsave(argv[optind]); int len = strlen(internal_name); if (len > 4 && strcmp(internal_name + len - 4, ".tfm") == 0) internal_name[len - 4] = '\0'; char *s = strrchr(internal_name, '/'); printf("internalname %s\n", s ? s + 1 : internal_name); int n; if (t.get_param(2, &n)) { if (n > 0) printf("spacewidth %d\n", n*MULTIPLIER); } if (t.get_param(1, &n) && n != 0) printf("slant %f\n", atan2(n/double(1<<20), 1.0)*180.0/M_PI); int xheight; if (!t.get_param(5, &xheight)) xheight = 0; int i; // Print the list of ligatures. // First find the indices of each character that can participate in // a ligature. for (i = 0; i < 256; i++) for (int j = 0; j < sizeof(lig_chars)/sizeof(lig_chars[0]); j++) for (char_list *p = table[i]; p; p = p->next) if (strcmp(lig_chars[j].ch, p->ch) == 0) lig_chars[j].i = i; // For each possible ligature, if its participants all exist, // and it appears as a ligature in the tfm file, include in // the list of ligatures. int started = 0; for (i = 0; i < sizeof(lig_table)/sizeof(lig_table[0]); i++) { int i1 = lig_chars[lig_table[i].c1].i; int i2 = lig_chars[lig_table[i].c2].i; int r = lig_chars[lig_table[i].res].i; if (i1 >= 0 && i2 >= 0 && r >= 0) { unsigned char c; if (t.get_lig(i1, i2, &c) && c == r) { if (!started) { started = 1; fputs("ligatures", stdout); } printf(" %s", lig_table[i].ch); } } } if (started) fputs(" 0\n", stdout); printf("checksum %d\n", t.get_checksum()); printf("designsize %d\n", t.get_design_size()); // Now print out the kerning information. int had_kern = 0; kern_iterator iter(&t); unsigned char c1, c2; int k; while (iter.next(&c1, &c2, &k)) if (c2 != skewchar) { k *= MULTIPLIER; char_list *q = table[c2]; for (char_list *p1 = table[c1]; p1; p1 = p1->next) for (char_list *p2 = q; p2; p2 = p2->next) { if (!had_kern) { printf("kernpairs\n"); had_kern = 1; } printf("%s %s %d\n", p1->ch, p2->ch, k); } } printf("charset\n"); char_list unnamed("---"); for (i = 0; i < 256; i++) if (t.contains(i)) { char_list *p = table[i] ? table[i] : &unnamed; int m[6]; m[0] = t.get_width(i); m[1] = t.get_height(i); m[2] = t.get_depth(i); m[3] = t.get_italic(i); m[4] = g.get_left_adjustment(i); m[5] = g.get_right_adjustment(i); printf("%s\t%d", p->ch, m[0]*MULTIPLIER); for (int j = int(sizeof(m)/sizeof(m[0])) - 1; j > 0; j--) if (m[j] != 0) break; for (int k = 1; k <= j; k++) printf(",%d", m[k]*MULTIPLIER); int type = 0; if (m[2] > 0) type = 1; if (m[1] > xheight) type += 2; printf("\t%d\t%04o\n", type, i); for (p = p->next; p; p = p->next) printf("%s\t\"\n", p->ch); } return 0;}static void usage(){ fprintf(stderr, "usage: %s [-sv] [-g gf_file] [-k skewchar] tfm_file map_file font\n", program_name); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -