/*
 * fontconfig/src/fccfg.c
 *
 * Copyright © 2000 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of the author(s) not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  The authors make no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/* Objects MT-safe for readonly access. */

#include "fcint.h"
#include <dirent.h>
#include <sys/types.h>

#if defined (_WIN32) && !defined (R_OK)
#define R_OK 4
#endif

static FcConfig    *_fcConfig; /* MT-safe */

static FcConfig *
FcConfigEnsure (void)
{
    FcConfig	*config;
retry:
    config = fc_atomic_ptr_get (&_fcConfig);
    if (!config)
    {
	config = FcInitLoadConfigAndFonts ();

	if (!fc_atomic_ptr_cmpexch (&_fcConfig, NULL, config)) {
	    FcConfigDestroy (config);
	    goto retry;
	}
    }
    return config;
}

FcBool
FcConfigInit (void)
{
  return FcConfigEnsure () ? FcTrue : FcFalse;
}

void
FcConfigFini (void)
{
    FcConfig *cfg = fc_atomic_ptr_get (&_fcConfig);
    if (cfg && fc_atomic_ptr_cmpexch (&_fcConfig, cfg, NULL))
	FcConfigDestroy (cfg);
}


FcConfig *
FcConfigCreate (void)
{
    FcSetName	set;
    FcConfig	*config;

    config = malloc (sizeof (FcConfig));
    if (!config)
	goto bail0;

    config->configDirs = FcStrSetCreate ();
    if (!config->configDirs)
	goto bail1;

    config->configFiles = FcStrSetCreate ();
    if (!config->configFiles)
	goto bail2;

    config->fontDirs = FcStrSetCreate ();
    if (!config->fontDirs)
	goto bail3;

    config->acceptGlobs = FcStrSetCreate ();
    if (!config->acceptGlobs)
	goto bail4;

    config->rejectGlobs = FcStrSetCreate ();
    if (!config->rejectGlobs)
	goto bail5;

    config->acceptPatterns = FcFontSetCreate ();
    if (!config->acceptPatterns)
	goto bail6;

    config->rejectPatterns = FcFontSetCreate ();
    if (!config->rejectPatterns)
	goto bail7;

    config->cacheDirs = FcStrSetCreate ();
    if (!config->cacheDirs)
	goto bail8;

    config->blanks = 0;

    config->substPattern = 0;
    config->substFont = 0;
    config->substScan = 0;
    config->maxObjects = 0;
    for (set = FcSetSystem; set <= FcSetApplication; set++)
	config->fonts[set] = 0;

    config->rescanTime = time(0);
    config->rescanInterval = 30;

    config->expr_pool = NULL;

    config->sysRoot = NULL;

    FcRefInit (&config->ref, 1);

    return config;

bail8:
    FcFontSetDestroy (config->rejectPatterns);
bail7:
    FcFontSetDestroy (config->acceptPatterns);
bail6:
    FcStrSetDestroy (config->rejectGlobs);
bail5:
    FcStrSetDestroy (config->acceptGlobs);
bail4:
    FcStrSetDestroy (config->fontDirs);
bail3:
    FcStrSetDestroy (config->configFiles);
bail2:
    FcStrSetDestroy (config->configDirs);
bail1:
    free (config);
bail0:
    return 0;
}

static FcFileTime
FcConfigNewestFile (FcStrSet *files)
{
    FcStrList	    *list = FcStrListCreate (files);
    FcFileTime	    newest = { 0, FcFalse };
    FcChar8	    *file;
    struct  stat    statb;

    if (list)
    {
	while ((file = FcStrListNext (list)))
	    if (FcStat (file, &statb) == 0)
		if (!newest.set || statb.st_mtime - newest.time > 0)
		{
		    newest.set = FcTrue;
		    newest.time = statb.st_mtime;
		}
	FcStrListDone (list);
    }
    return newest;
}

FcBool
FcConfigUptoDate (FcConfig *config)
{
    FcFileTime	config_time, config_dir_time, font_time;
    time_t	now = time(0);
    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return FcFalse;
    }
    config_time = FcConfigNewestFile (config->configFiles);
    config_dir_time = FcConfigNewestFile (config->configDirs);
    font_time = FcConfigNewestFile (config->fontDirs);
    if ((config_time.set && config_time.time - config->rescanTime > 0) ||
	(config_dir_time.set && (config_dir_time.time - config->rescanTime) > 0) ||
	(font_time.set && (font_time.time - config->rescanTime) > 0))
    {
	/* We need to check for potential clock problems here (OLPC ticket #6046) */
	if ((config_time.set && (config_time.time - now) > 0) ||
    	(config_dir_time.set && (config_dir_time.time - now) > 0) ||
        (font_time.set && (font_time.time - now) > 0))
	{
	    fprintf (stderr,
                    "Fontconfig warning: Directory/file mtime in the future. New fonts may not be detected.\n");
	    config->rescanTime = now;
	    return FcTrue;
	}
	else
	    return FcFalse;
    }
    config->rescanTime = now;
    return FcTrue;
}

static void
FcSubstDestroy (FcSubst *s)
{
    FcSubst *n;

    while (s)
    {
	n = s->next;
	if (s->rule)
	    FcRuleDestroy (s->rule);
	free (s);
	s = n;
    }
}

FcExpr *
FcConfigAllocExpr (FcConfig *config)
{
    if (!config->expr_pool || config->expr_pool->next == config->expr_pool->end)
    {
	FcExprPage *new_page;

	new_page = malloc (sizeof (FcExprPage));
	if (!new_page)
	    return 0;

	new_page->next_page = config->expr_pool;
	new_page->next = new_page->exprs;
	config->expr_pool = new_page;
    }

    return config->expr_pool->next++;
}

FcConfig *
FcConfigReference (FcConfig *config)
{
    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return 0;
    }

    FcRefInc (&config->ref);

    return config;
}

void
FcConfigDestroy (FcConfig *config)
{
    FcSetName	set;
    FcExprPage	*page;

    if (FcRefDec (&config->ref) != 1)
	return;

    (void) fc_atomic_ptr_cmpexch (&_fcConfig, config, NULL);

    FcStrSetDestroy (config->configDirs);
    FcStrSetDestroy (config->fontDirs);
    FcStrSetDestroy (config->cacheDirs);
    FcStrSetDestroy (config->configFiles);
    FcStrSetDestroy (config->acceptGlobs);
    FcStrSetDestroy (config->rejectGlobs);
    FcFontSetDestroy (config->acceptPatterns);
    FcFontSetDestroy (config->rejectPatterns);

    if (config->blanks)
	FcBlanksDestroy (config->blanks);

    FcSubstDestroy (config->substPattern);
    FcSubstDestroy (config->substFont);
    FcSubstDestroy (config->substScan);
    for (set = FcSetSystem; set <= FcSetApplication; set++)
	if (config->fonts[set])
	    FcFontSetDestroy (config->fonts[set]);

    page = config->expr_pool;
    while (page)
    {
      FcExprPage *next = page->next_page;
      free (page);
      page = next;
    }
    if (config->sysRoot)
	FcStrFree (config->sysRoot);

    free (config);
}

/*
 * Add cache to configuration, adding fonts and directories
 */

FcBool
FcConfigAddCache (FcConfig *config, FcCache *cache,
		  FcSetName set, FcStrSet *dirSet)
{
    FcFontSet	*fs;
    intptr_t	*dirs;
    int		i;

    /*
     * Add fonts
     */
    fs = FcCacheSet (cache);
    if (fs)
    {
	int	nref = 0;
	
	for (i = 0; i < fs->nfont; i++)
	{
	    FcPattern	*font = FcFontSetFont (fs, i);
	    FcChar8	*font_file;

	    /*
	     * Check to see if font is banned by filename
	     */
	    if (FcPatternObjectGetString (font, FC_FILE_OBJECT,
					  0, &font_file) == FcResultMatch &&
		!FcConfigAcceptFilename (config, font_file))
	    {
		continue;
	    }
		
	    /*
	     * Check to see if font is banned by pattern
	     */
	    if (!FcConfigAcceptFont (config, font))
		continue;
		
	    if (FcFontSetAdd (config->fonts[set], font))
		nref++;
	}
	FcDirCacheReference (cache, nref);
    }

    /*
     * Add directories
     */
    dirs = FcCacheDirs (cache);
    if (dirs)
    {
	for (i = 0; i < cache->dirs_count; i++)
	{
	    FcChar8	*dir = FcOffsetToPtr (dirs, dirs[i], FcChar8);
	    if (FcConfigAcceptFilename (config, dir))
		FcStrSetAddFilename (dirSet, dir);
	}
    }
    return FcTrue;
}

static FcBool
FcConfigAddDirList (FcConfig *config, FcSetName set, FcStrSet *dirSet)
{
    FcStrList	    *dirlist;
    FcChar8	    *dir;
    FcCache	    *cache;

    dirlist = FcStrListCreate (dirSet);
    if (!dirlist)
        return FcFalse;
	
    while ((dir = FcStrListNext (dirlist)))
    {
	if (FcDebug () & FC_DBG_FONTSET)
	    printf ("adding fonts from%s\n", dir);
	cache = FcDirCacheRead (dir, FcFalse, config);
	if (!cache)
	    continue;
	FcConfigAddCache (config, cache, set, dirSet);
	FcDirCacheUnload (cache);
    }
    FcStrListDone (dirlist);
    return FcTrue;
}

/*
 * Scan the current list of directories in the configuration
 * and build the set of available fonts.
 */

FcBool
FcConfigBuildFonts (FcConfig *config)
{
    FcFontSet	    *fonts;

    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return FcFalse;
    }
	
    fonts = FcFontSetCreate ();
    if (!fonts)
	return FcFalse;

    FcConfigSetFonts (config, fonts, FcSetSystem);

    if (!FcConfigAddDirList (config, FcSetSystem, config->fontDirs))
	return FcFalse;
    if (FcDebug () & FC_DBG_FONTSET)
	FcFontSetPrint (fonts);
    return FcTrue;
}

FcBool
FcConfigSetCurrent (FcConfig *config)
{
    FcConfig *cfg;

retry:
    cfg = fc_atomic_ptr_get (&_fcConfig);

    if (config == cfg)
	return FcTrue;

    if (config && !config->fonts[FcSetSystem])
	if (!FcConfigBuildFonts (config))
	    return FcFalse;

    if (!fc_atomic_ptr_cmpexch (&_fcConfig, cfg, config))
	goto retry;

    if (cfg)
	FcConfigDestroy (cfg);

    return FcTrue;
}

FcConfig *
FcConfigGetCurrent (void)
{
    return FcConfigEnsure ();
}

FcBool
FcConfigAddConfigDir (FcConfig	    *config,
		      const FcChar8 *d)
{
    return FcStrSetAddFilename (config->configDirs, d);
}

FcStrList *
FcConfigGetConfigDirs (FcConfig   *config)
{
    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return 0;
    }
    return FcStrListCreate (config->configDirs);
}

FcBool
FcConfigAddFontDir (FcConfig	    *config,
		    const FcChar8   *d)
{
    return FcStrSetAddFilename (config->fontDirs, d);
}

FcBool
FcConfigAddDir (FcConfig	    *config,
		const FcChar8	    *d)
{
    return (FcConfigAddConfigDir (config, d) &&
	    FcConfigAddFontDir (config, d));
}

FcStrList *
FcConfigGetFontDirs (FcConfig	*config)
{
    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return 0;
    }
    return FcStrListCreate (config->fontDirs);
}

FcBool
FcConfigAddCacheDir (FcConfig	    *config,
		     const FcChar8  *d)
{
    return FcStrSetAddFilename (config->cacheDirs, d);
}

FcStrList *
FcConfigGetCacheDirs (const FcConfig *config)
{
    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return 0;
    }
    return FcStrListCreate (config->cacheDirs);
}

FcBool
FcConfigAddConfigFile (FcConfig	    *config,
		       const FcChar8   *f)
{
    FcBool	ret;
    FcChar8	*file = FcConfigFilename (f);

    if (!file)
	return FcFalse;

    ret = FcStrSetAdd (config->configFiles, file);
    FcStrFree (file);
    return ret;
}

FcStrList *
FcConfigGetConfigFiles (FcConfig    *config)
{
    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return 0;
    }
    return FcStrListCreate (config->configFiles);
}

FcChar8 *
FcConfigGetCache (FcConfig  *config FC_UNUSED)
{
    return NULL;
}

FcFontSet *
FcConfigGetFonts (FcConfig	*config,
		  FcSetName	set)
{
    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return 0;
    }
    return config->fonts[set];
}

void
FcConfigSetFonts (FcConfig	*config,
		  FcFontSet	*fonts,
		  FcSetName	set)
{
    if (config->fonts[set])
	FcFontSetDestroy (config->fonts[set]);
    config->fonts[set] = fonts;
}

FcBlanks *
FcConfigGetBlanks (FcConfig	*config)
{
    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return 0;
    }
    return config->blanks;
}

FcBool
FcConfigAddBlank (FcConfig	*config,
		  FcChar32    	blank)
{
    FcBlanks	*b, *freeme = 0;

    b = config->blanks;
    if (!b)
    {
	freeme = b = FcBlanksCreate ();
	if (!b)
	    return FcFalse;
    }
    if (!FcBlanksAdd (b, blank))
    {
        if (freeme)
            FcBlanksDestroy (freeme);
	return FcFalse;
    }
    config->blanks = b;
    return FcTrue;
}

int
FcConfigGetRescanInterval (FcConfig *config)
{
    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return 0;
    }
    return config->rescanInterval;
}

FcBool
FcConfigSetRescanInterval (FcConfig *config, int rescanInterval)
{
    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return FcFalse;
    }
    config->rescanInterval = rescanInterval;
    return FcTrue;
}

/*
 * A couple of typos escaped into the library
 */
int
FcConfigGetRescanInverval (FcConfig *config)
{
    return FcConfigGetRescanInterval (config);
}

FcBool
FcConfigSetRescanInverval (FcConfig *config, int rescanInterval)
{
    return FcConfigSetRescanInterval (config, rescanInterval);
}

FcBool
FcConfigAddRule (FcConfig	*config,
		 FcRule		*rule,
		 FcMatchKind	kind)
{
    FcSubst	*subst, **prev;
    FcRule	*r;
    int		n = 0;

    if (!rule)
	return FcFalse;
    switch (kind) {
    case FcMatchPattern:
	prev = &config->substPattern;
	break;
    case FcMatchFont:
	prev = &config->substFont;
	break;
    case FcMatchScan:
	prev = &config->substScan;
	break;
    default:
	return FcFalse;
    }
    subst = (FcSubst *) malloc (sizeof (FcSubst));
    if (!subst)
	return FcFalse;
    for (; *prev; prev = &(*prev)->next);
    *prev = subst;
    subst->next = NULL;
    subst->rule = rule;
    for (r = rule; r; r = r->next)
    {
	switch (r->type)
	{
	case FcRuleTest:
	    if (r->u.test &&
		r->u.test->kind == FcMatchDefault)
		r->u.test->kind = kind;

	    if (n < r->u.test->object)
		n = r->u.test->object;
	    break;
	case FcRuleEdit:
	    if (n < r->u.edit->object)
		n = r->u.edit->object;
	    break;
	default:
	    break;
	}
    }
    n = FC_OBJ_ID (n) - FC_MAX_BASE_OBJECT;
    if (config->maxObjects < n)
	config->maxObjects = n;
    if (FcDebug () & FC_DBG_EDIT)
    {
	printf ("Add Subst ");
	FcSubstPrint (subst);
    }
    return FcTrue;
}

static FcValue
FcConfigPromote (FcValue v, FcValue u, FcValuePromotionBuffer *buf)
{
    if (v.type == FcTypeInteger)
    {
	v.type = FcTypeDouble;
	v.u.d = (double) v.u.i;
    }
    else if (v.type == FcTypeVoid && u.type == FcTypeMatrix)
    {
	v.u.m = &FcIdentityMatrix;
	v.type = FcTypeMatrix;
    }
    else if (buf && v.type == FcTypeString && u.type == FcTypeLangSet)
    {
	v.u.l = FcLangSetPromote (v.u.s, buf);
	v.type = FcTypeLangSet;
    }
    return v;
}

FcBool
FcConfigCompareValue (const FcValue	*left_o,
		      unsigned int      op_,
		      const FcValue	*right_o)
{
    FcValue	left = FcValueCanonicalize(left_o);
    FcValue	right = FcValueCanonicalize(right_o);
    FcBool	ret = FcFalse;
    FcOp	op = FC_OP_GET_OP (op_);
    int		flags = FC_OP_GET_FLAGS (op_);
    FcValuePromotionBuffer buf1, buf2;

    left = FcConfigPromote (left, right, &buf1);
    right = FcConfigPromote (right, left, &buf2);
    if (left.type == right.type)
    {
	switch (left.type) {
	case FcTypeUnknown:
	    break;	/* No way to guess how to compare for this object */
	case FcTypeInteger:
	    break;	/* FcConfigPromote prevents this from happening */
	case FcTypeDouble:
	    switch ((int) op) {
	    case FcOpEqual:
	    case FcOpContains:
	    case FcOpListing:
		ret = left.u.d == right.u.d;
		break;
	    case FcOpNotEqual:
	    case FcOpNotContains:
		ret = left.u.d != right.u.d;
		break;
	    case FcOpLess:
		ret = left.u.d < right.u.d;
		break;
	    case FcOpLessEqual:
		ret = left.u.d <= right.u.d;
		break;
	    case FcOpMore:
		ret = left.u.d > right.u.d;
		break;
	    case FcOpMoreEqual:
		ret = left.u.d >= right.u.d;
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeBool:
	    switch ((int) op) {
	    case FcOpEqual:
	    case FcOpContains:
	    case FcOpListing:
		ret = left.u.b == right.u.b;
		break;
	    case FcOpNotEqual:
	    case FcOpNotContains:
		ret = left.u.b != right.u.b;
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeString:
	    switch ((int) op) {
	    case FcOpEqual:
	    case FcOpListing:
		if (flags & FcOpFlagIgnoreBlanks)
		    ret = FcStrCmpIgnoreBlanksAndCase (left.u.s, right.u.s) == 0;
		else
		    ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0;
		break;
	    case FcOpContains:
		ret = FcStrStrIgnoreCase (left.u.s, right.u.s) != 0;
		break;
	    case FcOpNotEqual:
		if (flags & FcOpFlagIgnoreBlanks)
		    ret = FcStrCmpIgnoreBlanksAndCase (left.u.s, right.u.s) != 0;
		else
		    ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0;
		break;
	    case FcOpNotContains:
		ret = FcStrStrIgnoreCase (left.u.s, right.u.s) == 0;
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeMatrix:
	    switch ((int) op) {
	    case FcOpEqual:
	    case FcOpContains:
	    case FcOpListing:
		ret = FcMatrixEqual (left.u.m, right.u.m);
		break;
	    case FcOpNotEqual:
	    case FcOpNotContains:
		ret = !FcMatrixEqual (left.u.m, right.u.m);
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeCharSet:
	    switch ((int) op) {
	    case FcOpContains:
	    case FcOpListing:
		/* left contains right if right is a subset of left */
		ret = FcCharSetIsSubset (right.u.c, left.u.c);
		break;
	    case FcOpNotContains:
		/* left contains right if right is a subset of left */
		ret = !FcCharSetIsSubset (right.u.c, left.u.c);
		break;
	    case FcOpEqual:
		ret = FcCharSetEqual (left.u.c, right.u.c);
		break;
	    case FcOpNotEqual:
		ret = !FcCharSetEqual (left.u.c, right.u.c);
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeLangSet:
	    switch ((int) op) {
	    case FcOpContains:
	    case FcOpListing:
		ret = FcLangSetContains (left.u.l, right.u.l);
		break;
	    case FcOpNotContains:
		ret = !FcLangSetContains (left.u.l, right.u.l);
		break;
	    case FcOpEqual:
		ret = FcLangSetEqual (left.u.l, right.u.l);
		break;
	    case FcOpNotEqual:
		ret = !FcLangSetEqual (left.u.l, right.u.l);
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeVoid:
	    switch ((int) op) {
	    case FcOpEqual:
	    case FcOpContains:
	    case FcOpListing:
		ret = FcTrue;
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeFTFace:
	    switch ((int) op) {
	    case FcOpEqual:
	    case FcOpContains:
	    case FcOpListing:
		ret = left.u.f == right.u.f;
		break;
	    case FcOpNotEqual:
	    case FcOpNotContains:
		ret = left.u.f != right.u.f;
		break;
	    default:
		break;
	    }
	    break;
	}
    }
    else
    {
	if (op == FcOpNotEqual || op == FcOpNotContains)
	    ret = FcTrue;
    }
    return ret;
}


#define _FcDoubleFloor(d)	((int) (d))
#define _FcDoubleCeil(d)	((double) (int) (d) == (d) ? (int) (d) : (int) ((d) + 1))
#define FcDoubleFloor(d)	((d) >= 0 ? _FcDoubleFloor(d) : -_FcDoubleCeil(-(d)))
#define FcDoubleCeil(d)		((d) >= 0 ? _FcDoubleCeil(d) : -_FcDoubleFloor(-(d)))
#define FcDoubleRound(d)	FcDoubleFloor ((d) + 0.5)
#define FcDoubleTrunc(d)	((d) >= 0 ? _FcDoubleFloor (d) : -_FcDoubleFloor (-(d)))

static FcValue
FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e)
{
    FcValue	v, vl, vr;
    FcMatrix	*m;
    FcChar8     *str;
    FcOp	op = FC_OP_GET_OP (e->op);

    switch ((int) op) {
    case FcOpInteger:
	v.type = FcTypeInteger;
	v.u.i = e->u.ival;
	break;
    case FcOpDouble:
	v.type = FcTypeDouble;
	v.u.d = e->u.dval;
	break;
    case FcOpString:
	v.type = FcTypeString;
	v.u.s = e->u.sval;
	v = FcValueSave (v);
	break;
    case FcOpMatrix:
	{
	  FcMatrix m;
	  FcValue xx, xy, yx, yy;
	  v.type = FcTypeMatrix;
	  xx = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->xx), v, NULL);
	  xy = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->xy), v, NULL);
	  yx = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->yx), v, NULL);
	  yy = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->yy), v, NULL);
	  if (xx.type == FcTypeDouble && xy.type == FcTypeDouble &&
	      yx.type == FcTypeDouble && yy.type == FcTypeDouble)
	  {
	    m.xx = xx.u.d;
	    m.xy = xy.u.d;
	    m.yx = yx.u.d;
	    m.yy = yy.u.d;
	    v.u.m = &m;
	  }
	  else
	    v.type = FcTypeVoid;
	  v = FcValueSave (v);
	}
	break;
    case FcOpCharSet:
	v.type = FcTypeCharSet;
	v.u.c = e->u.cval;
	v = FcValueSave (v);
	break;
    case FcOpLangSet:
	v.type = FcTypeLangSet;
	v.u.l = e->u.lval;
	v = FcValueSave (v);
	break;
    case FcOpBool:
	v.type = FcTypeBool;
	v.u.b = e->u.bval;
	break;
    case FcOpField:
	if (kind == FcMatchFont && e->u.name.kind == FcMatchPattern)
	{
	    if (FcResultMatch != FcPatternObjectGet (p_pat, e->u.name.object, 0, &v))
		v.type = FcTypeVoid;
	}
	else if (kind == FcMatchPattern && e->u.name.kind == FcMatchFont)
	{
	    fprintf (stderr,
                    "Fontconfig warning: <name> tag has target=\"font\" in a <match target=\"pattern\">.\n");
	    v.type = FcTypeVoid;
	}
	else
	{
	    if (FcResultMatch != FcPatternObjectGet (p, e->u.name.object, 0, &v))
		v.type = FcTypeVoid;
	}
	v = FcValueSave (v);
	break;
    case FcOpConst:
	if (FcNameConstant (e->u.constant, &v.u.i))
	    v.type = FcTypeInteger;
	else
	    v.type = FcTypeVoid;
	break;
    case FcOpQuest:
	vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
	if (vl.type == FcTypeBool)
	{
	    if (vl.u.b)
		v = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right->u.tree.left);
	    else
		v = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right->u.tree.right);
	}
	else
	    v.type = FcTypeVoid;
	FcValueDestroy (vl);
	break;
    case FcOpEqual:
    case FcOpNotEqual:
    case FcOpLess:
    case FcOpLessEqual:
    case FcOpMore:
    case FcOpMoreEqual:
    case FcOpContains:
    case FcOpNotContains:
    case FcOpListing:
	vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
	vr = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right);
	v.type = FcTypeBool;
	v.u.b = FcConfigCompareValue (&vl, e->op, &vr);
	FcValueDestroy (vl);
	FcValueDestroy (vr);
	break;	
    case FcOpOr:
    case FcOpAnd:
    case FcOpPlus:
    case FcOpMinus:
    case FcOpTimes:
    case FcOpDivide:
	vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
	vr = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right);
	vl = FcConfigPromote (vl, vr, NULL);
	vr = FcConfigPromote (vr, vl, NULL);
	if (vl.type == vr.type)
	{
	    switch ((int) vl.type) {
	    case FcTypeDouble:
		switch ((int) op) {
		case FcOpPlus:	
		    v.type = FcTypeDouble;
		    v.u.d = vl.u.d + vr.u.d;
		    break;
		case FcOpMinus:
		    v.type = FcTypeDouble;
		    v.u.d = vl.u.d - vr.u.d;
		    break;
		case FcOpTimes:
		    v.type = FcTypeDouble;
		    v.u.d = vl.u.d * vr.u.d;
		    break;
		case FcOpDivide:
		    v.type = FcTypeDouble;
		    v.u.d = vl.u.d / vr.u.d;
		    break;
		default:
		    v.type = FcTypeVoid;
		    break;
		}
		if (v.type == FcTypeDouble &&
		    v.u.d == (double) (int) v.u.d)
		{
		    v.type = FcTypeInteger;
		    v.u.i = (int) v.u.d;
		}
		break;
	    case FcTypeBool:
		switch ((int) op) {
		case FcOpOr:
		    v.type = FcTypeBool;
		    v.u.b = vl.u.b || vr.u.b;
		    break;
		case FcOpAnd:
		    v.type = FcTypeBool;
		    v.u.b = vl.u.b && vr.u.b;
		    break;
		default:
		    v.type = FcTypeVoid;
		    break;
		}
		break;
	    case FcTypeString:
		switch ((int) op) {
		case FcOpPlus:
		    v.type = FcTypeString;
		    str = FcStrPlus (vl.u.s, vr.u.s);
		    v.u.s = FcStrdup (str);
		    FcStrFree (str);
			
		    if (!v.u.s)
			v.type = FcTypeVoid;
		    break;
		default:
		    v.type = FcTypeVoid;
		    break;
		}
		break;
	    case FcTypeMatrix:
		switch ((int) op) {
		case FcOpTimes:
		    v.type = FcTypeMatrix;
		    m = malloc (sizeof (FcMatrix));
		    if (m)
		    {
			FcMatrixMultiply (m, vl.u.m, vr.u.m);
			v.u.m = m;
		    }
		    else
		    {
			v.type = FcTypeVoid;
		    }
		    break;
		default:
		    v.type = FcTypeVoid;
		    break;
		}
		break;
	    case FcTypeCharSet:
		switch ((int) op) {
		case FcOpPlus:
		    v.type = FcTypeCharSet;
		    v.u.c = FcCharSetUnion (vl.u.c, vr.u.c);
		    if (!v.u.c)
			v.type = FcTypeVoid;
		    break;
		case FcOpMinus:
		    v.type = FcTypeCharSet;
		    v.u.c = FcCharSetSubtract (vl.u.c, vr.u.c);
		    if (!v.u.c)
			v.type = FcTypeVoid;
		    break;
		default:
		    v.type = FcTypeVoid;
		    break;
		}
		break;
	    case FcTypeLangSet:
		switch ((int) op) {
		case FcOpPlus:
		    v.type = FcTypeLangSet;
		    v.u.l = FcLangSetUnion (vl.u.l, vr.u.l);
		    if (!v.u.l)
			v.type = FcTypeVoid;
		    break;
		case FcOpMinus:
		    v.type = FcTypeLangSet;
		    v.u.l = FcLangSetSubtract (vl.u.l, vr.u.l);
		    if (!v.u.l)
			v.type = FcTypeVoid;
		    break;
		default:
		    v.type = FcTypeVoid;
		    break;
		}
		break;
	    default:
		v.type = FcTypeVoid;
		break;
	    }
	}
	else
	    v.type = FcTypeVoid;
	FcValueDestroy (vl);
	FcValueDestroy (vr);
	break;
    case FcOpNot:
	vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
	switch ((int) vl.type) {
	case FcTypeBool:
	    v.type = FcTypeBool;
	    v.u.b = !vl.u.b;
	    break;
	default:
	    v.type = FcTypeVoid;
	    break;
	}
	FcValueDestroy (vl);
	break;
    case FcOpFloor:
	vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
	switch ((int) vl.type) {
	case FcTypeInteger:
	    v = vl;
	    break;
	case FcTypeDouble:
	    v.type = FcTypeInteger;
	    v.u.i = FcDoubleFloor (vl.u.d);
	    break;
	default:
	    v.type = FcTypeVoid;
	    break;
	}
	FcValueDestroy (vl);
	break;
    case FcOpCeil:
	vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
	switch ((int) vl.type) {
	case FcTypeInteger:
	    v = vl;
	    break;
	case FcTypeDouble:
	    v.type = FcTypeInteger;
	    v.u.i = FcDoubleCeil (vl.u.d);
	    break;
	default:
	    v.type = FcTypeVoid;
	    break;
	}
	FcValueDestroy (vl);
	break;
    case FcOpRound:
	vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
	switch ((int) vl.type) {
	case FcTypeInteger:
	    v = vl;
	    break;
	case FcTypeDouble:
	    v.type = FcTypeInteger;
	    v.u.i = FcDoubleRound (vl.u.d);
	    break;
	default:
	    v.type = FcTypeVoid;
	    break;
	}
	FcValueDestroy (vl);
	break;
    case FcOpTrunc:
	vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
	switch ((int) vl.type) {
	case FcTypeInteger:
	    v = vl;
	    break;
	case FcTypeDouble:
	    v.type = FcTypeInteger;
	    v.u.i = FcDoubleTrunc (vl.u.d);
	    break;
	default:
	    v.type = FcTypeVoid;
	    break;
	}
	FcValueDestroy (vl);
	break;
    default:
	v.type = FcTypeVoid;
	break;
    }
    return v;
}

static FcValueList *
FcConfigMatchValueList (FcPattern	*p,
			FcPattern	*p_pat,
			FcMatchKind      kind,
			FcTest		*t,
			FcValueList	*values)
{
    FcValueList	    *ret = 0;
    FcExpr	    *e = t->expr;
    FcValue	    value;
    FcValueList	    *v;

    while (e)
    {
	/* Compute the value of the match expression */
	if (FC_OP_GET_OP (e->op) == FcOpComma)
	{
	    value = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
	    e = e->u.tree.right;
	}
	else
	{
	    value = FcConfigEvaluate (p, p_pat, kind, e);
	    e = 0;
	}

	for (v = values; v; v = FcValueListNext(v))
	{
	    /* Compare the pattern value to the match expression value */
	    if (FcConfigCompareValue (&v->value, t->op, &value))
	    {
		if (!ret)
		    ret = v;
	    }
	    else
	    {
		if (t->qual == FcQualAll)
		{
		    ret = 0;
		    break;
		}
	    }
	}
	FcValueDestroy (value);
    }
    return ret;
}

static FcValueList *
FcConfigValues (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e, FcValueBinding binding)
{
    FcValueList	*l;

    if (!e)
	return 0;
    l = (FcValueList *) malloc (sizeof (FcValueList));
    if (!l)
	return 0;
    if (FC_OP_GET_OP (e->op) == FcOpComma)
    {
	l->value = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
	l->next = FcConfigValues (p, p_pat, kind, e->u.tree.right, binding);
    }
    else
    {
	l->value = FcConfigEvaluate (p, p_pat, kind, e);
	l->next = NULL;
    }
    l->binding = binding;
    if (l->value.type == FcTypeVoid)
    {
	FcValueList  *next = FcValueListNext(l);

	free (l);
	l = next;
    }

    return l;
}

static FcBool
FcConfigAdd (FcValueListPtr *head,
	     FcValueList    *position,
	     FcBool	    append,
	     FcValueList    *new,
	     FcObject        object)
{
    FcValueListPtr  *prev, l, last, v;
    FcValueBinding  sameBinding;

    /*
     * Make sure the stored type is valid for built-in objects
     */
    for (l = new; l != NULL; l = FcValueListNext (l))
    {
	if (!FcObjectValidType (object, l->value.type))
	{
	    fprintf (stderr,
		     "Fontconfig warning: FcPattern object %s does not accept value", FcObjectName (object));
	    FcValuePrintFile (stderr, l->value);
	    fprintf (stderr, "\n");

	    if (FcDebug () & FC_DBG_EDIT)
	    {
		printf ("Not adding\n");
	    }

	    return FcFalse;
	}
    }

    if (position)
	sameBinding = position->binding;
    else
	sameBinding = FcValueBindingWeak;
    for (v = new; v != NULL; v = FcValueListNext(v))
	if (v->binding == FcValueBindingSame)
	    v->binding = sameBinding;
    if (append)
    {
	if (position)
	    prev = &position->next;
	else
	    for (prev = head; *prev != NULL;
		 prev = &(*prev)->next)
		;
    }
    else
    {
	if (position)
	{
	    for (prev = head; *prev != NULL;
		 prev = &(*prev)->next)
	    {
		if (*prev == position)
		    break;
	    }
	}
	else
	    prev = head;

	if (FcDebug () & FC_DBG_EDIT)
	{
	    if (*prev == NULL)
		printf ("position not on list\n");
	}
    }

    if (FcDebug () & FC_DBG_EDIT)
    {
	printf ("%s list before ", append ? "Append" : "Prepend");
	FcValueListPrintWithPosition (*head, *prev);
	printf ("\n");
    }

    if (new)
    {
	last = new;
	while (last->next != NULL)
	    last = last->next;

	last->next = *prev;
	*prev = new;
    }

    if (FcDebug () & FC_DBG_EDIT)
    {
	printf ("%s list after ", append ? "Append" : "Prepend");
	FcValueListPrint (*head);
	printf ("\n");
    }

    return FcTrue;
}

static void
FcConfigDel (FcValueListPtr *head,
	     FcValueList    *position)
{
    FcValueListPtr *prev;

    for (prev = head; *prev != NULL; prev = &(*prev)->next)
    {
	if (*prev == position)
	{
	    *prev = position->next;
	    position->next = NULL;
	    FcValueListDestroy (position);
	    break;
	}
    }
}

static void
FcConfigPatternAdd (FcPattern	*p,
		    FcObject	object,
		    FcValueList	*list,
		    FcBool	append)
{
    if (list)
    {
	FcPatternElt    *e = FcPatternObjectInsertElt (p, object);

	if (!e)
	    return;
	FcConfigAdd (&e->values, 0, append, list, object);
    }
}

/*
 * Delete all values associated with a field
 */
static void
FcConfigPatternDel (FcPattern	*p,
		    FcObject	object)
{
    FcPatternElt    *e = FcPatternObjectFindElt (p, object);
    if (!e)
	return;
    while (e->values != NULL)
	FcConfigDel (&e->values, e->values);
}

static void
FcConfigPatternCanon (FcPattern	    *p,
		      FcObject	    object)
{
    FcPatternElt    *e = FcPatternObjectFindElt (p, object);
    if (!e)
	return;
    if (e->values == NULL)
	FcPatternObjectDel (p, object);
}

FcBool
FcConfigSubstituteWithPat (FcConfig    *config,
			   FcPattern   *p,
			   FcPattern   *p_pat,
			   FcMatchKind kind)
{
    FcValue v;
    FcSubst	    *s;
    FcRule          *r;
    FcValueList	    *l, **value = NULL, *vl;
    FcPattern	    *m;
    FcStrSet	    *strs;
    FcObject	    object = FC_INVALID_OBJECT;
    FcPatternElt    **elt = NULL, *e;
    int		    i, nobjs;
    FcBool	    retval = FcTrue;
    FcTest	    **tst = NULL;

    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return FcFalse;
    }

    switch (kind) {
    case FcMatchPattern:
	s = config->substPattern;
	strs = FcGetDefaultLangs ();
	if (strs)
	{
	    FcStrList *l = FcStrListCreate (strs);
	    FcChar8 *lang;
	    FcValue v;

	    FcStrSetDestroy (strs);
	    while (l && (lang = FcStrListNext (l)))
	    {
		v.type = FcTypeString;
		v.u.s = lang;
		FcPatternObjectAddWithBinding (p, FC_LANG_OBJECT, v, FcValueBindingWeak, FcTrue);
	    }
	    FcStrListDone (l);
	}
	if (FcPatternObjectGet (p, FC_PRGNAME_OBJECT, 0, &v) == FcResultNoMatch)
	{
	    FcChar8 *prgname = FcGetPrgname ();
	    if (prgname)
		FcPatternObjectAddString (p, FC_PRGNAME_OBJECT, prgname);
	}
	break;
    case FcMatchFont:
	s = config->substFont;
	break;
    case FcMatchScan:
	s = config->substScan;
	break;
    default:
	return FcFalse;
    }

    nobjs = FC_MAX_BASE_OBJECT + config->maxObjects + 2;
    value = (FcValueList **) malloc (SIZEOF_VOID_P * nobjs);
    if (!value)
    {
	retval = FcFalse;
	goto bail1;
    }
    elt = (FcPatternElt **) malloc (SIZEOF_VOID_P * nobjs);
    if (!elt)
    {
	retval = FcFalse;
	goto bail1;
    }
    tst = (FcTest **) malloc (SIZEOF_VOID_P * nobjs);
    if (!tst)
    {
	retval = FcFalse;
	goto bail1;
    }

    if (FcDebug () & FC_DBG_EDIT)
    {
	printf ("FcConfigSubstitute ");
	FcPatternPrint (p);
    }
    for (; s; s = s->next)
    {
	r = s->rule;
	for (i = 0; i < nobjs; i++)
	{
	    elt[i] = NULL;
	    value[i] = NULL;
	    tst[i] = NULL;
	}
	for (; r; r = r->next)
	{
	    switch (r->type) {
	    case FcRuleUnknown:
		/* shouldn't be reached */
		break;
	    case FcRuleTest:
		object = FC_OBJ_ID (r->u.test->object);
		/*
		 * Check the tests to see if
		 * they all match the pattern
		 */
		if (FcDebug () & FC_DBG_EDIT)
		{
		    printf ("FcConfigSubstitute test ");
		    FcTestPrint (r->u.test);
		}
		if (kind == FcMatchFont && r->u.test->kind == FcMatchPattern)
		    m = p_pat;
		else
		    m = p;
		if (m)
		    e = FcPatternObjectFindElt (m, r->u.test->object);
		else
		    e = NULL;
		/* different 'kind' won't be the target of edit */
		if (!elt[object] && kind == r->u.test->kind)
		{
		    elt[object] = e;
		    tst[object] = r->u.test;
		}
		/*
		 * If there's no such field in the font,
		 * then FcQualAll matches while FcQualAny does not
		 */
		if (!e)
		{
		    if (r->u.test->qual == FcQualAll)
		    {
			value[object] = NULL;
			continue;
		    }
		    else
		    {
			if (FcDebug () & FC_DBG_EDIT)
			    printf ("No match\n");
			goto bail;
		    }
		}
		/*
		 * Check to see if there is a match, mark the location
		 * to apply match-relative edits
		 */
		vl = FcConfigMatchValueList (m, p_pat, kind, r->u.test, e->values);
		/* different 'kind' won't be the target of edit */
		if (!value[object] && kind == r->u.test->kind)
		    value[object] = vl;
		if (!vl ||
		    (r->u.test->qual == FcQualFirst && vl != e->values) ||
		    (r->u.test->qual == FcQualNotFirst && vl == e->values))
		{
		    if (FcDebug () & FC_DBG_EDIT)
			printf ("No match\n");
		    goto bail;
		}
		break;
	    case FcRuleEdit:
		object = FC_OBJ_ID (r->u.edit->object);
		if (FcDebug () & FC_DBG_EDIT)
		{
		    printf ("Substitute ");
		    FcEditPrint (r->u.edit);
		    printf ("\n\n");
		}
		/*
		 * Evaluate the list of expressions
		 */
		l = FcConfigValues (p, p_pat,kind,  r->u.edit->expr, r->u.edit->binding);
		if (tst[object] && (tst[object]->kind == FcMatchFont || kind == FcMatchPattern))
		    elt[object] = FcPatternObjectFindElt (p, tst[object]->object);

		switch (FC_OP_GET_OP (r->u.edit->op)) {
		case FcOpAssign:
		    /*
		     * If there was a test, then replace the matched
		     * value with the new list of values
		     */
		    if (value[object])
		    {
			FcValueList	*thisValue = value[object];
			FcValueList	*nextValue = l;

			/*
			 * Append the new list of values after the current value
			 */
			FcConfigAdd (&elt[object]->values, thisValue, FcTrue, l, r->u.edit->object);
			/*
			 * Delete the marked value
			 */
			if (thisValue)
			    FcConfigDel (&elt[object]->values, thisValue);
			/*
			 * Adjust a pointer into the value list to ensure
			 * future edits occur at the same place
			 */
			value[object] = nextValue;
			break;
		    }
		    /* fall through ... */
		case FcOpAssignReplace:
		    /*
		     * Delete all of the values and insert
		     * the new set
		     */
		    FcConfigPatternDel (p, r->u.edit->object);
		    FcConfigPatternAdd (p, r->u.edit->object, l, FcTrue);
		    /*
		     * Adjust a pointer into the value list as they no
		     * longer point to anything valid
		     */
		    value[object] = NULL;
		    break;
		case FcOpPrepend:
		    if (value[object])
		    {
			FcConfigAdd (&elt[object]->values, value[object], FcFalse, l, r->u.edit->object);
			break;
		    }
		    /* fall through ... */
		case FcOpPrependFirst:
		    FcConfigPatternAdd (p, r->u.edit->object, l, FcFalse);
		    break;
		case FcOpAppend:
		    if (value[object])
		    {
			FcConfigAdd (&elt[object]->values, value[object], FcTrue, l, r->u.edit->object);
			break;
		    }
		    /* fall through ... */
		case FcOpAppendLast:
		    FcConfigPatternAdd (p, r->u.edit->object, l, FcTrue);
		    break;
		case FcOpDelete:
		    if (value[object])
		    {
			FcConfigDel (&elt[object]->values, value[object]);
			break;
		    }
		    /* fall through ... */
		case FcOpDeleteAll:
		    FcConfigPatternDel (p, r->u.edit->object);
		    break;
		default:
		    FcValueListDestroy (l);
		    break;
		}
		/*
		 * Now go through the pattern and eliminate
		 * any properties without data
		 */
		FcConfigPatternCanon (p, r->u.edit->object);

		if (FcDebug () & FC_DBG_EDIT)
		{
		    printf ("FcConfigSubstitute edit");
		    FcPatternPrint (p);
		}
		break;
	    }
	}
    bail:;
    }
    if (FcDebug () & FC_DBG_EDIT)
    {
	printf ("FcConfigSubstitute done");
	FcPatternPrint (p);
    }
bail1:
    if (elt)
	free (elt);
    if (value)
	free (value);
    if (tst)
	free (tst);

    return retval;
}

FcBool
FcConfigSubstitute (FcConfig	*config,
		    FcPattern	*p,
		    FcMatchKind	kind)
{
    return FcConfigSubstituteWithPat (config, p, 0, kind);
}

#if defined (_WIN32)

static FcChar8 fontconfig_path[1000] = ""; /* MT-dontcare */

#  if (defined (PIC) || defined (DLL_EXPORT))

BOOL WINAPI
DllMain (HINSTANCE hinstDLL,
	 DWORD     fdwReason,
	 LPVOID    lpvReserved);

BOOL WINAPI
DllMain (HINSTANCE hinstDLL,
	 DWORD     fdwReason,
	 LPVOID    lpvReserved)
{
  FcChar8 *p;

  switch (fdwReason) {
  case DLL_PROCESS_ATTACH:
      if (!GetModuleFileName ((HMODULE) hinstDLL, (LPCH) fontconfig_path,
			      sizeof (fontconfig_path)))
	  break;

      /* If the fontconfig DLL is in a "bin" or "lib" subfolder,
       * assume it's a Unix-style installation tree, and use
       * "etc/fonts" in there as FONTCONFIG_PATH. Otherwise use the
       * folder where the DLL is as FONTCONFIG_PATH.
       */
      p = (FcChar8 *) strrchr ((const char *) fontconfig_path, '\\');
      if (p)
      {
	  *p = '\0';
	  p = (FcChar8 *) strrchr ((const char *) fontconfig_path, '\\');
	  if (p && (FcStrCmpIgnoreCase (p + 1, (const FcChar8 *) "bin") == 0 ||
		    FcStrCmpIgnoreCase (p + 1, (const FcChar8 *) "lib") == 0))
	      *p = '\0';
	  strcat ((char *) fontconfig_path, "\\etc\\fonts");
      }
      else
          fontconfig_path[0] = '\0';

      break;
  }

  return TRUE;
}

#  endif /* !PIC */

#undef FONTCONFIG_PATH
#define FONTCONFIG_PATH fontconfig_path

#endif /* !_WIN32 */

#ifndef FONTCONFIG_FILE
#define FONTCONFIG_FILE	"fonts.conf"
#endif

static FcChar8 *
FcConfigFileExists (const FcChar8 *dir, const FcChar8 *file)
{
    FcChar8    *path;
    int         size, osize;

    if (!dir)
	dir = (FcChar8 *) "";

    osize = strlen ((char *) dir) + 1 + strlen ((char *) file) + 1;
    /*
     * workaround valgrind warning because glibc takes advantage of how it knows memory is
     * allocated to implement strlen by reading in groups of 4
     */
    size = (osize + 3) & ~3;

    path = malloc (size);
    if (!path)
	return 0;

    strcpy ((char *) path, (const char *) dir);
    /* make sure there's a single separator */
#ifdef _WIN32
    if ((!path[0] || (path[strlen((char *) path)-1] != '/' &&
		      path[strlen((char *) path)-1] != '\\')) &&
	!(file[0] == '/' ||
	  file[0] == '\\' ||
	  (isalpha (file[0]) && file[1] == ':' && (file[2] == '/' || file[2] == '\\'))))
	strcat ((char *) path, "\\");
#else
    if ((!path[0] || path[strlen((char *) path)-1] != '/') && file[0] != '/')
	strcat ((char *) path, "/");
    else
	osize--;
#endif
    strcat ((char *) path, (char *) file);

    if (access ((char *) path, R_OK) == 0)
	return path;

    FcStrFree (path);

    return 0;
}

static FcChar8 **
FcConfigGetPath (void)
{
    FcChar8    **path;
    FcChar8    *env, *e, *colon;
    FcChar8    *dir;
    int	    npath;
    int	    i;

    npath = 2;	/* default dir + null */
    env = (FcChar8 *) getenv ("FONTCONFIG_PATH");
    if (env)
    {
	e = env;
	npath++;
	while (*e)
	    if (*e++ == FC_SEARCH_PATH_SEPARATOR)
		npath++;
    }
    path = calloc (npath, sizeof (FcChar8 *));
    if (!path)
	goto bail0;
    i = 0;

    if (env)
    {
	e = env;
	while (*e)
	{
	    colon = (FcChar8 *) strchr ((char *) e, FC_SEARCH_PATH_SEPARATOR);
	    if (!colon)
		colon = e + strlen ((char *) e);
	    path[i] = malloc (colon - e + 1);
	    if (!path[i])
		goto bail1;
	    strncpy ((char *) path[i], (const char *) e, colon - e);
	    path[i][colon - e] = '\0';
	    if (*colon)
		e = colon + 1;
	    else
		e = colon;
	    i++;
	}
    }

#ifdef _WIN32
	if (fontconfig_path[0] == '\0')
	{
		char *p;
		if(!GetModuleFileName(NULL, (LPCH) fontconfig_path, sizeof(fontconfig_path)))
			goto bail1;
		p = strrchr ((const char *) fontconfig_path, '\\');
		if (p) *p = '\0';
		strcat ((char *) fontconfig_path, "\\fonts");
	}
#endif
    dir = (FcChar8 *) FONTCONFIG_PATH;
    path[i] = malloc (strlen ((char *) dir) + 1);
    if (!path[i])
	goto bail1;
    strcpy ((char *) path[i], (const char *) dir);
    return path;

bail1:
    for (i = 0; path[i]; i++)
	free (path[i]);
    free (path);
bail0:
    return 0;
}

static void
FcConfigFreePath (FcChar8 **path)
{
    FcChar8    **p;

    for (p = path; *p; p++)
	free (*p);
    free (path);
}

static FcBool	_FcConfigHomeEnabled = FcTrue; /* MT-goodenough */

FcChar8 *
FcConfigHome (void)
{
    if (_FcConfigHomeEnabled)
    {
        char *home = getenv ("HOME");

#ifdef _WIN32
	if (home == NULL)
	    home = getenv ("USERPROFILE");
#endif

	return (FcChar8 *) home;
    }
    return 0;
}

FcChar8 *
FcConfigXdgCacheHome (void)
{
    const char *env = getenv ("XDG_CACHE_HOME");
    FcChar8 *ret = NULL;

    if (env)
	ret = FcStrCopy ((const FcChar8 *)env);
    else
    {
	const FcChar8 *home = FcConfigHome ();
	size_t len = home ? strlen ((const char *)home) : 0;

	ret = malloc (len + 7 + 1);
	if (ret)
	{
	    memcpy (ret, home, len);
	    memcpy (&ret[len], FC_DIR_SEPARATOR_S ".cache", 7);
	    ret[len + 7] = 0;
	}
    }

    return ret;
}

FcChar8 *
FcConfigXdgConfigHome (void)
{
    const char *env = getenv ("XDG_CONFIG_HOME");
    FcChar8 *ret = NULL;

    if (env)
	ret = FcStrCopy ((const FcChar8 *)env);
    else
    {
	const FcChar8 *home = FcConfigHome ();
	size_t len = home ? strlen ((const char *)home) : 0;

	ret = malloc (len + 8 + 1);
	if (ret)
	{
	    memcpy (ret, home, len);
	    memcpy (&ret[len], FC_DIR_SEPARATOR_S ".config", 8);
	    ret[len + 8] = 0;
	}
    }

    return ret;
}

FcChar8 *
FcConfigXdgDataHome (void)
{
    const char *env = getenv ("XDG_DATA_HOME");
    FcChar8 *ret = NULL;

    if (env)
	ret = FcStrCopy ((const FcChar8 *)env);
    else
    {
	const FcChar8 *home = FcConfigHome ();
	size_t len = home ? strlen ((const char *)home) : 0;

	ret = malloc (len + 13 + 1);
	if (ret)
	{
	    memcpy (ret, home, len);
	    memcpy (&ret[len], FC_DIR_SEPARATOR_S ".local" FC_DIR_SEPARATOR_S "share", 13);
	    ret[len + 13] = 0;
	}
    }

    return ret;
}

FcBool
FcConfigEnableHome (FcBool enable)
{
    FcBool  prev = _FcConfigHomeEnabled;
    _FcConfigHomeEnabled = enable;
    return prev;
}

FcChar8 *
FcConfigFilename (const FcChar8 *url)
{
    FcChar8    *file, *dir, **path, **p;

    if (!url || !*url)
    {
	url = (FcChar8 *) getenv ("FONTCONFIG_FILE");
	if (!url)
	    url = (FcChar8 *) FONTCONFIG_FILE;
    }
    file = 0;

#ifdef _WIN32
    if (isalpha (*url) &&
	url[1] == ':' &&
	(url[2] == '/' || url[2] == '\\'))
	goto absolute_path;
#endif

    switch (*url) {
    case '~':
	dir = FcConfigHome ();
	if (dir)
	    file = FcConfigFileExists (dir, url + 1);
	else
	    file = 0;
	break;
#ifdef _WIN32
    case '\\':
    absolute_path:
#endif
    case '/':
	file = FcConfigFileExists (0, url);
	break;
    default:
	path = FcConfigGetPath ();
	if (!path)
	    return NULL;
	for (p = path; *p; p++)
	{
	    file = FcConfigFileExists (*p, url);
	    if (file)
		break;
	}
	FcConfigFreePath (path);
	break;
    }

    return file;
}

/*
 * Manage the application-specific fonts
 */

FcBool
FcConfigAppFontAddFile (FcConfig    *config,
			const FcChar8  *file)
{
    FcFontSet	*set;
    FcStrSet	*subdirs;
    FcStrList	*sublist;
    FcChar8	*subdir;

    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return FcFalse;
    }

    subdirs = FcStrSetCreate ();
    if (!subdirs)
	return FcFalse;

    set = FcConfigGetFonts (config, FcSetApplication);
    if (!set)
    {
	set = FcFontSetCreate ();
	if (!set)
	{
	    FcStrSetDestroy (subdirs);
	    return FcFalse;
	}
	FcConfigSetFonts (config, set, FcSetApplication);
    }
	
    if (!FcFileScanConfig (set, subdirs, config->blanks, file, config))
    {
	FcStrSetDestroy (subdirs);
	return FcFalse;
    }
    if ((sublist = FcStrListCreate (subdirs)))
    {
	while ((subdir = FcStrListNext (sublist)))
	{
	    FcConfigAppFontAddDir (config, subdir);
	}
	FcStrListDone (sublist);
    }
    FcStrSetDestroy (subdirs);
    return FcTrue;
}

FcBool
FcConfigAppFontAddDir (FcConfig	    *config,
		       const FcChar8   *dir)
{
    FcFontSet	*set;
    FcStrSet	*dirs;

    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return FcFalse;
    }

    dirs = FcStrSetCreate ();
    if (!dirs)
	return FcFalse;

    set = FcConfigGetFonts (config, FcSetApplication);
    if (!set)
    {
	set = FcFontSetCreate ();
	if (!set)
	{
	    FcStrSetDestroy (dirs);
	    return FcFalse;
	}
	FcConfigSetFonts (config, set, FcSetApplication);
    }

    FcStrSetAddFilename (dirs, dir);

    if (!FcConfigAddDirList (config, FcSetApplication, dirs))
    {
	FcStrSetDestroy (dirs);
	return FcFalse;
    }
    FcStrSetDestroy (dirs);
    return FcTrue;
}

void
FcConfigAppFontClear (FcConfig	    *config)
{
    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return;
    }

    FcConfigSetFonts (config, 0, FcSetApplication);
}

/*
 * Manage filename-based font source selectors
 */

FcBool
FcConfigGlobAdd (FcConfig	*config,
		 const FcChar8  *glob,
		 FcBool		accept)
{
    FcStrSet	*set = accept ? config->acceptGlobs : config->rejectGlobs;

    return FcStrSetAdd (set, glob);
}

static FcBool
FcConfigGlobsMatch (const FcStrSet	*globs,
		    const FcChar8	*string)
{
    int	i;

    for (i = 0; i < globs->num; i++)
	if (FcStrGlobMatch (globs->strs[i], string))
	    return FcTrue;
    return FcFalse;
}

FcBool
FcConfigAcceptFilename (FcConfig	*config,
			const FcChar8	*filename)
{
    if (FcConfigGlobsMatch (config->acceptGlobs, filename))
	return FcTrue;
    if (FcConfigGlobsMatch (config->rejectGlobs, filename))
	return FcFalse;
    return FcTrue;
}

/*
 * Manage font-pattern based font source selectors
 */

FcBool
FcConfigPatternsAdd (FcConfig	*config,
		     FcPattern	*pattern,
		     FcBool	accept)
{
    FcFontSet	*set = accept ? config->acceptPatterns : config->rejectPatterns;

    return FcFontSetAdd (set, pattern);
}

static FcBool
FcConfigPatternsMatch (const FcFontSet	*patterns,
		       const FcPattern	*font)
{
    int i;

    for (i = 0; i < patterns->nfont; i++)
	if (FcListPatternMatchAny (patterns->fonts[i], font))
	    return FcTrue;
    return FcFalse;
}

FcBool
FcConfigAcceptFont (FcConfig	    *config,
		    const FcPattern *font)
{
    if (FcConfigPatternsMatch (config->acceptPatterns, font))
	return FcTrue;
    if (FcConfigPatternsMatch (config->rejectPatterns, font))
	return FcFalse;
    return FcTrue;
}

const FcChar8 *
FcConfigGetSysRoot (const FcConfig *config)
{
    if (!config)
    {
	config = FcConfigGetCurrent ();
	if (!config)
	    return NULL;
    }

    return config->sysRoot;
}

void
FcConfigSetSysRoot (FcConfig      *config,
		    const FcChar8 *sysroot)
{
    FcChar8 *s;
    FcBool init = FcFalse;

    if (!config)
    {
	/* We can't use FcConfigGetCurrent() here to ensure
	 * the sysroot is set prior to initialize FcConfig,
	 * to avoid loading caches from non-sysroot dirs.
	 * So postpone the initialization later.
	 */
	config = fc_atomic_ptr_get (&_fcConfig);
	if (!config)
	{
	    config = FcConfigCreate ();
	    if (!config)
		return;
	    init = FcTrue;
	}
    }

    s = FcStrCopyFilename (sysroot);
    if (!s)
	return;

    if (config->sysRoot)
	FcStrFree (config->sysRoot);

    config->sysRoot = s;
    if (init)
    {
	config = FcInitLoadOwnConfigAndFonts (config);
	FcConfigSetCurrent (config);
    }
}

#define __fccfg__
#include "fcaliastail.h"
#undef __fccfg__
