diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/ttf2afm.c')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/ttf2afm.c | 1053 |
1 files changed, 0 insertions, 1053 deletions
diff --git a/Build/source/texk/web2c/luatexdir/ttf2afm.c b/Build/source/texk/web2c/luatexdir/ttf2afm.c deleted file mode 100644 index 45524e658fa..00000000000 --- a/Build/source/texk/web2c/luatexdir/ttf2afm.c +++ /dev/null @@ -1,1053 +0,0 @@ -/* -Copyright (c) 1996-2006 Han The Thanh, <thanh@pdftex.org> - -This file is part of pdfTeX. - -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -$Id$ -*/ - -/* -#include <kpathsea/c-auto.h> -#include <kpathsea/c-fopen.h> -#include <kpathsea/c-limits.h> -#include <kpathsea/c-memstr.h> -#include <kpathsea/c-proto.h> -#include <kpathsea/c-std.h> -#include <kpathsea/c-unistd.h> -#include <kpathsea/c-vararg.h> -#include <kpathsea/getopt.h> -*/ -#include <kpathsea/kpathsea.h> -#include <time.h> -#include <libgen.h> -#include <pdftexdir/ptexmac.h> -#include <pdftexdir/writettf.h> -#include <string.h> - -/* constants used for print_glyph */ -#define AS_NAME 0 -#define AS_INDEX 1 -#define AS_UNICODE 2 - -#define VERSION "1.02" - -/* FIXME */ -#define NOGLYPH_ASSIGNED_YET USHRT_MAX - -#define enc_getchar() xgetc(encfile) -#define enc_eof() feof(encfile) -#define pdftex_fail ttf_fail - -#define print_str(S) if (S != NULL) fprintf(outfile, #S " %s\n", S) -#define print_dimen(N) if (N != 0) fprintf(outfile, #N " %i\n", (int)get_ttf_funit(N)) - -#define get_ttf_funit(n) \ - (n < 0 ? -((-n/upem)*1000 + ((-n%upem)*1000)/upem) :\ - ((n/upem)*1000 + ((n%upem)*1000)/upem)) - -typedef struct _unicode_entry { - TTF_USHORT code; - struct _unicode_entry *next; -} unicode_entry; - -typedef struct { - TTF_ULONG wx; - const char *name; - TTF_USHORT index; - TTF_LONG bbox[4]; - TTF_LONG offset; - char found; - unicode_entry *unicode_list; -} mtx_entry; - -typedef struct _kern_entry { - TTF_FWORD value; - TTF_USHORT adjacent; - struct _kern_entry *next; -} kern_entry; - - -char *FontName = NULL; -char *FullName = NULL; -char *FamilyName = NULL; -char *Notice = NULL; -char *Version = NULL; -char *Weight = NULL; -TTF_LONG ItalicAngle = 0; -TTF_LONG IsFixedPitch = 0; -TTF_LONG FontBBox1 = 0; -TTF_LONG FontBBox2 = 0; -TTF_LONG FontBBox3 = 0; -TTF_LONG FontBBox4 = 0; -TTF_LONG UnderlinePosition = 0; -TTF_LONG UnderlineThickness = 0; -TTF_LONG CapHeight = 0; -TTF_LONG XHeight = 0; -TTF_LONG Ascender = 0; -TTF_LONG Descender = 0; - -char *cur_file_name = NULL; -char *bname = NULL; -FILE *fontfile, *encfile, *outfile = NULL; -char enc_line[ENC_BUF_SIZE]; -int print_glyph = AS_NAME; /* print glyph as names by default */ -int print_cmap = 0; -int use_ext_enc = 0; /* use external encoding? */ -int select_unicode = 1; /* use the first unicode mapping by default */ -int printing_enc = 0; /* set to 1 while printing encodings */ - - -TTF_USHORT upem; -TTF_USHORT ntabs; -int nhmtx; -int post_format; -int loca_format; -int nglyphs; -int nkernpairs = 0; -int names_count = 0; -char *ps_glyphs_buf = NULL; -dirtab_entry *dir_tab; -mtx_entry *mtx_tab; -kern_entry *kern_tab; -char *enc_names[256]; - -cmap_entry *cmap_tab; -TTF_USHORT ncmapsubtabs; -long cmap_offset; - -TTF_USHORT unicode_map[0xFFFF]; - -#include "macnames.c" - -void ttf_fail(char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - fprintf(stderr, "\nError: ttf2afm"); - if (cur_file_name) - fprintf(stderr, " (file %s)", cur_file_name); - fprintf(stderr, ": "); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); - va_end(args); - exit(-1); -} - -void ttf_warn(char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - fprintf(stderr, "\nWarning: ttf2afm"); - if (cur_file_name) - fprintf(stderr, " (file %s)", cur_file_name); - fprintf(stderr, ": "); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); - va_end(args); -} - -int xgetc(FILE * stream) -{ - int c = getc(stream); - if (c < 0 && c != EOF) - ttf_fail("getc() failed"); - return c; -} - -long ttf_getnum(int s) -{ - long i = 0; - int c; - while (s > 0) { - if ((c = xgetc(fontfile)) < 0) - ttf_fail("unexpected EOF"); - i = (i << 8) + c; - s--; - } - return i; -} - -dirtab_entry *name_lookup(char *s) -{ - dirtab_entry *p; - for (p = dir_tab; p - dir_tab < ntabs; p++) - if (strncmp(p->tag, s, 4) == 0) - break; - if (p - dir_tab == ntabs) - p = NULL; - return p; -} - -void ttf_seek_tab(char *name, TTF_LONG offset) -{ - dirtab_entry *p = name_lookup(name); - if (p == NULL) - ttf_fail("can't find table `%s'", name); - if (fseek(fontfile, p->offset + offset, SEEK_SET) < 0) - ttf_fail("fseek() failed while reading `%s' table", name); -} - -void ttf_seek_off(char *name, TTF_LONG offset) -{ - if (fseek(fontfile, offset, SEEK_SET) < 0) - ttf_fail("fseek() failed while reading `%s' table", name); -} - -void store_kern_value(TTF_USHORT i, TTF_USHORT j, TTF_FWORD v) -{ - kern_entry *pk; - for (pk = kern_tab + i; pk->next != NULL; pk = pk->next); - pk->next = xtalloc(1, kern_entry); - pk = pk->next; - pk->next = NULL; - pk->adjacent = j; - pk->value = v; -} - -TTF_FWORD get_kern_value(TTF_USHORT i, TTF_USHORT j) -{ - kern_entry *pk; - for (pk = kern_tab + i; pk->next != NULL; pk = pk->next) - if (pk->adjacent == j) - return pk->value; - return 0; -} - -void free_tabs() -{ - int i; - kern_entry *p, *q, *r; - unicode_entry *u, *v; - mtx_entry *pm; - xfree(ps_glyphs_buf); - xfree(dir_tab); - xfree(cmap_tab); - for (pm = mtx_tab; pm - mtx_tab < nglyphs; pm++) - if (pm->unicode_list != NULL) { - for (u = pm->unicode_list; u != NULL; u = v) { - v = u->next; - xfree(u); - } - } - xfree(mtx_tab); - for (i = 0; i < 256; i++) - if (enc_names[i] != notdef) - free(enc_names[i]); - if (kern_tab == NULL) - return; - for (p = kern_tab; p - kern_tab < nglyphs; p++) - if (p->next != NULL) { - for (q = p->next; q != NULL; q = r) { - r = q->next; - xfree(q); - } - } - xfree(kern_tab); -} - -void enc_getline() -{ - char *p; - int c; - restart: - if (enc_eof()) - ttf_fail("unexpected end of file"); - p = enc_line; - do { - c = enc_getchar(); - append_char_to_buf(c, p, enc_line, ENC_BUF_SIZE); - } while (c != 10); - append_eol(p, enc_line, ENC_BUF_SIZE); - if (p - enc_line <= 2 || *enc_line == '%') - goto restart; -} - -void read_encoding(char *encname) -{ - char buf[ENC_BUF_SIZE], *q, *r; - int i; - cur_file_name = encname; - if ((encfile = kpse_open_file(encname, kpse_enc_format)) == NULL) - ttf_fail("can't open encoding file for reading"); - enc_getline(); - if (*enc_line != '/' || (r = strchr(enc_line, '[')) == 0) - ttf_fail("invalid encoding vector: name or `[' missing:\n%s", enc_line); - for (i = 0; i < 256; i++) - enc_names[i] = (char *) notdef; - if (r[1] == 32) - r += 2; - else - r++; - for (;;) { - while (*r == '/') { - for (q = buf, r++; *r != ' ' && *r != 10 && *r != ']' && *r != '/'; - *q++ = *r++); - *q = 0; - if (*r == ' ') - r++; - if (strcmp(buf, notdef) != 0) - enc_names[names_count] = xstrdup(buf); - if (++names_count > 256) - ttf_fail("encoding vector contains more than 256 names"); - } - if (*r != 10 && *r != '%') { - if (str_prefix(r, "] def")) - goto done; - else - ttf_fail - ("invalid encoding vector: a name or `] def' expected:\n%s", - enc_line); - } - enc_getline(); - r = enc_line; - } - done: - xfclose(encfile, cur_file_name); - if (names_count != 256) - ttf_warn("encoding vector contains only %i names (expected %i)", - names_count, 256); -} - -void append_unicode(long glyph_index, TTF_USHORT code) -{ - mtx_entry *m; - unicode_entry *u, *v; - assert(glyph_index >= 0 && glyph_index < nglyphs); - u = xtalloc(1, unicode_entry); - m = mtx_tab + glyph_index; - u->next = NULL; - u->code = code; - if (m->unicode_list == NULL) - m->unicode_list = u; - else { - for (v = m->unicode_list; v->next != NULL; v = v->next); - v->next = u; - } -} - -void read_cmap() -{ - cmap_entry *e; - seg_entry *seg_tab, *s; - TTF_USHORT *glyphId, format, segCount; - long int n, i, k, length, index; - int unicode_map_count = 0; - ttf_seek_tab("cmap", TTF_USHORT_SIZE); /* skip the table vesrion number (=0) */ - ncmapsubtabs = get_ushort(); - cmap_offset = xftell(fontfile, cur_file_name) - 2 * TTF_USHORT_SIZE; - cmap_tab = xtalloc(ncmapsubtabs, cmap_entry); - for (e = cmap_tab; e - cmap_tab < ncmapsubtabs; e++) { - e->platform_id = get_ushort(); - e->encoding_id = get_ushort(); - e->offset = get_ulong(); - } - for (i = 0; i < 0xFFFF; ++i) - unicode_map[i] = NOGLYPH_ASSIGNED_YET; - for (e = cmap_tab; e - cmap_tab < ncmapsubtabs; e++) { - ttf_seek_off("cmap", cmap_offset + e->offset); - format = get_ushort(); - if (is_unicode_mapping(e) && format == 4) { - ++unicode_map_count; - if (unicode_map_count == select_unicode) - goto read_unicode_mapping; - } - continue; - read_unicode_mapping: - length = get_ushort(); /* length of subtable */ - (void) get_ushort(); /* skip the version number */ - segCount = get_ushort() / 2; - (void) get_ushort(); /* skip searchRange */ - (void) get_ushort(); /* skip entrySelector */ - (void) get_ushort(); /* skip rangeShift */ - seg_tab = xtalloc(segCount, seg_entry); - for (s = seg_tab; s - seg_tab < segCount; s++) - s->endCode = get_ushort(); - (void) get_ushort(); /* skip reversedPad */ - for (s = seg_tab; s - seg_tab < segCount; s++) - s->startCode = get_ushort(); - for (s = seg_tab; s - seg_tab < segCount; s++) - s->idDelta = get_ushort(); - for (s = seg_tab; s - seg_tab < segCount; s++) - s->idRangeOffset = get_ushort(); - length -= 8 * TTF_USHORT_SIZE + 4 * segCount * TTF_USHORT_SIZE; - n = length / TTF_USHORT_SIZE; /* number of glyphID's */ - glyphId = xtalloc(n, TTF_USHORT); - for (i = 0; i < n; i++) - glyphId[i] = get_ushort(); - for (s = seg_tab; s - seg_tab < segCount; s++) { - for (i = s->startCode; i <= s->endCode; i++) { - if (i == 0xFFFF) - break; - if (s->idRangeOffset != 0xFFFF) { - if (s->idRangeOffset == 0) - index = (s->idDelta + i) & 0xFFFF; - else { - k = (i - s->startCode) + s->idRangeOffset / 2 + - (s - seg_tab) - segCount; - assert(k >= 0 && k < n); - index = glyphId[k]; - if (index != 0) - index = (index + s->idDelta) & 0xFFFF; - } - if (index < 0 || index >= nglyphs) - ttf_fail("cmap: glyph index out of range [0..%i)", - nglyphs); - if (unicode_map[i] != NOGLYPH_ASSIGNED_YET) - ttf_fail - ("cmap: unicode %.4X is mapped to multiple glyphs", - i); - if (unicode_map[i] == 0) - ttf_warn("unicode %.4X is mapped to glyph 0", i); - unicode_map[i] = index; - append_unicode(index, i); - } - } - } - xfree(seg_tab); - xfree(glyphId); - break; - } - if (e - cmap_tab == ncmapsubtabs) - ttf_fail("Invalid argument `-m %i': out of range [1..%i]", - select_unicode, unicode_map_count); -} - -void read_font() -{ - long i, j, k, l, n, m, platform_id, encoding_id; - TTF_FWORD kern_value; - char buf[1024], *p; - dirtab_entry *pd; - kern_entry *pk; - mtx_entry *pm; - ttf_skip(TTF_FIXED_SIZE); - ntabs = get_ushort(); - ttf_skip(3 * TTF_USHORT_SIZE); - dir_tab = xtalloc(ntabs, dirtab_entry); - for (pd = dir_tab; pd - dir_tab < ntabs; pd++) { - pd->tag[0] = get_char(); - pd->tag[1] = get_char(); - pd->tag[2] = get_char(); - pd->tag[3] = get_char(); - ttf_skip(TTF_ULONG_SIZE); - pd->offset = get_ulong(); - pd->length = get_ulong(); - } - ttf_seek_tab("head", - 2 * TTF_FIXED_SIZE + 2 * TTF_ULONG_SIZE + TTF_USHORT_SIZE); - upem = get_ushort(); - ttf_skip(16); - FontBBox1 = get_fword(); - FontBBox2 = get_fword(); - FontBBox3 = get_fword(); - FontBBox4 = get_fword(); - ttf_skip(TTF_USHORT_SIZE); - ttf_skip(TTF_USHORT_SIZE + TTF_SHORT_SIZE); - loca_format = get_short(); - ttf_seek_tab("maxp", TTF_FIXED_SIZE); - nglyphs = get_ushort(); - mtx_tab = xtalloc(nglyphs + 1, mtx_entry); - for (pm = mtx_tab; pm - mtx_tab < nglyphs + 1; pm++) { - pm->name = NULL; /* notdef */ - pm->found = 0; - pm->unicode_list = NULL; - } - ttf_seek_tab("hhea", TTF_FIXED_SIZE); - Ascender = get_fword(); - Descender = get_fword(); - ttf_skip(TTF_FWORD_SIZE + TTF_UFWORD_SIZE + 3 * TTF_FWORD_SIZE + - 8 * TTF_SHORT_SIZE); - nhmtx = get_ushort(); - ttf_seek_tab("hmtx", 0); - for (pm = mtx_tab; pm - mtx_tab < nhmtx; pm++) { - pm->wx = get_ufword(); - ttf_skip(TTF_FWORD_SIZE); - } - i = pm[-1].wx; - for (; pm - mtx_tab < nglyphs; pm++) - pm->wx = i; - ttf_seek_tab("post", 0); - post_format = get_fixed(); - ItalicAngle = get_fixed(); - UnderlinePosition = get_fword(); - UnderlineThickness = get_fword(); - IsFixedPitch = get_ulong(); - ttf_skip(4 * TTF_ULONG_SIZE); - switch (post_format) { - case 0x00010000: - for (pm = mtx_tab; pm - mtx_tab < NMACGLYPHS; pm++) - pm->name = (char *) mac_glyph_names[pm - mtx_tab]; - break; - case 0x00020000: - l = get_ushort(); /* some fonts have this value different from nglyphs */ - for (pm = mtx_tab; pm - mtx_tab < l; pm++) - pm->index = get_ushort(); - if ((pd = name_lookup("post")) == NULL) - ttf_fail("can't find table `post'"); - n = pd->length - (xftell(fontfile, cur_file_name) - pd->offset); - ps_glyphs_buf = xtalloc(n + 1, char); - for (m = 0, p = ps_glyphs_buf; p - ps_glyphs_buf < n;) { - for (i = get_byte(); i > 0; i--) - *p++ = get_char(); - *p++ = 0; - m++; - } - for (pm = mtx_tab; pm - mtx_tab < l; pm++) { - if (pm->index < NMACGLYPHS) - pm->name = (char *) mac_glyph_names[pm->index]; - else { - k = pm->index - NMACGLYPHS; - if (k < m) { - for (p = ps_glyphs_buf; k > 0; k--) - p = (char *) strend(p) + 1; - pm->name = p; - } else { - pm->name = NULL; /* index out of valid range, fix name to notdef */ - } - } - } - break; - case 0x00030000: - if (print_glyph == AS_NAME) { - ttf_warn - ("no names available in `post' table, print glyph names as indices"); - print_glyph = AS_INDEX; - } - break; - default: - ttf_fail("unsupported format (%.8X) of `post' table", post_format); - } - ttf_seek_tab("loca", 0); - for (pm = mtx_tab; pm - mtx_tab < nglyphs + 1; pm++) - pm->offset = (loca_format == 1 ? get_ulong() : get_ushort() << 1); - if ((pd = name_lookup("glyf")) == NULL) - ttf_fail("can't find table `glyf'"); - for (n = pd->offset, pm = mtx_tab; pm - mtx_tab < nglyphs; pm++) { - ttf_seek_off("glyf", n + pm->offset); - ttf_skip(TTF_SHORT_SIZE); - pm->bbox[0] = get_fword(); - pm->bbox[1] = get_fword(); - pm->bbox[2] = get_fword(); - pm->bbox[3] = get_fword(); - } - - ttf_seek_tab("name", 0); - i = ftell(fontfile); - (void) get_ushort(); /* skip Format selector (=0) */ - n = get_ushort(); /* number of name records */ - j = get_ushort() + i; /* start of string storage */ - i += 3 * TTF_USHORT_SIZE; /* update the current offset */ - while (n-- > 0) { - ttf_seek_off("name", i); - platform_id = get_ushort(); - encoding_id = get_ushort(); - (void) get_ushort(); /* skip language_id */ - k = get_ushort(); /* name_id */ - l = get_ushort(); /* string length */ - if ((platform_id == 1 && encoding_id == 0) && - (k == 0 || k == 1 || k == 4 || k == 5 || k == 6)) { - ttf_seek_off("name", j + get_ushort()); - for (p = buf; l-- > 0; p++) - *p = get_char(); - *p++ = 0; - p = xstrdup(buf); - switch (k) { - case 0: - Notice = p; - break; - case 1: - FamilyName = p; - break; - case 4: - FullName = p; - break; - case 5: - Version = p; - break; - case 6: - FontName = p; - break; - } - if (Notice != NULL && FamilyName != NULL && - FullName != NULL && FontName != NULL && Version != NULL) - break; - } - i += 6 * TTF_USHORT_SIZE; - } - if ((pd = name_lookup("PCLT")) != NULL) { - ttf_seek_off("PCLT", - pd->offset + TTF_FIXED_SIZE + TTF_ULONG_SIZE + - TTF_USHORT_SIZE); - XHeight = get_ushort(); - if (XHeight > FontBBox4) { - ttf_warn("XHeight is too big (%i)\n" - "This is likely a font bug, so I discarded this parameter.", - (int) get_ttf_funit(XHeight)); - XHeight = 0; - } - ttf_skip(2 * TTF_USHORT_SIZE); - CapHeight = get_ushort(); - if (CapHeight > FontBBox4) { - ttf_warn("CapHeight is too big (%i)\n" - "This is likely a font bug, so I discarded this parameter.", - (int) get_ttf_funit(CapHeight)); - CapHeight = 0; - } - } - if ((pd = name_lookup("OS/2")) != NULL) { - ttf_seek_off("OS/2", pd->offset + TTF_USHORT_SIZE + TTF_SHORT_SIZE); - switch (get_ushort()) { - case 100: - Weight = xstrdup("Thin"); - break; - case 200: - Weight = xstrdup("ExtraLight"); - break; - case 300: - Weight = xstrdup("Light"); - break; - case 400: - Weight = xstrdup("Normal"); - break; - case 500: - Weight = xstrdup("Medium"); - break; - case 600: - Weight = xstrdup("SemiBold"); - break; - case 700: - Weight = xstrdup("Bold"); - break; - case 800: - Weight = xstrdup("ExtraBold"); - break; - case 900: - Weight = xstrdup("Black"); - break; - } - } - read_cmap(); - if ((pd = name_lookup("kern")) == NULL) - return; - kern_tab = xtalloc(nglyphs, kern_entry); - for (pk = kern_tab; pk - kern_tab < nglyphs; pk++) { - pk->next = NULL; - pk->value = 0; - } - ttf_seek_off("kern", pd->offset + TTF_USHORT_SIZE); - for (n = get_ushort(); n > 0; n--) { - ttf_skip(2 * TTF_USHORT_SIZE); - k = get_ushort(); - if (!(k & 1) || (k & 2) || (k & 4)) - return; - if (k >> 8 != 0) { - ttf_warn("warning: only format 0 supported of `kern' \ - subtables, others are ignored\n"); - continue; - } - k = get_ushort(); - ttf_skip(3 * TTF_USHORT_SIZE); - while (k-- > 0) { - i = get_ushort(); - j = get_ushort(); - kern_value = get_fword(); - if (kern_value != 0) { - store_kern_value(i, j, kern_value); - nkernpairs++; - } - } - } -} - -int null_glyph(const char *s) -{ - return (s == NULL || s == notdef); - /* - strcmp(s, ".null") == 0 || - strcmp(s, ".notdef") == 0 || - strcmp(s, "CR") == 0 || - strcmp(s, "nonmarkingreturn") == 0 - */ -} - -void print_glyph_name(FILE * f, long glyph_index, int convention) -{ - unicode_entry *u; - static char buf[1024]; - const char *n; - assert(glyph_index >= 0 && glyph_index < nglyphs); - n = mtx_tab[glyph_index].name; - if (printing_enc && (n == notdef || glyph_index == 0)) { - fputs(notdef, f); - return; - } - switch (convention) { - case AS_NAME: - if (!null_glyph(n)) - fprintf(f, "%s", mtx_tab[glyph_index].name); - else if (n == notdef && glyph_index == 0) - fputs(notdef, f); - else - fprintf(f, "%s%li", GLYPH_PREFIX_INDEX, glyph_index); - break; - case AS_INDEX: - fprintf(f, "%s%li", GLYPH_PREFIX_INDEX, glyph_index); - break; - case AS_UNICODE: - u = mtx_tab[glyph_index].unicode_list; - if (glyph_index == 0 || u == NULL) - fprintf(f, "%s%li", GLYPH_PREFIX_INDEX, glyph_index); - else { - fprintf(f, "%s%.4X", GLYPH_PREFIX_UNICODE, u->code); - if (u->next != NULL) { - *buf = 0; - for (; u != NULL; u = u->next) { - assert(strlen(buf) + strlen(GLYPH_PREFIX_UNICODE) + 4 < - sizeof(buf)); - sprintf(strend(buf), "%s%.4X ", GLYPH_PREFIX_UNICODE, - u->code); - } - ttf_warn - ("glyph %li have multiple encodings (the first one being used): %s", - glyph_index, buf); - } - } - break; - } -} - -void print_char_metric(FILE * f, int charcode, long glyph_index) -{ - assert(glyph_index >= 0 && glyph_index < nglyphs); - fprintf(f, "C %i ; WX %i ; N ", (int) charcode, - (int) get_ttf_funit(mtx_tab[glyph_index].wx)); - print_glyph_name(f, glyph_index, print_glyph); - fprintf(f, " ; B %i %i %i %i ;\n", - (int) get_ttf_funit(mtx_tab[glyph_index].bbox[0]), - (int) get_ttf_funit(mtx_tab[glyph_index].bbox[1]), - (int) get_ttf_funit(mtx_tab[glyph_index].bbox[2]), - (int) get_ttf_funit(mtx_tab[glyph_index].bbox[3])); -} - -void print_afm(char *date, char *fontname) -{ - int ncharmetrics; - mtx_entry *pm; - short mtx_index[256], *idx; - unsigned int index; - char **pe; - kern_entry *pk, *qk; - fputs("StartFontMetrics 2.0\n", outfile); - fprintf(outfile, - "Comment Converted at %s by ttf2afm from font file `%s'\n", date, - fontname); - print_str(FontName); - print_str(FullName); - print_str(FamilyName); - print_str(Weight); - fprintf(outfile, "ItalicAngle %i", (int) (ItalicAngle / 0x10000)); - if (ItalicAngle % 0x10000 > 0) - fprintf(outfile, ".%i", - (int) ((ItalicAngle % 0x10000) * 1000) / 0x10000); - fputs("\n", outfile); - fprintf(outfile, "IsFixedPitch %s\n", IsFixedPitch ? "true" : "false"); - fprintf(outfile, "FontBBox %i %i %i %i\n", - (int) get_ttf_funit(FontBBox1), - (int) get_ttf_funit(FontBBox2), - (int) get_ttf_funit(FontBBox3), (int) get_ttf_funit(FontBBox4)); - print_dimen(UnderlinePosition); - print_dimen(UnderlineThickness); - print_str(Version); - print_str(Notice); - fputs("EncodingScheme FontSpecific\n", outfile); - print_dimen(CapHeight); - print_dimen(XHeight); - print_dimen(Ascender); - print_dimen(Descender); - ncharmetrics = nglyphs; - if (use_ext_enc == 0) { /* external encoding vector not given */ - fprintf(outfile, "StartCharMetrics %u\n", ncharmetrics); - for (pm = mtx_tab; pm - mtx_tab < nglyphs; pm++) { - pm->found = 1; - print_char_metric(outfile, -1, pm - mtx_tab); - } - } else { /* external encoding vector given */ - for (idx = mtx_index; idx - mtx_index < 256; *idx++ = 0); - for (pe = enc_names; pe - enc_names < names_count; pe++) { - if (*pe == notdef) - continue; - /* scan form `uniABCD' */ - if (sscanf(*pe, GLYPH_PREFIX_UNICODE "%4X", &index) == 1) { - if (unicode_map[index] != NOGLYPH_ASSIGNED_YET) { - pm = mtx_tab + unicode_map[index]; - mtx_index[pe - enc_names] = pm - mtx_tab; - pm->found = 1; - } else - ttf_warn("`unicode %s%.4X' is not mapped to any glyph", - GLYPH_PREFIX_UNICODE, index); - continue; - } - /* scan form `index123' */ - if (sscanf(*pe, GLYPH_PREFIX_INDEX "%u", &index) == 1) { - if (index >= nglyphs) - ttf_fail("`%s' out of valid range [0..%i)", *pe, nglyphs); - pm = mtx_tab + index; - mtx_index[pe - enc_names] = pm - mtx_tab; - pm->found = 1; - continue; - } - for (pm = mtx_tab; pm - mtx_tab < nglyphs; pm++) - if (pm->name != NULL && strcmp(*pe, pm->name) == 0) - break; - if (pm - mtx_tab < nglyphs) { - mtx_index[pe - enc_names] = pm - mtx_tab; - pm->found = 1; - continue; - } else - ttf_warn("glyph `%s' not found", *pe); - } - fprintf(outfile, "StartCharMetrics %u\n", ncharmetrics); - for (idx = mtx_index; idx - mtx_index < 256; idx++) { - if (*idx != 0 && mtx_tab[*idx].found == 1) - print_char_metric(outfile, idx - mtx_index, *idx); - } - for (pm = mtx_tab; pm - mtx_tab < nglyphs; pm++) { - if (pm->found == 0) - print_char_metric(outfile, -1, pm - mtx_tab); - } - } - fputs("EndCharMetrics\n", outfile); - if (nkernpairs == 0) - goto end_kerns; - fprintf(outfile, "StartKernData\nStartKernPairs %i\n", nkernpairs); - for (pk = kern_tab; pk - kern_tab < nglyphs; pk++) - for (qk = pk; qk != NULL; qk = qk->next) - if (qk->value != 0) { - fputs("KPX ", outfile); - print_glyph_name(outfile, pk - kern_tab, print_glyph); - fputs(" ", outfile); - print_glyph_name(outfile, qk->adjacent, print_glyph); - fprintf(outfile, " %i\n", get_ttf_funit(qk->value)); - } - fputs("EndKernPairs\nEndKernData\n", outfile); - end_kerns: - fputs("EndFontMetrics\n", outfile); -} - -void print_encoding(char *fontname) -{ - long int i, k, first_code, length; - FILE *file; - TTF_USHORT format; - char *enc_name, *end_enc_name; - cmap_entry *e; - printing_enc = 1; - enc_name = xtalloc(strlen(bname) + 20, char); - strcpy(enc_name, bname); - end_enc_name = strend(enc_name); - for (e = cmap_tab; e - cmap_tab < ncmapsubtabs; e++) { - ttf_seek_off("cmap", cmap_offset + e->offset); - format = get_ushort(); - if (format != 0 && format != 4 && format != 6) { - ttf_warn("format %i of encoding subtable unsupported", - (int) format); - continue; - } - sprintf(end_enc_name, ".e%i%i", - (int) e->platform_id, (int) e->encoding_id); - if ((file = xfopen(enc_name, FOPEN_W_MODE)) == NULL) - ttf_fail("cannot open file for writing (%s)\n", enc_name); - fprintf(file, "%% Encoding table from font file %s\n", fontname); - fprintf(file, "%% Platform ID %i", (int) e->platform_id); - switch (e->platform_id) { - case 0: - fprintf(file, " (Apple Unicode)"); - break; - case 1: - fprintf(file, " (Macintosh)"); - break; - case 2: - fprintf(file, " (ISO)"); - break; - case 3: - fprintf(file, " (Microsoft)"); - break; - } - fprintf(file, "\n"); - fprintf(file, "%% Encoding ID %i", (int) e->encoding_id); - if (e->platform_id == 1 && e->encoding_id == 0) - fprintf(file, " (Roman)"); - if (e->platform_id == 3) - switch (e->encoding_id) { - case 0: - fprintf(file, " (Symbol)"); - break; - case 1: - fprintf(file, " (Unicode)"); - break; - } - fprintf(file, "\n"); - fprintf(file, "%% Format %i", (int) (format)); - switch (format) { - case 0: - fprintf(file, " (byte encoding table)"); - break; - case 4: - fprintf(file, " (segment mapping to delta values)"); - break; - case 6: - fprintf(file, " (trimmed table mapping)"); - break; - } - fprintf(file, "\n"); - fprintf(file, "/Encoding%i [\n", (int) (e - cmap_tab + 1)); - switch (format) { - case 0: - (void) get_ushort(); /* skip length */ - (void) get_ushort(); /* skip version number */ - for (i = 0; i < 256; i++) { - fputs("/", file); - print_glyph_name(file, get_byte(), print_glyph); - fputs("\n", file); - } - break; - case 4: - for (i = 0; i < nglyphs; ++i) { - fprintf(file, "%% Glyph %li -> ", i); - print_glyph_name(file, i, AS_UNICODE); - fputs("\n", file); - } - break; - case 6: - (void) get_ushort(); /* skip table length */ - (void) get_ushort(); /* skip version number */ - first_code = get_ushort(); /* first character code */ - for (i = 0; i < first_code; ++i) - fprintf(file, "/%s\n", notdef); - length = get_ushort(); /* number of character codes */ - for (i = first_code; i < first_code + length; i++) { - k = get_ushort(); - if (i > 255) - fputs("% ", file); - fputs("/", file); - print_glyph_name(file, k, print_glyph); - fputs("\n", file); - } - for (i = first_code + length; i < 256; i++) - fprintf(file, "/%s\n", notdef); - break; - default: - ttf_warn("format %i of encoding subtable unsupported", - (int) format); - } - fprintf(file, "] def\n"); - } - xfree(enc_name); -} - -void usage() -{ - cur_file_name = NULL; - fprintf(stderr, - "Usage: ttf2afm [-i|-u|-c|-v] [-e enc] [-o filename] [-m NUM] fontfile\n" - " -i: force printing glyph names in form 'index123'\n" - " -u: force printing glyph names in form 'uniABCD'\n" - " -c: print encoding tables to `basename.e<platformID><encodingID>'\n" - " -v: print version\n" - " -e enc: encode the AFM output using encoding vector from `enc'\n" - " -o filename: write output to file `filename' instead of stdout\n" - " -m NUM: select unicode mapping (default = 1, ie the first)\n" - " fontfile: the TrueType fontfile\n" - "\nPlease send bug reports or feature requests to <pdftex@tug.org>\n"); - _exit(-1); -} - -int main(int argc, char **argv) -{ - char date[128], *s; - time_t t = time(&t); - int c; - kpse_set_progname(argv[0]); - kpse_init_prog("ttf2afm", 0, 0, 0); - while ((c = getopt(argc, argv, "iucve:o:m:")) != -1) - switch (c) { - case 'i': - print_glyph = AS_INDEX; - break; - case 'u': - print_glyph = AS_UNICODE; - break; - case 'c': - print_cmap = 1; - break; - case 'e': - cur_file_name = optarg; - read_encoding(cur_file_name); - use_ext_enc = 1; - break; - case 'o': - cur_file_name = optarg; - outfile = xfopen(cur_file_name, FOPEN_W_MODE); - if (outfile == NULL) - ttf_fail("cannot open file for writing"); - break; - case 'm': - select_unicode = atoi(optarg); - break; - case 'v': - fprintf(stderr, - "ttf2afm version " VERSION "\n" - "Copyright (C) 1997-2005 Han The Thanh.\n" - "There is NO warranty. Redistribution of this software is\n" - "covered by the terms of both the pdfTeX copyright and\n" - "the GNU General Public License.\n" - "For more information about these matters, see the files\n" - "named COPYING and the pdfTeX source.\n" - "Primary author of ttf2afm: Han The Thanh.\n"); - _exit(0); - default: - usage(); - } - if (argc - optind != 1) - usage(); - sprintf(date, "%s\n", ctime(&t)); - *(char *) strchr(date, '\n') = 0; - cur_file_name = argv[optind]; - if (print_cmap) { - bname = xstrdup(xbasename(cur_file_name)); - if ((s = strrchr(bname, '.')) != NULL) - *s = 0; - } - if ((fontfile = - kpse_open_file(cur_file_name, kpse_truetype_format)) == NULL) - ttf_fail("can't open font file for reading"); - read_font(); - if (outfile == NULL) - outfile = stdout; - print_afm(date, cur_file_name); - if (print_cmap) - print_encoding(cur_file_name); - xfree(FontName); - xfree(FullName); - xfree(FamilyName); - xfree(Notice); - xfree(Version); - xfree(Weight); - free_tabs(); - xfclose(fontfile, cur_file_name); - return 0; -} |