/* Copyright (c) 1997-1998 by Juliusz Chroboczek */ #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 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; } off_t surely_lseek(int fildes, off_t offset, int whence) { off_t result; if((result=lseek(fildes,offset,whence))<0) ttf_fail("Bad TTF file"); return 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++; } }