--- Begin Message ---
X-Debbugs-CC: Juliusz Chroboczek <juliusz.chroboc...@pps.jussieu.fr>
Package: xfonts-utils
Version: 1:7.4+1
Severity: wishlist
Hi Juliusz, everyone,
in the medium run it might be nice to use /usr/share/fonts/truetype in
the X font path. However, fonts seem to be organized into subdirectories.
To facilitate using the directory with adding only one element to the X
font path, the attached patch implements recursive scanning of
subdirectories in mkfontscale.
I appreciate feedback and if you could consider adopting it.
Acknowledgement: Julien Cristau answered questions on IRC, so if I have
gotten anything right here, it's to his credit, all errors are my own.
Kind regards and thanks for your work on Debian and X
T.
P.S.: If this patch seems feasible (even if only in Debian), I would
submit a follow-up to add a packaging system trigger to keep font
information up to date in that directory.
--
Thomas Viehmann, http://thomas.viehmann.net/
diff -dur orig/xfonts-utils-7.4+1/mkfontscale/mkfontscale.c xfonts-utils-7.4+1/mkfontscale/mkfontscale.c
--- orig/xfonts-utils-7.4+1/mkfontscale/mkfontscale.c 2008-05-11 00:01:42.000000000 +0200
+++ xfonts-utils-7.4+1/mkfontscale/mkfontscale.c 2009-07-30 20:49:23.000000000 +0200
@@ -31,6 +31,7 @@
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
+#include <sys/stat.h>
#include <X11/Xos.h>
#include <X11/fonts/fontenc.h>
@@ -103,6 +104,7 @@
static FT_Library ft_library;
static float bigEncodingFuzz = 0.02;
+static int recurse;
static int relative;
static int doScalable;
static int doBitmaps;
@@ -154,6 +156,7 @@
doScalable = 1;
onlyEncodings = 0;
relative = 0;
+ recurse = 0;
reencodeLegacy = 1;
encodingsToDo = NULL;
@@ -217,6 +220,9 @@
} else if(strcmp(argv[argn], "-r") == 0) {
relative = 1;
argn++;
+ } else if(strcmp(argv[argn], "-R") == 0) {
+ recurse = 1;
+ argn++;
} else if(strcmp(argv[argn], "-l") == 0) {
reencodeLegacy = !reencodeLegacy;
argn++;
@@ -749,57 +755,20 @@
return 0;
}
+
static int
-doDirectory(char *dirname_given, int numEncodings, ListPtr encodingsToDo)
+scanDirectory(char *dirname, char *dir_prefix, int xl, HashTablePtr entries)
{
- char *dirname, *fontscale_name, *filename, *encdir;
- FILE *fontscale, *encfile;
DIR *dirp;
struct dirent *entry;
+ struct stat statbuf;
+ ListPtr encoding, xlfd, lp;
+ char* filename;
+ char* prefixedname;
+ int rc, found;
+ int isBitmap=0;
FT_Error ftrc;
FT_Face face;
- ListPtr encoding, xlfd, lp;
- HashTablePtr entries;
- HashBucketPtr *array;
- int i, n, found, rc;
- int isBitmap=0,xl=0;
-
- if (exclusionSuffix)
- xl = strlen (exclusionSuffix);
-
- i = strlen(dirname_given);
- if(i == 0)
- dirname = dsprintf("./");
- else if(dirname_given[i - 1] != '/')
- dirname = dsprintf("%s/", dirname_given);
- else
- dirname = dsprintf("%s", dirname_given);
-
- if(dirname == NULL) {
- perror("dirname");
- exit(1);
- }
-
- if (onlyEncodings)
- goto encodings;
-
- entries = makeHashTable();
- if(doBitmaps && !doScalable) {
- readFontScale(entries, dirname);
- }
-
- if(strcmp(outfilename, "-") == 0)
- fontscale_name = NULL;
- else {
- if(outfilename[0] == '/')
- fontscale_name = dsprintf("%s", outfilename);
- else
- fontscale_name = dsprintf("%s%s", dirname, outfilename);
- if(fontscale_name == NULL) {
- perror("fontscale_name");
- exit(1);
- }
- }
dirp = opendir(dirname);
if(dirp == NULL) {
@@ -808,17 +777,6 @@
return 0;
}
- if(fontscale_name == NULL)
- fontscale = stdout;
- else
- fontscale = fopen(fontscale_name, "wb");
-
- if(fontscale == NULL) {
- fprintf(stderr, "%s: ", fontscale_name);
- perror("fopen(w)");
- return 0;
- }
-
while((entry = readdir(dirp)) != NULL) {
int have_face = 0;
char *xlfd_name = NULL;
@@ -831,7 +789,24 @@
}
filename = dsprintf("%s%s", dirname, entry->d_name);
+ if (recurse & (strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0)
+ && (stat(filename, &statbuf) == 0) && S_ISDIR(statbuf.st_mode)) {
+ char* prefix;
+ int retval;
+ free(filename);
+ filename = dsprintf("%s%s/", dirname, entry->d_name);
+ prefix = dsprintf("%s%s/", dir_prefix, entry->d_name);
+ retval = scanDirectory(filename, prefix, xl, entries);
+ free(filename);
+ free(prefix);
+ if (retval == 0) {
+ closedir(dirp);
+ return 0;
+ }
+ continue;
+ }
+ prefixedname = dsprintf("%s%s", dir_prefix, entry->d_name);
if(doBitmaps)
rc = bitmapIdentify(filename, &xlfd_name);
else
@@ -892,7 +867,7 @@
xlfd = listCons(s, xlfd);
} else {
/* Not a reencodable font -- skip all the rest of the loop body */
- putHash(entries, xlfd_name, entry->d_name, filePrio(entry->d_name));
+ putHash(entries, xlfd_name, prefixedname, filePrio(entry->d_name));
goto done;
}
}
@@ -926,7 +901,7 @@
found = 1;
snprintf(buf, MAXFONTNAMELEN, "%s-%s",
lp->value, encoding->value);
- putHash(entries, buf, entry->d_name, filePrio(entry->d_name));
+ putHash(entries, buf, prefixedname, filePrio(entry->d_name));
}
}
for(encoding = extra_encodings; encoding;
@@ -935,7 +910,7 @@
/* Do not set found! */
snprintf(buf, MAXFONTNAMELEN, "%s-%s",
lp->value, encoding->value);
- putHash(entries, buf, entry->d_name, filePrio(entry->d_name));
+ putHash(entries, buf, prefixedname, filePrio(entry->d_name));
}
}
}
@@ -946,10 +921,76 @@
}
deepDestroyList(xlfd);
xlfd = NULL;
+ free(prefixedname);
free(filename);
}
closedir(dirp);
+ return 1;
+}
+
+
+static int
+doDirectory(char *dirname_given, int numEncodings, ListPtr encodingsToDo)
+{
+ char *dirname, *fontscale_name, *filename, *encdir;
+ FILE *fontscale, *encfile;
+ HashTablePtr entries;
+ HashBucketPtr *array;
+ ListPtr lp;
+ int i, n;
+ int xl=0;
+
+ if (exclusionSuffix)
+ xl = strlen (exclusionSuffix);
+
+ i = strlen(dirname_given);
+ if(i == 0)
+ dirname = dsprintf("./");
+ else if(dirname_given[i - 1] != '/')
+ dirname = dsprintf("%s/", dirname_given);
+ else
+ dirname = dsprintf("%s", dirname_given);
+
+ if(dirname == NULL) {
+ perror("dirname");
+ exit(1);
+ }
+
+ if (onlyEncodings)
+ goto encodings;
+
+ entries = makeHashTable();
+ if(doBitmaps && !doScalable) {
+ readFontScale(entries, dirname);
+ }
+ if (scanDirectory(dirname, "", xl, entries) == 0)
+ return 0;
+
+ if(strcmp(outfilename, "-") == 0)
+ fontscale_name = NULL;
+ else {
+ if(outfilename[0] == '/')
+ fontscale_name = dsprintf("%s", outfilename);
+ else
+ fontscale_name = dsprintf("%s%s", dirname, outfilename);
+ if(fontscale_name == NULL) {
+ perror("fontscale_name");
+ exit(1);
+ }
+ }
+
+ if(fontscale_name == NULL)
+ fontscale = stdout;
+ else
+ fontscale = fopen(fontscale_name, "wb");
+
+ if(fontscale == NULL) {
+ fprintf(stderr, "%s: ", fontscale_name);
+ perror("fopen(w)");
+ return 0;
+ }
+
n = hashElements(entries);
fprintf(fontscale, "%d\n", n);
array = hashArray(entries, 1);
--- End Message ---