2 * Copyright (c) 1993, 2009, Oracle and/or its affiliates. All rights reserved.
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 (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
23 /* Code copied from libXfont is:
25 Copyright 1991, 1998 The Open Group
27 Permission to use, copy, modify, distribute, and sell this software and its
28 documentation for any purpose is hereby granted without fee, provided that
29 the above copyright notice appear in all copies and that both that
30 copyright notice and this permission notice appear in supporting
33 The above copyright notice and this permission notice shall be included in
34 all copies or substantial portions of the Software.
36 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
39 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
40 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
41 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 Except as contained in this notice, the name of The Open Group shall not be
44 used in advertising or otherwise to promote the sale, use or other dealings
45 in this Software without prior written authorization from The Open Group.
50 * Ensure that a fonts.alias file only contains aliases for fonts that exist
51 * We do this by first reading in the fonts.dir file and then for
52 * each entry in the fonts.alias file we verify that the alias can
53 * be resolved. Most this of this code is borrowed from
54 * libXfont with minor modifications.
56 #include <X11/fonts/fntfilst.h>
58 #include <sys/types.h>
65 #include <X11/keysym.h>
67 #define EBadFontPath 0
68 #define EBadFontName 0
73 static char *programName
;
75 static int lexc(FILE *file
);
78 ErrorF (const char * f
, ...)
83 fprintf(stderr
, "%s: ", programName
);
84 vfprintf(stderr
, f
, args
);
88 /* Provide pseudo renderers for font file formats we may find in fonts.dir
89 files during installation, but which libXfont does not support */
92 PseudoOpenScalable (FontPathElementPtr fpe
, FontPtr
*ppFont
, int flags
,
93 FontEntryPtr entry
, char *fileName
, FontScalablePtr vals
,
94 fsBitmapFormat format
, fsBitmapFormatMask fmask
,
95 FontPtr non_cachable_font
)
102 PseudoGetInfoScalable (FontPathElementPtr fpe
, FontInfoPtr info
,
103 FontEntryPtr entry
, FontNamePtr fontName
,
104 char *fileName
, FontScalablePtr vals
)
109 static FontRendererRec PseudoRenderers
[] = {
110 { ".spd", 4, NULL
, PseudoOpenScalable
, NULL
, PseudoGetInfoScalable
, 0 }
114 PseudoFontFileRegisterFpeFunctions (void)
118 for (i
= 0; i
< (sizeof(PseudoRenderers
) / sizeof(FontRendererRec
)); i
++) {
119 FontFileRegisterRenderer(&PseudoRenderers
[i
]);
124 ProcessFontsDirectory (
126 FontDirectoryPtr
*pdir
)
128 char file_name
[MAXFONTNAMELEN
];
129 char font_name
[MAXFONTNAMELEN
];
130 char dir_file
[MAXFONTNAMELEN
];
135 FontDirectoryPtr dir
= NullFontDirectory
;
137 i
= strlcpy(dir_file
, directory
, sizeof(dir_file
));
138 if (directory
[i
- 1] != '/')
139 strlcat(dir_file
, "/", sizeof(dir_file
));
140 strlcat(dir_file
, FontDirFile
, sizeof(dir_file
));
141 file
= fopen(dir_file
, "r");
143 if (fstat (fileno(file
), &statb
) == -1)
145 count
= fscanf(file
, "%d\n", &i
);
146 if ((count
== EOF
) || (count
!= 1)) {
150 dir
= FontFileMakeDir(directory
, i
);
155 dir
->dir_mtime
= statb
.st_mtime
;
156 while ((count
= fscanf(file
, "%1024s %[^\n]\n", file_name
, font_name
))
159 FontFileFreeDir (dir
);
163 if (!FontFileAddFontFile (dir
, font_name
, file_name
))
165 FontFileFreeDir (dir
);
171 } else if (errno
!= ENOENT
) {
193 static int charClass
;
203 Begin
, Normal
, Quoted
207 static char *tokenBuf
= (char *) NULL
;
208 static unsigned int tokenSize
= 0;
214 if (count
== tokenSize
) {
218 nsize
= tokenSize
? (tokenSize
<< 1) : 64;
219 nbuf
= realloc(tokenBuf
, nsize
);
224 t
= tokenBuf
+ count
;
245 *lexToken
= tokenBuf
;
263 *lexToken
= (char *) NULL
;
264 return charClass
== END
? DONE
: NEWLINE
;
267 *lexToken
= tokenBuf
;
309 static inline unsigned char
310 ISOLatin1ToLower(unsigned char source
)
312 if (source
>= XK_A
&& source
<= XK_Z
)
313 return source
+ (XK_a
- XK_A
);
314 if (source
>= XK_Agrave
&& source
<= XK_Odiaeresis
)
315 return source
+ (XK_agrave
- XK_Agrave
);
316 if (source
>= XK_Ooblique
&& source
<= XK_Thorn
)
317 return source
+ (XK_oslash
- XK_Ooblique
);
322 copyISOLatin1Lowered(char *dest
, char *source
, int length
)
325 for (i
= 0; i
< length
; i
++, source
++, dest
++)
326 *dest
= ISOLatin1ToLower(*source
);
338 int status
= Success
;
340 while (status
== Success
) {
341 token
= lexAlias(file
, &lexToken
);
349 status
= EAllocError
;
352 strlcpy(alias
, lexToken
, MAXFONTNAMELEN
);
353 token
= lexAlias(file
, &lexToken
);
358 status
= EBadFontPath
;
361 status
= EAllocError
;
364 copyISOLatin1Lowered(alias
, alias
, strlen(alias
));
365 copyISOLatin1Lowered(font_name
, lexToken
, strlen(lexToken
));
374 #define FontAliasEntry 8
380 FontDirectoryPtr dir
)
382 char lowerName
[MAXFONTNAMELEN
];
386 FontScalableRec vals
;
387 FontBitmapEntryPtr bitmap
;
393 if (namelen
>= MAXFONTNAMELEN
)
395 copyISOLatin1Lowered (lowerName
, name
, namelen
);
396 lowerName
[namelen
] = '\0';
397 tmpName
.name
= lowerName
;
398 tmpName
.length
= namelen
;
399 tmpName
.ndashes
= FontFileCountDashes (lowerName
, namelen
);
400 /* Match XLFD patterns */
401 if (tmpName
.ndashes
== 14 &&
402 FontParseXLFDName (lowerName
, &vals
, FONT_XLFD_REPLACE_ZERO
))
405 tmpName
.length
= strlen (lowerName
);
406 entry
= FontFileFindNameInDir (&dir
->scalable
, &tmpName
);
415 /* Match non XLFD pattern */
416 if (entry
= FontFileFindNameInDir (&dir
->nonScalable
, &tmpName
))
418 switch (entry
->type
) {
419 case FONT_ENTRY_BITMAP
:
420 bitmap
= &entry
->u
.bitmap
;
423 case FONT_ENTRY_ALIAS
:
424 if (entry
->u
.alias
.resolved
) {
425 strlcpy(name
, entry
->u
.alias
.resolved
, MAXFONTNAMELEN
);
426 ret
= FontAliasEntry
;
444 FontParseXLFDName(lowerName
, &vals
, FONT_XLFD_REPLACE_ZERO
);
445 tmpName
.length
= strlen (lowerName
);
450 p
= lowerName
+ tmpName
.length
;
451 while (p
> lowerName
&& isdigit(p
[-1]))
455 vals
.point
= atoi(p
) * 10;
465 tmpName
.length
= p
- lowerName
;
471 (entry
= FontFileFindNameInDir (&dir
->nonScalable
, &tmpName
)) &&
472 entry
->type
== FONT_ENTRY_ALIAS
)
474 if (entry
->u
.alias
.resolved
) {
475 strlcpy(name
, entry
->u
.alias
.resolved
, MAXFONTNAMELEN
);
476 return FontAliasEntry
;
490 #define TempFileSuffix "_TMPFILE"
494 FontDirectoryPtr dir
,
495 const char *aliasfilename
)
497 char alias
[MAXFONTNAMELEN
];
498 char font_name
[MAXFONTNAMELEN
];
499 char save_font_name
[MAXFONTNAMELEN
];
500 char aliasfile
[MAXFONTNAMELEN
];
501 char tmpfile
[MAXFONTNAMELEN
];
502 char outfile
[MAXFONTNAMELEN
];
504 FILE *file
, *newfile
;
508 int containsSpace
= 0;
510 strlcpy(aliasfile
, dir
->directory
, sizeof(aliasfile
));
511 strlcat(aliasfile
, aliasfilename
, sizeof(aliasfile
));
512 file
= fopen(aliasfile
, "r");
514 return; /* fail silently -- if no alias file, we're done */
516 if (fstat (fileno(file
), &statb
) == -1)
519 strlcpy(tmpfile
, aliasfile
, sizeof(tmpfile
));
520 strlcat(tmpfile
, TempFileSuffix
, sizeof(tmpfile
));
521 newfile
= fopen(tmpfile
, "w");
524 ErrorF("Can't create new alias file %s\n", tmpfile
);
528 while ((ret
= ReadAliases(file
, alias
, font_name
)) != FileClosed
) {
529 strlcpy(save_font_name
, font_name
, sizeof(save_font_name
));
530 while ((retvalue
= OpenAndVerifyFont(font_name
,strlen(font_name
), dir
))
534 if (strcmp(alias
,save_font_name
) == 0) {
535 /* 4258475: don't add if the names are the same */
537 fprintf(stderr
,"%s\t%s aliased to itself!\n", alias
, save_font_name
);
539 } else if (retvalue
== Success
) {
540 /* add this alias to list of known aliases */
541 if (strchr(alias
, ' '))
544 if (!FontFileAddFontAlias (dir
, alias
, save_font_name
))
546 fprintf(stderr
, "installalias: unable to add alias to list\n");
548 ; /* do nothing -- fail silently */
552 fprintf(newfile
, "\"%s\"\t\"%s\"\n",alias
, save_font_name
);
554 fprintf(newfile
, "%s\t\"%s\"\n",alias
, save_font_name
);
559 fprintf(stderr
,"%s\t%s not found\n", alias
, save_font_name
);
564 strlcpy(outfile
, dir
->directory
, sizeof(outfile
));
565 strlcat(outfile
, "fonts.alias", sizeof(outfile
));
566 ret
= rename(tmpfile
, outfile
);
568 ErrorF("Unable to rename %s to %s.\n", tmpfile
, outfile
);
574 GetDefaultPointSize (void)
580 FontResolutionPtr
GetClientResolutions (int *num
)
586 int RegisterFPEFunctions ( NameCheckFunc name_func
,
587 InitFpeFunc init_func
,
588 FreeFpeFunc free_func
,
589 ResetFpeFunc reset_func
,
590 OpenFontFunc open_func
,
591 CloseFontFunc close_func
,
592 ListFontsFunc list_func
,
593 StartLfwiFunc start_lfwi_func
,
594 NextLfwiFunc next_lfwi_func
,
595 WakeupFpeFunc wakeup_func
,
596 ClientDiedFunc client_died
,
597 LoadGlyphsFunc load_glyphs
,
598 StartLaFunc start_list_alias_func
,
599 NextLaFunc next_list_alias_func
,
600 SetPathFunc set_path_func
)
606 InitFontFileFunctions(void)
608 FontFileRegisterFpeFunctions();
609 PseudoFontFileRegisterFpeFunctions();
614 main(int argc
, char **argv
)
617 FontDirectoryPtr dir
;
618 const char *aliasFileName
= "fonts.alias";
619 char *defaultDirectoryList
[] = { ".", NULL
};
620 char **directoryList
= defaultDirectoryList
;
621 int directoryCount
= 1;
624 programName
= argv
[0];
626 InitFontFileFunctions();
629 aliasFileName
= argv
[1];
633 directoryCount
= argc
;
634 directoryList
= argv
;
638 for (/* i initialized above */ ; i
< directoryCount
; i
++) {
639 ret
= ProcessFontsDirectory(directoryList
[i
], &dir
);
640 if (ret
== Success
) {
641 ProcessAliasFile(dir
, aliasFileName
);
643 char curdir
[PATH_MAX
];
644 const char *directory
= directoryList
[i
];
645 if (strcmp(directory
, ".") == 0) {
646 getcwd(curdir
, sizeof(curdir
));
649 ErrorF("failed to process fonts.dir file in %s\n", directory
);