static FcBool
FcCacheDirsValid (FcConfig *config, FcCache *cache)
{
    FcStrSet *dirs = FcStrSetCreateEx (FCSS_GROW_BY_64);
    FcBool ret = FcFalse;
    const FcChar8 *sysroot = FcConfigGetSysRoot (config);
    FcChar8 *d;

    if (!dirs)
	goto bail;
    if (sysroot)
	d = FcStrBuildFilename (sysroot, FcCacheDir (cache), NULL);
    else
	d = FcStrdup (FcCacheDir (cache));
    if (!FcDirScanOnly (dirs, d, config))
	goto bail1;
    ret = cache->dirs_count == dirs->num;
    if (FcDebug () & FC_DBG_CACHE)
	printf ("%s: cache: %d, fs: %d\n", d, cache->dirs_count, dirs->num);

bail1:
    FcStrSetDestroy (dirs);
    FcStrFree (d);
bail:
    return ret;
}
/*
 * Look for a cache file for the specified dir. Attempt
 * to use each one we find, stopping when the callback
 * indicates success
 */
static FcBool
FcDirCacheProcess (FcConfig *config, const FcChar8 *dir,
		   FcBool (*callback) (FcConfig *config, int fd, struct stat *fd_stat,
				       struct stat *dir_stat, void *closure),
		   void *closure, FcChar8 **cache_file_ret)
{
    int		fd = -1;
    FcChar8	cache_base[CACHEBASE_LEN];
    FcStrList	*list;
    FcChar8	*cache_dir, *d;
    struct stat file_stat, dir_stat;
    FcBool	ret = FcFalse;
    const FcChar8 *sysroot = FcConfigGetSysRoot (config);

    if (sysroot)
	d = FcStrBuildFilename (sysroot, dir, NULL);
    else
	d = FcStrdup (dir);
    if (FcStatChecksum (d, &dir_stat) < 0)
    {
	FcStrFree (d);
        return FcFalse;
    }
    FcStrFree (d);

    FcDirCacheBasename (dir, cache_base);

    list = FcStrListCreate (config->cacheDirs);
    if (!list)
        return FcFalse;
	
    while ((cache_dir = FcStrListNext (list)))
    {
        FcChar8	*cache_hashed;

	if (sysroot)
	    cache_hashed = FcStrBuildFilename (sysroot, cache_dir, cache_base, NULL);
	else
	    cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL);
        if (!cache_hashed)
	    break;
        fd = FcDirCacheOpenFile (cache_hashed, &file_stat);
        if (fd >= 0) {
	    ret = (*callback) (config, fd, &file_stat, &dir_stat, closure);
	    close (fd);
	    if (ret)
	    {
		if (cache_file_ret)
		    *cache_file_ret = cache_hashed;
		else
		    FcStrFree (cache_hashed);
		break;
	    }
	}
    	FcStrFree (cache_hashed);
    }
    FcStrListDone (list);

    return ret;
}
Beispiel #3
0
static FcValue
FcNameConvert (FcType type, FcChar8 *string)
{
    FcValue	v;
    FcMatrix	m;
    double	b, e;
    char	*p;

    v.type = type;
    switch ((int) v.type) {
    case FcTypeInteger:
	if (!FcNameConstant (string, &v.u.i))
	    v.u.i = atoi ((char *) string);
	break;
    case FcTypeString:
	v.u.s = FcStrdup (string);
	if (!v.u.s)
	    v.type = FcTypeVoid;
	break;
    case FcTypeBool:
	if (!FcNameBool (string, &v.u.b))
	    v.u.b = FcFalse;
	break;
    case FcTypeDouble:
	v.u.d = strtod ((char *) string, 0);
	break;
    case FcTypeMatrix:
	FcMatrixInit (&m);
	sscanf ((char *) string, "%lg %lg %lg %lg", &m.xx, &m.xy, &m.yx, &m.yy);
	v.u.m = FcMatrixCopy (&m);
	break;
    case FcTypeCharSet:
	v.u.c = FcNameParseCharSet (string);
	if (!v.u.c)
	    v.type = FcTypeVoid;
	break;
    case FcTypeLangSet:
	v.u.l = FcNameParseLangSet (string);
	if (!v.u.l)
	    v.type = FcTypeVoid;
	break;
    case FcTypeRange:
	if (sscanf ((char *) string, "(%lg %lg)", &b, &e) != 2)
	{
	    v.u.d = strtod ((char *) string, &p);
	    if (p != NULL && p[0] != 0)
	    {
		v.type = FcTypeVoid;
		break;
	    }
	    v.type = FcTypeDouble;
	}
	else
	    v.u.r = FcRangeCreateDouble (b, e);
	break;
    default:
	break;
    }
    return v;
}
Beispiel #4
0
static FcBool
FcCacheTimeValid (FcConfig *config, FcCache *cache, struct stat *dir_stat)
{
    struct stat	dir_static;

    if (!dir_stat)
    {
	const FcChar8 *sysroot = FcConfigGetSysRoot (config);
	FcChar8 *d;

	if (sysroot)
	    d = FcStrBuildFilename (sysroot, FcCacheDir (cache), NULL);
	else
	    d = FcStrdup (FcCacheDir (cache));
	if (FcStatChecksum (d, &dir_static) < 0)
	{
	    FcStrFree (d);
	    return FcFalse;
	}
	FcStrFree (d);
	dir_stat = &dir_static;
    }
    if (FcDebug () & FC_DBG_CACHE)
	printf ("FcCacheTimeValid dir \"%s\" cache checksum %d dir checksum %d\n",
		FcCacheDir (cache), cache->checksum, (int) dir_stat->st_mtime);
    return cache->checksum == (int) dir_stat->st_mtime;
}
Beispiel #5
0
static FcObjectType *_FcObjectLookupOtherTypeByName(const char *str,
        FcObject *id) {
    struct FcObjectOtherTypeInfo *ots, *ot;

retry:
    ots = fc_atomic_ptr_get(&other_types);

    for (ot = ots; ot; ot = ot->next)
        if (0 == strcmp(ot->object.object, str)) break;

    if (!ot) {
        ot = malloc(sizeof(*ot));
        if (!ot) return NULL;

        ot->object.object = (const char *)FcStrdup(str);
        ot->object.type = FcTypeUnknown;
        ot->id = fc_atomic_int_add(next_id, +1);
        ot->next = ots;

        if (!fc_atomic_ptr_cmpexch(&other_types, ots, ot)) {
            free(ot);
            goto retry;
        }
    }

    if (id) *id = ot->id;

    return &ot->object;
}
Beispiel #6
0
FcChar8 *FcGetDefaultLang(void) {
    FcChar8 *lang;
retry:
    lang = fc_atomic_ptr_get(&default_lang);
    if (!lang) {
        FcStrSet *langs = FcGetDefaultLangs();
        lang = FcStrdup(langs->strs[0]);
        FcStrSetDestroy(langs);

        if (!fc_atomic_ptr_cmpexch(&default_lang, NULL, lang)) {
            free(lang);
            goto retry;
        }
    }

    return lang;
}
Beispiel #7
0
static FcValue
FcNameConvert (FcType type, FcChar8 *string)
{
    FcValue	v;
    FcMatrix	m;

    v.type = type;
    switch ((int) v.type) {
    case FcTypeInteger:
	if (!FcNameConstant (string, &v.u.i))
	    v.u.i = atoi ((char *) string);
	break;
    case FcTypeString:
	v.u.s = FcStrdup (string);
	if (!v.u.s)
	    v.type = FcTypeVoid;
	break;
    case FcTypeBool:
	if (!FcNameBool (string, &v.u.b))
	    v.u.b = FcFalse;
	break;
    case FcTypeDouble:
	v.u.d = strtod ((char *) string, 0);
	break;
    case FcTypeMatrix:
	FcMatrixInit (&m);
	sscanf ((char *) string, "%lg %lg %lg %lg", &m.xx, &m.xy, &m.yx, &m.yy);
	v.u.m = FcMatrixCopy (&m);
	break;
    case FcTypeCharSet:
	v.u.c = FcNameParseCharSet (string);
	if (!v.u.c)
	    v.type = FcTypeVoid;
	break;
    case FcTypeLangSet:
	v.u.l = FcNameParseLangSet (string);
	if (!v.u.l)
	    v.type = FcTypeVoid;
	break;
    default:
	break;
    }
    return v;
}
static FcBool
FcCacheTimeValid (FcConfig *config, FcCache *cache, struct stat *dir_stat)
{
    struct stat	dir_static;
    FcBool fnano = FcTrue;

    if (!dir_stat)
    {
	const FcChar8 *sysroot = FcConfigGetSysRoot (config);
	FcChar8 *d;

	if (sysroot)
	    d = FcStrBuildFilename (sysroot, FcCacheDir (cache), NULL);
	else
	    d = FcStrdup (FcCacheDir (cache));
	if (FcStatChecksum (d, &dir_static) < 0)
	{
	    FcStrFree (d);
	    return FcFalse;
	}
	FcStrFree (d);
	dir_stat = &dir_static;
    }
#ifdef HAVE_STRUCT_STAT_ST_MTIM
    fnano = (cache->checksum_nano == dir_stat->st_mtim.tv_nsec);
    if (FcDebug () & FC_DBG_CACHE)
	printf ("FcCacheTimeValid dir \"%s\" cache checksum %d.%ld dir checksum %d.%ld\n",
		FcCacheDir (cache), cache->checksum, (long)cache->checksum_nano, (int) dir_stat->st_mtime, dir_stat->st_mtim.tv_nsec);
#else
    if (FcDebug () & FC_DBG_CACHE)
	printf ("FcCacheTimeValid dir \"%s\" cache checksum %d dir checksum %d\n",
		FcCacheDir (cache), cache->checksum, (int) dir_stat->st_mtime);
#endif

    return cache->checksum == (int) dir_stat->st_mtime && fnano;
}
Beispiel #9
0
FcChar8 *FcGetPrgname(void) {
    FcChar8 *prgname;
retry:
    prgname = fc_atomic_ptr_get(&default_prgname);
    if (!prgname) {
#ifdef _WIN32
        char buf[MAX_PATH + 1];

        /* TODO This is ASCII-only; fix it. */
        if (GetModuleFileNameA(GetModuleHandle(NULL), buf,
                               sizeof(buf) / sizeof(buf[0])) > 0) {
            char *p;
            unsigned int len;

            p = strrchr(buf, '\\');
            if (p)
                p++;
            else
                p = buf;

            len = strlen(p);

            if (len > 4 && 0 == strcmp(p + len - 4, ".exe")) {
                len -= 4;
                buf[len] = '\0';
            }

            prgname = FcStrdup(p);
        }
#elif defined(HAVE_GETPROGNAME)
        const char *q = getprogname();
        if (q)
            prgname = FcStrdup(q);
        else
            prgname = FcStrdup("");
#else
#if defined(HAVE_GETEXECNAME)
        const char *p = getexecname();
#elif defined(HAVE_READLINK)
        char buf[PATH_MAX + 1];
        int len;
        char *p = NULL;

        len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
        if (len != -1) {
            buf[len] = '\0';
            p = buf;
        }
#else
        char *p = NULL;
#endif
        if (p) {
            char *r = strrchr(p, '/');
            if (r)
                r++;
            else
                r = p;

            prgname = FcStrdup(r);
        }

        if (!prgname) prgname = FcStrdup("");
#endif

        if (!fc_atomic_ptr_cmpexch(&default_prgname, NULL, prgname)) {
            free(prgname);
            goto retry;
        }
    }

    if (prgname && !prgname[0]) return NULL;

    return prgname;
}
Beispiel #10
0
FcChar8 *
FcStrCopy (const FcChar8 *s)
{
    return FcStrdup (s);
}
Beispiel #11
0
void
FcDefaultSubstitute (FcPattern *pattern)
{
    FcValue v, namelang, v2;
    int	    i;

    if (FcPatternObjectGet (pattern, FC_WEIGHT_OBJECT, 0, &v) == FcResultNoMatch )
	FcPatternObjectAddInteger (pattern, FC_WEIGHT_OBJECT, FC_WEIGHT_MEDIUM);

    if (FcPatternObjectGet (pattern, FC_SLANT_OBJECT, 0, &v) == FcResultNoMatch)
	FcPatternObjectAddInteger (pattern, FC_SLANT_OBJECT, FC_SLANT_ROMAN);

    if (FcPatternObjectGet (pattern, FC_WIDTH_OBJECT, 0, &v) == FcResultNoMatch)
	FcPatternObjectAddInteger (pattern, FC_WIDTH_OBJECT, FC_WIDTH_NORMAL);

    for (i = 0; i < NUM_FC_BOOL_DEFAULTS; i++)
	if (FcPatternObjectGet (pattern, FcBoolDefaults[i].field, 0, &v) == FcResultNoMatch)
	    FcPatternObjectAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value);

    if (FcPatternObjectGet (pattern, FC_PIXEL_SIZE_OBJECT, 0, &v) == FcResultNoMatch)
    {
	double	dpi, size, scale;

	if (FcPatternObjectGetDouble (pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch)
	{
	    size = 12.0;
	    (void) FcPatternObjectDel (pattern, FC_SIZE_OBJECT);
	    FcPatternObjectAddDouble (pattern, FC_SIZE_OBJECT, size);
	}
	if (FcPatternObjectGetDouble (pattern, FC_SCALE_OBJECT, 0, &scale) != FcResultMatch)
	{
	    scale = 1.0;
	    (void) FcPatternObjectDel (pattern, FC_SCALE_OBJECT);
	    FcPatternObjectAddDouble (pattern, FC_SCALE_OBJECT, scale);
	}
	size *= scale;
	if (FcPatternObjectGetDouble (pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch)
	{
	    dpi = 75.0;
	    (void) FcPatternObjectDel (pattern, FC_DPI_OBJECT);
	    FcPatternObjectAddDouble (pattern, FC_DPI_OBJECT, dpi);
	}
	size *= dpi / 72.0;
	FcPatternObjectAddDouble (pattern, FC_PIXEL_SIZE_OBJECT, size);
    }

    if (FcPatternObjectGet (pattern, FC_FONTVERSION_OBJECT, 0, &v) == FcResultNoMatch)
    {
	FcPatternObjectAddInteger (pattern, FC_FONTVERSION_OBJECT, 0x7fffffff);
    }

    if (FcPatternObjectGet (pattern, FC_HINT_STYLE_OBJECT, 0, &v) == FcResultNoMatch)
    {
	FcPatternObjectAddInteger (pattern, FC_HINT_STYLE_OBJECT, FC_HINT_FULL);
    }
    if (FcPatternObjectGet (pattern, FC_NAMELANG_OBJECT, 0, &v) == FcResultNoMatch)
    {
	FcPatternObjectAddString (pattern, FC_NAMELANG_OBJECT, FcGetDefaultLang ());
    }
    /* shouldn't be failed. */
    FcPatternObjectGet (pattern, FC_NAMELANG_OBJECT, 0, &namelang);
    /* Add a fallback to ensure the english name when the requested language
     * isn't available. this would helps for the fonts that have non-English
     * name at the beginning.
     */
    /* Set "en-us" instead of "en" to avoid giving higher score to "en".
     * This is a hack for the case that the orth is not like ll-cc, because,
     * if no namelang isn't explicitly set, it will has something like ll-cc
     * according to current locale. which may causes FcLangDifferentTerritory
     * at FcLangCompare(). thus, the English name is selected so that
     * exact matched "en" has higher score than ll-cc.
     */
    v2.type = FcTypeString;
    v2.u.s = FcStrdup ("en-us");
    if (FcPatternObjectGet (pattern, FC_FAMILYLANG_OBJECT, 0, &v) == FcResultNoMatch)
    {
	FcPatternObjectAdd (pattern, FC_FAMILYLANG_OBJECT, namelang, FcTrue);
	FcPatternObjectAddWithBinding (pattern, FC_FAMILYLANG_OBJECT, v2, FcValueBindingWeak, FcTrue);
    }
    if (FcPatternObjectGet (pattern, FC_STYLELANG_OBJECT, 0, &v) == FcResultNoMatch)
    {
	FcPatternObjectAdd (pattern, FC_STYLELANG_OBJECT, namelang, FcTrue);
	FcPatternObjectAddWithBinding (pattern, FC_STYLELANG_OBJECT, v2, FcValueBindingWeak, FcTrue);
    }
    if (FcPatternObjectGet (pattern, FC_FULLNAMELANG_OBJECT, 0, &v) == FcResultNoMatch)
    {
	FcPatternObjectAdd (pattern, FC_FULLNAMELANG_OBJECT, namelang, FcTrue);
	FcPatternObjectAddWithBinding (pattern, FC_FULLNAMELANG_OBJECT, v2, FcValueBindingWeak, FcTrue);
    }
    FcFree (v2.u.s);
}