Example #1
0
QStringList QFontconfigDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
{
    QStringList fallbackFamilies;
    FcPattern *pattern = FcPatternCreate();
    if (!pattern)
        return fallbackFamilies;

    FcValue value;
    value.type = FcTypeString;
    QByteArray cs = family.toUtf8();
    value.u.s = (const FcChar8 *)cs.data();
    FcPatternAdd(pattern,FC_FAMILY,value,true);

    int slant_value = FC_SLANT_ROMAN;
    if (style == QFont::StyleItalic)
        slant_value = FC_SLANT_ITALIC;
    else if (style == QFont::StyleOblique)
        slant_value = FC_SLANT_OBLIQUE;
    FcPatternAddInteger(pattern, FC_SLANT, slant_value);

    if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
        Q_ASSERT(script < QUnicodeTables::ScriptCount);
        FcLangSet *ls = FcLangSetCreate();
        FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
        FcPatternAddLangSet(pattern, FC_LANG, ls);
        FcLangSetDestroy(ls);
    }

    const char *stylehint = getFcFamilyForStyleHint(styleHint);
    if (stylehint) {
        value.u.s = (const FcChar8 *)stylehint;
        FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
    }

    FcConfigSubstitute(0, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);

    FcResult result = FcResultMatch;
    FcFontSet *fontSet = FcFontSort(0,pattern,FcFalse,0,&result);
    FcPatternDestroy(pattern);

    if (fontSet)
    {
        for (int i = 0; i < fontSet->nfont; i++) {
            FcChar8 *value = 0;
            if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
                continue;
            //         capitalize(value);
            QString familyName = QString::fromUtf8((const char *)value);
            if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive)) {
                fallbackFamilies << familyName;
            }
        }
        FcFontSetDestroy(fontSet);
    }
//    qDebug() << "fallbackFamilies for:" << family << fallbackFamilies;

    return fallbackFamilies;
}
Example #2
0
CAMLprim value pattern_add(value pat, value prop, value append)
{
  CAMLparam0();
  FcPatternAdd(FcPattern_val(pat),
      String_val(Field(prop, 0)),
      fcvalue_from_caml(Field(prop, 1)),
      Bool_val(append) ? FcTrue : FcFalse);
  CAMLreturn(Val_unit);
}
Example #3
0
static void claro_ft2_set_family(claro_font_pattern_t * pattern, const char * family)
{
    FcPattern * fc_pattern;
    FcValue val;
    
    val.u.s = family;
    val.type = FcTypeString;

    g_return_if_fail(pattern != NULL);

    fc_pattern = (FcPattern *)pattern->native;

    g_assert(FcPatternAdd(fc_pattern, FC_FAMILY, val, TRUE));     
}
Example #4
0
// coverity[+alloc : arg-*0]
GpStatus
GdipNewInstalledFontCollection (GpFontCollection **font_collection)
{
    if (!font_collection)
        return InvalidParameter;

    /*
     * Ensure we leak this data only a single time, because:
     * (a) there is no API to free it;
     * (b) other libgdiplus structures depends on that allocated data;
     */
    if (!system_fonts) {
        FcObjectSet *os = FcObjectSetBuild (FC_FAMILY, FC_FOUNDRY, NULL);
        FcPattern *pat = FcPatternCreate ();
        FcValue val;
        FcFontSet *col;

        /* Only Scalable fonts for now */
        val.type = FcTypeBool;
        val.u.b = FcTrue;
        FcPatternAdd (pat, FC_SCALABLE, val, TRUE);
        FcObjectSetAdd (os, FC_SCALABLE);

        col = FcFontList (0, pat, os);
        FcPatternDestroy (pat);
        FcObjectSetDestroy (os);

        system_fonts = (GpFontCollection *) GdipAlloc (sizeof (GpFontCollection));
        if (system_fonts) {
            system_fonts->fontset = col;
            system_fonts->config = NULL;
        }
    }

    *font_collection = system_fonts;
    return Ok;
}
Example #5
0
const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font,
                                                          const UChar* characters,
                                                          int length)
{
    FcCharSet* cset = FcCharSetCreate();
    for (int i = 0; i < length; ++i)
        FcCharSetAddChar(cset, characters[i]);

    FcPattern* pattern = FcPatternCreate();

    FcValue fcvalue;
    fcvalue.type = FcTypeCharSet;
    fcvalue.u.c = cset;
    FcPatternAdd(pattern, FC_CHARSET, fcvalue, 0);

    FcConfigSubstitute(0, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);

    FcResult result;
    FcPattern* match = FcFontMatch(0, pattern, &result);
    FcPatternDestroy(pattern);

    SimpleFontData* ret = 0;

    if (match) {
        FcChar8* family;
        if (FcPatternGetString(match, FC_FAMILY, 0, &family) == FcResultMatch) {
            AtomicString fontFamily(reinterpret_cast<char*>(family));
            ret = getCachedFontData(getCachedFontPlatformData(font.fontDescription(), fontFamily, false));
        }
        FcPatternDestroy(match);
    }

    FcCharSetDestroy(cset);

    return ret;
}
Example #6
0
FcPattern *
FcNameParse (const FcChar8 *name)
{
    FcChar8		*save;
    FcPattern		*pat;
    double		d;
    FcChar8		*e;
    FcChar8		delim;
    FcValue		v;
    FcMatrix		m;
    const FcObjectType	*t;
    const FcConstant	*c;

    /* freed below */
    save = malloc (strlen ((char *) name) + 1);
    if (!save)
	goto bail0;
    pat = FcPatternCreate ();
    if (!pat)
	goto bail1;

    for (;;)
    {
	name = FcNameFindNext (name, "-,:", save, &delim);
	if (save[0])
	{
	    if (!FcPatternAddString (pat, FC_FAMILY, save))
		goto bail2;
	}
	if (delim != ',')
	    break;
    }
    if (delim == '-')
    {
	for (;;)
	{
	    name = FcNameFindNext (name, "-,:", save, &delim);
	    d = strtod ((char *) save, (char **) &e);
	    if (e != save)
	    {
		if (!FcPatternAddDouble (pat, FC_SIZE, d))
		    goto bail2;
	    }
	    if (delim != ',')
		break;
	}
    }
    while (delim == ':')
    {
	name = FcNameFindNext (name, "=_:", save, &delim);
	if (save[0])
	{
	    if (delim == '=' || delim == '_')
	    {
		t = FcNameGetObjectType ((char *) save);
		for (;;)
		{
		    name = FcNameFindNext (name, ":,", save, &delim);
		    if (t)
		    {
			v = FcNameConvert (t->type, save, &m);
			if (!FcPatternAdd (pat, t->object, v, FcTrue))
			{
			    switch (v.type) {
			    case FcTypeCharSet:
				FcCharSetDestroy ((FcCharSet *) v.u.c);
				break;
			    case FcTypeLangSet:
				FcLangSetDestroy ((FcLangSet *) v.u.l);
				break;
			    default:
				break;
			    }
			    goto bail2;
			}
			switch (v.type) {
			case FcTypeCharSet:
			    FcCharSetDestroy ((FcCharSet *) v.u.c);
			    break;
			case FcTypeLangSet:
			    FcLangSetDestroy ((FcLangSet *) v.u.l);
			    break;
			default:
			    break;
			}
		    }
		    if (delim != ',')
			break;
		}
	    }
	    else
	    {
		if ((c = FcNameGetConstant (save)))
		{
		    if (!FcPatternAddInteger (pat, c->object, c->value))
			goto bail2;
		}
	    }
	}
    }

    free (save);
    return pat;

bail2:
    FcPatternDestroy (pat);
bail1:
    free (save);
bail0:
    return 0;
}
Example #7
0
static FcBool
FcListAppend (FcListHashTable	*table,
	      FcPattern		*font,
	      FcObjectSet	*os,
	      const FcChar8	*lang)
{
    int		    o;
    FcPatternElt    *e;
    FcValueListPtr  v;
    FcChar32	    hash;
    FcListBucket    **prev, *bucket;
    int             familyidx = -1;
    int             fullnameidx = -1;
    int             styleidx = -1;
    int             defidx = 0;
    int             idx;

    hash = FcListPatternHash (font, os);
    for (prev = &table->buckets[hash % FC_LIST_HASH_SIZE];
	 (bucket = *prev); prev = &(bucket->next))
    {
	if (bucket->hash == hash &&
	    FcListPatternEqual (bucket->pattern, font, os))
	    return FcTrue;
    }
    bucket = (FcListBucket *) malloc (sizeof (FcListBucket));
    if (!bucket)
	goto bail0;
    FcMemAlloc (FC_MEM_LISTBUCK, sizeof (FcListBucket));
    bucket->next = 0;
    bucket->hash = hash;
    bucket->pattern = FcPatternCreate ();
    if (!bucket->pattern)
	goto bail1;

    for (o = 0; o < os->nobject; o++)
    {
	if (!strcmp (os->objects[o], FC_FAMILY) || !strcmp (os->objects[o], FC_FAMILYLANG))
	{
	    if (familyidx < 0)
		familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG_OBJECT, lang);
	    defidx = familyidx;
	}
	else if (!strcmp (os->objects[o], FC_FULLNAME) || !strcmp (os->objects[o], FC_FULLNAMELANG))
	{
	    if (fullnameidx < 0)
		fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG_OBJECT, lang);
	    defidx = fullnameidx;
	}
	else if (!strcmp (os->objects[o], FC_STYLE) || !strcmp (os->objects[o], FC_STYLELANG))
	{
	    if (styleidx < 0)
		styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG_OBJECT, lang);
	    defidx = styleidx;
	}
	else
	    defidx = 0;

	e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[o]));
	if (e)
	{
	    for (v = FcPatternEltValues(e), idx = 0; v;
		 v = FcValueListNext(v), ++idx)
	    {
		if (!FcPatternAdd (bucket->pattern,
				   os->objects[o],
				   FcValueCanonicalize(&v->value), defidx != idx))
		    goto bail2;
	    }
	}
    }
    *prev = bucket;
    ++table->entries;

    return FcTrue;

bail2:
    FcPatternDestroy (bucket->pattern);
bail1:
    FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket));
    free (bucket);
bail0:
    return FcFalse;
}
Example #8
0
void WebFontInfo::renderStyleForStrike(const char* family, int sizeAndStyle, WebFontRenderStyle* out)
{
    bool isBold = sizeAndStyle & 1;
    bool isItalic = sizeAndStyle & 2;
    int pixelSize = sizeAndStyle >> 2;

    FcPattern* pattern = FcPatternCreate();
    FcValue fcvalue;

    fcvalue.type = FcTypeString;
    fcvalue.u.s = reinterpret_cast<const FcChar8 *>(family);
    FcPatternAdd(pattern, FC_FAMILY, fcvalue, FcFalse);

    fcvalue.type = FcTypeInteger;
    fcvalue.u.i = isBold ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL;
    FcPatternAdd(pattern, FC_WEIGHT, fcvalue, FcFalse);

    fcvalue.type = FcTypeInteger;
    fcvalue.u.i = isItalic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN;
    FcPatternAdd(pattern, FC_SLANT, fcvalue, FcFalse);

    fcvalue.type = FcTypeBool;
    fcvalue.u.b = FcTrue;
    FcPatternAdd(pattern, FC_SCALABLE, fcvalue, FcFalse);

    fcvalue.type = FcTypeDouble;
    fcvalue.u.d = pixelSize;
    FcPatternAdd(pattern, FC_SIZE, fcvalue, FcFalse);

    FcConfigSubstitute(0, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);

    FcResult result;
    // Some versions of fontconfig don't actually write a value into result.
    // However, it's not clear from the documentation if result should be a
    // non-0 pointer: future versions might expect to be able to write to
    // it. So we pass in a valid pointer and ignore it.
    FcPattern* match = FcFontMatch(0, pattern, &result);
    FcPatternDestroy(pattern);

    out->setDefaults();

    if (!match)
        return;

    FcBool b;
    int i;

    if (FcPatternGetBool(match, FC_ANTIALIAS, 0, &b) == FcResultMatch)
        out->useAntiAlias = b;
    if (FcPatternGetBool(match, FC_EMBEDDED_BITMAP, 0, &b) == FcResultMatch)
        out->useBitmaps = b;
    if (FcPatternGetBool(match, FC_AUTOHINT, 0, &b) == FcResultMatch)
        out->useAutoHint = b;
    if (FcPatternGetBool(match, FC_HINTING, 0, &b) == FcResultMatch)
        out->useHinting = b;
    if (FcPatternGetInteger(match, FC_HINT_STYLE, 0, &i) == FcResultMatch)
        out->hintStyle = i;
    if (FcPatternGetInteger(match, FC_RGBA, 0, &i) == FcResultMatch) {
        switch (i) {
        case FC_RGBA_NONE:
            out->useSubpixel = 0;
            break;
        case FC_RGBA_RGB:
        case FC_RGBA_BGR:
        case FC_RGBA_VRGB:
        case FC_RGBA_VBGR:
            out->useSubpixel = 1;
            break;
        default:
            // This includes FC_RGBA_UNKNOWN.
            out->useSubpixel = 2;
            break;
        }
    }

    FcPatternDestroy(match);
}
Example #9
0
QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
    QStringList fallbackFamilies;
    FcPattern *pattern = FcPatternCreate();
    if (!pattern)
        return fallbackFamilies;

    FcValue value;
    value.type = FcTypeString;
    QByteArray cs = family.toUtf8();
    value.u.s = (const FcChar8 *)cs.data();
    FcPatternAdd(pattern,FC_FAMILY,value,true);

    int slant_value = FC_SLANT_ROMAN;
    if (style == QFont::StyleItalic)
        slant_value = FC_SLANT_ITALIC;
    else if (style == QFont::StyleOblique)
        slant_value = FC_SLANT_OBLIQUE;
    FcPatternAddInteger(pattern, FC_SLANT, slant_value);

    Q_ASSERT(uint(script) < QChar::ScriptCount);
    if (*specialLanguages[script] != '\0') {
        FcLangSet *ls = FcLangSetCreate();
        FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
        FcPatternAddLangSet(pattern, FC_LANG, ls);
        FcLangSetDestroy(ls);
    } else if (!family.isEmpty()) {
        // If script is Common or Han, then it may include languages like CJK,
        // we should attach system default language set to the pattern
        // to obtain correct font fallback list (i.e. if LANG=zh_CN
        // then we normally want to use a Chinese font for CJK text;
        // while a Japanese font should be used for that if LANG=ja)
        FcPattern *dummy = FcPatternCreate();
        FcDefaultSubstitute(dummy);
        FcChar8 *lang = 0;
        FcResult res = FcPatternGetString(dummy, FC_LANG, 0, &lang);
        if (res == FcResultMatch)
            FcPatternAddString(pattern, FC_LANG, lang);
        FcPatternDestroy(dummy);
    }

    const char *stylehint = getFcFamilyForStyleHint(styleHint);
    if (stylehint) {
        value.u.s = (const FcChar8 *)stylehint;
        FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
    }

    FcConfigSubstitute(0, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);

    FcResult result = FcResultMatch;
    FcFontSet *fontSet = FcFontSort(0,pattern,FcFalse,0,&result);
    FcPatternDestroy(pattern);

    if (fontSet) {
        for (int i = 0; i < fontSet->nfont; i++) {
            FcChar8 *value = 0;
            if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
                continue;
            //         capitalize(value);
            QString familyName = QString::fromUtf8((const char *)value);
            if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive) &&
                familyName.compare(family, Qt::CaseInsensitive)) {
                fallbackFamilies << familyName;
            }
        }
        FcFontSetDestroy(fontSet);
    }
//    qDebug() << "fallbackFamilies for:" << family << style << styleHint << script << fallbackFamilies;

    return fallbackFamilies;
}
Example #10
0
QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QChar::Script script, void *usrPtr)
{
    if (!usrPtr)
        return 0;
    QFontDef fontDef = f;

    QFontEngineFT *engine;
    FontFile *fontfile = static_cast<FontFile *> (usrPtr);
    QFontEngine::FaceId fid;
    fid.filename = QFile::encodeName(fontfile->fileName);
    fid.index = fontfile->indexValue;

    bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
    engine = new QFontEngineFT(fontDef);

    QFontEngineFT::GlyphFormat format;
    // try and get the pattern
    FcPattern *pattern = FcPatternCreate();

    FcValue value;
    value.type = FcTypeString;
        QByteArray cs = fontDef.family.toUtf8();
    value.u.s = (const FcChar8 *)cs.data();
    FcPatternAdd(pattern,FC_FAMILY,value,true);

    value.u.s = (const FcChar8 *)fid.filename.data();
    FcPatternAdd(pattern,FC_FILE,value,true);

    value.type = FcTypeInteger;
    value.u.i = fid.index;
    FcPatternAdd(pattern,FC_INDEX,value,true);

    FcResult result;
    FcPattern *match = FcFontMatch(0, pattern, &result);
    if (match) {
        QFontEngineFT::HintStyle default_hint_style;
        if (f.hintingPreference != QFont::PreferDefaultHinting) {
            switch (f.hintingPreference) {
            case QFont::PreferNoHinting:
                default_hint_style = QFontEngineFT::HintNone;
                break;
            case QFont::PreferVerticalHinting:
                default_hint_style = QFontEngineFT::HintLight;
                break;
            case QFont::PreferFullHinting:
            default:
                default_hint_style = QFontEngineFT::HintFull;
                break;
            }
        } else {
            int hint_style = 0;
            if (FcPatternGetInteger (match, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
                hint_style = QFontEngineFT::HintFull;
            switch (hint_style) {
            case FC_HINT_NONE:
                default_hint_style = QFontEngineFT::HintNone;
                break;
            case FC_HINT_SLIGHT:
                default_hint_style = QFontEngineFT::HintLight;
                break;
            case FC_HINT_MEDIUM:
                default_hint_style = QFontEngineFT::HintMedium;
                break;
            default:
                default_hint_style = QFontEngineFT::HintFull;
                break;
            }
        }

        if (antialias) {
            // If antialiasing is not fully disabled, fontconfig may still disable it on a font match basis.
            FcBool fc_antialias;
            if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) != FcResultMatch)
                fc_antialias = true;
            antialias = fc_antialias;
        }

        if (f.hintingPreference == QFont::PreferDefaultHinting) {
            const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services();
            if (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY")) {
                void *hintStyleResource =
                        QGuiApplication::platformNativeInterface()->nativeResourceForScreen("hintstyle",
                                                                                            QGuiApplication::primaryScreen());
                int hintStyle = int(reinterpret_cast<qintptr>(hintStyleResource));
                if (hintStyle > 0)
                    default_hint_style = QFontEngine::HintStyle(hintStyle - 1);
            }
        }

        engine->setDefaultHintStyle(default_hint_style);

        if (antialias) {
            QFontEngineFT::SubpixelAntialiasingType subpixelType = QFontEngineFT::Subpixel_None;
            int subpixel = FC_RGBA_NONE;

            FcPatternGetInteger(match, FC_RGBA, 0, &subpixel);
            if (subpixel == FC_RGBA_UNKNOWN)
                subpixel = FC_RGBA_NONE;

            switch (subpixel) {
                case FC_RGBA_NONE: subpixelType = QFontEngineFT::Subpixel_None; break;
                case FC_RGBA_RGB: subpixelType = QFontEngineFT::Subpixel_RGB; break;
                case FC_RGBA_BGR: subpixelType = QFontEngineFT::Subpixel_BGR; break;
                case FC_RGBA_VRGB: subpixelType = QFontEngineFT::Subpixel_VRGB; break;
                case FC_RGBA_VBGR: subpixelType = QFontEngineFT::Subpixel_VBGR; break;
                default: break;
            }

            format = subpixelType == QFontEngineFT::Subpixel_None
                        ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_A32;
            engine->subpixelType = subpixelType;
        } else
            format = QFontEngineFT::Format_Mono;

        FcPatternDestroy(match);
    } else
        format = antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;

    FcPatternDestroy(pattern);

    if (!engine->init(fid,antialias,format)) {
        delete engine;
        engine = 0;
        return engine;
    }
    if (engine->invalid()) {
        delete engine;
        engine = 0;
    } else if (!engine->supportsScript(script)) {
        qWarning("  OpenType support missing for script %d", int(script));
        delete engine;
        engine = 0;
    }

    return engine;
}
Example #11
0
vlc_family_t *FontConfig_GetFallbacks( filter_t *p_filter, const char *psz_family,
                                       uni_char_t codepoint )
{

    VLC_UNUSED( codepoint );

    vlc_family_t *p_family = NULL;
    filter_sys_t *p_sys    = p_filter->p_sys;

    char *psz_lc = ToLower( psz_family );

    if( unlikely( !psz_lc ) )
        return NULL;

    p_family = vlc_dictionary_value_for_key( &p_sys->fallback_map, psz_lc );

    if( p_family != kVLCDictionaryNotFound )
    {
        free( psz_lc );
        return p_family;
    }
    else
        p_family = NULL;

    const char *psz_last_name = "";
    FcPattern  *p_pattern = FcPatternCreate();
    FcValue     family;
    family.type = FcTypeString;
    family.u.s = ( const FcChar8* ) psz_family;
    FcPatternAdd( p_pattern, FC_FAMILY, family, FcFalse );
    if( FcConfigSubstitute( NULL, p_pattern, FcMatchPattern ) == FcTrue )
    {
        FcDefaultSubstitute( p_pattern );
        FcResult result;
        FcFontSet* p_font_set = FcFontSort( NULL, p_pattern, FcTrue, NULL, &result );
        if( p_font_set )
        {
            for( int i = 0; i < p_font_set->nfont; ++i )
            {
                char* psz_name = NULL;
                FcPatternGetString( p_font_set->fonts[i],
                                    FC_FAMILY, 0, ( FcChar8** )( &psz_name ) );

                /* Avoid duplicate family names */
                if( strcasecmp( psz_last_name, psz_name ) )
                {
                    vlc_family_t *p_temp = NewFamily( p_filter, psz_name,
                                                      &p_family, NULL, NULL );

                    if( unlikely( !p_temp ) )
                    {
                        FcFontSetDestroy( p_font_set );
                        FcPatternDestroy( p_pattern );
                        if( p_family )
                            FreeFamilies( p_family, NULL );
                        free( psz_lc );
                        return NULL;
                    }

                    psz_last_name = p_temp->psz_name;
                }
            }
            FcFontSetDestroy( p_font_set );
        }
    }
    FcPatternDestroy( p_pattern );

    if( p_family )
        vlc_dictionary_insert( &p_sys->fallback_map, psz_lc, p_family );

    free( psz_lc );
    return p_family;
}
Example #12
0
File: xftpat.c Project: aosm/X11
Bool
XftPatternAdd (XftPattern *p, const char *object, XftValue value, Bool append)
{
    return FcPatternAdd (p, object, value, append);
}
Example #13
0
void WebFontInfo::fallbackFontForChar(WebUChar32 c, const char* preferredLocale, WebFallbackFont* fallbackFont)
{
    FcCharSet* cset = FcCharSetCreate();
    FcCharSetAddChar(cset, c);
    FcPattern* pattern = FcPatternCreate();

    FcValue fcvalue;
    fcvalue.type = FcTypeCharSet;
    fcvalue.u.c = cset;
    FcPatternAdd(pattern, FC_CHARSET, fcvalue, FcFalse);

    fcvalue.type = FcTypeBool;
    fcvalue.u.b = FcTrue;
    FcPatternAdd(pattern, FC_SCALABLE, fcvalue, FcFalse);

    if (preferredLocale) {
        FcLangSet* langset = FcLangSetCreate();
        FcLangSetAdd(langset, reinterpret_cast<const FcChar8 *>(preferredLocale));
        FcPatternAddLangSet(pattern, FC_LANG, langset);
        FcLangSetDestroy(langset);
    }

    FcConfigSubstitute(0, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);

    FcResult result;
    FcFontSet* fontSet = FcFontSort(0, pattern, 0, 0, &result);
    FcPatternDestroy(pattern);
    FcCharSetDestroy(cset);

    if (!fontSet) {
        fallbackFont->name = WebCString();
        fallbackFont->isBold = false;
        fallbackFont->isItalic = false;
        return;
    }
    // Older versions of fontconfig have a bug where they cannot select
    // only scalable fonts so we have to manually filter the results.
    for (int i = 0; i < fontSet->nfont; ++i) {
        FcPattern* current = fontSet->fonts[i];
        FcBool isScalable;

        if (FcPatternGetBool(current, FC_SCALABLE, 0, &isScalable) != FcResultMatch
            || !isScalable)
            continue;

        // fontconfig can also return fonts which are unreadable
        FcChar8* cFilename;
        if (FcPatternGetString(current, FC_FILE, 0, &cFilename) != FcResultMatch)
            continue;

        if (access(reinterpret_cast<char*>(cFilename), R_OK))
            continue;

        const char* fontFilename = reinterpret_cast<char*>(cFilename);
        fallbackFont->filename = WebCString(fontFilename, strlen(fontFilename));

        // Index into font collection.
        int ttcIndex;
        if (FcPatternGetInteger(current, FC_INDEX, 0, &ttcIndex) != FcResultMatch && ttcIndex < 0)
            continue;
        fallbackFont->ttcIndex = ttcIndex;

        FcChar8* familyName;
        if (FcPatternGetString(current, FC_FAMILY, 0, &familyName) == FcResultMatch) {
            const char* charFamily = reinterpret_cast<char*>(familyName);
            fallbackFont->name = WebCString(charFamily, strlen(charFamily));
        }
        int weight;
        if (FcPatternGetInteger(current, FC_WEIGHT, 0, &weight) == FcResultMatch)
            fallbackFont->isBold = weight >= FC_WEIGHT_BOLD;
        else
            fallbackFont->isBold = false;
        int slant;
        if (FcPatternGetInteger(current, FC_SLANT, 0, &slant) == FcResultMatch)
            fallbackFont->isItalic = slant != FC_SLANT_ROMAN;
        else
            fallbackFont->isItalic = false;
        FcFontSetDestroy(fontSet);
        return;
    }

    FcFontSetDestroy(fontSet);
}
Example #14
0
QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::Script script, void *usrPtr)
{
    if (!usrPtr)
        return 0;
    QFontDef fontDef = f;

    QFontEngineFT *engine;
    FontFile *fontfile = static_cast<FontFile *> (usrPtr);
    QFontEngine::FaceId fid;
    fid.filename = fontfile->fileName.toLocal8Bit();
    fid.index = fontfile->indexValue;

    bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
    engine = new QFontEngineFT(fontDef);

    QFontEngineFT::GlyphFormat format;
    // try and get the pattern
    FcPattern *pattern = FcPatternCreate();

    FcValue value;
    value.type = FcTypeString;
        QByteArray cs = fontDef.family.toUtf8();
    value.u.s = (const FcChar8 *)cs.data();
    FcPatternAdd(pattern,FC_FAMILY,value,true);

    value.u.s = (const FcChar8 *)fid.filename.data();
    FcPatternAdd(pattern,FC_FILE,value,true);

    value.type = FcTypeInteger;
    value.u.i = fid.index;
    FcPatternAdd(pattern,FC_INDEX,value,true);

    FcResult result;
    FcPattern *match = FcFontMatch(0, pattern, &result);
    if (match) {
        QFontEngineFT::HintStyle default_hint_style;
        if (f.hintingPreference != QFont::PreferDefaultHinting) {
            switch (f.hintingPreference) {
            case QFont::PreferNoHinting:
                default_hint_style = QFontEngineFT::HintNone;
                break;
            case QFont::PreferVerticalHinting:
                default_hint_style = QFontEngineFT::HintLight;
                break;
            case QFont::PreferFullHinting:
            default:
                default_hint_style = QFontEngineFT::HintFull;
                break;
            }
        } else {
            int hint_style = 0;
            if (FcPatternGetInteger (match, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
                hint_style = QFontEngineFT::HintFull;
            switch (hint_style) {
            case FC_HINT_NONE:
                default_hint_style = QFontEngineFT::HintNone;
                break;
            case FC_HINT_SLIGHT:
                default_hint_style = QFontEngineFT::HintLight;
                break;
            case FC_HINT_MEDIUM:
                default_hint_style = QFontEngineFT::HintMedium;
                break;
            default:
                default_hint_style = QFontEngineFT::HintFull;
                break;
            }
        }
        engine->setDefaultHintStyle(default_hint_style);

        if (antialias) {
            QFontEngineFT::SubpixelAntialiasingType subpixelType = QFontEngineFT::Subpixel_None;
            int subpixel = FC_RGBA_NONE;

            FcPatternGetInteger(match, FC_RGBA, 0, &subpixel);
            if (subpixel == FC_RGBA_UNKNOWN)
                subpixel = FC_RGBA_NONE;

            switch (subpixel) {
                case FC_RGBA_NONE: subpixelType = QFontEngineFT::Subpixel_None; break;
                case FC_RGBA_RGB: subpixelType = QFontEngineFT::Subpixel_RGB; break;
                case FC_RGBA_BGR: subpixelType = QFontEngineFT::Subpixel_BGR; break;
                case FC_RGBA_VRGB: subpixelType = QFontEngineFT::Subpixel_VRGB; break;
                case FC_RGBA_VBGR: subpixelType = QFontEngineFT::Subpixel_VBGR; break;
                default: break;
            }

            format = subpixelType == QFontEngineFT::Subpixel_None
                        ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_A32;
            engine->subpixelType = subpixelType;
        } else
            format = QFontEngineFT::Format_Mono;

        FcPatternDestroy(match);
    } else
        format = antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;

    FcPatternDestroy(pattern);

    if (!engine->init(fid,antialias,format)) {
        delete engine;
        engine = 0;
        return engine;
    }
    if (engine->invalid()) {
        delete engine;
        engine = 0;
    } else if (scriptRequiresOpenType(script)) {
        HB_Face hbFace = engine->initializedHarfbuzzFace();
        if (!hbFace || !hbFace->supported_scripts[script]) {
            delete engine;
            engine = 0;
        }
    }

    return engine;
}
Example #15
0
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, const char *str)
{
	if (!FcInit()) return false;

	bool ret = false;

	/* Fontconfig doesn't handle full language isocodes, only the part
	 * before the _ of e.g. en_GB is used, so "remove" everything after
	 * the _. */
	char lang[16];
	strecpy(lang, language_isocode, lastof(lang));
	char *split = strchr(lang, '_');
	if (split != NULL) *split = '\0';

	FcPattern *pat;
	FcPattern *match;
	FcResult result;
	FcChar8 *file;
	FcFontSet *fs;
	FcValue val;
	val.type = FcTypeString;
	val.u.s = (FcChar8*)lang;

	/* First create a pattern to match the wanted language */
	pat = FcPatternCreate();
	/* And fill it with the language and other defaults */
	if (pat == NULL ||
			!FcPatternAdd(pat, "lang", val, false) ||
			!FcConfigSubstitute(0, pat, FcMatchPattern)) {
		goto error_pattern;
	}

	FcDefaultSubstitute(pat);

	/* Then create a font set and match that */
	match = FcFontMatch(0, pat, &result);

	if (match == NULL) {
		goto error_pattern;
	}

	/* Find all fonts that do match */
	fs = FcFontSetCreate();
	FcFontSetAdd(fs, match);

	/* And take the first, if it exists */
	if (fs->nfont <= 0 || FcPatternGetString(fs->fonts[0], FC_FILE, 0, &file)) {
		goto error_fontset;
	}

	strecpy(settings->small_font,  (const char*)file, lastof(settings->small_font));
	strecpy(settings->medium_font, (const char*)file, lastof(settings->medium_font));
	strecpy(settings->large_font,  (const char*)file, lastof(settings->large_font));

	ret = true;

error_fontset:
	FcFontSetDestroy(fs);
error_pattern:
	if (pat != NULL) FcPatternDestroy(pat);
	FcFini();
	return ret;
}
Example #16
0
QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::Script script, void *usrPtr)
{
    if (!usrPtr)
        return 0;
    QFontDef fontDef = f;

    QFontEngineFT *engine;
    FontFile *fontfile = static_cast<FontFile *> (usrPtr);
    QFontEngine::FaceId fid;
    fid.filename = fontfile->fileName.toLocal8Bit();
    fid.index = fontfile->indexValue;

    //try and get the pattern
    FcPattern *pattern = FcPatternCreate();

    bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
    QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;

    engine = new QFontEngineFT(fontDef);

    FcValue value;
    value.type = FcTypeString;
        QByteArray cs = fontDef.family.toUtf8();
    value.u.s = (const FcChar8 *)cs.data();
    FcPatternAdd(pattern,FC_FAMILY,value,true);


    value.u.s = (const FcChar8 *)fid.filename.data();
    FcPatternAdd(pattern,FC_FILE,value,true);

    value.type = FcTypeInteger;
    value.u.i = fid.index;
    FcPatternAdd(pattern,FC_INDEX,value,true);

    QFontEngineFT::HintStyle default_hint_style;

    if (FcConfigSubstitute(0,pattern,FcMatchPattern)) {

        //hinting
        int hint_style = 0;
        if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
            hint_style = QFontEngineFT::HintFull;
        switch (hint_style) {
        case FC_HINT_NONE:
            default_hint_style = QFontEngineFT::HintNone;
            break;
        case FC_HINT_SLIGHT:
            default_hint_style = QFontEngineFT::HintLight;
            break;
        case FC_HINT_MEDIUM:
            default_hint_style = QFontEngineFT::HintMedium;
            break;
        default:
            default_hint_style = QFontEngineFT::HintFull;
            break;
        }
    }

    engine->setDefaultHintStyle(default_hint_style);
    if (!engine->init(fid,antialias,format)) {
        delete engine;
        engine = 0;
        return engine;
    }
    if (engine->invalid()) {
        delete engine;
        engine = 0;
    } else if (scriptRequiresOpenType(script)) {
        HB_Face hbFace = engine->harfbuzzFace();
        if (!hbFace || !hbFace->supported_scripts[script]) {
            delete engine;
            engine = 0;
        }
    }

    return engine;
}
Example #17
0
Common::SeekableReadStream *FontconfigFontProvider::createReadStreamForFont(const Common::String &name, uint32 style) {
	if (!_config)
		return 0;

	Common::String styleName = makeStyleString(style);

	FcPattern *pattern = FcPatternCreate();

	// Match on the family name
	FcValue value;
	value.type = FcTypeString;
	value.u.s = reinterpret_cast<const FcChar8 *>(name.c_str());
	if (!FcPatternAdd(pattern, FC_FAMILY, value, FcFalse)) {
		FcPatternDestroy(pattern);
		return 0;
	}

	// Match on the style string
	value.u.s = reinterpret_cast<const FcChar8 *>(styleName.c_str());
	if (!FcPatternAdd(pattern, FC_STYLE, value, FcFalse)) {
		FcPatternDestroy(pattern);
		return 0;
	}

	// Only allow TrueType fonts
	// Might change in the future.
	value.u.s = reinterpret_cast<const FcChar8 *>("TrueType");
	if (!FcPatternAdd(pattern, FC_FONTFORMAT, value, FcFalse)) {
		FcPatternDestroy(pattern);
		return 0;
	}

	// Call these functions
	// Might be doing pattern matching. Documentation is awful.
	FcConfigSubstitute(0, pattern, FcMatchPattern);
	FcDefaultSubstitute(pattern);

	// Fetch the match
	FcResult result;
	FcFontSet* fontSet = FcFontSort(0, pattern, 0, 0, &result);
	FcPatternDestroy(pattern);

	if (!fontSet)
		return 0;

	for (int i = 0; i < fontSet->nfont; i++) {
		FcPattern *foundPattern = fontSet->fonts[i];

		// Get the family name of the font
		FcChar8 *familyName;
		if (FcPatternGetString(foundPattern, FC_FAMILY, 0, &familyName) != FcResultMatch)
			continue;

		// If we don't actually match, bail out. We don't want to end
		// up with the default fontconfig font, which would look horrible.
		if (!name.equalsIgnoreCase(reinterpret_cast<const char *>(familyName)))
			continue;

		// Get the name of the font
		FcChar8 *fileName;
		if (FcPatternGetString(foundPattern, FC_FILE, 0, &fileName) != FcResultMatch)
			continue;

		// Let's make sure we can actually get that
		Common::FSNode fontNode(reinterpret_cast<const char *>(fileName));
		if (!fontNode.exists() || !fontNode.isReadable())
			continue;

		debug(1, "Matched %s %s -> '%s'", name.c_str(), styleName.c_str(), fontNode.getPath().c_str());

		FcFontSetDestroy(fontSet);
		return fontNode.createReadStream();
	}

	// We ain't found s#&t
	FcFontSetDestroy(fontSet);
	return 0;
}
Example #18
0
    void find_font(font & f, std::string const& name, int height, int weight, int style)
    {
        // FIXME: shouldn't require fonts to be empty
        BOOST_ASSERT(!f);

        FcValue fcval;

        // build pattern
        FcPattern * pattern = FcPatternCreate();

        // typeface name
        fcval.type = FcTypeString;
        fcval.u.s = (FcChar8 const*) name.c_str();
        FcPatternAdd(pattern, FC_FAMILY, fcval, FcTrue);

        // pixel size
        fcval.type = FcTypeInteger;
        fcval.u.i = height;
        FcPatternAdd(pattern, FC_PIXEL_SIZE, fcval, FcTrue);

        // italic
        if (style & font_style::italic)
        {
            fcval.type = FcTypeInteger;
            fcval.u.i = FC_SLANT_ITALIC;
            FcPatternAdd(pattern, FC_SLANT, fcval, FcTrue);
        }

        // weight
        fcval.type = FcTypeInteger;
        switch (weight)
        {
        case font_weight::thin:          fcval.u.i = FC_WEIGHT_THIN; break;
        case font_weight::extra_light:   fcval.u.i = FC_WEIGHT_EXTRALIGHT; break;
        case font_weight::light:         fcval.u.i = FC_WEIGHT_LIGHT; break;
        case font_weight::normal:        fcval.u.i = FC_WEIGHT_NORMAL; break;
        case font_weight::medium:        fcval.u.i = FC_WEIGHT_MEDIUM; break;
        case font_weight::semi_bold:     fcval.u.i = FC_WEIGHT_SEMIBOLD; break;
        case font_weight::bold:          fcval.u.i = FC_WEIGHT_BOLD; break;
        case font_weight::ultra_bold:    fcval.u.i = FC_WEIGHT_ULTRABOLD; break;
        case font_weight::heavy:         fcval.u.i = FC_WEIGHT_HEAVY; break;
        default:                         fcval.u.i = FC_WEIGHT_NORMAL; break;
        };
        FcPatternAdd(pattern, FC_WEIGHT, fcval, FcTrue);

        // transform pattern
        FcConfigSubstitute(NULL, pattern, FcMatchPattern);
        FcDefaultSubstitute(pattern);

        FcResult res;
        FcPattern * real_pattern = FcFontMatch(NULL, pattern, &res);

        FcPatternDestroy(pattern);

        // get filename
        if (real_pattern)
        {
            char * fname;
            int id;

            FcPatternGetString(real_pattern, FC_FILE, 0, (FcChar8 **) &fname);
            FcPatternGetInteger(real_pattern, FC_INDEX, 0, &id);

            // load font
            FT_Face face;
            if (FT_New_Face(::ftlib, fname, id, &face))
                return;

            FcPatternDestroy(real_pattern);

            // create font
            ft_font_extra * extra = static_cast<ft_font_extra *>(f.extra_data);

            extra->face = face;

            FT_Set_Pixel_Sizes(face, 0, height);

            // get avg char width/height
            point pt = detail::font_units_to_pixels(face, face->max_advance_width, face->max_advance_height);
            extra->width = pt.x;
            extra->height = pt.y;

            pt = detail::font_units_to_pixels(face, 0, face->ascender);
            extra->ascender = pt.y;

            pt = detail::font_units_to_pixels(face, 0, face->descender);
            extra->descender = pt.y;
        }
    }