📄 ttf2tfm.c
字号:
/* * ttf2tfm.c * * This file is part of the ttf2pk package. * * Copyright 1997-1999, 2000, 2002 by * Frederic Loyer <loyer@ensta.fr> * Werner Lemberg <wl@gnu.org>. *//* * This program converts TTF files to TeX TFM files, and optionally * to TeX VPL files that retain all kerning and ligature information. * Both files make the characters not normally encoded by TeX available * by character codes greater than 0x7F. *//* * Adapted from afm2tfm by F. Loyer <loyer@ensta.fr>. */#include <stdio.h>#include <stdlib.h>#include <stddef.h> /* for size_t */#include <string.h>#ifdef MIKTEX#include <miktex.h>#endif#include "ttf2tfm.h"#include "newobj.h"#include "ttfenc.h"#include "ligkern.h"#include "texenc.h"#include "ttfaux.h"#include "tfmaux.h"#include "vplaux.h"#include "errormsg.h"#include "filesrch.h"#include "parse.h"#include "subfont.h"char ident[] = "ttf2tfm version 1.5";char progname[] = "ttf2tfm"; /* for error/warning messages *//* command line options */static char makevpl; /* can be 1 or 2 */static Boolean pedantic;static Boolean quiet;static Boolean forceoctal;/* * Re-encode the TTF font. */static voidhandlereencoding(Font *fnt){ int i; ttfinfo *ti; char *p; if (fnt->inencname) { fnt->inencoding = readencoding(&(fnt->inencname), fnt, True); /* reset all pointers in the mapping table */ for (i = 0; i <= 0xFF; i++) if (NULL != (ti = fnt->inencptrs[i])) { ti->incode = -1; fnt->inencptrs[i] = NULL; } /* * Reencode TTF <--> raw TeX. Only these code points will be used * for the output encoding. */ for (i = 0; i <= 0xFF; i++) { p = fnt->inencoding->vec[i]; if (p && *p) { if ((ti = findadobe(p, fnt->charlist))) { if (ti->incode >= 0) { warning("Character `%s' encoded twice in input encoding\n" " (positions %x and %x; the latter is ignored).", p, ti->incode, i); fnt->inencoding->vec[i] = ".notdef"; continue; } if (ti->charcode >= 0) { ti->incode = i; fnt->inencptrs[i] = ti; } } else { warning("Cannot find character `%s'\n" " specified in input encoding.", p); } } } fnt->codingscheme = fnt->inencoding->name; } if (!quiet) { if (fnt->inencname) printf("\nUsing %s as input encoding.\n", fnt->inencname); else { printf( "\nUsing the first 256 glyphs in the following input encoding:\n\n"); for (i = 0; i <= 0xFF; i++) { if ((ti = fnt->inencptrs[i])) printf(" 0x%02x %s\n", i, ti->adobename); } printf("\n"); } } if (fnt->outencname) fnt->outencoding = readencoding(&(fnt->outencname), fnt, False); else fnt->outencoding = readencoding(NULL, fnt, False);}static voidassignchars(Font *fnt){ register char **p; register int i, j, k; register ttfinfo *ti; int nextfree = 0x80; /* * First, we assign all those that match perfectly. */ for (i = 0, p = fnt->outencoding->vec; i <= 0xFF; i++, p++) if ((ti = findmappedadobe(*p, fnt->inencptrs))) { if (ti->outcode >= 0) fnt->nextout[i] = ti->outcode; /* linked list */ ti->outcode = i; fnt->outencptrs[i] = ti; } else if (strcmp(*p, ".notdef") != 0) warning("Cannot map character `%s'\n" " specified in output encoding.", *p); if (pedantic) goto end; /* * Next, we assign all the others, retaining the TTF code positions, * possibly multiplying assigned characters, unless the output encoding * was precisely specified. */ for (i = 0; i <= 0xFF; i++) if ((ti = fnt->inencptrs[i]) && ti->charcode >= 0 && ti->charcode <= 0xFF && ti->outcode < 0 && fnt->outencptrs[ti->charcode] == NULL) { ti->outcode = ti->charcode; fnt->outencptrs[ti->charcode] = ti; } /* * Finally, we map all remaining characters into free locations beginning * with 0x80. */ for (i = 0; i <= 0xFF; i++) if ((ti = fnt->inencptrs[i]) && ti->outcode < 0) { while (fnt->outencptrs[nextfree]) { nextfree = (nextfree + 1) & 0xFF; if (nextfree == 0x80) goto finishup; /* all slots full */ } ti->outcode = nextfree; fnt->outencptrs[nextfree] = ti; }finishup: /* * Now, if any of the characters are encoded multiple times, we want * ti->outcode to be the first one assigned, since that is most likely * to be the most important one. So we reverse the above lists. */ for (i = 0; i <= 0xFF; i++) if ((ti = fnt->inencptrs[i]) && ti->outcode >= 0) { k = -1; while (fnt->nextout[ti->outcode] >= 0) { j = fnt->nextout[ti->outcode]; fnt->nextout[ti->outcode] = k; k = ti->outcode; ti->outcode = j; } fnt->nextout[ti->outcode] = k; }end: if (!quiet) { printf("\nUsing the following output encoding:\n\n"); for (i = 0; i <= 0xFF; i++) { if ((ti = fnt->outencptrs[i])) printf(" 0x%02x %s\n", i, ti->adobename); } printf("\n"); }}#define VERSION "\Copyright (C) 1997-1999, 2000, 2002 Frederic Loyer and Werner Lemberg.\n\There is NO warranty. You may redistribute this software\n\under the terms of the GNU General Public License\n\and the Dvips copyright.\n\\n\For more information about these matters, see the files\n\named COPYING and ttf2tfm.c.\n\\n\Primary authors of ttf2tfm: F. Loyer and W. Lemberg.\n\\n\ttf2tfm is based on afm2tfm from T. Rokicki\n\and the FreeType project from\n\David Turner, Robert Wilhelm, and Werner Lemberg.\n\"static voidversion(void){ fputs(ident, stdout); fprintf(stdout, " (%s)\n", TeX_search_version()); fputs(VERSION, stdout); exit(0);}#define USAGE "\ Convert a TrueType font table to TeX's font metric format.\n\\n\-c REAL use REAL for height of small caps made with -V [0.8]\n\-e REAL widen (extend) characters by a factor of REAL [1.0]\n\-E INT select INT as the TTF encoding ID [1]\n\-f INT select INT as the font index in a TTC [0]\n\-l create 1st/2nd byte ligatures in subfonts\n\-L LIGFILE[.sfd] create 1st/2nd byte ligatures in subfonts using LIGFILE\n\-n use PS names of TrueType font\n\-N use only PS names and no cmap\n\-O use octal for all character codes in the vpl file\n\-p ENCFILE[.enc] read ENCFILE for the TTF->raw TeX mapping\n\-P INT select INT as the TTF platform ID [3]\n\-q suppress informational output\n\-r OLDNAME NEWNAME replace glyph name OLDNAME with NEWNAME\n\-R RPLFILE[.rpl] read RPLFILE containing glyph replacement names\n\-s REAL oblique (slant) characters by REAL, usually <<1 [0.0]\n\-t ENCFILE[.enc] read ENCFILE for the encoding of the vpl file\n\-T ENCFILE[.enc] equivalent to -p ENCFILE -t ENCFILE\n\-u output only characters from encodings, nothing extra\n\-v FILE[.vpl] make a VPL file for conversion to VF\n\-V SCFILE[.vpl] like -v, but synthesize smallcaps as lowercase\n\-w generate subfont enc. vectors containing glyph indices\n\-x rotate subfont glyphs by 90 degrees\n\-y REAL move rotated glyphs down by a factor of REAL [0.25]\n\--help print this message and exit\n\--version print version number and exit\n\"static voidusage(void){ fputs("Usage: ttf2tfm FILE[.ttf|.ttc] [OPTION]... [FILE[.tfm]]\n", stdout); fputs(USAGE, stdout); exit(0);}static voidhandle_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);#if defined(MSDOS) || defined(OS2) || defined(ATARIST) /* 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]);#else fnt->titlebuf = (char *)mymalloc(strlen(argv[0]) + strlen(argv[1]) + 1 + 1); sprintf(fnt->titlebuf, "%s %s", argv[0], argv[1]);#endif /* * 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':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -