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

X Strike Force SVN commit: rev 128 - people/jch/xc/lib/font/fontfile



Author: jch
Date: 2003-06-02 16:31:08 -0500 (Mon, 02 Jun 2003)
New Revision: 128

Added:
   people/jch/xc/lib/font/fontfile/fcfpe.c
Modified:
   people/jch/xc/lib/font/fontfile/Imakefile
   people/jch/xc/lib/font/fontfile/register.c
Log:
Add preliminary version of fontconfig-based FPE.

Modified: people/jch/xc/lib/font/fontfile/Imakefile
==============================================================================
--- people/jch/xc/lib/font/fontfile/Imakefile	2003-06-02 21:19:01 UTC (rev 127)
+++ people/jch/xc/lib/font/fontfile/Imakefile	2003-06-02 21:31:08 UTC (rev 128)
@@ -14,7 +14,7 @@
 #endif
 
    INCLUDES = -I$(FONTINCSRC) -I../include -I$(SERVERSRC)/include \
-	      -I$(INCLUDESRC)
+	      -I$(INCLUDESRC) -I/usr/include/fontconfig
     HEADERS = 
 #ifdef FontFormatDefines
 FORMAT_DEFS = FontFormatDefines
@@ -60,11 +60,11 @@
        SRCS = dirfile.c fontdir.c fontfile.c fileio.c fontscale.c \
               defaults.c bitsource.c register.c renderers.c bufio.c \
               decompress.c filewr.c printerfont.c ffcheck.c \
-	      fontenc.c encparse.c $(COMPAT_SRC) $(GUNZIP_SRC)
+	      fontenc.c encparse.c fcfpe.c $(COMPAT_SRC) $(GUNZIP_SRC)
        OBJS = dirfile.o fontdir.o fontfile.o fileio.o fontscale.o \
               defaults.o bitsource.o register.o renderers.o bufio.o \
               decompress.o filewr.o printerfont.o ffcheck.o \
-              fontenc.o encparse.o $(COMPAT_OBJ) $(GUNZIP_OBJ)
+              fontenc.o encparse.o fcfpe.o $(COMPAT_OBJ) $(GUNZIP_OBJ)
 
 #define DoNormalLib NormalLibFont
 #define DoSharedLib SharedLibFont

Added: people/jch/xc/lib/font/fontfile/fcfpe.c
==============================================================================
--- people/jch/xc/lib/font/fontfile/fcfpe.c	2003-06-02 21:19:01 UTC (rev 127)
+++ people/jch/xc/lib/font/fontfile/fcfpe.c	2003-06-02 21:31:08 UTC (rev 128)
@@ -0,0 +1,833 @@
+/*
+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 "fontconfig.h"
+#include "fntfilst.h"
+
+static struct {
+    char *lang;
+    char *encoding
+} langEncodings[] = {
+    {"fr", "iso8859-1"},
+    {"pl", "iso8859-2"},
+    {"eo", "iso8859-3"},
+    {"lt", "iso8859-4"},
+    {"ru", "iso8859-5"},
+    {"el", "iso8859-7"},
+    {"he", "iso8859-8"},
+    {"tr", "iso8859-9"},
+    {"lt", "iso8859-13"},
+    {"ga", "iso8859-14"},
+    {"fr", "iso8859-15"},
+    {"ru", "koi8-r"},
+    {"zh-cn", "gb2312.1980-0"},
+    {"zh-tw", "big5-0"},
+    {"jp", "jisx0201.1976-0"}, 
+    {"jp", "jisx0208.1990-0"},
+    {"ko", "ksc5601.1987-0"},
+    {NULL, "iso10646-1"},
+};
+
+#define NUMENCODINGS (sizeof(langEncodings) / sizeof(langEncodings[0]))
+
+static int
+lwr(char x)
+{
+    if('A' <= x && x <= 'Z')
+        return x - 'A' + 'a';
+    else
+        return x;
+}
+
+static int
+lower(char *p)
+{
+    while(*p) {
+        *p = lwr(*p);
+        p++;
+    }
+}
+
+static int
+compare(char *a, char *b)
+{
+    while(*a && *b) {
+        if(lwr(*a) != lwr(*b))
+            return 0;
+        a++; b++;
+    }
+    return (*a == 0 && *b == 0);
+}
+
+static char *
+getString(FcPattern *pat, const char *ob, char *def)
+{
+    FcResult res;
+    FcChar8 *r;
+    res = FcPatternGetString(pat, ob, 0, &r);
+    if(res != FcResultMatch || r == NULL)
+        return def;
+    return (char*)r;
+}
+
+static int
+getInteger(FcPattern *pat, const char *ob, int def)
+{
+    FcResult res;
+    int r;
+    res = FcPatternGetInteger(pat, ob, 0, &r);
+    if(res != FcResultMatch)
+        return def;
+    return r;
+}
+
+static int
+getDouble(FcPattern *pat, const char *ob, double def)
+{
+    FcResult res;
+    double r;
+    res = FcPatternGetDouble(pat, ob, 0, &r);
+    if(res != FcResultMatch)
+        return def;
+    return r;
+}
+
+static char *
+getWeight(FcPattern *pat)
+{
+    int w = getInteger(pat, FC_WEIGHT, FC_WEIGHT_REGULAR);
+    if(w <= FC_WEIGHT_THIN)
+        return "thin";
+    else if(w <= FC_WEIGHT_EXTRALIGHT)
+        return "extralight";
+    else if(w <= FC_WEIGHT_LIGHT)
+        return "light";
+    else if(w <= FC_WEIGHT_MEDIUM)
+        return "medium";
+    else if(w <= FC_WEIGHT_SEMIBOLD)
+        return "semibold";
+    else if(w <= FC_WEIGHT_BOLD)
+        return "bold";
+    else if(w <= FC_WEIGHT_EXTRABOLD)
+        return "extrabold";
+    else 
+        return "black";
+}
+
+static char *
+getSlant(FcPattern *pat)
+{
+    int s = getInteger(pat, FC_SLANT, FC_SLANT_ROMAN);
+    switch(s) {
+    case FC_SLANT_ITALIC: return "i";
+    case FC_SLANT_OBLIQUE: return "o";
+    default: return "r";
+    }
+}
+
+static char *
+getWidth(FcPattern *pat)
+{
+    int w = getInteger(pat, FC_WIDTH, FC_WIDTH_NORMAL);
+    if(w <= FC_WIDTH_ULTRACONDENSED)
+        return "ultracondensed";
+    else if(w <= FC_WIDTH_EXTRACONDENSED)
+        return "extracondensed";
+    else if(w <= FC_WIDTH_CONDENSED)
+        return "condensed";
+    else if(w <= FC_WIDTH_SEMICONDENSED)
+        return "semicondensed";
+    else if(w <= FC_WIDTH_NORMAL)
+        return "normal";
+    else if(w <= FC_WIDTH_SEMIEXPANDED)
+        return "semiexpanded";
+    else if(w <= FC_WIDTH_EXPANDED)
+        return "expanded";
+    else if(w <= FC_WIDTH_EXTRAEXPANDED)
+        return "extraexpanded";
+    else
+        return "ultraexpanded";
+}
+
+int
+FcPatternHasLang(FcPattern *pat, char *lang)
+{
+    FcResult res;
+    FcLangResult lr;
+    FcLangSet *r;
+    res = FcPatternGetLangSet(pat, FC_LANG, 0, &r);
+    if(res != FcResultMatch) {
+        return 0;
+    }
+    lr = FcLangSetHasLang(r, (FcChar8*)lang);
+    return (lr < FcLangDifferentLang);
+}
+
+char *
+encodingLang(char *encoding)
+{
+    int i, j;
+    i = 0;
+    for(i = 0; i < NUMENCODINGS; i++) {
+        if(compare(langEncodings[i].encoding, encoding))
+            return langEncodings[i].lang;
+    }
+    return NULL;
+}
+
+char *
+FcXLFD(FcPattern *pat, int i)
+{
+    static char buf[MAXFONTNAMELEN];
+    int n;
+    char *foundry, *family, *weight, *slant, *width, *adstyle, *spacing;
+    double pxlsize, size;
+    int dpi, decipoints, awidth;
+
+    if(i >= NUMENCODINGS)
+        return NULL;
+
+    if(langEncodings[i].lang && !FcPatternHasLang(pat, langEncodings[i].lang))
+        return NULL;
+
+    foundry = getString(pat, FC_FOUNDRY, "misc");
+    family = getString(pat, FC_FAMILY, "unknown");
+    weight = getWeight(pat);
+    slant = getSlant(pat);
+    width = getWidth(pat);
+
+    adstyle = "";
+    pxlsize = getDouble(pat, FC_PIXEL_SIZE, 0.0);
+    if(pxlsize == 0.0) {
+        size = 0.0;
+        decipoints = 0;
+        dpi = 0;
+        awidth = 0;
+    } else {
+        size = getDouble(pat, FC_SIZE, 0.0);
+        dpi = (int)(getDouble(pat, FC_DPI, 0.0) + 0.5);
+        if(size != 0.0) {
+            decipoints = (int)(size * 10 + 0.5);
+            if(dpi == 0)
+                dpi = (int)(pxlsize / size * 72.0 + 0.5);
+        } else {
+            if(dpi == 0)
+                dpi = 100.0;
+            decipoints = (int)(pxlsize / dpi * 72 * 10 + 0.5);
+        }
+        awidth = 0;
+        /* Implement awidth in fontconfig */
+        if(awidth == 0) {
+            int w = getInteger(pat, FC_WIDTH, FC_WIDTH_NORMAL);
+            awidth = 
+                (int)(pxlsize / 13 * 
+                      ((w - FC_WIDTH_SEMICONDENSED) / 
+                       (double)(FC_WIDTH_NORMAL - FC_WIDTH_SEMICONDENSED)) *
+                      20 + 60);
+       }
+    }
+
+    switch(getInteger(pat, FC_SPACING, FC_PROPORTIONAL)) {
+    case FC_MONO: spacing = "m"; break;
+    case FC_CHARCELL: spacing = "c"; break;
+    default: spacing = "p"; break;
+    }
+
+    if(pxlsize == 0)
+        dpi = 0;
+
+    n = snprintf(buf, MAXFONTNAMELEN,
+                 "-%s-%s-%s-%s-%s-%s"
+                 "-%d-%d-%d-%d-%s-%d-%s",
+                 foundry, family, weight, slant, width, adstyle,
+                 (int)(pxlsize + 0.5), decipoints, dpi, dpi,
+                 spacing, awidth, langEncodings[i].encoding);
+    if(n >= MAXFONTNAMELEN)
+        return NULL;
+    lower(buf);
+    return buf;
+}
+
+
+/* It is impossible in general to provide an FcPattern equivalent to
+   an XLFD pattern (what does "*-100-*" mean?).  The following returns
+   an FcPattern that corresponds to a superset of the XLFD pattern;
+   this assumes that any noise will be filtered out later. */
+FcPattern *
+XLFDPattern(char *xlfd)
+{
+    int i, j, k, n, ndashes, val;
+    char *foundry;
+    char buf[MAXFONTNAMELEN];
+    FcPattern *pat;
+
+    pat = FcPatternCreate();
+    if(pat == NULL)
+        return NULL;
+
+    n = strlen(xlfd);
+    if(n < 1 || xlfd[0] != '-')
+        return pat;
+    ndashes = 0;
+    for(i = 0; i < n; i++)
+        if(xlfd[i] == '-')
+            ndashes++;
+    if(ndashes != 14)
+        return pat;
+
+    i = 0; j = 0;
+    for(k = 1; k < n; k++) {
+        if(xlfd[k] != '-' && xlfd[k] != '\0')
+            continue;
+        if(!memchr(xlfd + j + 1, '*', k - j - 1) &&
+           (k != j + 2 || xlfd[j + 1] != '0')) {
+            memcpy(buf, xlfd + j + 1, k - j - 1);
+            buf[k - j - 1] = '\0';
+            switch(i) {
+            case 0:
+                if(!compare(buf, "misc"))
+                    FcPatternAddString(pat, FC_FOUNDRY, buf);
+                break;
+            case 1:
+                FcPatternAddString(pat, FC_FAMILY, buf);
+                break;
+            case 2:
+                /* These entries can be incomplete, but any entries
+                privided must be consistent with getWeight and friends
+                above. */
+                if(compare(buf, "light"))
+                    FcPatternAddInteger(pat, FC_WEIGHT, FC_WEIGHT_LIGHT);
+                /* But unfortunately not medium and regular */
+                else if(compare(buf, "semibold"))
+                    FcPatternAddInteger(pat, FC_WEIGHT, FC_WEIGHT_SEMIBOLD);
+                else if(compare(buf, "bold"))
+                    FcPatternAddInteger(pat, FC_WEIGHT, FC_WEIGHT_BOLD);
+                else if(compare(buf, "black"))
+                    FcPatternAddInteger(pat, FC_WEIGHT, FC_WEIGHT_BLACK);
+                break;
+            case 3:
+                if(compare(buf, "r"))
+                    FcPatternAddInteger(pat, FC_SLANT, FC_SLANT_ROMAN);
+                else if(compare(buf, "i"))
+                    FcPatternAddInteger(pat, FC_SLANT, FC_SLANT_ITALIC);
+                else if(compare(buf, "o"))
+                    FcPatternAddInteger(pat, FC_SLANT, FC_SLANT_OBLIQUE);
+                break;
+            case 4:
+                if(compare(buf, "condensed"))
+                    FcPatternAddInteger(pat, FC_WIDTH, FC_WIDTH_CONDENSED);
+                else if(compare(buf, "semicondensed"))
+                    FcPatternAddInteger(pat, FC_WIDTH, FC_WIDTH_SEMICONDENSED);
+                /* But unfortunately not normal */
+                else if(compare(buf, "semiexpanded"))
+                    FcPatternAddInteger(pat, FC_WIDTH, FC_WIDTH_SEMIEXPANDED);
+                else if(compare(buf, "expanded"))
+                    FcPatternAddInteger(pat, FC_WIDTH, FC_WIDTH_EXPANDED);
+                break;
+            case 6:
+                val = atoi(buf);
+                if(val != 0)
+                    FcPatternAddDouble(pat, FC_PIXEL_SIZE, (double)val);
+                break;
+            case 12:
+                strcat(buf, xlfd + k);
+                if(!strchr(buf, '*')) {
+                    char *lang = encodingLang(buf);
+                    if(lang) {
+                        FcLangSet *ls;
+                        ls = FcLangSetCreate();
+                        if(ls) {
+                            FcLangSetAdd(ls, (FcChar8*)lang);
+                            FcPatternAddLangSet(pat, FC_LANG, ls);
+                        }
+                    }
+                }
+                break;
+            }
+        }
+        i++;
+        j = k;
+    }
+    return pat;
+}
+
+/* Copied from fontdir.c */
+static int
+PatternMatch(char *pat, int patdashes, char *string, int stringdashes)
+{
+    char        c,
+                t;
+
+    if (stringdashes < patdashes)
+	return 0;
+    for (;;) {
+	switch (c = *pat++) {
+	case '*':
+	    if (!(c = *pat++))
+		return 1;
+	    if (c == '-') {
+		patdashes--;
+		for (;;) {
+		    while ((t = *string++) != '-')
+			if (!t)
+			    return 0;
+		    stringdashes--;
+		    if (PatternMatch(pat, patdashes, string, stringdashes))
+			return 1;
+		    if (stringdashes == patdashes)
+			return 0;
+		}
+	    } else {
+		for (;;) {
+		    while ((t = *string++) != c) {
+			if (!t)
+			    return 0;
+			if (t == '-') {
+			    if (stringdashes-- < patdashes)
+				return 0;
+			}
+		    }
+		    if (PatternMatch(pat, patdashes, string, stringdashes))
+			return 1;
+		}
+	    }
+	case '?':
+	    if (*string++ == '-')
+		stringdashes--;
+	    break;
+	case '\0':
+	    return (*string == '\0');
+	case '-':
+	    if (*string++ == '-') {
+		patdashes--;
+		stringdashes--;
+		break;
+	    }
+	    return 0;
+	default:
+	    if (c == *string++)
+		break;
+	    return 0;
+	}
+    }
+}
+                
+
+static FcObjectSet *objectSet = NULL, *objectSetF = NULL;
+static FontScalableRec defaults;
+
+int
+FontConfigNameCheck(char *name)
+{
+    if(strcmp(name, "fontconfig") == 0)
+        return 1;
+    return 0;
+}
+
+int
+FontConfigInitFPE(FontPathElementPtr fpe)
+{
+    int rc;
+    rc = FcInit();
+    if(!rc)
+        return BadFontPath;
+
+    if(objectSet == NULL)
+        objectSet = 
+            FcObjectSetBuild(FC_FAMILY, FC_FOUNDRY, FC_STYLE,
+                             FC_SIZE, FC_PIXEL_SIZE, FC_DPI,
+                             FC_SPACING, FC_WEIGHT, FC_SLANT, FC_WIDTH, 
+                             FC_SPACING, FC_LANG, 0);
+    if(objectSet == NULL)
+        return AllocError;
+    if(objectSetF == NULL)
+        objectSetF = 
+            FcObjectSetBuild(FC_FAMILY, FC_FOUNDRY, FC_STYLE,
+                             FC_SIZE, FC_PIXEL_SIZE, FC_DPI,
+                             FC_SPACING, FC_WEIGHT, FC_SLANT, FC_WIDTH, 
+                             FC_SPACING, FC_LANG, FC_FILE, 0);
+    if(objectSetF == NULL)
+        return AllocError;
+
+    defaults.point_matrix[0] = defaults.point_matrix[3] = 13.0;
+    defaults.point_matrix[1] = defaults.point_matrix[2] = 0.0;
+    defaults.values_supplied = POINTSIZE_SCALAR | PIXELSIZE_UNDEFINED;
+    defaults.width = -1;
+    defaults.x = defaults.y = 75;
+    FontFileCompleteXLFD(&defaults, &defaults);
+
+    return Successful;
+}
+
+int
+FontConfigResetFPE(FontPathElementPtr fpe)
+{
+    int rc;
+    rc = FcInitReinitialize();
+    if(!rc)
+        return BadFontPath;
+    return Successful;
+}
+
+int
+FontConfigFreeFPE(FontPathElementPtr fpe)
+{
+    int rc;
+    FcObjectSetDestroy(objectSet);
+    objectSet = NULL;
+    FcObjectSetDestroy(objectSetF);
+    objectSetF = NULL;
+    rc = FcInitReinitialize();
+    return Successful;
+}
+
+int
+FontConfigOpenFont(pointer client, FontPathElementPtr fpe, Mask flags, 
+                   char *name, int namelen, 
+                   fsBitmapFormat format, fsBitmapFormatMask fmask,
+                   XID id, FontPtr *pFont, char **aliasName, 
+                   FontPtr non_cachable_font)
+{
+    FcPattern *pat = NULL;
+    FcFontSet *set = NULL;
+    char tmpName[MAXFONTNAMELEN];
+    int ndashes = FontFileCountDashes(name, namelen);
+    char *xlfd, *filename;
+    int i, j, ret, rc;
+    FontRendererPtr renderer;
+    FontEntryRec entry;
+    FontScalableRec vals;
+
+    if(namelen >= MAXFONTNAMELEN)
+        goto fail;
+
+    CopyISOLatin1Lowered(tmpName, name, namelen);
+    tmpName[namelen] = '\0';
+
+    pat = XLFDPattern(tmpName);
+    if(pat == NULL)
+        goto fail;
+        
+    set = FcFontList(NULL, pat, objectSetF);
+    if(set == NULL) goto fail;
+
+    ret = BadFontName;
+    for(i = 0; i < set->nfont; i++) {
+        for(j = 0; j < NUMENCODINGS; j++) {
+            xlfd = FcXLFD(set->fonts[i], j);
+            if(xlfd == NULL) continue;
+            if(!PatternMatch(tmpName, ndashes, xlfd, 14)) continue;
+            filename = getString(set->fonts[i], FC_FILE, NULL);
+            if(!filename) continue;
+            renderer = FontFileMatchRenderer(filename);
+            if(!renderer) continue;
+            if(!renderer->OpenScalable) continue;
+            entry.name.name = xlfd;
+            entry.name.length = strlen(xlfd);
+            entry.name.ndashes = 14;
+            entry.type = FONT_ENTRY_SCALABLE;
+            entry.u.scalable.renderer = renderer;
+            entry.u.scalable.fileName = filename;
+            entry.u.scalable.extra = NULL;
+            rc = FontParseXLFDName(xlfd, &vals, FONT_XLFD_REPLACE_NONE);
+            if(rc) {
+                FontFileCompleteXLFD(&vals, &defaults);
+                ret = 
+                    renderer->OpenScalable(fpe, pFont, flags, &entry, filename,
+                                           &vals, format, fmask,
+                                           non_cachable_font);
+            } else {
+                ret = BadFontName;
+            }
+            if(ret == Successful) {
+                if(*pFont) {
+                    (*pFont)->fpe = fpe;
+                    goto done;
+                } else {
+                    ret = BadFontName;
+                }
+            }
+        }
+    }
+ done:
+    FcFontSetDestroy(set);
+    FcPatternDestroy(pat);    
+    return ret;
+
+ fail:
+    if(set) FcFontSetDestroy(set);
+    if(pat) FcPatternDestroy(pat);
+    return AllocError;
+}
+
+void
+FontConfigCloseFont(FontPathElementPtr fpe, FontPtr pFont)
+{
+    pFont->unload_font(pFont);
+}
+
+int
+FontConfigListFontsFilenames(pointer client, FontPathElementPtr fpe,
+                             char *name, int namelen, int max, 
+                             FontNamesPtr names, FontNamesPtr filenames)
+{
+    char *xlfd;
+    FcPattern *pat = NULL;
+    FcFontSet *set = NULL;
+    int ndashes = FontFileCountDashes(name, namelen);
+    int i, j, n;
+    int ret;
+    char tmpName[MAXFONTNAMELEN];
+
+    if(namelen >= MAXFONTNAMELEN)
+        goto fail;
+    CopyISOLatin1Lowered(tmpName, name, namelen);
+    tmpName[namelen] = '\0';
+    
+    pat = XLFDPattern(tmpName);
+    if(pat == NULL)
+        goto fail;
+
+    set = FcFontList(NULL, pat, filenames ? objectSetF : objectSet);
+    if(set == NULL) goto fail;
+
+    n = 0;
+    ret = Successful;
+    for(i = 0; i < set->nfont; i++) {
+        if(n >= max)
+            break;
+        for(j = 0; j < NUMENCODINGS; j++) {
+            xlfd = FcXLFD(set->fonts[i], j);
+            if(xlfd == NULL)
+                continue;
+            if(!PatternMatch(tmpName, ndashes, xlfd, 14)) continue;
+            ret = AddFontNamesName(names, xlfd, strlen(xlfd));
+            if(ret != Successful)
+                goto done;
+            if(filenames) {
+                char *filename = getString(pat, FC_FILE, NULL);
+                if(!filename) {
+                    ret = AllocError;
+                    goto done;
+                }
+                ret = AddFontNamesName(filenames, filename, strlen(filename));
+                if(ret != Successful)
+                    break;
+            }
+        }
+    }
+ done:
+    FcFontSetDestroy(set);
+    FcPatternDestroy(pat);
+    return ret;
+
+ fail:
+    if(set) FcFontSetDestroy(set);
+    if(pat) FcPatternDestroy(pat);
+    return AllocError;
+}
+
+int
+FontConfigListFonts(pointer client, FontPathElementPtr fpe, char *name, 
+                    int namelen, int max, FontNamesPtr names)
+{
+    return FontConfigListFontsFilenames(client, fpe, name, namelen,
+                                        max, names, NULL);
+}
+
+typedef struct _ListData {
+    FontNamesPtr names;
+    FontNamesPtr filenames;
+    int current;
+} ListDataRec, *ListDataPtr;
+
+int
+FontConfigStartListFontsWithInfo(pointer client, FontPathElementPtr fpe, 
+                                 char *pat, int len, int max, 
+                                 pointer *privatep)
+{
+    ListDataPtr data;
+    int ret;
+
+    data = xalloc(sizeof(ListDataRec));
+    if(!data) return AllocError;
+    data->names = MakeFontNamesRecord(0);
+    if(!data->names) {
+        xfree(data);
+        return AllocError;
+    }
+    data->filenames = MakeFontNamesRecord(0);
+    if(!data->filenames) {
+        FreeFontNames(data->names);
+        xfree(data);
+        return AllocError;
+    }
+    ret = FontConfigListFontsFilenames(client, fpe, pat, len, max,
+                                       data->names, data->filenames);
+    if(ret != Successful) {
+        FreeFontNames(data->filenames);
+        FreeFontNames(data->names);
+        xfree(data);
+        return ret;
+    }
+    data->current = 0;
+    *privatep = data;
+    return Successful;
+}
+
+int
+FontConfigListNextFontWithInfo(pointer client, FontPathElementPtr fpe, 
+                               char **namep, int *namelenp, 
+                               FontInfoPtr *pFontInfo,
+                               int *numFonts, pointer private)
+{
+    ListDataPtr data = private;
+    char *name, *filename;
+    int namelen;
+    int ret, rc;
+    FontRendererPtr renderer;
+    FontEntryRec entry;
+    FontScalableRec vals;
+    FontNameRec tmpName;
+
+    if(data->current >= data->names->nnames) {
+        FreeFontNames(data->filenames);
+        FreeFontNames(data->names);
+        xfree(data);
+        return BadFontName;
+    }
+    name = data->names->names[data->current];
+    namelen = data->names->length[data->current];
+    filename = data->filenames->names[data->current];
+    renderer = FontFileMatchRenderer(filename);
+    if(!renderer) goto fail;
+    if(!renderer->GetInfoScalable) goto fail;
+    entry.name.name = name;
+    entry.name.length = strlen(name);
+    entry.name.ndashes = 14;
+    entry.type = FONT_ENTRY_SCALABLE;
+    entry.u.scalable.renderer = renderer;
+    entry.u.scalable.fileName = filename;
+    entry.u.scalable.extra = NULL;
+    tmpName.name = name;
+    tmpName.length = namelen;
+    tmpName.ndashes = 14;
+    rc = FontParseXLFDName(name, &vals, FONT_XLFD_REPLACE_NONE);
+    if(rc) {
+        FontFileCompleteXLFD(&vals, &defaults);
+        ret = renderer->GetInfoScalable(fpe, *pFontInfo, &entry,
+                                        &tmpName, filename, &vals);
+    } else {
+        ret = BadFontName;
+    }
+    if(ret == BadFontName)
+        ret = AllocError;
+    *namep = name;
+    *namelenp = namelen;
+    ++data->current;
+    *numFonts = data->names->nnames - data->current;
+    return ret;
+
+ fail:
+    *namep = name;
+    *namelenp = namelen;
+    ++data->current;
+    *numFonts = data->names->nnames - data->current;
+    return AllocError;
+}
+
+int
+FontConfigStartListFontsAndAliases(pointer client, FontPathElementPtr fpe, 
+                                   char *pat, int len, int max, 
+                                   pointer *privatep)
+{
+    ListDataPtr data;
+    int ret;
+
+    data = xalloc(sizeof(ListDataRec));
+    if(!data) return AllocError;
+    data->names = MakeFontNamesRecord(0);
+    if(!data->names) {
+        xfree(data);
+        return AllocError;
+    }
+    data->filenames = NULL;
+    ret = FontConfigListFonts(client, fpe, pat, len, max, data->names);
+    if(ret != Successful) {
+        FreeFontNames(data->names);
+        xfree(data);
+        return ret;
+    }
+    data->current = 0;
+    *privatep = data;
+    return Successful;
+}
+
+int
+FontConfigListNextFontOrAlias(pointer client, FontPathElementPtr fpe, 
+                              char **namep, int *namelenp, char **resolvedp,
+                              int *resolvedlenp, pointer private)
+{
+    ListDataPtr data = private;
+    char *name;
+    int namelen;
+
+    if(data->current >= data->names->nnames) {
+        FreeFontNames(data->names);
+        xfree(data);
+        return BadFontName;
+    }
+    name = data->names->names[data->current];
+    namelen = data->names->length[data->current];
+    *namep = name;
+    *namelenp = namelen;
+    ++data->current;
+    return Successful;
+}
+
+static int font_config_type;
+
+void
+FontConfigEmptyBitmapSource(void)
+{
+    return;
+}
+
+void
+FontConfigRegisterFpeFunctions()
+{
+    font_config_type = RegisterFPEFunctions(FontConfigNameCheck,
+                                            FontConfigInitFPE,
+                                            FontConfigFreeFPE,
+                                            FontConfigResetFPE,
+                                            FontConfigOpenFont,
+                                            FontConfigCloseFont,
+                                            FontConfigListFonts,
+                                            FontConfigStartListFontsWithInfo,
+                                            FontConfigListNextFontWithInfo,
+                                            NULL, /* wakeup_fpe */
+                                            NULL, /* client_died */
+                                            NULL, /* load_glyphs */
+                                            FontConfigStartListFontsAndAliases,
+                                            FontConfigListNextFontOrAlias,
+                                            FontConfigEmptyBitmapSource);
+}

Modified: people/jch/xc/lib/font/fontfile/register.c
==============================================================================
--- people/jch/xc/lib/font/fontfile/register.c	2003-06-02 21:19:01 UTC (rev 127)
+++ people/jch/xc/lib/font/fontfile/register.c	2003-06-02 21:31:08 UTC (rev 128)
@@ -83,5 +83,6 @@
 #endif
 
     FontFileRegisterLocalFpeFunctions ();
+    FontConfigRegisterFpeFunctions ();
 }
 



Reply to: