3 Copyright 1991, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
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 THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
28 * Author: Keith Packard, MIT X Consortium
34 * Read fonts.dir and fonts.alias files
40 #include <X11/fonts/fntfilst.h>
42 #include <sys/types.h>
46 static Bool AddFileNameAliases ( FontDirectoryPtr dir );
47 static int ReadFontAlias ( char *directory, Bool isFile,
48 FontDirectoryPtr *pdir );
49 static int lexAlias ( FILE *file, char **lexToken );
50 static int lexc ( FILE *file );
53 FontFileReadDirectory (char *directory, FontDirectoryPtr *pdir)
55 char file_name[MAXFONTFILENAMELEN];
56 char font_name[MAXFONTNAMELEN];
57 char dir_file[MAXFONTFILENAMELEN];
58 char dir_path[MAXFONTFILENAMELEN];
65 static char format[24] = "";
70 FontDirectoryPtr dir = NullFontDirectory;
72 if (strlen(directory) + 1 + sizeof(FontDirFile) > sizeof(dir_file))
75 /* Check for font directory attributes */
77 if ((ptr = strchr(directory, ':'))) {
79 /* OS/2 and WIN32 path might start with a drive letter, don't clip this */
80 if ((ptr = strchr(directory+2, ':'))) {
82 strncpy(dir_path, directory, ptr - directory);
83 dir_path[ptr - directory] = '\0';
85 strcpy(dir_path, directory);
87 strcpy(dir_file, dir_path);
88 if (dir_file[strlen(dir_file) - 1] != '/')
89 strcat(dir_file, "/");
90 strcat(dir_file, FontDirFile);
91 file = fopen(dir_file, "rt");
94 if (fstat (fileno(file), &statb) == -1)
96 if (stat (dir_file, &statb) == -1)
102 count = fscanf(file, "%d\n", &num_fonts);
103 if ((count == EOF) || (count != 1)) {
107 dir = FontFileMakeDir(directory, num_fonts);
112 dir->dir_mtime = statb.st_mtime;
113 if (format[0] == '\0')
114 sprintf(format, "%%%ds %%%d[^\n]\n",
115 MAXFONTFILENAMELEN-1, MAXFONTNAMELEN-1);
117 while ((count = fscanf(file, format, file_name, font_name)) != EOF) {
119 /* strip any existing trailing CR */
120 for (i=0; i<strlen(font_name); i++) {
121 if (font_name[i]=='\r') font_name[i] = '\0';
125 FontFileFreeDir (dir);
131 * We blindly try to load all the font files specified.
132 * In theory, we might want to warn that some of the fonts
133 * couldn't be loaded.
135 FontFileAddFontFile (dir, font_name, file_name);
139 } else if (errno != ENOENT) {
142 status = ReadFontAlias(dir_path, FALSE, &dir);
143 if (status != Successful) {
145 FontFileFreeDir (dir);
151 FontFileSortDir(dir);
158 FontFileDirectoryChanged(FontDirectoryPtr dir)
160 char dir_file[MAXFONTFILENAMELEN];
163 if (strlen(dir->directory) + sizeof(FontDirFile) > sizeof(dir_file))
166 strcpy (dir_file, dir->directory);
167 strcat (dir_file, FontDirFile);
168 if (stat (dir_file, &statb) == -1)
170 if (errno != ENOENT || dir->dir_mtime != 0)
172 return FALSE; /* doesn't exist and never did: no change */
174 if (dir->dir_mtime != statb.st_mtime)
177 if ((strlen(dir->directory) + sizeof(FontAliasFile)) > sizeof(dir_file))
179 strcpy (dir_file, dir->directory);
180 strcat (dir_file, FontAliasFile);
181 if (stat (dir_file, &statb) == -1)
183 if (errno != ENOENT || dir->alias_mtime != 0)
185 return FALSE; /* doesn't exist and never did: no change */
187 if (dir->alias_mtime != statb.st_mtime)
193 * Make each of the file names an automatic alias for each of the files.
197 AddFileNameAliases(FontDirectoryPtr dir)
200 char copy[MAXFONTFILENAMELEN];
203 FontRendererPtr renderer;
207 table = &dir->nonScalable;
208 for (i = 0; i < table->used; i++) {
209 if (table->entries[i].type != FONT_ENTRY_BITMAP)
211 fileName = table->entries[i].u.bitmap.fileName;
212 renderer = FontFileMatchRenderer (fileName);
216 len = strlen (fileName) - renderer->fileSuffixLen;
217 if (len >= sizeof(copy))
219 CopyISOLatin1Lowered (copy, fileName, len);
223 name.ndashes = FontFileCountDashes (copy, len);
225 if (!FontFileFindNameInDir(table, &name)) {
226 if (!FontFileAddFontAlias (dir, copy, table->entries[i].name.name))
234 * parse the font.alias file. Format is:
238 * To imbed white-space in an alias name, enclose it like "font name"
239 * in double quotes. \ escapes and character, so
240 * "font name \"With Double Quotes\" \\ and \\ back-slashes"
243 * A line beginning with a ! denotes a newline-terminated comment.
256 ReadFontAlias(char *directory, Bool isFile, FontDirectoryPtr *pdir)
258 char alias[MAXFONTNAMELEN];
259 char font_name[MAXFONTNAMELEN];
260 char alias_file[MAXFONTFILENAMELEN];
262 FontDirectoryPtr dir;
265 int status = Successful;
268 if (strlen(directory) >= sizeof(alias_file))
271 strcpy(alias_file, directory);
273 if (strlen(directory) + 1 + sizeof(FontAliasFile) > sizeof(alias_file))
275 if (directory[strlen(directory) - 1] != '/')
276 strcat(alias_file, "/");
277 strcat(alias_file, FontAliasFile);
279 file = fopen(alias_file, "rt");
281 return ((errno == ENOENT) ? Successful : BadFontPath);
283 *pdir = dir = FontFileMakeDir(directory, 10);
290 if (fstat (fileno (file), &statb) == -1)
292 if (stat (alias_file, &statb) == -1)
298 dir->alias_mtime = statb.st_mtime;
299 while (status == Successful) {
300 token = lexAlias(file, &lexToken);
311 if (strlen(lexToken) >= sizeof(alias)) {
312 status = BadFontPath;
315 strcpy(alias, lexToken);
316 token = lexAlias(file, &lexToken);
319 if (strcmp(alias, "FILE_NAMES_ALIASES"))
320 status = BadFontPath;
321 else if (!AddFileNameAliases(dir))
325 status = BadFontPath;
331 if (strlen(lexToken) >= sizeof(font_name)) {
332 status = BadFontPath;
335 CopyISOLatin1Lowered(alias, alias, strlen(alias));
336 CopyISOLatin1Lowered(font_name, lexToken, strlen(lexToken));
337 if (!FontFileAddFontAlias (dir, alias, font_name))
354 static int charClass;
357 lexAlias(FILE *file, char **lexToken)
362 Begin, Normal, Quoted, Comment
366 static char *tokenBuf = (char *) NULL;
367 static int tokenSize = 0;
373 if (count == tokenSize) {
377 nsize = tokenSize ? (tokenSize << 1) : 64;
378 nbuf = realloc(tokenBuf, nsize);
383 t = tokenBuf + count;
407 *lexToken = tokenBuf;
431 *lexToken = (char *) NULL;
432 return charClass == END ? DONE : NEWLINE;
435 *lexToken = tokenBuf;