#include #include #include #include #include #include #include "types.h" #include "proto.h" #include "externs.h" /* numbers in the font file are big endian; the getnum function ensures that irrespective of architecture, we read them correctly However, sections of the code that came from ttfps use macros to fix endianness, and that requirest that the executable is compiled correctly, the next function is used to test this. */ long 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; } void endianness_test() { union { TTF_BYTE b[4]; TTF_ULONG l; } x; TTF_ULONG v; x.b[0]=1; x.b[1]=2; x.b[2]=3; x.b[3]=4; v=UL(x.l); if(v!=(((((1<<8)+2)<<8)+3)<<8)+4) { fprintf(stderr,"Error: Code badly compiled for this architecture\n"); fprintf(stderr,"Please set SMALLENDIAN and recompile\n"); exit(2); } } 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 = 0; return p; } void seek_tab(char *name, TTF_LONG offset) { dirtab_entry *p = name_lookup(name); if (p == 0) 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 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 != 0; pk = pk->next); pk->next = ttf_alloc(1, kern_entry); pk = pk->next; pk->next = 0; 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 != 0; pk = pk->next) if (pk->adjacent == j) return pk->value; return 0; } void free_tabs() { int i; kern_entry *p, *q, *r; free(ps_glyphs_buf); free(dir_tab); free(mtx_tab); for (i = 0; i <= MAX_CHAR_CODE; i++) if (enc_names[i] != notdef) free(enc_names[i]); for (p = kern_tab; p - kern_tab < nglyphs; p++) if (p->next != 0) { for (q = p->next; q != 0; q = r) { r = q->next; free(q); } } free(kern_tab); } char * ucs_to_uni(short unsigned int u) { char* uni = (char*) mymalloc(8); sprintf(uni+3, "%04x",(unsigned int) u); * uni = 'u'; *(uni + 1) = 'n'; *(uni + 2) = 'i'; return uni; } int null_glyph(char *s) { if (s != 0 && (strcmp(s, ".null") == 0 || strcmp(s, ".notdef") == 0)) return 1; return 0; } #define fix_glyph_name(s) ((s) != 0 ? (s) : null_name) #define dont_print(s) (!print_all && !print_index && null_glyph(s)) #define glyph_found(i) (print_all || mtx_tab[i].found) void print_glyph_name(FILE *f, int i) { char *s = mtx_tab[i].name; switch (print_index) { case 0: fprintf(f, fix_glyph_name(s)); break; case 1: fprintf(f, "%s%i", INDEXED_GLYPH_PREFIX, i); break; case 2: if (i < 0x0100) fprintf(f, "%s0x%.2X", INDEXED_GLYPH_PREFIX, i); else fprintf(f, "%s0x%.4X", INDEXED_GLYPH_PREFIX, i); break; } } int compare_name(const void *a, const void *b) { mtx_entry * m1 = (mtx_entry*) a; mtx_entry * m2 = (mtx_entry*) b; return (strcmp(m1->name, m2->name)); } void print_uni(char *date, char *fontname, FILE * unifile) { mtx_entry *pm; fprintf(unifile, "# Generated at %s from font file `%s' \n# by AbiWord (www.abisource.com)\n# WARNING: THIS FILE MUST BE SORTED ALPHABETICALLY BY THE STRINGS\n" "%d\n", date, fontname, nglyphs); for (pm = mtx_tab; pm - mtx_tab < nglyphs; pm++) if(!pm->name) pm->name = notdef; qsort(mtx_tab, nglyphs, sizeof(mtx_entry), compare_name); for (pm = mtx_tab; pm - mtx_tab < nglyphs; pm++) fprintf(unifile, "%s,0x%04x\n", pm->name, pm->uni); } void print_encodings() { struct enc_vector ** ev = (struct enc_vector **) &known_encodings[0]; printf("Known encodings:\n"); printf(" ISO-8859-1\n"); while (*ev) { printf(" %s\n", (*ev)->name); ev++; } printf(" StandardEncoding\n\nWhen run without" " the -e parameter, Adobe StandardEncoding\nwill be used.\n\n" " THIS PROGRAM IS NOT TO BE USED WITH CJK FONTS !!! Please see the instructions\n" " on installing CJK fonts in the AbiWord docs.\n\n" ); exit(0); } void set_encoding(char *e) { struct enc_vector ** ev = (struct enc_vector **) &known_encodings[0]; while (*ev) if(!strcmp((*ev)->name, e)) { encoding = e; curr_encoding = *ev; return; } else ev++; ttf_fail("unknown encoding %s; use `ttftool -e print' for list of\n" "supported encodings.\n", e); } void ttf_fail(char *fmt,...) { va_list args; va_start(args, fmt); fprintf(stderr, "\nError: ttftool"); 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 warn(int verb, char *fmt,...) { va_list args; va_start(args, fmt); if(verb <= verbosity) { fprintf(stderr, "Warning "); if (cur_file_name) fprintf(stderr, "(%s)", cur_file_name); fprintf(stderr, ": "); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); } va_end(args); } void msg(int verb, char *fmt,...) { va_list args; va_start(args, fmt); if(verb <= verbosity) { 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; } void *mymalloc(size_t size) { void *p; if((p=malloc(size))==NULL) ttf_fail("Unable to allocate memory\n"); return p; } void * mycalloc(size_t nelem, size_t elsize) { void *p; if((p=calloc(nelem, elsize))==NULL) ttf_fail("Unable to allocate memory\n"); return p; } void * myrealloc(void *ptr, size_t size) { void *p; if((p=realloc(ptr, size))==NULL) ttf_fail("Unable to allocate memory"); return p; } /* gcc on Solaris has a funny trick of using a struct to * represent off_t, which screws up constant values and * arithmetic, so I'm replacing off_t in/from surely_lseek * with long - fjf */ long surely_lseek(int fildes, long long_offset, int whence) { long long_result; off_t result; off_t offset; #if defined(SunOS) && _FILE_OFFSET_BITS == 64 #if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG) offset = long_offset; #else /* TODO: Check - is this the correct way round? */ offset._l[0] = 0; offset._l[1] = long_offset; #endif #else offset = long_offset; #endif result = lseek (fildes, offset, whence); #if defined(SunOS) && _FILE_OFFSET_BITS == 64 #if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG) long_result = result; #else /* TODO: Check - is this the correct way round? */ long_result = result._l[1]; #endif #else long_result = result; #endif if (long_result < 0) ttf_fail ("Bad TTF file"); return long_result; } void syserror(char *string) { perror(string); exit(3); /*NOTREACHED*/ } size_t surely_read(int fildes, void *buf, size_t nbyte) { ssize_t n; if((n=read(fildes,buf,nbyte))=040 && *s!='(' && *s!=')') putc(*s,stream); else fprintf(stream,"\\%03o",(unsigned char)*s); s++; } }