[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#539338: mkfontscale: add option to recurse subdirectories



X-Debbugs-CC: Juliusz Chroboczek <Juliusz.Chroboczek@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);

Reply to: