Author: jch
Date: 2003-06-05 11:54:39 -0500 (Thu, 05 Jun 2003)
New Revision: 147

Added:
   people/jch/xc/programs/mkfontscale/hash.c
   people/jch/xc/programs/mkfontscale/hash.h
   people/jch/xc/programs/mkfontscale/ident.c
   people/jch/xc/programs/mkfontscale/ident.h
Modified:
   people/jch/xc/programs/mkfontscale/Imakefile
   people/jch/xc/programs/mkfontscale/list.c
   people/jch/xc/programs/mkfontscale/list.h
   people/jch/xc/programs/mkfontscale/mkfontscale.c
   people/jch/xc/programs/mkfontscale/mkfontscale.man
Log:
Modified mkfontscale to process bitmap fonts, both legacy formats (BDF, PCF) 
and formats supported by FreeType (such as bitmap-only TTF fonts).

Mkfontscale -b -s -l should now be a drop-in replacement for mkfontdir.


Modified: people/jch/xc/programs/mkfontscale/mkfontscale.man
==============================================================================
--- people/jch/xc/programs/mkfontscale/mkfontscale.man  2003-06-05 13:30:06 UTC 
(rev 146)
+++ people/jch/xc/programs/mkfontscale/mkfontscale.man  2003-06-05 16:54:39 UTC 
(rev 147)
@@ -6,16 +6,27 @@
 .SH SYNOPSIS
 .B mkfontscale
 [
+.B \-b 
+] [
+.B \-s
+] [
 .B \-o 
 .I filename
-]
-[
-.B \-e 
+] [
+.B \-x
 .I encoding
 ] \|.\|.\|. [
 .B \-f 
 .I fuzz
 ] [
+.B \-l
+] [
+.B \-e
+.I directory
+] [
+.B \-p
+.I prefix
+] [
 .B \-\-
 ] [
 .I directory
@@ -37,19 +48,30 @@
 program.
 .SH OPTIONS
 .TP
+.B \-b
+read bitmap fonts.  By default, bitmap fonts are ignored.
+.TP
+.B \-s
+ignore scalable fonts.  By default, scalable fonts are read.  If
+.B \-b
+is set, this flag has the side effect of enabling the reading of
+.B fonts.scale
+files.
 .BI \-o " filename"
 send program output to
 .IR filename ;
 default is
-.BR fonts.scale .
-If
+.B fonts.scale 
+if bitmap fonts are not being read, and
+.B fonts.dir
+if they are.  If
 .I filename
 is relative, it is created in the directory being processed.  If it is
 the special value 
 .BR \- ,
 output is written to standard output.
 .TP
-.BI \-e " encoding"
+.BI \-x " encoding"
 add
 .I encoding
 to the list of encodings searched for.
@@ -59,15 +81,44 @@
 .I fuzz
 percent.  Defaults to 2%.
 .TP
+.B \-l
+Write
+.B fonts.dir
+files suitable for implementations that cannot reencode legacy fonts
+(BDF and PCF).  By default, it is assumed that the implementation can
+reencode Unicode-encoded legacy fonts.
+.TP
+.B -e
+specifies a directory with encoding files.  Every such
+directory is scanned for encoding files, the list of which is then
+written to an "encodings.dir" file in every font directory.
+.TP
+.B -p
+Specifies a prefix that is prepended to the encoding file path names
+when they are written to the "encodings.dir" file.  The prefix is
+prepended litterally: if a `/' is required between the prefix and the path
+names, it must be supplied explicitly as part of the prefix.
+.TP
 .B \-\- 
 end of options.
 .SH SEE ALSO
 X(__miscmansuffix__), Xserver(1), mkfontdir(1), ttmkfdir(1), xfs(1), xset(1)
 .SH NOTES
+The format of the
+.BR fonts.scale ,
+.B fonts.dir
+and
+.B encodings.dir
+files is documented in the mkfontdir(1) manual page.
+
 .B Mkfontscale
 will overwrite any
 .B fonts.scale
 file even if it has been hand-edited.
+
+.B mkfontscale -b -l
+is equivalent to
+.BR mkfontdir .
 .SH AUTHOR
 .B Mkfontscale
 was written by Juliusz Chroboczek <[EMAIL PROTECTED]> for the XFree86

Modified: people/jch/xc/programs/mkfontscale/list.h
==============================================================================
--- people/jch/xc/programs/mkfontscale/list.h   2003-06-05 13:30:06 UTC (rev 
146)
+++ people/jch/xc/programs/mkfontscale/list.h   2003-06-05 16:54:39 UTC (rev 
147)
@@ -40,16 +40,3 @@
 void destroyList(ListPtr old);
 void deepDestroyList(ListPtr old);
 
-typedef struct _Acell {
-    char *key;
-    char *value;
-    int prio;
-} AcellRec, *AcellPtr;
-
-AcellPtr acell(ListPtr alist);
-AcellPtr assoc(char *key, ListPtr alist);
-ListPtr acons(char *key, char *value, ListPtr alist);
-ListPtr aconsPrio(char *key, char *value, int prio, ListPtr alist);
-
-void destroyAlist(ListPtr old);
-void deepDestroyAlist(ListPtr old);

Added: people/jch/xc/programs/mkfontscale/ident.c
==============================================================================
--- people/jch/xc/programs/mkfontscale/ident.c  2003-06-05 13:30:06 UTC (rev 
146)
+++ people/jch/xc/programs/mkfontscale/ident.c  2003-06-05 16:54:39 UTC (rev 
147)
@@ -0,0 +1,330 @@
+/*
+  Copyright (c) 2003 by Juliusz Chroboczek
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+*/
+
+/* The function identifyBitmap returns -1 if filename is definitively not
+   a font file, 1 if it is a single-face bitmap font with a XLFD name,
+   and 0 if it should be processed normally.  identifyBitmap is
+   much faster than parsing the whole font. */
+
+#include <stdlib.h>
+#include "zlib.h"
+
+#define PCF_VERSION (('p'<<24)|('c'<<16)|('f'<<8)|1)
+#define PCF_PROPERTIES (1 << 0)
+
+typedef struct _Prop {
+    unsigned name;
+    int isString;
+    unsigned value;
+} PropRec, *PropPtr;
+
+static int pcfIdentify(gzFile f, char **name);
+static int bdfIdentify(gzFile f, char **name);
+
+static int
+getLSB32(gzFile f)
+{
+    int rc;
+    unsigned char c[4];
+
+    rc = gzread(f, c, 4);
+    if(rc != 4)
+        return -1;
+    return (c[0]) | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
+}
+
+static int
+getInt8(gzFile f, int format)
+{
+    unsigned char c;
+    int rc;
+
+    rc = gzread(f, &c, 1);
+    if(rc != 1)
+        return -1;
+    return c;
+}
+
+static int
+getInt32(gzFile f, int format)
+{
+    int rc;
+    unsigned char c[4];
+
+    rc = gzread(f, c, 4);
+    if(rc != 4)
+        return -1;
+
+    if(format & (1 << 2)) {
+        return (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | (c[3]);
+    } else {
+        return (c[0]) | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
+    }
+}
+
+static int
+pcfskip(gzFile f, int n)
+{
+    char buf[32];
+    int i, rc;
+    while(n > 0) {
+        i = (n > 32 ? 32 : n);
+        rc = gzread(f, buf, i);
+        if(rc != i)
+            return -1;
+        n -= rc;
+    }
+    return 1;
+}
+
+int 
+bitmapIdentify(char *filename, char **name)
+{
+    gzFile f;
+    int magic;
+
+    f = gzopen(filename, "rb");
+    if(f == NULL)
+        return -1;
+
+    magic = getLSB32(f);
+    if(magic == PCF_VERSION)
+        return pcfIdentify(f, name);
+    else if(magic == ('S' | ('T' << 8) | ('A' << 16) | ('R') << 24))
+        return bdfIdentify(f, name);
+
+    gzclose(f);
+    return 0;
+}
+
+static int
+pcfIdentify(gzFile f, char **name)
+{
+    int prop_position;
+    PropPtr props = NULL;
+    int version, format, count, prop_size, nprops, i, string_size, rc;
+    char *strings = NULL, *s;
+    char buf[4];
+
+    count = getLSB32(f);
+    if(count <= 0)
+        goto fail;
+
+    prop_position = -1;
+    for(i = 0; i < count; i++) {
+        int type, format, size, offset;
+        type = getLSB32(f);
+        format = getLSB32(f);
+        size = getLSB32(f);
+        offset = getLSB32(f);
+        if(type == PCF_PROPERTIES) {
+            prop_position = offset;
+            prop_size = size;
+            break;
+        }
+    }
+    if(prop_position < 0)
+        goto fail;
+
+    rc = gzseek(f, prop_position, SEEK_SET);
+    if(rc < 0)
+        goto fail;
+    
+    format = getLSB32(f);
+    if((format & 0xFFFFFF00) != 0)
+        goto fail;
+    nprops = getInt32(f, format);
+    if(nprops <= 0 || nprops > 1000)
+        goto fail;
+    props = malloc(nprops * sizeof(PropRec));
+    if(props == NULL)
+        goto fail;
+
+    for(i = 0; i < nprops; i++) {
+        props[i].name = getInt32(f, format);
+        props[i].isString = getInt8(f, format);
+        props[i].value = getInt32(f, format);
+    }
+    if(nprops & 3) {
+        rc = pcfskip(f, 4 - (nprops & 3));
+        if(rc < 0)
+            goto fail;
+    }
+
+    string_size = getInt32(f, format);
+    if(string_size < 0 || string_size > 100000)
+        goto fail;
+    strings = malloc(string_size);
+    if(!strings)
+        goto fail;
+
+    rc = gzread(f, strings, string_size);
+    if(rc != string_size)
+        goto fail;
+
+    for(i = 0; i < nprops; i++) {
+        if(!props[i].isString ||
+           props[i].name >= string_size - 4 ||
+           props[i].value >= string_size)
+            continue;
+        if(strcmp(strings + props[i].name, "FONT") == 0)
+            break;
+    }
+
+    if(i >= nprops)
+        goto fail;
+
+    s = malloc(strlen(strings + props[i].value) + 1);
+    if(s == NULL)
+        goto fail;
+    strcpy(s, strings + props[i].value);
+    *name = s;
+    free(strings);
+    free(props);
+    gzclose(f);
+    return 1;
+
+ fail:
+    if(strings) free(strings);
+    if(props) free(props);
+    gzclose(f);
+    return 0;
+}
+
+#define NKEY 20
+
+static char*
+getKeyword(gzFile *f, int *eol)
+{
+    static char keyword[NKEY + 1];
+    int c, i;
+    i = 0;
+    while(i < NKEY) {
+        c = gzgetc(f);
+        if(c == ' ' || c == '\n') {
+            if(i <= 0)
+                return NULL;
+            if(eol)
+                *eol = (c == '\n');
+            keyword[i] = '\0';
+            return keyword;
+        }
+        if(c < 'A' || c > 'Z')
+            return NULL;
+        keyword[i++] = c;
+    }
+    return NULL;
+}
+
+static int
+bdfskip(gzFile *f)
+{
+    int c;
+    do {
+        c = gzgetc(f);
+    } while(c >= 0 && c != '\n');
+    if(c < 0)
+        return -1;
+    return 1;
+}
+
+static char *
+bdfend(gzFile *f)
+{
+    int c;
+    char *buf = NULL;
+    int bufsize = 0;
+    int i = 0;
+
+    do {
+        c = gzgetc(f);
+    } while (c == ' ');
+
+    while(i < 1000) {
+        if(c < 0 || (c == '\n' && i == 0)) {
+            goto fail;
+        }
+        if(bufsize < i + 1) {
+            char *newbuf;
+            if(bufsize == 0) {
+                bufsize = 20;
+                newbuf = malloc(bufsize);
+            } else {
+                bufsize = 2 * bufsize;
+                newbuf = realloc(buf, bufsize);
+            }
+            if(newbuf == NULL)
+                goto fail;
+            buf = newbuf;
+        }
+        if(c == '\n') {
+            buf[i] = '\0';
+            return buf;
+        }
+        buf[i++] = c;
+        c = gzgetc(f);
+    }
+
+ fail:
+    if(buf)
+        free(buf);
+    return NULL;
+}
+
+static int
+bdfIdentify(gzFile f, char **name)
+{
+    char *k;
+    int rc;
+    int eol;
+    /* bitmapIdentify already read "STAR", so we need to check for
+       "TFONT" */
+    k = getKeyword(f, &eol);
+    if(k == NULL || eol)
+        goto fail;
+    if(strcmp(k, "TFONT") != 0)
+        goto fail;
+    while(1) {
+        if(!eol) {
+            rc = bdfskip(f);
+            if(rc < 0) 
+                goto fail;
+        }
+        k = getKeyword(f, &eol);
+        if(k == NULL)
+            goto fail;
+        else if(strcmp(k, "FONT") == 0) {
+            if(eol)
+                goto fail;
+            k = bdfend(f);
+            if(k == NULL)
+                goto fail;
+            *name = k;
+            gzclose(f);
+            return 1;
+        } else if(strcmp(k, "CHARS") == 0)
+            goto fail;
+    }
+ fail:
+    gzclose(f);
+    return 0;
+}

Added: people/jch/xc/programs/mkfontscale/hash.c
==============================================================================
--- people/jch/xc/programs/mkfontscale/hash.c   2003-06-05 13:30:06 UTC (rev 
146)
+++ people/jch/xc/programs/mkfontscale/hash.c   2003-06-05 16:54:39 UTC (rev 
147)
@@ -0,0 +1,236 @@
+/*
+  Copyright (c) 2003 by Juliusz Chroboczek
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "hash.h"
+#include "list.h"
+
+#define LOG2_NUMBUCKETS 10
+#define NUMBUCKETS (1 << LOG2_NUMBUCKETS)
+
+static unsigned
+hash(char *string)
+{
+    int i;
+    unsigned u = 0;
+    for(i = 0; string[i] != '\0'; i++)
+        u = (u<<5) + (u >> (LOG2_NUMBUCKETS - 5)) + (unsigned char)string[i];
+    return (u & (NUMBUCKETS - 1));
+}
+
+static char
+lwr(char a)
+{
+    if(a >= 'A' && a <= 'Z')
+        return a | 0x20;
+    else
+        return a;
+}
+
+static void
+strcpy_lwr(char *dst, char *src)
+{
+    while(1) {
+        *dst = lwr(*src);
+        if(*src == '\0')
+            break;
+        src++;
+        dst++;
+    }
+}
+
+static int
+strcmp_lwr(char *a, char *b)
+{
+    while(*a != '\0' && *b != '\0') {
+        if(lwr(*a) != lwr(*b)) {
+            if(lwr(*a) < lwr(*b))
+                return -1;
+            if(lwr(*a) > lwr(*b))
+                return 1;
+        }
+        a++;
+        b++;
+    }
+    if (*a != '\0')
+        return -1;
+    else if(*b == '\0')
+        return 1;
+    else
+        return 0;
+}
+
+HashTablePtr
+makeHashTable()
+{
+    return calloc(NUMBUCKETS, sizeof(HashBucketPtr));
+}
+
+void
+destroyHashTable(HashTablePtr table)
+{
+    int i;
+    HashBucketPtr bp;
+
+    for(i = 0; i < NUMBUCKETS; i++) {
+        while(table[i]) {
+            bp = table[i];
+            table[i] = table[i]->next;
+            free(bp->key);
+            free(bp->value);
+            free(bp);
+        }
+    }
+    free(table);
+}
+
+char *
+getHash(HashTablePtr table, char *key)
+{
+    int i = hash(key);
+    HashBucketPtr bp;
+    for(bp = table[i]; bp; bp = bp->next) {
+        if(strcmp_lwr(bp->key, key) == 0)
+            return bp->value;
+    }
+    return NULL;
+}
+
+int
+putHash(HashTablePtr table, char *key, char *value, int prio)
+{
+    int i = hash(key);
+    char *keycopy = NULL, *valuecopy = NULL;
+    HashBucketPtr bp;
+    for(bp = table[i]; bp; bp = bp->next) {
+        if(strcmp_lwr(bp->key, key) == 0) {
+            if(prio > bp->prio) {
+                keycopy = malloc(strlen(key) + 1);
+                if(keycopy == NULL) goto fail;
+                strcpy_lwr(keycopy, key);
+                valuecopy = malloc(strlen(value) + 1);
+                if(valuecopy == NULL) goto fail;
+                strcpy(valuecopy, value);
+                free(bp->key);
+                free(bp->value);
+                bp->key = keycopy;
+                bp->value = valuecopy;
+            }
+            return 1;
+        }
+    }
+    keycopy = malloc(strlen(key) + 1);
+    if(keycopy == NULL)
+        goto fail;
+    strcpy_lwr(keycopy, key);
+    valuecopy = malloc(strlen(value) + 1);
+    if(valuecopy == NULL)
+        goto fail;
+    strcpy(valuecopy, value);
+    bp = malloc(sizeof(HashBucketRec));
+    if(bp == NULL)
+        goto fail;
+    bp->key = keycopy;
+    bp->value = valuecopy;
+    bp->prio = prio;
+    bp->next = table[i];
+    table[i] = bp;
+    return 1;
+
+ fail:
+    if(keycopy) free(keycopy);
+    if(valuecopy) free(valuecopy);
+    return -1;
+}
+
+int
+hashElements(HashTablePtr table)
+{
+    int i, n;
+    HashBucketPtr bp;
+
+    n = 0;
+    for(i = 0; i < NUMBUCKETS; i++) {
+        for(bp = table[i]; bp; bp = bp->next) {
+            n++;
+        }
+    }
+    return n;
+}
+
+static int
+key_first_cmp(void *v1, void *v2)
+{
+    HashBucketPtr *b1 = v1, *b2 = v2;
+    int c1 = strcmp_lwr((*b1)->key, (*b2)->key);
+    if(c1 != 0) return c1;
+    return strcmp((*b1)->value, (*b2)->value);
+}
+
+static int
+value_first_cmp(void *v1, void *v2)
+{
+    HashBucketPtr *b1 = v1, *b2 = v2;
+    int c1 = strcmp((*b1)->value, (*b2)->value);
+    if(c1 != 0) return c1;
+    return strcmp_lwr((*b1)->key, (*b2)->key);
+}
+
+HashBucketPtr *
+hashArray(HashTablePtr table, int value_first)
+{
+    int i, j, n;
+    HashBucketPtr *dst;
+    
+    n = hashElements(table);
+    dst = malloc((n + 1) * sizeof(HashBucketPtr));
+    if(dst == NULL)
+        return NULL;
+
+    j = 0;
+    for(i = 0; i < NUMBUCKETS; i++) {
+        while(table[i]) {
+            dst[j++] = table[i];
+            table[i] = table[i]->next;
+        }
+    }
+    qsort(dst, j, sizeof(HashBucketPtr),
+          value_first ? value_first_cmp : key_first_cmp);
+    dst[j++] = NULL;
+    free(table);
+
+    return dst;
+}
+
+void
+destroyHashArray(HashBucketPtr *array)
+{
+    int i = 0;
+    while(array[i]) {
+        free(array[i]->key);
+        free(array[i]->value);
+        free(array[i]);
+        i++;
+    }
+    free(array);
+}

Modified: people/jch/xc/programs/mkfontscale/Imakefile
==============================================================================
--- people/jch/xc/programs/mkfontscale/Imakefile        2003-06-05 13:30:06 UTC 
(rev 146)
+++ people/jch/xc/programs/mkfontscale/Imakefile        2003-06-05 16:54:39 UTC 
(rev 147)
@@ -5,9 +5,9 @@
 
 SYS_LIBRARIES = GzipLibrary
 
-SRCS = mkfontscale.c list.c
+SRCS = mkfontscale.c list.c hash.c ident.c
 
-OBJS = mkfontscale.o list.o
+OBJS = mkfontscale.o list.o hash.o ident.o
 
 #if !HasSnprintf
 SNPRINTF_DEFINES  = -DNEED_SNPRINTF

Modified: people/jch/xc/programs/mkfontscale/mkfontscale.c
==============================================================================
--- people/jch/xc/programs/mkfontscale/mkfontscale.c    2003-06-05 13:30:06 UTC 
(rev 146)
+++ people/jch/xc/programs/mkfontscale/mkfontscale.c    2003-06-05 16:54:39 UTC 
(rev 147)
@@ -28,6 +28,7 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include <X11/fonts/fontenc.h>
 #include <freetype/freetype.h>
@@ -35,12 +36,23 @@
 #include <freetype/tttables.h>
 #include <freetype/ttnameid.h>
 #include <freetype/t1tables.h>
+#include <freetype/ftbdf.h>
+#include <freetype/tttables.h>
 
 #include "list.h"
+#include "hash.h"
 #include "data.h"
+#include "ident.h"
 
 #define NPREFIX 1024
 
+#ifndef MAXFONTFILENAMELEN
+#define MAXFONTFILENAMELEN 1024
+#endif
+#ifndef MAXFONTNAMELEN
+#define MAXFONTNAMELEN 1024
+#endif
+
 char *encodings_array[] =
     { "iso8859-1", "iso8859-2", "iso8859-3", "iso8859-4", "iso8859-5",
       "iso8859-6", "iso8859-7", "iso8859-8", "iso8859-9", "iso8859-10",
@@ -68,6 +80,8 @@
 static int find_cmap(int type, int pid, int eid, FT_Face face);
 static char* notice_foundry(char *notice);
 static char* vendor_foundry(signed char *vendor);
+int readFontScale(HashTablePtr entries, char *dirname);
+ListPtr makeXLFD(char *filename, FT_Face face, int);
 
 static FT_Library ft_library;
 static float bigEncodingFuzz = 0.02;
@@ -83,8 +97,10 @@
 usage(void)
 {
     fprintf(stderr, 
-            "mkfontscale [ -o filename ] [ -e encoding ] [ -f fuzz ] "
-            "[ directory ]\n");
+            "mkfontscale [ -b ] [ -s ] [ -o filename ] \n"
+            "            [ -x encoding ] [ -f fuzz ] [ -l ] "
+            "[ -e directory ] [ -p prefix ]\n"
+            "            [ directory ]...\n");
 }
 
 int
@@ -93,7 +109,7 @@
     int argn;
     FT_Error ftrc;
     int rc;
-    char prefix[NPREFIX + 1];
+    char prefix[NPREFIX];
 
     if(getcwd(prefix, NPREFIX - 1) == NULL) {
         perror("Couldn't get cwd");
@@ -101,7 +117,6 @@
     }
     if(prefix[strlen(prefix) - 1] != '/')
         strcat(prefix, "/");
-    encodingPrefix = prefix;
 
     outfilename = NULL;
 
@@ -123,14 +138,14 @@
         if(argv[argn][1] == '-') {
             argn++;
             break;
-        } else if(argv[argn][1] == 'e') {
+        } else if(strcmp(argv[argn], "-x") == 0) {
             if(argn >= argc - 1) {
                 usage();
                 exit(1);
             }
             makeList(&argv[argn + 1], 1, encodings, 0);
             argn += 2;
-        } else if(argv[argn][1] == 'p') {
+        } else if(strcmp(argv[argn], "-p") == 0) {
             if(argn >= argc - 1) {
                 usage();
                 exit(1);
@@ -140,10 +155,8 @@
                 exit(1);
             }
             strcpy(prefix, argv[argn + 1]);
-            if(prefix[strlen(prefix) - 1] != '/')
-                strcat(prefix, "/");
             argn += 2;
-        } else if(argv[argn][1] == 'E') {
+        } else if(strcmp(argv[argn], "-e") == 0) {
             if(argn >= argc - 1) {
                 usage();
                 exit(1);
@@ -153,23 +166,23 @@
             if(rc < 0)
                 exit(1);
             argn += 2;
-        } else if(argv[argn][1] == 'b') {
-            doBitmaps = !doBitmaps;
+        } else if(strcmp(argv[argn], "-b") == 0) {
+            doBitmaps = 1;
             argn++;
-        } else if(argv[argn][1] == 's') {
-            doScalable = !doScalable;
+        } else if(strcmp(argv[argn], "-s") == 0) {
+            doScalable = 0;
             argn++;
-        } else if(argv[argn][1] == 'r') {
+        } else if(strcmp(argv[argn], "-l") == 0) {
             reencodeLegacy = !reencodeLegacy;
             argn++;
-        } else if(argv[argn][1] == 'o') {
+        } else if(strcmp(argv[argn], "-o") == 0) {
             if(argn >= argc - 1) {
                 usage();
                 exit(1);
             }
             outfilename = argv[argn + 1];
             argn += 2;
-        } else if(argv[argn][1] == 'f') {
+        } else if(strcmp(argv[argn], "-f") == 0) {
             if(argn >= argc - 1) {
                 usage();
                 exit(1);
@@ -182,6 +195,8 @@
         }
     }
 
+    encodingPrefix = dsprintf("%s", prefix);
+
     if(outfilename == NULL) {
         if(doBitmaps)
             outfilename = "fonts.dir";
@@ -432,7 +447,251 @@
     return t;
 }
 
+ListPtr
+makeXLFD(char *filename, FT_Face face, int isBitmap)
+{
+    ListPtr xlfd = NULL;
+    char *foundry, *family, *weight, *slant, *sWidth, *adstyle, 
+        *spacing, *full_name;
+    TT_Header *head;
+    TT_HoriHeader *hhea;
+    TT_OS2 *os2;
+    TT_Postscript *post;
+    PS_FontInfoRec *t1info, t1info_rec;
+    int rc;
+
+    foundry = NULL;
+    family = NULL;
+    weight = NULL;
+    slant = NULL;
+    sWidth = NULL;
+    adstyle = NULL;
+    spacing = NULL;
+    full_name = NULL;
+
+    head = FT_Get_Sfnt_Table(face, ft_sfnt_head);
+    hhea = FT_Get_Sfnt_Table(face, ft_sfnt_hhea);
+    os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+    post = FT_Get_Sfnt_Table(face, ft_sfnt_post);
+
+    rc = FT_Get_PS_Font_Info(face, &t1info_rec);
+    if(rc == 0)
+        t1info = &t1info_rec;
+    else
+        t1info = NULL;
+        
+    if(!family)
+        family = getName(face, TT_NAME_ID_FONT_FAMILY);
+    if(!family)
+        family = getName(face, TT_NAME_ID_FULL_NAME);
+    if(!family)
+        family = getName(face, TT_NAME_ID_PS_NAME);
+
+    if(!full_name)
+        full_name = getName(face, TT_NAME_ID_FULL_NAME);
+    if(!full_name)
+        full_name = getName(face, TT_NAME_ID_PS_NAME);
+
+    if(os2 && os2->version != 0xFFFF) {
+        if(!weight)
+            weight = os2Weight(os2->usWeightClass);
+        if(!sWidth)
+            sWidth = os2Width(os2->usWidthClass);
+        if(!foundry)
+            foundry = vendor_foundry(os2->achVendID);
+        if(!slant)
+            slant = os2->fsSelection & 1 ? "i" : "r";
+    }
+
+    if(post) {
+        if(!spacing) {
+            if(post->isFixedPitch) {
+                if(hhea->min_Left_Side_Bearing >= 0 &&
+                   hhea->xMax_Extent <= hhea->advance_Width_Max) {
+                    spacing = "c";
+                } else {
+                    spacing = "m";
+                }
+            } else {
+                spacing = "p";
+            }
+        }
+    }
+            
+    if(t1info) {
+        if(!family)
+            family = t1info->family_name;
+        if(!family)
+            family = t1info->full_name;
+        if(!full_name)
+            full_name = t1info->full_name;
+        if(!foundry)
+            foundry = notice_foundry(t1info->notice);
+        if(!weight)
+            weight = t1Weight(t1info->weight);
+        if(!spacing)
+            spacing = t1info->is_fixed_pitch ? "m" : "p";
+        if(!slant) {
+            /* Bitstream fonts have positive italic angle. */
+            slant =
+                t1info->italic_angle <= -4 || t1info->italic_angle >= 4 ?
+                "i" : "r";
+        }
+    }
+
+    if(!full_name) {
+        fprintf(stderr, "Couldn't determine full name for %s\n", filename);
+        full_name = filename;
+    }
+
+    if(head) {
+        if(!slant)
+            slant = head->Mac_Style & 2 ? "i" : "r";
+        if(!weight)
+            weight = head->Mac_Style & 1 ? "bold" : "medium";
+    }
+
+    if(!slant) {
+        fprintf(stderr, "Couldn't determine slant for %s\n", filename);
+        slant = "r";
+    }
+
+    if(!weight) {
+        fprintf(stderr, "Couldn't determine weight for %s\n", filename);
+        weight = "medium";
+    }
+
+    if(!foundry) {
+        char *notice;
+        notice = getName(face, TT_NAME_ID_TRADEMARK);
+        if(notice) {
+            foundry = notice_foundry(notice);
+        }
+        if(!foundry) {
+            notice = getName(face, TT_NAME_ID_MANUFACTURER);
+            if(notice) {
+                foundry = notice_foundry(notice);
+            }
+        }
+    }
+
+    if(strcmp(slant, "i") == 0) {
+        if(strstr(full_name, "Oblique"))
+            slant = "o";
+        if(strstr(full_name, "Slanted"))
+            slant = "o";
+    }
+
+    if(!sWidth)
+        sWidth = nameWidth(full_name);
+
+    if(!foundry) foundry = "misc";
+    if(!family) {
+        fprintf(stderr, "Couldn't get family name for %s\n", filename);
+        family = filename;
+    }
+
+    if(!weight) weight = "medium";
+    if(!slant) slant = "r";
+    if(!sWidth) sWidth = "normal";
+    if(!adstyle) adstyle = "";
+    if(!spacing) spacing = "p";
+
+    /* Yes, it's a memory leak. */
+    foundry = safe(foundry);
+    family = safe(family);
+
+    if(!isBitmap) {
+        xlfd = listConsF(xlfd,
+                         "-%s-%s-%s-%s-%s-%s-0-0-0-0-%s-0",
+                         foundry, family,
+                         weight, slant, sWidth, adstyle, spacing);
+    } else {
+        int i, w, h, xres, yres;
+        for(i = 0; i < face->num_fixed_sizes; i++) {
+            w = face->available_sizes[i].width;
+            h = face->available_sizes[i].height;
+            xres = 75;
+            yres = (double)h / w * xres;
+            xlfd = listConsF(xlfd,
+                             "-%s-%s-%s-%s-%s-%s-%d-%d-%d-%d-%s-%d",
+                             foundry, family,
+                             weight, slant, sWidth, adstyle,
+                             h, ((int)(h / (double)yres + 0.5)) * 10,
+                             xres, yres,
+                             spacing, 60);
+        }
+    }
+    return xlfd;
+}
+
 int
+readFontScale(HashTablePtr entries, char *dirname)
+{
+    int n = strlen(dirname);
+    char *filename;
+    FILE *in;
+    int rc, count, i;
+    char file[MAXFONTFILENAMELEN], font[MAXFONTNAMELEN];
+    char format[100];
+
+    snprintf(format, 100, "%%%ds %%%d[^\n]\n", 
+             MAXFONTFILENAMELEN, MAXFONTNAMELEN);
+
+    if(dirname[n - 1] == '/')
+        filename = dsprintf("%sfonts.scale", dirname);
+    else
+        filename = dsprintf("%s/fonts.scale", dirname);
+    if(filename == NULL)
+        return -1;
+
+    in = fopen(filename, "r");
+    free(filename);
+    if(in == NULL) {
+        if(errno != ENOENT)
+            perror("open(fonts.scale)");
+        return -1;
+    }
+
+    rc = fscanf(in, "%d\n", &count);
+    if(rc != 1) {
+        fprintf(stderr, "Invalid fonts.scale in %s.\n", dirname);
+        fclose(in);
+        return -1;
+    }
+
+    for(i = 0; i < count; i++) {
+        rc = fscanf(in, format, file, font);
+        if(rc != 2)
+            break;
+        putHash(entries, font, file, 100);
+    }
+    fclose(in);
+    return 1;
+}
+
+static int
+filePrio(char *filename)
+{
+    int n = strlen(filename);
+    if(n < 4)
+        return 0;
+    if(memcmp(filename + n - 4, ".otf", 4) == 0)
+        return 4;
+    if(memcmp(filename + n - 4, ".OTF", 4) == 0)
+        return 4;
+    if(memcmp(filename + n - 4, ".ttf", 4) == 0)
+        return 3;
+    if(memcmp(filename + n - 4, ".TTF", 4) == 0)
+        return 3;
+    if(memcmp(filename + n - 3, ".gz", 3) == 0)
+        return 2;
+    if(memcmp(filename + n - 2, ".Z", 2) == 0)
+        return 1;
+    return 0;
+}
+
+int
 doDirectory(char *dirname_given, int doEncodings, ListPtr encodingsToDo)
 {
     char *dirname, *fontscale_name, *filename;
@@ -441,15 +700,11 @@
     struct dirent *entry;
     FT_Error ftrc;
     FT_Face face;
-    TT_Header *head;
-    TT_HoriHeader *hhea;
-    TT_OS2 *os2;
-    TT_Postscript *post;
-    PS_FontInfoRec *t1info, t1info_rec;
-    char *foundry, *family, *weight, *slant, *sWidth, *adstyle, 
-        *spacing, *full_name;
-    ListPtr encoding, entries = NULL;
-    int i, found, rc;
+    ListPtr encoding, xlfd, lp;
+    HashTablePtr entries;
+    HashBucketPtr *array;
+    int i, n, found, rc;
+    int isBitmap;
 
     i = strlen(dirname_given);
     if(i == 0)
@@ -481,10 +736,15 @@
         }
         fprintf(out, "%d\n", listLength(encodingsToDo));
         for(l = encodingsToDo; l; l = l->next) {
-            fprintf(out, "%s %s\n", acell(l)->key, acell(l)->value);
+            fprintf(out, "%s\n", l->value);
         }
     }
 
+    entries = makeHashTable();
+    if(doBitmaps && !doScalable) {
+        readFontScale(entries, dirname);
+    }
+
     if(strcmp(outfilename, "-") == 0)
         fontscale_name = NULL;
     else {
@@ -515,191 +775,138 @@
         perror("fopen(w)");
         return 0;
     }
-    
-    for(;;) {
-        entry = readdir(dirp);
-        if(entry == NULL)
-            break;
+
+    while((entry = readdir(dirp)) != NULL) {
+        int have_face = 0;
+        char *xlfd_name = NULL;
+        xlfd = NULL;
         filename = dsprintf("%s%s", dirname, entry->d_name);
-        ftrc = FT_New_Face(ft_library, filename, 0, &face);
-        if(ftrc)
-            continue;
 
-        if((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0) {
-            if(!doBitmaps)
-                continue;
-        } else {
-            if(!doScalable)
-                continue;
-        }
+        if(doBitmaps)
+            rc = bitmapIdentify(filename, &xlfd_name);
+        else
+            rc = 0;
 
-        found = 0;
+        if(rc < 0)
+            goto done;
 
-        foundry = NULL;
-        family = NULL;
-        weight = NULL;
-        slant = NULL;
-        sWidth = NULL;
-        adstyle = NULL;
-        spacing = NULL;
-        full_name = NULL;
+        if(rc == 0) {
+            ftrc = FT_New_Face(ft_library, filename, 0, &face);
+            if(ftrc)
+                goto done;
+            have_face = 1;
 
-        head = FT_Get_Sfnt_Table(face, ft_sfnt_head);
-        hhea = FT_Get_Sfnt_Table(face, ft_sfnt_hhea);
-        os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
-        post = FT_Get_Sfnt_Table(face, ft_sfnt_post);
+            isBitmap = ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0);
 
-        rc = FT_Get_PS_Font_Info(face, &t1info_rec);
-        if(rc == 0)
-            t1info = &t1info_rec;
-        else
-            t1info = NULL;
+            if(!isBitmap) {
+                /* Workaround for bitmap-only TTF fonts */
+                if(face->num_fixed_sizes > 0) {
+                    TT_MaxProfile *maxp;
+                    maxp = FT_Get_Sfnt_Table(face, ft_sfnt_maxp);
+                    if(maxp != NULL && maxp->maxContours == 0)
+                        isBitmap = 1;
+                }
+            }
         
-        if(!family)
-            family = getName(face, TT_NAME_ID_FONT_FAMILY);
-        if(!family)
-            family = getName(face, TT_NAME_ID_FULL_NAME);
-        if(!family)
-            family = getName(face, TT_NAME_ID_PS_NAME);
+            if(isBitmap) {
+                if(!doBitmaps)
+                    goto done;
+            } else {
+                if(!doScalable)
+                    goto done;
+            }
 
-        if(!full_name)
-            full_name = getName(face, TT_NAME_ID_FULL_NAME);
-        if(!full_name)
-            full_name = getName(face, TT_NAME_ID_PS_NAME);
-
-        if(os2 && os2->version != 0xFFFF) {
-            if(!weight)
-                weight = os2Weight(os2->usWeightClass);
-            if(!sWidth)
-                sWidth = os2Width(os2->usWidthClass);
-            if(!foundry)
-                foundry = vendor_foundry(os2->achVendID);
-            if(!slant)
-                slant = os2->fsSelection & 1 ? "i" : "r";
-        }
-
-        if(post) {
-            if(!spacing) {
-                if(post->isFixedPitch) {
-                    if(hhea->min_Left_Side_Bearing >= 0 &&
-                       hhea->xMax_Extent <= hhea->advance_Width_Max) {
-                        spacing = "c";
-                    } else {
-                        spacing = "m";
-                    }
-                } else {
-                    spacing = "p";
+            if(isBitmap) {
+                BDF_PropertyRec prop;
+                int n;
+                rc = FT_Get_BDF_Property(face, "FONT", &prop);
+                if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) {
+                    n = strlen(prop.u.atom);
+                    xlfd_name = malloc(strlen(prop.u.atom) + 1);
+                    if(xlfd_name == NULL)
+                        goto done;
+                    strcpy(xlfd_name, prop.u.atom);
                 }
             }
         }
-            
-        if(t1info) {
-            if(!family)
-                family = t1info->family_name;
-            if(!family)
-                family = t1info->full_name;
-            if(!full_name)
-                full_name = t1info->full_name;
-            if(!foundry)
-                foundry = notice_foundry(t1info->notice);
-            if(!weight)
-                weight = t1Weight(t1info->weight);
-            if(!spacing)
-                spacing = t1info->is_fixed_pitch ? "m" : "p";
-            if(!slant) {
-                /* Bitstream fonts have positive italic angle. */
-                slant =
-                    t1info->italic_angle <= -4 || t1info->italic_angle >= 4 ?
-                    "i" : "r";
+
+        if(xlfd_name) {
+            /* We know it's a bitmap font, and we know its XLFD */
+            char *s;
+            int n = strlen(xlfd_name);
+            if(reencodeLegacy &&
+               n >= 12 && strcasecmp(xlfd_name + n - 11, "-iso10646-1") == 0) {
+                s = malloc(n - 10);
+                memcpy(s, xlfd_name, n - 11);
+                s[n - 11] = '\0';
+                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));
+                goto done;
             }
         }
 
-        if(head) {
-            if(!slant)
-                slant = head->Mac_Style & 2 ? "i" : "r";
-            if(!weight)
-                weight = head->Mac_Style & 1 ? "bold" : "medium";
-        }
+        if(!have_face) {
+            ftrc = FT_New_Face(ft_library, filename, 0, &face);
+            if(ftrc)
+                goto done;
+            have_face = 1;
+            isBitmap = ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0);
 
-        if(!slant) {
-            fprintf(stderr, "Couldn't determine slant for %s\n", filename);
-            slant = "r";
+            if(!isBitmap) {
+                if(face->num_fixed_sizes > 0) {
+                    TT_MaxProfile *maxp;
+                    maxp = FT_Get_Sfnt_Table(face, ft_sfnt_maxp);
+                    if(maxp != NULL && maxp->maxContours == 0)
+                        isBitmap = 1;
+                }
+            }
         }
 
-        if(!weight) {
-            fprintf(stderr, "Couldn't determine weight for %s\n", filename);
-            weight = "medium";
-        }
+        if(xlfd == NULL)
+            xlfd = makeXLFD(entry->d_name, face, isBitmap);
 
-        if(!foundry) {
-            char *notice;
-            notice = getName(face, TT_NAME_ID_TRADEMARK);
-            if(notice) {
-                foundry = notice_foundry(notice);
+        found = 0;
+
+        for(lp = xlfd; lp; lp = lp->next) {
+            char buf[MAXFONTNAMELEN];
+            for(encoding = encodings; encoding; encoding = encoding->next) {
+                if(checkEncoding(face, encoding->value)) {
+                    found = 1;
+                    snprintf(buf, MAXFONTNAMELEN, "%s-%s",
+                            lp->value, encoding->value);
+                    putHash(entries, buf, entry->d_name, 
filePrio(entry->d_name));
+                }
             }
-            if(!foundry) {
-                notice = getName(face, TT_NAME_ID_MANUFACTURER);
-                if(notice) {
-                    foundry = notice_foundry(notice);
+            for(encoding = extra_encodings; encoding; 
+                encoding = encoding->next) {
+                if(checkExtraEncoding(face, encoding->value, found)) {
+                    /* Do not set found! */
+                    snprintf(buf, MAXFONTNAMELEN, "%s-%s",
+                            lp->value, encoding->value);
+                    putHash(entries, buf, entry->d_name, 
filePrio(entry->d_name));
                 }
             }
         }
-
-        if(strcmp(slant, "i") == 0) {
-            if(strstr(full_name, "Oblique"))
-                slant = "o";
-            if(strstr(full_name, "Slanted"))
-                slant = "o";
+    done:
+        if(have_face) {
+            FT_Done_Face(face);
+            have_face = 0;
         }
-
-        if(!sWidth)
-            sWidth = nameWidth(full_name);
-
-        if(!foundry) foundry = "misc";
-        if(!family) {
-            fprintf(stderr, "Couldn't get family name for %s\n", filename);
-            family = entry->d_name;
-        }
-
-        if(!weight) weight = "medium";
-        if(!slant) slant = "r";
-        if(!sWidth) sWidth = "normal";
-        if(!adstyle) adstyle = "";
-        if(!spacing) spacing = "p";
-
-        /* Yes, it's a memory leak. */
-        foundry = safe(foundry);
-        family = safe(family);
-
-        for(encoding = encodings; encoding; encoding = encoding->next)
-            if(checkEncoding(face, encoding->value)) {
-                found = 1;
-                entries = listConsF(entries,
-                                    "%s -%s-%s-%s-%s-%s-%s-0-0-0-0-%s-0-%s",
-                                    entry->d_name,
-                                    foundry, family, 
-                                    weight, slant, sWidth, adstyle, spacing,
-                                    encoding->value);
-            }
-        for(encoding = extra_encodings; encoding; encoding = encoding->next)
-            if(checkExtraEncoding(face, encoding->value, found)) {
-                /* Do not set found! */
-                entries = listConsF(entries,
-                                    "%s -%s-%s-%s-%s-%s-%s-0-0-0-0-%s-0-%s",
-                                    entry->d_name,
-                                    foundry, family, 
-                                    weight, slant, sWidth, adstyle, spacing,
-                                    encoding->value);
-            }
+        deepDestroyList(xlfd);
+        xlfd = NULL;
         free(filename);
     }
-    entries = reverseList(entries);
-    fprintf(fontscale, "%d\n", listLength(entries));
-    while(entries) {
-        fprintf(fontscale, "%s\n", entries->value);
-        entries = entries->next;
-    }
-    deepDestroyList(entries);
+
+    closedir(dirp);
+    n = hashElements(entries);
+    fprintf(fontscale, "%d\n", n);
+    array = hashArray(entries, 1);
+    for(i = 0; i < n; i++)
+        fprintf(fontscale, "%s %s\n", array[i]->value, array[i]->key);
+    destroyHashArray(array);
+    entries = NULL;
     if(fontscale_name) {
         fclose(fontscale);
         free(fontscale_name);
@@ -983,6 +1190,7 @@
         fullname = dsprintf("%s/%s", dirname, file->d_name);
         if(fullname == NULL) {
             fprintf(stderr, "Couldn't allocate fullname\n");
+            closedir(dirp);
             return -1;
         }
         
@@ -996,18 +1204,21 @@
                 n = dsprintf("%s%s", encodingPrefix, fullname);
                 if(n == NULL) {
                     fprintf(stderr, "Couldn't allocate name\n");
+                    closedir(dirp);
                     return -1;
                 }
                 free(fullname);
                 fullname = n;
             }
-            encodingsToDo = acons(fullname, *name, encodingsToDo);
+            encodingsToDo = listConsF(encodingsToDo, "%s %s", fullname, *name);
             if(encodingsToDo == NULL) {
                 fprintf(stderr, "Couldn't allocate encodings\n");
+                closedir(dirp);
                 return -1;
             }
         }
         free(names);            /* only the spine */
     }
+    closedir(dirp);
     return 0;
 }

Added: people/jch/xc/programs/mkfontscale/hash.h
==============================================================================
--- people/jch/xc/programs/mkfontscale/hash.h   2003-06-05 13:30:06 UTC (rev 
146)
+++ people/jch/xc/programs/mkfontscale/hash.h   2003-06-05 16:54:39 UTC (rev 
147)
@@ -0,0 +1,37 @@
+/*
+  Copyright (c) 2003 by Juliusz Chroboczek
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+*/
+
+typedef struct _HashBucket {
+    char *key;
+    char *value;
+    int prio;
+    struct _HashBucket *next;
+} HashBucketRec, *HashBucketPtr;
+
+typedef HashBucketPtr* HashTablePtr;
+
+HashTablePtr makeHashTable(void);
+void destroyHashTable(HashTablePtr table);
+char *getHash(HashTablePtr table, char *key);
+int putHash(HashTablePtr table, char *key, char *value, int prio);
+int hashElements(HashTablePtr table);
+HashBucketPtr *hashArray(HashTablePtr table, int value_first);

Added: people/jch/xc/programs/mkfontscale/ident.h
==============================================================================
--- people/jch/xc/programs/mkfontscale/ident.h  2003-06-05 13:30:06 UTC (rev 
146)
+++ people/jch/xc/programs/mkfontscale/ident.h  2003-06-05 16:54:39 UTC (rev 
147)
@@ -0,0 +1,26 @@
+/*
+  Copyright (c) 2003 by Juliusz Chroboczek
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+*/
+
+int bitmapIdentify(char *filename, char **xlfd);
+    
+
+    

Modified: people/jch/xc/programs/mkfontscale/list.c
==============================================================================
--- people/jch/xc/programs/mkfontscale/list.c   2003-06-05 13:30:06 UTC (rev 
146)
+++ people/jch/xc/programs/mkfontscale/list.c   2003-06-05 16:54:39 UTC (rev 
147)
@@ -231,11 +231,10 @@
     ListPtr next;
     if(!old)
         return;
-    next = old->next;
     while(old) {
+        next = old->next;
         free(old);
         old = next;
-        next = old->next;
     }
 }
 
@@ -245,97 +244,10 @@
     ListPtr next;
     if(!old)
         return;
-    next = old->next;
     while(old) {
+        next = old->next;
         free(old->value);
         free(old);
         old = next;
-        next = old->next;
     }
 }
-
-AcellPtr
-acell(ListPtr alist)
-{
-     return (AcellPtr)alist->value;
-}
-
-AcellPtr
-assoc(char *key, ListPtr alist)
-{
-    ListPtr l;
-    AcellPtr acell;
-    l = alist;
-    while(l) {
-        acell = (AcellPtr)l->value;
-        if(strcmp(acell->key, key) == 0)
-            return acell;
-        l = l->next;
-    }
-    return NULL;
-}
-
-ListPtr
-acons(char *key, char *value, ListPtr alist)
-{
-    AcellPtr acell;
-    acell = malloc(sizeof(AcellRec));
-    if(acell == NULL)
-        return NULL;
-    acell->key = key;
-    acell->value = value;
-    acell->prio = 0;
-    return listCons((char*)acell, alist);
-}
-
-ListPtr
-aconsPrio(char *key, char *value, int prio, ListPtr alist)
-{
-    ListPtr l;
-    AcellPtr acell;
-    l = alist;
-    while(l) {
-        acell = (AcellPtr)l->value;
-        if(strcmp(acell->key, key) == 0)
-            break;
-        l = l->next;
-    }
-    if(l && acell->prio >= prio)
-        return alist;
-
-    acell = malloc(sizeof(AcellRec));
-    if(acell == NULL)
-        return NULL;
-    acell->key = key;
-    acell->value = value;
-    acell->prio = prio;
-    return listCons((char*)acell, alist);
-}                   
-
-void 
-destroyAlist(ListPtr old)
-{
-    return deepDestroyList(old);
-}
-
-void 
-deepDestroyAlist(ListPtr old)
-{
-    ListPtr next;
-    AcellPtr acell;
-
-    if(!old)
-        return;
-    next = old->next;
-    while(old) {
-        acell = (AcellPtr)old->value;
-        free(acell->key);
-        free(acell->value);
-        free(acell);
-        free(old);
-        old = next;
-        next = old->next;
-    }
-}
-
-    

Reply via email to