* Based on ttf2pfa by Andrew Weeks <ccsaw@bath.ac.uk>
* With help from Frank M. Siegert <fms@this.net>
*
- * see COPYRIGHT
+ * see COPYRIGHT for full copyright notice
*
***********************************************************************
*
#include <ctype.h>
#include <math.h>
+#include "../../config.h"
+
#ifdef _GNU_SOURCE
#include <getopt.h>
#endif
-#ifndef WINDOWS
+#ifndef WIN32
# include <unistd.h>
# include <netinet/in.h>
# define BITBUCKET "/dev/null"
# include <sys/wait.h>
#else
# define WINDOWS_FUNCTIONS /* ask to define functions - in one file only */
-# include "windows.h"
+# include "win_missing.h"
# define BITBUCKET "NUL"
#endif
/* table of front-ends */
extern struct frontsw ttf_sw;
+extern struct frontsw bdf_sw;
#if defined(USE_FREETYPE)
extern struct frontsw freetype_sw;
#endif
struct frontsw *frontswtab[] = {
+ &bdf_sw,
#if defined(USE_FREETYPE) && defined(PREFER_FREETYPE)
&freetype_sw,
#endif
int correctvsize=0; /* try to correct the vertical size of characters */
int wantuid = 0; /* user wants UniqueID entry in the font */
int allglyphs = 0; /* convert all glyphs, not only 256 of them */
-int warnlevel = -1; /* the level of permitted warnings */
+int warnlevel = 3; /* the level of permitted warnings */
int forcemap = 0; /* do mapping even on non-Unicode fonts */
/* options - maximal limits */
int max_stemdepth = 128; /* maximal depth of stem stack in interpreter (128 - limit from X11) */
int subhints; /* enables autogeneration of substituted hints */
int trybold; /* try to guess whether the font is bold */
int correctwidth; /* try to correct the character width */
+int vectorize; /* vectorize the bitmaps */
+int use_autotrace; /* use the autotrace library on bitmap */
+/* options - suboptions of File Generation, defaults are set in table */
+int gen_pfa; /* generate the font file */
+int gen_afm; /* generate the metrics file */
+int gen_dvienc; /* generate the dvips encoding file */
/* not quite options to select a particular source encoding */
int force_pid = -1; /* specific platform id */
int force_eid = -1; /* specific encoding id */
-/* table of Outline Processing (may think also as Optimization) options */
-static struct {
+/* structure to define the sub-option lists controlled by the
+ * case: uppercase enables them, lowercase disables
+ */
+struct subo_case {
char disbl; /* character to disable - enforced lowercase */
char enbl; /* character to enable - auto-set as toupper(disbl) */
int *valp; /* pointer to the actual variable containing value */
int dflt; /* default value */
char *descr; /* description */
-} opotbl[] = {
- { 'b', 0/*auto-set*/, &trybold, 1, "guessing of the ForceBold hint" },
- { 'h', 0/*auto-set*/, &hints, 1, "autogeneration of hints" },
- { 'u', 0/*auto-set*/, &subhints, 1, "hint substitution technique" },
- { 'o', 0/*auto-set*/, &optimize, 1, "space optimization of font files" },
- { 's', 0/*auto-set*/, &smooth, 1, "smoothing and repair of outlines" },
- { 't', 0/*auto-set*/, &transform, 1, "auto-scaling to the standard matrix 1000x1000" },
- { 'w', 0/*auto-set*/, &correctwidth, 0, "correct the glyph widths (use only for buggy fonts)" },
};
int debug = DEBUG; /* debugging flag */
-FILE *pfa_file, *afm_file;
+FILE *null_file, *pfa_file, *afm_file, *dvienc_file;
int numglyphs;
struct font_metrics fontm;
}
/*
+ * When we print errors about bad names we want to print these names in
+ * some decent-looking form
+ */
+
+static char *
+nametoprint(
+ unsigned char *s
+)
+{
+ static char res[50];
+ int c, i;
+
+ for(i=0; ( c =* s )!=0 && i<sizeof(res)-8; s++) {
+ if(c < ' ' || c > 126) {
+ sprintf(res+i, "\\x%02X", c);
+ i+=4;
+ } else {
+ res[i++] = c;
+ }
+ }
+ if(*s != 0) {
+ res[i++] = '.';
+ res[i++] = '.';
+ res[i++] = '.';
+ }
+ res[i++] = 0;
+ return res;
+}
+
+/*
* Scale the values according to the scale_factor
*/
if (smooth) {
smoothjoints(g);
assertpath(g->entries, __FILE__, __LINE__, g->name);
-
- flattencurves(g);
}
ncurves = 0;
for(ge = g->entries; ge; ge = ge->next)
ncurves++;
}
- if (ncurves > 100) {
- WARNING_2 fprintf(stderr,
+ if (ncurves > 200) {
+ WARNING_3 fprintf(stderr,
"** Glyph %s is too long, may display incorrectly\n",
g->name);
}
for (n = 0; n < numglyphs; n++) {
int c;
for (i = 0; (c = glyph_list[n].name[i]) != 0; i++) {
- if (!(isalnum(c) || c == '.' || c == '_' )
+ if (!(isalnum(c) || c == '.' || c == '_' || c == '-')
|| i==0 && isdigit(c)) { /* must not start with a digit */
WARNING_3 fprintf(stderr, "Glyph %d %s (%s), ",
n, isdigit(c) ? "name starts with a digit" :
"has bad characters in name",
- glyph_list[n].name);
- glyph_list[n].name = malloc(10);
- sprintf(glyph_list[n].name, "_%d", n);
+ nametoprint(glyph_list[n].name));
+ glyph_list[n].name = malloc(16);
+ sprintf(glyph_list[n].name, "_b_%d", n);
WARNING_3 fprintf(stderr, "changing to %s\n", glyph_list[n].name);
break;
}
found = 0;
for (i = 0; i < n && !found; i++) {
if (strcmp(glyph_list[i].name, glyph_list[n].name) == 0) {
- glyph_list[n].name = malloc(10);
- sprintf(glyph_list[n].name, "_%d", n);
- WARNING_3 fprintf(stderr,
- "Glyph %d has the same name as %d: (%s), changing to %s\n",
- n, i,
- glyph_list[i].name,
- glyph_list[n].name);
+ if (( glyph_list[n].name = malloc(16) )==0) {
+ fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
+ exit(255);
+ }
+ sprintf(glyph_list[n].name, "_d_%d", n);
+
+ /* if the font has no names in it (what the native parser
+ * recognises as ps_fmt_3), FreeType returns all the
+ * names as .notdef, so don't complain in this case
+ */
+ if(strcmp(glyph_list[i].name, ".notdef")) {
+ WARNING_3 fprintf(stderr,
+ "Glyph %d has the same name as %d: (%s), changing to %s\n",
+ n, i,
+ glyph_list[i].name,
+ glyph_list[n].name);
+ }
found = 1;
}
}
unicode_map[n] = -1;
uni_lang_selected->init[i](uni_lang_arg);
unicode_prepare_buckets();
- if( cursw->glenc(glyph_list, encoding, unicode_map) == 0 )
+ type = cursw->glenc(glyph_list, encoding, unicode_map);
+ if( type == 0 )
/* if we have an 8-bit encoding we don't need more tries */
break;
}
unicode_map[n] = -1;
uni_lang[i].init[0](uni_lang_arg);
unicode_prepare_buckets();
- if( cursw->glenc(glyph_list, encoding, unicode_map) == 0 )
+ type = cursw->glenc(glyph_list, encoding, unicode_map);
+ if( type == 0 )
/* if we have an 8-bit encoding we don't need more tries */
break;
}
}
if (ps_fmt_3) {
- for (i = 0; i < 256; i++) { /* here 256, not ENCTABSZ */
- if (encoding[i] > 0) {
- glyph_list[encoding[i]].name = Fmt3Encoding[i];
+ /* get rid of the old names, they are all "UNKNOWN" anyawy */
+ for (i = 0; i < numglyphs; i++) {
+ glyph_list[i].name = 0;
+ }
+ if(type == 0) {
+ /* 8-bit - give 8859/1 names to the first 256 glyphs */
+ for (i = 0; i < 256; i++) { /* here 256, not ENCTABSZ */
+ if (encoding[i] > 0) {
+ glyph_list[encoding[i]].name = Fmt3Encoding[i];
+ }
+ }
+ } else if(type == 1) {
+ /* Unicode - give 8859/1 names to the first 256 glyphs of Unicode */
+ for (n = 0; n < 256; n++) { /* here 256, not ENCTABSZ */
+ i = unicode_rev_lookup(n);
+ if (i>=0 && encoding[i] > 0) {
+ glyph_list[encoding[i]].name = Fmt3Encoding[i];
+ }
+ }
+ } /* for other types of encodings just give generated names */
+ /* assign unique names to the rest of the glyphs */
+ for (i = 0; i < numglyphs; i++) {
+ if (glyph_list[i].name == 0) {
+ if (( glyph_list[i].name = malloc(16) )==0) {
+ fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
+ exit(255);
+ }
+ sprintf(glyph_list[i].name, "_d_%d", i);
}
}
}
/* all the encoding things are done */
for (i = 0; i < ENCTABSZ; i++)
- if(encoding[i] == -1) /* defaults to .notdef */
- encoding[i] = 0;
+ if(encoding[i] == -1) {
+ /* check whether this character might be a duplicate
+ * (in which case it would be missed by unicode_rev_lookup())
+ */
+ c = unicode_map[i];
+ if((type != 0 || forcemap) && c != -1) {
+ for(n = 0; n < i; n++) {
+ if(unicode_map[n] == c) {
+ encoding[i] = encoding[n];
+ }
+ }
+ }
+ if(encoding[i] == -1) /* still not found, defaults to .notdef */
+ encoding[i] = 0;
+ }
for (i = 0; i < 256; i++) /* here 256, not ENCTABSZ */
glyph_list[encoding[i]].char_no = i;
fplop("This build supports both short and long option names,\n");
fplop("the long options are listed before corresponding short ones\n");
- fplop(" --afm\n");
- fputs(" -A - write the .afm file to STDOUT instead of the font itself\n", stderr);
fplop(" --all-glyphs\n");
fputs(" -a - include all glyphs, even those not in the encoding table\n", stderr);
fplop(" --pfb\n");
fputs(" -e - produce a fully encoded .pfa file\n", stderr);
fplop(" --force-unicode\n");
fputs(" -F - force use of Unicode encoding even if other MS encoding detected\n", stderr);
+ fplop(" --generate suboptions\n");
+ fputs(" -G suboptions - control the file generation, run ttf2pt1 -G? for help\n", stderr);
fplop(" --language language\n");
fputs(" -l language - convert Unicode to specified language, run ttf2pt1 -l? for list\n", stderr);
fplop(" --language-map file\n");
fputs(" -V - print ttf2pt1 version number\n", stderr);
fplop(" --warning number\n");
fputs(" -W number - set the level of permitted warnings (0 - disable)\n", stderr);
- fputs("Obsolete options (will be removed in future releases, use -O? instead):\n", stderr);
- fputs(" -f - don't try to guess the value of the ForceBold hint\n", stderr);
- fputs(" -h - disable autogeneration of hints\n", stderr);
- fputs(" -H - disable hint substitution\n", stderr);
- fputs(" -o - disable outline optimization\n", stderr);
- fputs(" -s - disable outline smoothing\n", stderr);
- fputs(" -t - disable auto-scaling to 1000x1000 standard matrix\n", stderr);
- fputs(" -w - correct the glyph widths (use only for buggy fonts)\n", stderr);
+ fputs("Obsolete options (will be removed in future releases):\n", stderr);
+ fplop(" --afm\n");
+ fputs(" -A - write the .afm file to STDOUT instead of the font, now -GA\n", stderr);
+ fputs(" -f - don't try to guess the value of the ForceBold hint, now -Ob\n", stderr);
+ fputs(" -h - disable autogeneration of hints, now -Oh\n", stderr);
+ fputs(" -H - disable hint substitution, now -Ou\n", stderr);
+ fputs(" -o - disable outline optimization, now -Oo\n", stderr);
+ fputs(" -s - disable outline smoothing, now -Os\n", stderr);
+ fputs(" -t - disable auto-scaling to 1000x1000 standard matrix, now -Ot\n", stderr);
+ fputs(" -w - correct the glyph widths (use only for buggy fonts), now -OW\n", stderr);
fputs("With no <fontname>, write to <ttf-file> with suffix replaced.\n", stderr);
fputs("The last '-' means 'use STDOUT'.\n", stderr);
{
fprintf(stderr, "ttf2pt1 %s\n", TTF2PT1_VERSION);
}
+
+/* initialize a table of suboptions */
+static void
+init_subo_tbl(
+ struct subo_case *tbl
+)
+{
+ int i;
+
+ for(i=0; tbl[i].disbl != 0; i++) {
+ tbl[i].disbl = tolower(tbl[i].disbl);
+ tbl[i].enbl = toupper(tbl[i].disbl);
+ *(tbl[i].valp) = tbl[i].dflt;
+ }
+}
+
+/* print the default value of the suboptions */
+static void
+print_subo_dflt(
+ FILE *f,
+ struct subo_case *tbl
+)
+{
+ int i;
+
+ for(i=0; tbl[i].disbl != 0; i++) {
+ if(tbl[i].dflt)
+ putc(tbl[i].enbl, f);
+ else
+ putc(tbl[i].disbl, f);
+ }
+}
+
+/* print the usage message for the suboptions */
+static void
+print_subo_usage(
+ FILE *f,
+ struct subo_case *tbl
+)
+{
+ int i;
+
+ fprintf(f,"The lowercase suboptions disable features, corresponding\n");
+ fprintf(f,"uppercase suboptions enable them. The supported suboptions,\n");
+ fprintf(f,"their default states and the features they control are:\n");
+ for(i=0; tbl[i].disbl != 0; i++) {
+ fprintf(f," %c/%c - [%s] %s\n", tbl[i].disbl, tbl[i].enbl,
+ tbl[i].dflt ? "enabled" : "disabled", tbl[i].descr);
+ }
+}
+
+/* find and set the entry according to suboption,
+ * return the found entry (or if not found return NULL)
+ */
+struct subo_case *
+set_subo(
+ struct subo_case *tbl,
+ int subopt
+)
+{
+ int i;
+
+ for(i=0; tbl[i].disbl != 0; i++) {
+ if(subopt == tbl[i].disbl) {
+ *(tbl[i].valp) = 0;
+ return &tbl[i];
+ } else if(subopt == tbl[i].enbl) {
+ *(tbl[i].valp) = 1;
+ return &tbl[i];
+ }
+ }
+ return NULL;
+}
+
int
ttf2pt1_main(
{
int i, j;
time_t now;
- char filename[256];
+ char filename[4096];
int c,nchars,nmetrics;
int ws;
int forcebold= -1; /* -1 means "don't know" */
char *lang;
int oc;
int subid;
+ char *cmdline;
#ifdef _GNU_SOURCE
# define ttf2pt1_getopt(a, b, c, d, e) getopt_long(a, b, c, d, e)
static struct option longopts[] = {
{ "debug", 1, NULL, 'd' },
{ "encode", 0, NULL, 'e' },
{ "force-unicode", 0, NULL, 'F' },
+ { "generate", 1, NULL, 'G' },
{ "language", 1, NULL, 'l' },
{ "language-map", 1, NULL, 'L' },
{ "limit", 1, NULL, 'm' },
#else
# define ttf2pt1_getopt(a, b, c, d, e) getopt(a, b, c)
#endif
+ /* table of Outline Processing (may think also as Optimization) options */
+ static struct subo_case opotbl[] = {
+ { 'b', 0/*auto-set*/, &trybold, 1, "guessing of the ForceBold hint" },
+ { 'h', 0/*auto-set*/, &hints, 1, "autogeneration of hints" },
+ { 'u', 0/*auto-set*/, &subhints, 1, "hint substitution technique" },
+ { 'o', 0/*auto-set*/, &optimize, 1, "space optimization of font files" },
+ { 's', 0/*auto-set*/, &smooth, 1, "smoothing and repair of outlines" },
+ { 't', 0/*auto-set*/, &transform, 1, "auto-scaling to the standard matrix 1000x1000" },
+ { 'w', 0/*auto-set*/, &correctwidth, 0, "correct the glyph widths (use only for buggy fonts)" },
+ { 'v', 0/*auto-set*/, &vectorize, 0, "vectorize (trace) the bitmaps" },
+#ifdef USE_AUTOTRACE
+ { 'z', 0/*auto-set*/, &use_autotrace, 0, "use the autotrace library on bitmaps (works badly)" },
+#endif /*USE_AUTOTRACE*/
+ { 0, 0, 0, 0, 0} /* terminator */
+ };
+ /* table of the File Generation options */
+ static struct subo_case fgotbl[] = {
+ { 'f', 0/*auto-set*/, &gen_pfa, 1, "generate the font file (.t1a, .pfa or .pfb)" },
+ { 'a', 0/*auto-set*/, &gen_afm, 1, "generate the Adobe metrics file (.afm)" },
+ { 'e', 0/*auto-set*/, &gen_dvienc, 0, "generate the dvips encoding file (.enc)" },
+ { 0, 0, 0, 0, 0} /* terminator */
+ };
+ int *genlast = NULL;
+
- /* initialize sub-options of -O */
- for(i=0; i< (sizeof opotbl)/(sizeof opotbl[0]); i++) {
- opotbl[i].disbl = tolower(opotbl[i].disbl);
- opotbl[i].enbl = toupper(opotbl[i].disbl);
- *(opotbl[i].valp) = opotbl[i].dflt;
+ init_subo_tbl(opotbl); /* initialize sub-options of -O */
+ init_subo_tbl(fgotbl); /* initialize sub-options of -G */
+
+ /* save the command line for the record
+ * (we don't bother about escaping the shell special characters)
+ */
+
+ j = 0;
+ for(i=1; i<argc; i++) {
+ j += strlen(argv[i])+1;
+ }
+ if ((cmdline = malloc(j+1)) == NULL) {
+ fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
+ exit(255);
+ }
+ cmdline[0] = 0;
+ for(i=1; i<argc; i++) {
+ strcat(cmdline, argv[i]);
+ strcat(cmdline, " ");
}
+ for(i=0; (j=cmdline[i])!=0; i++)
+ if(j == '\n')
+ cmdline[i] = ' ';
- while(( oc=ttf2pt1_getopt(argc, argv, "FaoebAsthHfwVv:p:l:d:u:L:m:W:O:",
+
+ while(( oc=ttf2pt1_getopt(argc, argv, "FaoebAsthHfwVv:p:l:d:u:L:m:W:O:G:",
longopts, NULL) )!= -1) {
switch(oc) {
+ case 'W':
+ if(sscanf(optarg, "%d", &warnlevel) < 1 || warnlevel < 0) {
+ fprintf(stderr, "**** warning level must be a positive number\n");
+ exit(1);
+ }
+ break;
case 'F':
forcemap = 1;
break;
encode = pfbflag = 1;
break;
case 'A':
+ fputs("Warning: option -A is obsolete, use -GA instead\n", stderr);
wantafm = 1;
break;
case 'a':
}
case 'O':
{
- char subopt;
char *p;
- char dflt[20]; /* should be big enough */
- for(p=optarg; (subopt = *p) != 0; p++) {
- for(i=0; i< (sizeof opotbl)/(sizeof opotbl[0]); i++) {
- if(subopt == opotbl[i].disbl) {
- *(opotbl[i].valp) = 0;
- break;
- } else if(subopt == opotbl[i].enbl) {
- *(opotbl[i].valp) = 1;
- break;
- }
- }
- if( i == (sizeof opotbl)/(sizeof opotbl[0]) ) { /* found no match */
- if (subopt != '?')
- fprintf(stderr, "**** Unknown outline processing suboption '%c' ****\n", subopt);
+ for(p=optarg; *p != 0; p++) {
+ if(set_subo(opotbl, *p) == NULL) { /* found no match */
+ if (*p != '?')
+ fprintf(stderr, "**** Unknown outline processing suboption '%c' ****\n", *p);
fprintf(stderr,"The general form of the outline processing option is:\n");
fprintf(stderr," -O suboptions\n");
fprintf(stderr,"(To remember easily -O may be also thought of as \"optimization\").\n");
- fprintf(stderr,"The lowercase suboptions disable features, corresponding\n");
- fprintf(stderr,"uppercase suboptions enable them. The supported suboptions,\n");
- fprintf(stderr,"their default states and the features they control are:\n");
- p = dflt;
- for(i=0; i< (sizeof opotbl)/(sizeof opotbl[0]); i++) {
- fprintf(stderr," %c/%c - [%s] %s\n", opotbl[i].disbl, opotbl[i].enbl,
- opotbl[i].dflt ? "enabled" : "disabled", opotbl[i].descr);
- if(opotbl[i].dflt)
- *p++ = opotbl[i].enbl;
- else
- *p++ = opotbl[i].disbl;
- }
- *p = 0;
- fprintf(stderr, "The default state corresponds to the option -O %s\n", dflt);
+ print_subo_usage(stderr, opotbl);
+ fprintf(stderr, "The default state corresponds to the option -O ");
+ print_subo_dflt(stderr, opotbl);
+ fprintf(stderr, "\n");
+ exit(1);
+ }
+ }
+ break;
+ }
+ case 'G':
+ {
+ char *p;
+ struct subo_case *s;
+
+ for(p=optarg; *p != 0; p++) {
+ if(( s = set_subo(fgotbl, *p) )==NULL) { /* found no match */
+ if (*p != '?')
+ fprintf(stderr, "**** Unknown outline processing suboption '%c' ****\n", *p);
+ fprintf(stderr,"The general form of the file generation option is:\n");
+ fprintf(stderr," -G suboptions\n");
+ print_subo_usage(stderr, fgotbl);
+ fprintf(stderr, "The default state corresponds to the option -G ");
+ print_subo_dflt(stderr, fgotbl);
+ fprintf(stderr, "\n");
+ fprintf(stderr, "If the result is written to STDOUT, the last specified enabling suboption of -G\n");
+ fprintf(stderr, "selects the file to be written to STDOUT (the font file by default).\n");
exit(1);
}
+ if( *(s->valp) )
+ genlast = s->valp;
}
break;
}
/* open the input file */
cursw->open(argv[1], front_arg);
- /* Get base name of output file (if not specified)
+ /* Get base name of output file (if not specified)
* by removing (known) suffixes
*/
- if (argc == 2) {
- char *p;
- argv[2] = strdup (argv[1]);
+ if (argc == 2) {
+ char *p;
+ argv[2] = strdup (argv[1]);
p = strrchr(argv[2], '.');
- if (p != NULL)
- for (j = 0; (j < MAXSUFFIX) && (cursw->suffix[j]); j++)
- if (!strcmp(p+1, cursw->suffix[j])) {
- *p = '\0';
- break;
- }
+ if (p != NULL)
+ for (j = 0; (j < MAXSUFFIX) && (cursw->suffix[j]); j++)
+ if (!strcmp(p+1, cursw->suffix[j])) {
+ *p = '\0';
+ break;
+ }
+ }
+
+ if ((null_file = fopen(BITBUCKET, "w")) == NULL) {
+ fprintf(stderr, "**** Cannot open %s ****\n",
+ BITBUCKET);
+ exit(1);
}
if (argv[2][0] == '-' && argv[2][1] == 0) {
- pfa_file = stdout;
-#ifdef WINDOWS
+#ifdef WIN32
if(encode) {
fprintf(stderr, "**** can't write encoded file to stdout ***\n");
exit(1);
}
-#endif /* WINDOWS */
- if ((afm_file = fopen(BITBUCKET, "w+")) == NULL) {
- fprintf(stderr, "**** Cannot open %s ****\n",
- BITBUCKET);
- exit(1);
- }
- if(wantafm) { /* print .afm instead of .pfa */
- FILE *n;
- n=pfa_file;
- pfa_file=afm_file;
- afm_file=n;
- }
- } else {
-#ifndef WINDOWS
- sprintf(filename, "%s.%s", argv[2], encode ? (pfbflag ? "pfb" : "pfa") : "t1a" );
-#else /* WINDOWS */
- sprintf(filename, "%s.t1a", argv[2]);
-#endif /* WINDOWS */
- if ((pfa_file = fopen(filename, "w+b")) == NULL) {
- fprintf(stderr, "**** Cannot create %s ****\n", filename);
- exit(1);
+#endif /* WIN32 */
+ pfa_file = afm_file = dvienc_file = null_file;
+
+ if(wantafm || genlast == &gen_afm) { /* print .afm instead of .pfa */
+ afm_file=stdout;
+ } else if(genlast == &gen_dvienc) { /* print .enc instead of .pfa */
+ dvienc_file=stdout;
} else {
- WARNING_2 fprintf(stderr, "Creating file %s\n", filename);
+ pfa_file=stdout;
}
+ } else {
+#ifndef WIN32
+ snprintf(filename, sizeof filename, "%s.%s", argv[2], encode ? (pfbflag ? "pfb" : "pfa") : "t1a" );
+#else /* WIN32 */
+ snprintf(filename, sizeof filename, "%s.t1a", argv[2]);
+#endif /* WIN32 */
+ if(gen_pfa) {
+ if ((pfa_file = fopen(filename, "w+b")) == NULL) {
+ fprintf(stderr, "**** Cannot create %s ****\n", filename);
+ exit(1);
+ } else {
+ WARNING_2 fprintf(stderr, "Creating file %s\n", filename);
+ }
+ } else
+ pfa_file = null_file;
- sprintf(filename, "%s.afm", argv[2]) ;
- if ((afm_file = fopen(filename, "w+")) == NULL) {
- fprintf(stderr, "**** Cannot create %s ****\n", filename);
- exit(1);
- }
+ if(gen_afm) {
+ snprintf(filename, sizeof filename, "%s.afm", argv[2]) ;
+ if ((afm_file = fopen(filename, "w+")) == NULL) {
+ fprintf(stderr, "**** Cannot create %s ****\n", filename);
+ exit(1);
+ }
+ } else
+ afm_file = null_file;
+
+ if(gen_dvienc) {
+ snprintf(filename, sizeof filename, "%s.enc", argv[2]) ;
+ if ((dvienc_file = fopen(filename, "w+")) == NULL) {
+ fprintf(stderr, "**** Cannot create %s ****\n", filename);
+ exit(1);
+ }
+ } else
+ dvienc_file = null_file;
}
/*
* Now check whether we want a fully encoded .pfa file
*/
-#ifndef WINDOWS
- if (encode) {
+#ifndef WIN32
+ if (encode && pfa_file != null_file) {
int p[2];
extern FILE *ifp, *ofp; /* from t1asm.c */
fclose(ifp); fclose(ofp);
}
}
-#endif /* WINDOWS */
+#endif /* WIN32 */
numglyphs = cursw->nglyphs();
fprintf(pfa_file, "%%!PS-AdobeFont-1.0: %s %s\n", fontm.name_ps, fontm.name_copyright);
time(&now);
fprintf(pfa_file, "%%%%CreationDate: %s", ctime(&now));
- fprintf(pfa_file, "%% Converted from TrueType font %s by ttf2pt1 %s/%s\n%%\n", argv[1], TTF2PT1_VERSION, cursw->name);
+ fprintf(pfa_file, "%% Converted by ttf2pt1 %s/%s\n", TTF2PT1_VERSION, cursw->name);
+ fprintf(pfa_file, "%% Args: %s\n", cmdline);
fprintf(pfa_file, "%%%%EndComments\n");
fprintf(pfa_file, "12 dict begin\n/FontInfo 9 dict dup begin\n");
}
fprintf(afm_file, "StartCharMetrics %d\n", nmetrics);
+ fprintf(dvienc_file, "/%s%sEncoding [\n",
+ fontm.name_ps, uni_font_name_suffix);
+
for (i = 0; i < 256; i++) { /* here 256, not ENCTABSZ */
fprintf(pfa_file,
"dup %d /%s put\n", i, glyph_list[encoding[i]].name);
if( glyph_list[encoding[i]].flags & GF_USED ) {
print_glyph_metrics(i, encoding[i]);
}
+ if (encoding[i])
+ fprintf (dvienc_file, "/index0x%04X\n", encoding[i]);
+ else
+ fprintf (dvienc_file, "/.notdef\n");
}
/* print the metrics for glyphs not in encoding table */
if(strUID)
fprintf(pfa_file, "/UniqueID %s def\n", strUID);
else
- fprintf(pfa_file, "/UniqueID %lu def\n", numUID);
+ /* the range for private UIDs is 4 000 000 - 4 999 999 */
+ fprintf(pfa_file, "/UniqueID %lu def\n", numUID%1000000+4000000);
}
if(forcebold==0)
/* our sub to make the hint substitution code shorter */
fprintf(pfa_file, "dup 4 {\n\t1 3 callothersubr pop callsubr return\n\t} NP\n");
- /* print the hinting subroutines */
- subid=5;
- for (i = 0; i < numglyphs; i++) {
- if (glyph_list[i].flags & GF_USED) {
- subid+=print_glyph_subs(i, subid);
+ if(pfa_file != null_file) { /* save time if the output would be wasted */
+ /* print the hinting subroutines */
+ subid=5;
+ for (i = 0; i < numglyphs; i++) {
+ if (glyph_list[i].flags & GF_USED) {
+ subid+=print_glyph_subs(i, subid);
+ }
}
- }
- fprintf(pfa_file, "ND\n");
+ fprintf(pfa_file, "ND\n");
- fprintf(pfa_file, "2 index /CharStrings %d dict dup begin\n", nchars);
+ fprintf(pfa_file, "2 index /CharStrings %d dict dup begin\n", nchars);
- for (i = 0; i < numglyphs; i++) {
- if (glyph_list[i].flags & GF_USED) {
- print_glyph(i);
+ for (i = 0; i < numglyphs; i++) {
+ if (glyph_list[i].flags & GF_USED) {
+ print_glyph(i);
+ }
}
}
fprintf(pfa_file, "dup/FontName get exch definefont pop\n");
fprintf(pfa_file, "mark currentfile closefile\n");
fprintf(pfa_file, "cleartomark\n");
- fclose(pfa_file);
+ if(pfa_file != null_file)
+ fclose(pfa_file);
fprintf(afm_file, "EndCharMetrics\n");
- /* print the kerning data if present */
- cursw->kerning(glyph_list);
- print_kerning(afm_file);
+ if(afm_file != null_file) { /* save time if the output would be wasted */
+ /* print the kerning data if present */
+ cursw->kerning(glyph_list);
+ print_kerning(afm_file);
+ }
fprintf(afm_file, "EndFontMetrics\n");
- fclose(afm_file);
+ if(afm_file != null_file)
+ fclose(afm_file);
+
+ fprintf(dvienc_file, "] def\n");
+ if(dvienc_file != null_file)
+ fclose(dvienc_file);
WARNING_1 fprintf(stderr, "Finished - font files created\n");
cursw->close();
-#ifndef WINDOWS
+#ifndef WIN32
while (wait(&ws) > 0) {
}
#else
- if (encode) {
+ if (encode && pfa_file != null_file) {
extern FILE *ifp, *ofp; /* from t1asm.c */
- sprintf(filename, "%s.%s", argv[2], pfbflag ? "pfb" : "pfa" );
+ snprintf(filename, sizeof filename, "%s.%s", argv[2], pfbflag ? "pfb" : "pfa" );
if ((ofp = fopen(filename, "w+b")) == NULL) {
fprintf(stderr, "**** Cannot create %s ****\n", filename);
WARNING_2 fprintf(stderr, "Creating file %s\n", filename);
}
- sprintf(filename, "%s.t1a", argv[2]);
+ snprintf(filename, sizeof filename, "%s.t1a", argv[2]);
if ((ifp = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "**** Cannot read %s ****\n", filename);
if(unlink(filename) < 0)
WARNING_1 fprintf(stderr, "Unable to remove file %s\n", filename);
}
-#endif /* WINDOWS */
+#endif /* WIN32 */
+ fclose(null_file);
return 0;
}