int main(int argc, char** argv) { size_t l; unsigned int i; long index, code; FILE *config_file; char *configline, *oldconfigline, *p, *q; Font font; encoding *enc; long inenc_array[256]; char *fontname; size_t fontname_len; char *pk_filename, *tfm_filename, *enc_filename, *cfg_filename; char *real_ttfname, *real_cfg_filename; int dpi = 0, ptsize; Boolean hinting = True; Boolean quiet = False; Boolean no_dpi = False; Boolean testing = False; TeX_search_init(argv[0], "ttf2pk", "TTF2PK"); if (argc == 1) oops("Need at least two arguments.\n" "Try `ttf2pk --help' for more information."); if (argc == 2) { if (strcmp(argv[1], "--help") == 0) usage(); else if (strcmp(argv[1], "--version") == 0) version(); } while (argv[1][0] == '-') { if (argv[1][1] == 'q') quiet = True; else if (argv[1][1] == 'n') no_dpi = True; else if (argv[1][1] == 't') testing = True; else oops("Unknown option `%s'.\n" "Try `ttf2pk --help' for more information.", argv[1]); argv++; argc--; } if (testing) { if (argc != 2) oops("Need exactly one parameter for `-t' option.\n" "Try `ttf2pk --help' for more information."); } else if (argc != 3) oops("Need at most two arguments.\n" "Try `ttf2pk --help' for more information."); if (!quiet) printf("This is %s\n", ident); if (!testing) if ((dpi = atoi(argv[2])) <= 50) oops("dpi value must be larger than 50."); fontname = argv[1]; fontname_len = strlen(fontname); enc_filename = NULL; ptsize = 10; init_font_structure(&font); cfg_filename = newstring("ttfonts.map"); real_cfg_filename = TeX_search_config_file(&cfg_filename); if (!real_cfg_filename) oops("Cannot find file ttfonts.map."); config_file = fopen(real_cfg_filename, "rt"); if (config_file == NULL) oops("Cannot open file ttfonts.map."); do { configline = get_line(config_file); if (!configline) oops("Error while reading ttfonts.map."); if (!*configline) { /* * This is the only error message we suppress if the -q flag * is set, making it possible to call ttf2pk silently. */ if (!quiet) fprintf(stdout, "%s: ERROR: Cannot find font %s in ttfonts.map.\n", progname, fontname); exit(2); } } while (compare(&font, configline, fontname)); fclose(config_file); if (testing) { if (!quiet) fprintf(stdout, "%s\n", configline); exit(0); } /* * Parse the line from the config file. We split the config line buffer * into substrings according to the given options. */ l = strlen(configline); if (configline[l - 1] == '\n') configline[l - 1] = '\0'; /* strip newline */ oldconfigline = newstring(configline); p = configline; while (isspace(*p)) p++; while (*p && !isspace(*p)) p++; q = p; while (*p && isspace(*p)) p++; if (!*p) boops(oldconfigline, q - configline, "TTF file missing."); font.ttfname = p; while (*p && !isspace(*p)) p++; if (*p) *p++ = '\0'; for (; *p; p++) { if (isspace(*p)) continue; if (!strncmp(p, "Slant", 5)) { p = strip_equal(configline, oldconfigline, p + 5); if (sscanf(p, "%f", &(font.slant)) == 0) boops(oldconfigline, p - configline, "Bad `Slant' parameter."); } else if (!strncmp(p, "Encoding", 8)) { if (have_sfd) boops(oldconfigline, p - configline, "No `Encoding' parameter allowed for subfonts."); p = strip_equal(configline, oldconfigline, p + 8); if (!*p) boops(oldconfigline, p - configline, "Bad `Encoding' parameter."); enc_filename = p; } else if (!strncmp(p, "Extend", 6)) { p = strip_equal(configline, oldconfigline, p + 6); if (sscanf(p, "%f", &(font.efactor)) == 0) boops(oldconfigline, p - configline, "Bad `Extend' parameter."); } else if (!strncmp(p, "Fontindex", 9)) { p = strip_equal(configline, oldconfigline, p + 9); if (sscanf(p, "%lu", &(font.fontindex)) < 0) boops(oldconfigline, p - configline, "Bad `Fontindex' parameter."); } else if (!strncmp(p, "Pid", 3)) { p = strip_equal(configline, oldconfigline, p + 3); if (sscanf(p, "%hu", &(font.pid)) < 0) boops(oldconfigline, p - configline, "Bad `Pid' parameter."); have_pid = True; } else if (!strncmp(p, "Eid", 3)) { p = strip_equal(configline, oldconfigline, p + 3); if (sscanf(p, "%hu", &(font.eid)) < 0) boops(oldconfigline, p - configline, "Bad `Eid' parameter."); have_eid = True; } else if (!strncmp(p, "Hinting", 7)) { p = strip_equal(configline, oldconfigline, p + 7); if (p[1] == 'N' || p[1] == 'n' || p[0] == 'Y' || p[1] == 'y' || p[0] == '1') hinting = True; else if (p[1] == 'F' || p[1] == 'f' || p[0] == 'N' || p[1] == 'n' || p[0] == '0') hinting = False; else boops(oldconfigline, p - configline, "Bad `Hinting' parameter."); } else if (!strncmp(p, "PS", 2)) { p = strip_equal(configline, oldconfigline, p + 2); if (p[1] != '\0' && (p[2] == 'l' || p[2] == 'L')) font.PSnames = Only; else if (p[1] == 'N' || p[1] == 'n' || p[0] == 'Y' || p[0] == 'y' || p[0] == '1') font.PSnames = Yes; else if (p[1] == 'F' || p[1] == 'f' || p[0] == 'N' || p[0] == 'n' || p[0] == '0') font.PSnames = No; else boops(oldconfigline, p - configline, "Bad `PS' parameter."); if (have_sfd) boops(oldconfigline, p - configline, "No `PS' parameter allowed for subfonts."); } else if (!strncmp(p, "Rotate", 6)) { p = strip_equal(configline, oldconfigline, p + 6); if (p[1] == 'N' || p[1] == 'n' || p[0] == 'Y' || p[1] == 'y' || p[0] == '1') font.rotate = True; else if (p[1] == 'F' || p[1] == 'f' || p[0] == 'N' || p[1] == 'n' || p[0] == '0') font.rotate = False; else boops(oldconfigline, p - configline, "Bad `Rotate' parameter."); if (!have_sfd) boops(oldconfigline, p - configline, "No `Rotate' parameter allowed for non-subfonts."); } else if (!strncmp(p, "Y-Offset", 8)) { p = strip_equal(configline, oldconfigline, p + 8); if (sscanf(p, "%f", &(font.y_offset)) == 0) boops(oldconfigline, p - configline, "Bad `Y-Offset' parameter."); } else if (!strncmp(p, "Replacement", 11)) { p = strip_equal(configline, oldconfigline, p + 11); if (!*p) boops(oldconfigline, p - configline, "Bad `Replacement' parameter."); font.replacementname = p; } else { char *new_name, *old_name; stringlist *sl; old_name = p; while (*p && !isspace(*p) && *p != '=') p++; q = p; p = strip_equal(configline, oldconfigline, p); *q = '\0'; new_name = p; while (*p && !isspace(*p)) p++; if (*p) *p++ = '\0'; sl = newstringlist(); sl->new_name = new_name; sl->old_name = old_name; sl->next = font.replacements; font.replacements = sl; p--; /* to make the next while loop work */ } while (*p && !isspace(*p)) p++; if (*p) *p = '\0'; } if (font.PSnames == Only) if (have_pid || have_eid) boops(oldconfigline, 0, "No `Pid' or `Eid' parameters allowed if `PS=Only' is set."); font.replacementname = newstring(font.replacementname); get_replacements(&font); tfm_filename = newstring(fontname); TFMopen(&tfm_filename); pk_filename = mymalloc(fontname_len + 10); if (no_dpi) sprintf(pk_filename, "%s.pk", fontname); else sprintf(pk_filename, "%s.%dpk", fontname, dpi); PKopen(pk_filename, fontname, dpi); font.ttfname = newstring(font.ttfname); real_ttfname = TeX_search_ttf_file(&(font.ttfname)); if (!real_ttfname) oops("Cannot find `%s'.", font.ttfname); TTFopen(real_ttfname, &font, dpi, ptsize, quiet); enc_filename = newstring(enc_filename); enc = readencoding(&enc_filename, &font, True); if (enc) { char *name; restore_glyph(enc, &font); for (i = 0; i <= 0xFF; i++) { name = enc->vec[i]; if (!font.PSnames) { code = adobename_to_code(name); if (code < 0 && strcmp(name, ".notdef") != 0) warning("Cannot map character `%s'.", name); inenc_array[i] = code; } else { /* we search the glyph index */ index = TTFsearch_PS_name(name); if (index < 0) warning("Cannot map character `%s'.", name); inenc_array[i] = index | 0x10000; } } } else { if (font.replacements) warning("Replacement glyphs will be ignored."); if (have_sfd) TTFget_subfont(&font, inenc_array); else /* get the table of glyph names too */ enc = TTFget_first_glyphs(&font, inenc_array); } for (i = 0; i <= 0xFF; i++) { byte *bitmap; int w, h, hoff, voff; if ((code = inenc_array[i]) >= 0) { if (!quiet) { printf("Processing glyph %3ld %s index 0x%04x %s\n", (long)i, (code >= 0x10000) ? "glyph" : "code", (unsigned int)(code & 0xFFFF), enc ? enc->vec[i] : ""); fflush(stdout); } if (TTFprocess(&font, code, &bitmap, &w, &h, &hoff, &voff, hinting, quiet)) PKputglyph(i, -hoff, -voff, w - hoff, h - voff, w, h, bitmap); else warning("Cannot render glyph with %s index 0x%x.", (code >= 0x10000) ? "glyph" : "code", (unsigned int)(code & 0xFFFF)); } } PKclose(); exit(0); /* for safety reasons */ return 0; /* never reached */ }
static void handle_options(int argc, char *argv[], Font *fnt) { register int lastext; register int i; size_t l; int arginc; char *temp; char c; char *vpl_name = NULL; Boolean have_capheight = 0; Boolean have_sfd = 0; int sfd_begin, postfix_begin; int base_name; stringlist* sl; /* scan first whether the -q switch is set */ for (i = 1; i < argc; i++) if (argv[i][0] == '-' && argv[i][1] == 'q') quiet = True; if (!quiet) printf("This is %s\n", ident); /* Make VPL file identical to that created under Unix */ fnt->titlebuf = (char *)mymalloc(strlen(progname) + strlen(argv[1]) + 1 + 1); sprintf(fnt->titlebuf, "%s %s", progname, argv[1]); /* * TrueType font name. */ fnt->ttfname = newstring(argv[1]); /* * The other arguments. We delay the final processing of some switches * until the tfm font name has been scanned -- if it contains two `@'s, * many switches are ignored. */ while (argc > 2 && *argv[2] == '-') { arginc = 2; i = argv[2][1]; switch (i) { case 'v': makevpl = 1; if (argc <= 3) oops("Missing parameter for -v option."); if (vpl_name) free(vpl_name); vpl_name = newstring(argv[3]); handle_extension(&vpl_name, ".vpl"); break; case 'V': makevpl = 2; if (argc <= 3) oops("Missing parameter for -V option."); if (vpl_name) free(vpl_name); vpl_name = newstring(argv[3]); handle_extension(&vpl_name, ".vpl"); break; case 'f': if (argc <= 3) oops("Missing parameter for -f option."); if (sscanf(argv[3], "%lu", &(fnt->fontindex)) == 0) oops("Invalid font index."); fnt->fontindexparam = argv[3]; break; case 'E': if (argc <= 3) oops("Missing parameter for -E option."); if (sscanf(argv[3], "%hu", &(fnt->eid)) == 0) oops("Invalid encoding ID."); fnt->eidparam = argv[3]; break; case 'P': if (argc <= 3) oops("Missing parameter for -P option."); if (sscanf(argv[3], "%hu", &(fnt->pid)) == 0) oops("Invalid platform ID."); fnt->pidparam = argv[3]; break; case 'e': if (argc <= 3) oops("Missing parameter for -e option."); if (sscanf(argv[3], "%f", &(fnt->efactor)) == 0 || fnt->efactor < 0.01) oops("Bad extension factor."); fnt->efactorparam = argv[3]; break; case 'c': if (argc <= 3) oops("Missing parameter for -c option."); have_capheight = True; if (sscanf(argv[3], "%f", &(fnt->capheight)) == 0) fnt->capheight = 0; break; case 's': if (argc <= 3) oops("Missing parameter for -s option."); if (sscanf(argv[3], "%f", &(fnt->slant)) == 0) oops("Bad slant parameter."); fnt->slantparam = argv[3]; break; case 'p': if (argc <= 3) oops("Missing parameter for -p option."); if (fnt->inencname) free(fnt->inencname); fnt->inencname = newstring(argv[3]); break; case 'T': if (argc <= 3) oops("Missing parameter for -T option."); if (fnt->inencname) free(fnt->inencname); if (fnt->outencname) free(fnt->outencname); fnt->inencname = newstring(argv[3]); fnt->outencname = newstring(argv[3]); break; case 't': if (argc <= 3) oops("Missing parameter for -T option."); if (fnt->outencname) free(fnt->outencname); fnt->outencname = newstring(argv[3]); break; case 'r': if (argc <= 4) oops("Not enough parameters for -r option."); sl = newstringlist(); sl->old_name = newstring(argv[3]); sl->new_name = newstring(argv[4]); sl->single_replacement = True; sl->next = fnt->replacements; fnt->replacements = sl; arginc = 3; break; case 'R': if (argc <= 3) oops("Missing parameter for -R option."); if (fnt->replacementname) free(fnt->replacementname); fnt->replacementname = newstring(argv[3]); break; case 'y': if (argc <= 3) oops("Missing parameter for -y option."); if (sscanf(argv[3], "%f", &(fnt->y_offset)) == 0) oops("Invalid y-offset."); fnt->y_offsetparam = argv[3]; break; case 'O': forceoctal = True; arginc = 1; break; case 'n': fnt->PSnames = Yes; arginc = 1; break; case 'N': fnt->PSnames = Only; arginc = 1; break; case 'u': pedantic = True; arginc = 1; break; case 'q': quiet = True; arginc = 1; break; case 'L': if (argc <= 3) oops("Missing parameter for -L option."); if (fnt->ligname) free(fnt->ligname); fnt->ligname = newstring(argv[3]); fnt->subfont_ligs = True; break; case 'l': fnt->subfont_ligs = True; arginc = 1; break; case 'w': fnt->write_enc = True; arginc = 1; break; case 'x': fnt->rotate = True; arginc = 1; break; case 'o': if (argc <= 3) oops("Missing parameter for -o option."); if (vpl_name) free(vpl_name); vpl_name = newstring(argv[3]); handle_extension(&vpl_name, ".ovp"); break; default: if (argc <= 3 || argv[3][0] == '-') { warning("Unknown option `%s' will be ignored.\n", argv[2]); arginc = 1; } else warning("Unknown option `%s %s' will be ignored.\n", argv[2], argv[3]); } for (i = 0; i < arginc; i++) { l = strlen(fnt->titlebuf); fnt->titlebuf = (char *)myrealloc((void *)fnt->titlebuf, l + strlen(argv[2]) + 1 + 1); sprintf(fnt->titlebuf + strlen(fnt->titlebuf), " %s", argv[2]); argv++; argc--; } } /* Read replacement glyph name file */ get_replacements(fnt); if (argc > 3 || (argc == 3 && *argv[2] == '-')) oops("Need at most two non-option arguments."); /* * The tfm file name. */ if (argc == 2) temp = newstring(fnt->ttfname); else { temp = newstring(argv[2]); l = strlen(fnt->titlebuf); fnt->titlebuf = (char *)myrealloc((void *)fnt->titlebuf, l + strlen(argv[2]) + 1 + 1); sprintf(fnt->titlebuf + strlen(fnt->titlebuf), " %s", argv[2]); } handle_sfd(temp, &sfd_begin, &postfix_begin); if (sfd_begin > -1) { have_sfd = True; i = sfd_begin - 2; } else i = strlen(temp) - 1; /* * Now we search the beginning of the name without directory. */ for (; i >= 0; i--) if (temp[i] == '/' || temp[i] == ':' || temp[i] == '\\') break; base_name = i + 1; /* * We store the path (with the final directory separator). */ if (base_name > 0) { c = temp[base_name]; temp[base_name] = '\0'; fnt->tfm_path = newstring(temp); temp[base_name] = c; } if (have_sfd) { /* the prefix and the sfd file name */ if (temp[base_name]) fnt->outname = newstring(temp + base_name); fnt->sfdname = newstring(temp + sfd_begin); } else postfix_begin = base_name; /* * Get the extension. */ lastext = -1; for (i = postfix_begin; temp[i]; i++) if (temp[i] == '.') lastext = i; if (argc == 2 && lastext >= 0) { temp[lastext] = '\0'; /* remove TTF file extension */ lastext = -1; } if (lastext == -1) fnt->tfm_ext = newstring(".tfm"); else { fnt->tfm_ext = newstring(temp + lastext); temp[lastext] = '\0'; } if (have_sfd) { if (temp[postfix_begin]) fnt->outname_postfix = newstring(temp + postfix_begin); } else { if (temp[base_name]) fnt->outname = newstring(temp + base_name); else oops("Invalid tfm file name."); } /* * Now we can process the remaining parameters. */ if (have_sfd) { if (makevpl) { warning("Ignoring `-v' and `-V' switches for subfonts."); makevpl = 0; } if (vpl_name) if ((fnt->vplout = fopen(vpl_name, "wb")) == NULL) oops("Cannot open ovp output file."); if (have_capheight) warning("Ignoring `-c' switch for subfonts."); if (fnt->inencname || fnt->outencname) { warning("Ignoring `-p', `-t', and `-T' switches for subfonts."); fnt->inencname = NULL; fnt->outencname = NULL; } if (fnt->y_offsetparam && !fnt->rotate) warning("Ignoring `-y' switch for non-rotated subfonts."); if (fnt->PSnames) { warning("Ignoring `-n' or '-N' switch for subfonts."); fnt->PSnames = No; } init_sfd(fnt, True); } else { if (have_capheight && fnt->capheight < 0.01) oops("Bad small caps height."); if (vpl_name) if ((fnt->vplout = fopen(vpl_name, "wb")) == NULL) oops("Cannot open vpl output file."); if (fnt->subfont_ligs) { warning("Ignoring `-l' switch for non-subfont."); fnt->subfont_ligs = False; } if (fnt->rotate) { warning("Ignoring `-x' switch for non-subfont."); fnt->rotate = False; } if (fnt->write_enc) { warning("Ignoring `-w' switch for non-subfont."); fnt->write_enc = False; } if (fnt->y_offsetparam) warning("Ignoring `-y' switch for non-subfont."); } if (fnt->PSnames == Only) { if (fnt->pidparam || fnt->eidparam) { warning("Ignoring `-P' and `-E' options if `-N' switch is selected."); fnt->pidparam = NULL; fnt->eidparam = NULL; } } if (vpl_name) free(vpl_name); free(temp); }