changeset 135:bc697a218716

Somewhat unified path lookup between linux and windows and added font paths.
author Diggory Hardy <diggory.hardy@gmail.com>
date Fri, 30 Jan 2009 15:51:42 +0000
parents 7ababdf97748
children 4084f07f2c7a
files mde/file/paths.d mde/setup/Init.d
diffstat 2 files changed, 84 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/mde/file/paths.d	Thu Jan 29 14:59:45 2009 +0000
+++ b/mde/file/paths.d	Fri Jan 30 15:51:42 2009 +0000
@@ -127,14 +127,10 @@
         Cout ("\nConf paths found:");
         confDir.coutPaths;
         Cout ("\nLog file directory:\n\t")(logDir);
-	version (Windows) {
-	    Cout ("\nFont directory:\n\t")(fontDir).newline;
-	} else version (linux) {
-	    Cout ("\nFont files found:");
-	    foreach (f,p; fontFiles)
-		Cout ("\n\t")(f)("\t")(p[0..$-1]);
-	    Cout.newline;
-	}
+        Cout ("\nFont directories:");
+        foreach (path; fontPaths)
+            Cout ("\n\t")(path.toString);
+        Cout.newline;
     }
     
 private:
@@ -202,11 +198,34 @@
     ubyte pathsLen = 0;
 }
 
+/** Get the actual path of a font file, or throw NoFileException if not found.
+ *
+ * Returns a C string (null terminated). */
+char[] getFontPath (char[] file) {
+    foreach (path; fontPaths) {
+    	FilePath font = path.dup.append (file);
+    	if (font.exists && font.isFile)
+            return font.cString;
+    }
+    throw new NoFileException ("Unable to find font file: "~file);
+}
+
 /** These are the actual instances, one for each of the data and conf "directories". */
 mdeDirectory dataDir, confDir;
 char[] logDir;		/// Directory for log files
+FilePath[] fontPaths;	/// All directories for fonts
 
 //BEGIN Path resolution
+/// For command line args: these paths are added if non-null, with highest priority.
+char[] extraDataPath, extraConfPath;
+
+/** Add an extra font directory. May be called multiple times. */
+void addFontPath (char[] path) {
+    FilePath fp = FilePath (path);
+    if (fp.exists && fp.isFolder)
+        fontPaths ~= fp;
+}
+
 /** Find at least one path for each required directory. */
 debug (mdeUnitTest) {
     /** In unittest mode, add paths unittest/data and unittest/conf before init runs. */
@@ -218,102 +237,74 @@
 	// Don't bother with real paths or logDir or font dir(s) for unittest.
     }
 }
-version (linux) {
-    SortedMap!(char[],char[]) fontFiles;	// key is file name, value is CString path
-    /** Get the actual path of a font file, or throw NoFileException if not found.
-     *
-     * Returns a C string (null terminated). */
-    char[] getFontPath (char[] file) {
-	char[] ret;
-	if (fontFiles.get (file, ret))
-	    return ret;
-	throw new NoFileException ("Unable to find font file: "~file);
-    }
+void resolvePaths (char[] base = ".") {
+    size_t iFP = fontPaths.length;
+    fontPaths.length = fontPaths.length + 4;
     
-    // base-path not used on posix
-    void resolvePaths (char[] base = "data") {
+    version (linux) {
         // Home directory:
         char[] HOME = Environment.get("HOME", ".");
         
-        // Base paths:
-        // Static data (must exist):
-        FilePath staticPath =
-                findPath (false, "/usr/share/games/mde", "/usr/local/share/games/mde", base);
-        // Config (can just use defaults if necessary, so long as we can save afterwards):
+        // Installation base (should contain "data" and "conf"):
+        FilePath staticPath = findPath (false,
+                                        "/usr/share/games/mde",
+                                        "/usr/local/share/games/mde",
+                                        base~"/data");
+        // Path for user-adjusted files:
         FilePath userPath = findPath (true, HOME~"/.config/mde", HOME~"/.mde");
         
-        // Static data paths:
-        dataDir.addPath (staticPath.toString);      // we know this is valid anyway
-        dataDir.tryPath (userPath.toString ~ "/data");
-        if (extraDataPath) dataDir.tryPath (extraDataPath);
-        if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!");
-        
-        // Configuration paths:
+        dataDir.addPath (staticPath.toString);
         confDir.tryPath (staticPath.toString ~ "/conf");
         confDir.tryPath ("/etc/mde");
-        confDir.tryPath (userPath.toString ~ "/conf", true);
-        if (extraConfPath) confDir.tryPath (extraConfPath);
-        if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!");
         
-        // Logging path:
-        logDir = userPath.toString;
-	
 	// Font paths:
-	auto fs = new FileScan;
-	// Scan for directories containing truetype and type1 fonts:
-        fs.sweep ("/usr/share/fonts", delegate bool(FilePath fp, bool isDir)
-	    {	return isDir || fp.suffix == ".ttf" || fp.suffix == ".pfb";	},
-		   true);
-	fontFiles = new SortedMap!(char[],char[]);
-	foreach (fp; fs.files)
-	    fontFiles.add (fp.file, fp.cString);	// both strings should be slices of same memory
-    }
-} else version (Windows) {
-    char[] fontDir;
-    /** Get the actual path of a font file, or throw NoFileException if not found.
-     *
-     * Returns a C string (null terminated). */
-    char[] getFontPath (char[] file) {
-	FilePath path = new FilePath (fontDir~file);
-	if (path.exists && !path.isFolder)
-	    return path.cString;
-	throw new NoFileException ("Unable to find font file: "~file);
+        auto fontP1 = FilePath("/usr/share/fonts").toList;
+        foreach (fp1; fontP1)
+            if (fp1.isFolder)
+                foreach (fp2; fp1.toList)
+                    if (fp2.isFolder) {
+                        if (iFP >= fontPaths.length)
+                            fontPaths.length = fontPaths.length * 2;
+                        fontPaths[iFP++] = fp2;
+                    }
+    } else version (Windows) {
+        //FIXME: Get base path from registry
+        
+        FilePath staticPath = findPath (false, base~"/data");
+	FilePath userPath = findPath (true, getSpecialPath(CSIDL_LOCAL_APPDATA) ~ "/mde");
+        
+        dataDir.addPath (staticPath.toString);
+        confDir.tryPath (staticPath.toString ~ "/conf");
+	
+	// Font path:
+	fontPaths ~= FilePath(getSpecialPath (CSIDL_FONTS));
+    } else {
+    	static assert (false, "Platform is not linux or Windows: no support for paths on this platform yet!");
     }
     
-    void resolvePaths (char[] base = "./") {
-        //FIXME: Get base path from registry
-        
-        // Base paths:
-        FilePath installPath = findPath (false, base);
-        FilePath staticPath = findPath (false, installPath.toString);
-	FilePath userPath = findPath (true, getSpecialPath(CSIDL_LOCAL_APPDATA) ~ "/mde");
-        
-        // Static data paths:
-        dataDir.addPath (staticPath.toString);   // we know this is valid anyway
-	dataDir.tryPath (userPath.toString ~ "/data");
-        if (extraDataPath) dataDir.tryPath (extraDataPath);
-        if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!");
-        
-        // Configuration paths:
-        confDir.tryPath (staticPath.toString ~ "/conf");
-        confDir.tryPath (installPath.append("user").toString);
-        confDir.tryPath (userPath.toString ~ "/conf", true);
-        if (extraConfPath) confDir.tryPath (extraConfPath);
-        if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!");
-        
-        // Logging path:
-        logDir = userPath.toString;
-	
-	// Font path:
-	fontDir = getSpecialPath (CSIDL_FONTS) ~ "/";	// append separator
+    // Static data paths:
+    dataDir.tryPath (userPath.toString ~ "/data");
+    if (extraDataPath) dataDir.tryPath (extraDataPath);
+    
+    // Configuration paths:
+    confDir.tryPath (userPath.toString ~ "/conf", true);
+    if (extraConfPath) confDir.tryPath (extraConfPath);
+    
+    if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!");
+    if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!");
+    
+    for (int i = dataDir.pathsLen - 1; i >= 0; --i) {
+        FilePath font = FilePath (dataDir.paths[i] ~ "fonts");
+        Cout ("considering: ")(font.toString).newline;
+        if (font.exists && font.isFolder)
+            fontPaths[iFP++] = font;
     }
-} else {
-    static assert (false, "Platform is not linux or Windows: no support for paths on this platform yet!");
+    fontPaths.length = iFP;
+    
+    // Logging path:
+    logDir = userPath.toString;
 }
 
-/// For command line args: these paths are added if non-null, with highest priority.
-char[] extraDataPath, extraConfPath;
-
 private {
     class PathException : mdeException {
         this(char[] msg) {
--- a/mde/setup/Init.d	Thu Jan 29 14:59:45 2009 +0000
+++ b/mde/setup/Init.d	Fri Jan 30 15:51:42 2009 +0000
@@ -103,6 +103,7 @@
             args.define("base-path").parameters(1);
             args.define("data-path").parameters(1,-1);
             args.define("conf-path").parameters(1,-1);
+            args.define("font-path").parameters(1,-1);
             args.define("paths");
             args.define("q").aliases(["quick-exit"]);
             args.define("help").aliases(["h"]);
@@ -120,7 +121,9 @@
                 paths.extraDataPath = args["data-path"];
             if (args.contains("conf-path"))
                 paths.extraConfPath = args["conf-path"];
-	    
+	    if (args.contains("font-path"))
+                paths.addFontPath (args["font-path"]);
+            
             if (args.contains("base-path"))
                 paths.resolvePaths (args["base-path"]);
             else