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: