diff options
Diffstat (limited to 'tools/sci/bdfgname.cpp')
-rw-r--r-- | tools/sci/bdfgname.cpp | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/tools/sci/bdfgname.cpp b/tools/sci/bdfgname.cpp new file mode 100644 index 0000000000..694d82405c --- /dev/null +++ b/tools/sci/bdfgname.cpp @@ -0,0 +1,439 @@ +/* + * Copyright 2001 Computing Research Labs, New Mexico State University + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef lint +#ifdef __GNUC__ +static char rcsid[] __attribute__((unused)) = "$Id$"; +#else +static char rcsid[] = "$Id$"; +#endif +#endif + +#include "bdfP.h" + +typedef struct { + long code; + long start; + long end; + long pad; +} _bdf_adobe_name_t; + +static _bdf_adobe_name_t *adobe_names; +static unsigned long adobe_names_size; +static unsigned long adobe_names_used; + +/* + * Provide a maximum length for glyph names just to make things clearer. + */ +#define MAX_GLYPH_NAME_LEN 127 + +static int +#ifdef __STDC__ +getline(FILE *in, char *buf, int limit) +#else +getline(in, buf, limit) +FILE *in; +char *buf; +int limit; +#endif +{ + int c, i; + + c = EOF; + + for (i = 0; i < limit - 1; i++) { + if ((c = getc(in)) == EOF || (c == '\n' || c == '\r')) + break; + buf[i] = c; + } + buf[i] = 0; + + /* + * Discard the rest of the line which did not fit into the buffer. + */ + while (c != EOF && c != '\n' && c != '\r') + c = getc(in); + + if (c == '\r') { + /* + * Check for a trailing newline. + */ + c = getc(in); + if (c != '\n') + ungetc(c, in); + } + + return i; +} + +static long +#ifdef __STDC__ +_bdf_find_name(long code, char *name, FILE *in) +#else +_bdf_find_name(code, name, in) +long code; +char *name; +FILE *in; +#endif +{ + long c, i, pos; + char *sp, buf[256]; + + while (!feof(in)) { + pos = ftell(in); + (void) getline(in, buf, 256); + while (!feof(in) && (buf[0] == 0 || buf[0] == '#')) { + buf[0] = 0; + pos = ftell(in); + (void) getline(in, buf, 256); + } + + if (buf[0] == 0) + return -1; + + c = _bdf_atol(buf, 0, 16); + + if (c > code) { + /* + * Restore the last position read in case the code is not in the + * file and the current code is greater than the expected code. + */ + fseek(in, pos, 0L); + return -1; + } + + if (c == code) { + for (sp = buf; *sp != ';'; sp++) ; + sp++; + for (i = 0; *sp != ';' && i < MAX_GLYPH_NAME_LEN; sp++, i++) + name[i] = *sp; + name[i] = 0; + return i; + } + } + return -1; +} + +static int +#ifdef __STDC__ +by_encoding(const void *a, const void *b) +#else +by_encoding(a, b) +char *a, *b; +#endif +{ + _bdf_adobe_name_t *c1, *c2; + + c1 = (_bdf_adobe_name_t *) a; + c2 = (_bdf_adobe_name_t *) b; + if (c1->code < c2->code) + return -1; + else if (c1->code > c2->code) + return 1; + return 0; +} + +static void +#ifdef __STDC__ +_bdf_load_adobe_names(FILE *in) +#else +_bdf_load_adobe_names(in) +FILE *in; +#endif +{ + long c, pos; + char *sp, buf[256]; + + /* + * Go back to the beginning of the file to look for the code because the + * codes are not in order in the current Adobe Glyph Name list file. + */ + fseek(in, 0, 0); + + while (!feof(in)) { + pos = ftell(in); + (void) getline(in, buf, 256); + while (!feof(in) && (buf[0] == 0 || buf[0] == '#')) { + buf[0] = 0; + pos = ftell(in); + (void) getline(in, buf, 256); + } + + c = _bdf_atol(buf, 0, 16); + + /* + * Ignore the Adobe-specific names in the Private Use Area. + */ + if (c >= 0xe000 && c <= 0xf8ff) + continue; + + if (adobe_names_used == adobe_names_size) { + if (adobe_names_size == 0) + adobe_names = (_bdf_adobe_name_t *) + malloc(sizeof(_bdf_adobe_name_t) << 9); + else + adobe_names = (_bdf_adobe_name_t *) + realloc((char *) adobe_names, + sizeof(_bdf_adobe_name_t) * + (adobe_names_size + 512)); + (void) memset((char *)(adobe_names + adobe_names_size), 0, + sizeof(_bdf_adobe_name_t) << 9); + adobe_names_size += 512; + } + + adobe_names[adobe_names_used].code = c; + for (sp = buf; *sp != ';'; sp++) ; + sp++; + adobe_names[adobe_names_used].start = pos + (sp - buf); + for (; *sp != ';'; sp++) ; + adobe_names[adobe_names_used].end = pos + (sp - buf); + adobe_names_used++; + } + + /* + * Sort the results by code. + */ + qsort((char *) adobe_names, adobe_names_used, sizeof(_bdf_adobe_name_t), + by_encoding); +} + +static long +#ifdef __STDC__ +_bdf_find_adobe_name(long code, char *name, FILE *in) +#else +_bdf_find_adobe_name(code, name, in) +long code; +char *name; +FILE *in; +#endif +{ + long len; + int l, r, m; + + if (code < 0x20 || (code >= 0x7f && code <= 0x9f) || + code == 0xfffe || code == 0xffff) { + sprintf(name, "char%lu", code); + return (long) strlen(name); + } + + if (code >= 0xe000 && code <= 0xf8ff) { + sprintf(name, "uni%04lX", code & 0xffff); + return (long) strlen(name); + } + + if (adobe_names_size == 0) + _bdf_load_adobe_names(in); + + l = 0; + r = adobe_names_used - 1; + while (l <= r) { + m = (l + r) >> 1; + if (adobe_names[m].code < code) + l = m + 1; + else if (adobe_names[m].code > code) + r = m - 1; + else { + fseek(in, adobe_names[m].start, 0); + len = adobe_names[m].end - adobe_names[m].start; + if (len > MAX_GLYPH_NAME_LEN) + len = MAX_GLYPH_NAME_LEN; + len = (long) fread(name, sizeof(char), len, in); + name[len] = 0; + return len; + } + } + + sprintf(name, "uni%04lX", code & 0xffff); + return (long) strlen(name); +} + +static int +#ifdef __STDC__ +_bdf_set_glyph_names(FILE *in, bdf_font_t *font, bdf_callback_t callback, + int adobe) +#else +_bdf_set_glyph_names(in, font, callback, adobe) +FILE *in; +bdf_font_t *font; +bdf_callback_t callback; +int adobe; +#endif +{ + int changed; + long i, size, len; + bdf_glyph_t *gp; + bdf_callback_struct_t cb; + char name[MAX_GLYPH_NAME_LEN + 1]; + + if (callback != 0) { + cb.reason = BDF_GLYPH_NAME_START; + cb.current = 0; + cb.total = font->glyphs_used; + (*callback)(&cb, 0); + } + for (changed = 0, i = 0, gp = font->glyphs; i < font->glyphs_used; + i++, gp++) { + size = (adobe) ? + _bdf_find_adobe_name(gp->encoding, name, in) : + _bdf_find_name(gp->encoding, name, in); + if (size < 0) + continue; + + len = (gp->name) ? strlen(gp->name) : 0; + if (len == 0) { + gp->name = (char *) _bdf_strdup((unsigned char *) name, size + 1); + changed = 1; + } else if (size != len || strcmp(gp->name, name) != 0) { + /* + * Simply resize existing storage so lots of memory allocations + * are not needed. + */ + if (size > len) + gp->name = (char *) realloc(gp->name, size + 1); + (void) strcpy(gp->name, name); + changed = 1; + } + + if (callback != 0) { + cb.reason = BDF_GLYPH_NAME; + cb.current = i; + (*callback)(&cb, 0); + } + } + + if (callback != 0) { + cb.reason = BDF_GLYPH_NAME; + cb.current = cb.total; + (*callback)(&cb, 0); + } + + return changed; +} + +int +#ifdef __STDC__ +bdf_set_unicode_glyph_names(FILE *in, bdf_font_t *font, + bdf_callback_t callback) +#else +bdf_set_unicode_glyph_names(in, font, callback) +FILE *in; +bdf_font_t *font; +bdf_callback_t callback; +#endif +{ + return _bdf_set_glyph_names(in, font, callback, 0); +} + +int +#ifdef __STDC__ +bdf_set_adobe_glyph_names(FILE *in, bdf_font_t *font, bdf_callback_t callback) +#else +bdf_set_adobe_glyph_names(in, font, callback) +FILE *in; +bdf_font_t *font; +bdf_callback_t callback; +#endif +{ + return _bdf_set_glyph_names(in, font, callback, 1); +} + +int +#ifdef __STDC__ +bdf_set_glyph_code_names(int prefix, bdf_font_t *font, bdf_callback_t callback) +#else +bdf_set_glyph_code_names(prefix, font, callback) +int prefix; +bdf_font_t *font; +bdf_callback_t callback; +#endif +{ + int changed; + long i, size, len; + bdf_glyph_t *gp; + bdf_callback_struct_t cb; + char name[128]; + + if (callback != 0) { + cb.reason = BDF_GLYPH_NAME_START; + cb.current = 0; + cb.total = font->glyphs_used; + (*callback)(&cb, 0); + } + for (changed = 0, i = 0, gp = font->glyphs; i < font->glyphs_used; + i++, gp++) { + switch (prefix) { + case 'u': + sprintf(name, "uni%04lX", gp->encoding & 0xffff); + break; + case 'x': + sprintf(name, "0x%04lX", gp->encoding & 0xffff); + break; + case '+': + sprintf(name, "U+%04lX", gp->encoding & 0xffff); + break; + case '\\': + sprintf(name, "\\u%04lX", gp->encoding & 0xffff); + break; + } + size = 6; + + len = (gp->name) ? strlen(gp->name) : 0; + if (len == 0) { + gp->name = (char *) _bdf_strdup((unsigned char *) name, size + 1); + changed = 1; + } else if (size != len || strcmp(gp->name, name) != 0) { + /* + * Simply resize existing storage so lots of memory allocations + * are not needed. + */ + if (size > len) + gp->name = (char *) realloc(gp->name, size + 1); + (void) strcpy(gp->name, name); + changed = 1; + } + + if (callback != 0) { + cb.reason = BDF_GLYPH_NAME; + cb.current = i; + (*callback)(&cb, 0); + } + } + + if (callback != 0) { + cb.reason = BDF_GLYPH_NAME; + cb.current = cb.total; + (*callback)(&cb, 0); + } + + return changed; +} + +void +#ifdef __STDC__ +_bdf_glyph_name_cleanup(void) +#else +_bdf_glyph_name_cleanup() +#endif +{ + if (adobe_names_size > 0) + free((char *) adobe_names); + adobe_names_size = adobe_names_used = 0; +} |