2 * Copyright 2008 Department of Mathematical Sciences, New Mexico State University
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * DEPARTMENT OF MATHEMATICAL SCIENCES OR NEW MEXICO STATE UNIVERSITY BE
18 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 static _bdf_adobe_name_t *adobe_names;
33 static unsigned int adobe_names_size;
34 static unsigned int adobe_names_used;
37 * Provide a maximum length for glyph names just to make things clearer.
39 #define MAX_GLYPH_NAME_LEN 127
42 bdf_getline(FILE *in, char *buf, int limit)
48 for (i = 0; i < limit - 1; i++) {
49 if ((c = getc(in)) == EOF || (c == '\n' || c == '\r'))
56 * Discard the rest of the line which did not fit into the buffer.
58 while (c != EOF && c != '\n' && c != '\r')
63 * Check for a trailing newline.
74 _bdf_find_name(int code, char *name, FILE *in)
81 (void) bdf_getline(in, buf, 256);
82 while (!feof(in) && (buf[0] == 0 || buf[0] == '#')) {
85 (void) bdf_getline(in, buf, 256);
91 c = _bdf_atol(buf, 0, 16);
95 * Restore the last position read in case the code is not in the
96 * file and the current code is greater than the expected code.
103 for (sp = buf; *sp != ';'; sp++) ;
105 for (i = 0; *sp != ';' && i < MAX_GLYPH_NAME_LEN; sp++, i++)
115 by_encoding(const void *a, const void *b)
117 _bdf_adobe_name_t *c1, *c2;
119 c1 = (_bdf_adobe_name_t *) a;
120 c2 = (_bdf_adobe_name_t *) b;
121 if (c1->code < c2->code)
123 else if (c1->code > c2->code)
129 _bdf_load_adobe_names(FILE *in)
135 * Go back to the beginning of the file to look for the code because the
136 * codes are not in order in the current Adobe Glyph Name list file.
142 (void) bdf_getline(in, buf, 256);
143 while (!feof(in) && (buf[0] == 0 || buf[0] == '#')) {
146 (void) bdf_getline(in, buf, 256);
149 if (adobe_names_used == adobe_names_size) {
150 if (adobe_names_size == 0)
151 adobe_names = (_bdf_adobe_name_t *)
152 malloc(sizeof(_bdf_adobe_name_t) << 9);
154 adobe_names = (_bdf_adobe_name_t *)
155 realloc((char *) adobe_names,
156 sizeof(_bdf_adobe_name_t) *
157 (adobe_names_size + 512));
158 (void) memset((char *) (adobe_names + adobe_names_size), 0,
159 sizeof(_bdf_adobe_name_t) << 9);
160 adobe_names_size += 512;
163 adobe_names[adobe_names_used].start = pos;
164 for (sp = buf; *sp != ';'; sp++) ;
165 adobe_names[adobe_names_used].end = pos + (sp - buf);
168 c = _bdf_atol(sp, 0, 16);
171 * Ignore the Adobe-specific names in the Private Use Area.
173 if (c < 0xe000 || c > 0xf8ff)
174 adobe_names[adobe_names_used++].code = c;
178 * Sort the results by code.
180 qsort((char *) adobe_names, adobe_names_used, sizeof(_bdf_adobe_name_t),
185 _bdf_find_adobe_name(int code, char *name, FILE *in)
190 if (code < 0x20 || (code >= 0x7f && code <= 0x9f) ||
191 code == 0xfffe || code == 0xffff) {
192 sprintf(name, "char%u", code);
193 return (int) strlen(name);
196 if (code >= 0xe000 && code <= 0xf8ff) {
197 sprintf(name, "uni%04X", code & 0xffff);
198 return (int) strlen(name);
201 if (adobe_names_size == 0)
202 _bdf_load_adobe_names(in);
205 r = adobe_names_used - 1;
208 if (adobe_names[m].code < code)
210 else if (adobe_names[m].code > code)
213 fseek(in, adobe_names[m].start, 0);
214 len = adobe_names[m].end - adobe_names[m].start;
215 if (len > MAX_GLYPH_NAME_LEN)
216 len = MAX_GLYPH_NAME_LEN;
217 len = (int) fread(name, sizeof(char), len, in);
223 sprintf(name, "uni%04X", code & 0xffff);
224 return (int) strlen(name);
228 _bdf_set_glyph_names(FILE *in, bdf_font_t *font, bdf_callback_t callback,
234 bdf_callback_struct_t cb;
235 char name[MAX_GLYPH_NAME_LEN + 1];
238 cb.reason = BDF_GLYPH_NAME_START;
240 cb.total = font->glyphs_used;
243 for (changed = 0, i = 0, gp = font->glyphs; i < font->glyphs_used;
246 _bdf_find_adobe_name(gp->encoding, name, in) :
247 _bdf_find_name(gp->encoding, name, in);
251 len = (gp->name) ? strlen(gp->name) : 0;
253 gp->name = (char *) _bdf_strdup((unsigned char *) name, size + 1);
255 } else if (size != len || strcmp(gp->name, name) != 0) {
257 * Simply resize existing storage so lots of memory allocations
261 gp->name = (char *) realloc(gp->name, size + 1);
262 (void) strcpy(gp->name, name);
267 cb.reason = BDF_GLYPH_NAME;
274 cb.reason = BDF_GLYPH_NAME;
275 cb.current = cb.total;
283 bdf_set_unicode_glyph_names(FILE *in, bdf_font_t *font,
284 bdf_callback_t callback)
286 return _bdf_set_glyph_names(in, font, callback, 0);
290 bdf_set_adobe_glyph_names(FILE *in, bdf_font_t *font, bdf_callback_t callback)
292 return _bdf_set_glyph_names(in, font, callback, 1);
296 bdf_set_glyph_code_names(int prefix, bdf_font_t *font, bdf_callback_t callback)
301 bdf_callback_struct_t cb;
305 cb.reason = BDF_GLYPH_NAME_START;
307 cb.total = font->glyphs_used;
310 for (changed = 0, i = 0, gp = font->glyphs; i < font->glyphs_used;
313 case 'u': sprintf(name, "uni%04X", gp->encoding & 0xffff); break;
314 case 'x': sprintf(name, "0x%04X", gp->encoding & 0xffff); break;
315 case '+': sprintf(name, "U+%04X", gp->encoding & 0xffff); break;
316 case '\\': sprintf(name, "\\u%04X", gp->encoding & 0xffff); break;
320 len = (gp->name) ? strlen(gp->name) : 0;
322 gp->name = (char *) _bdf_strdup((unsigned char *) name, size + 1);
324 } else if (size != len || strcmp(gp->name, name) != 0) {
326 * Simply resize existing storage so lots of memory allocations
330 gp->name = (char *) realloc(gp->name, size + 1);
331 (void) strcpy(gp->name, name);
336 cb.reason = BDF_GLYPH_NAME;
343 cb.reason = BDF_GLYPH_NAME;
344 cb.current = cb.total;
352 _bdf_glyph_name_cleanup(void)
354 if (adobe_names_size > 0)
355 free((char *) adobe_names);
356 adobe_names_size = adobe_names_used = 0;