2012-05-10 17 views
7

Escuché que fontconfig es la mejor opción para obtener fuentes en Linux. Lamentablemente, he estado revisando su documentación de desarrollador y no tengo absolutamente ninguna pista de lo que estoy haciendo. Parece que no hay una función simple para obtener una lista de fuentes del sistema. Tengo que realizar una búsqueda de patrones en su lugar ... ¿verdad?¿Cómo se usa fontconfig para obtener la lista de fuentes (C/C++)?

En resumen, ¿cuál es la mejor manera de obtener una lista de tipos de letra verdaderos (su familia, cara y directorio) con fontconfig? Por supuesto, si hay algo mejor que fontconfig, ciertamente estoy abierto a otras soluciones.

Respuesta

4

Esto no es exactamente lo que está pidiendo, pero le dará la lista de fuentes disponibles.

#include <fontconfig.h> 

FcPattern *pat; 
FcFontSet *fs; 
FcObjectSet *os; 
FcChar8 *s, *file; 
FcConfig *config; 
FcBool result; 
int i; 

result = FcInit(); 
config = FcConfigGetCurrent(); 
FcConfigSetRescanInterval(config, 0); 

// show the fonts (debugging) 
pat = FcPatternCreate(); 
os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_LANG, (char *) 0); 
fs = FcFontList(config, pat, os); 
printf("Total fonts: %d", fs->nfont); 
for (i=0; fs && i < fs->nfont; i++) { 
FcPattern *font = fs->fonts[i];//FcFontSetFont(fs, i); 
FcPatternPrint(font); 
s = FcNameUnparse(font); 
if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) { 
    printf("Filename: %s", file); 
} 
printf("Font: %s", s); 
free(s); 
} 
if (fs) FcFontSetDestroy(fs); 
8

Tuve una pregunta similar, y encontré esta publicación (la documentación de fontconfig es un poco difícil de obtener). La respuesta de MindaugasJ fue útil, pero ten cuidado con las líneas adicionales llamando a cosas como FcPatternPrint() o imprimiendo los resultados de FcNameUnparse(). Además, debe agregar un argumento FC_FILE a la lista de argumentos pasados ​​a FcObjectSetBuild. Algo como esto:

FcConfig* config = FcInitLoadConfigAndFonts(); 
FcPattern* pat = FcPatternCreate(); 
FcObjectSet* os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, (char *) 0); 
FcFontSet* fs = FcFontList(config, pat, os); 
printf("Total matching fonts: %d\n", fs->nfont); 
for (int i=0; fs && i < fs->nfont; ++i) { 
    FcPattern* font = fs->fonts[i]; 
    FcChar8 *file, *style, *family; 
    if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch && 
     FcPatternGetString(font, FC_FAMILY, 0, &family) == FcResultMatch && 
     FcPatternGetString(font, FC_STYLE, 0, &style) == FcResultMatch) 
    { 
     printf("Filename: %s (family %s, style %s)\n", file, family, style); 
    } 
} 
if (fs) FcFontSetDestroy(fs); 

que tenía un problema ligeramente diferente de resolver en lo que necesitaba para encontrar el archivo de fuente para pasar a la función de FC_New_Face() freetype dado algún tipo de letra "nombre". Este código es capaz de utilizar fontconfig para encontrar el mejor archivo para que coincida con un nombre:

FcConfig* config = FcInitLoadConfigAndFonts(); 

// configure the search pattern, 
// assume "name" is a std::string with the desired font name in it 
FcPattern* pat = FcNameParse((const FcChar8*)(name.c_str())); 
FcConfigSubstitute(config, pat, FcMatchPattern); 
FcDefaultSubstitute(pat); 

// find the font 
FcPattern* font = FcFontMatch(config, pat, NULL); 
if (font) 
{ 
    FcChar8* file = NULL; 
    if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) 
    { 
     // save the file to another std::string 
     fontFile = (char*)file; 
    } 
    FcPatternDestroy(font); 
} 

FcPatternDestroy(pat); 
+1

hay error en su código: * FcChar8 archivo, el estilo, la familia; Olvidó agregar * por estilo y familia. Segfaults –

+0

Rechazaría si se abordaba la queja de Mislav. –

+0

Gracias a ambos por su código chicos, pero cuando ejecuté esto obtuve una afirmación en tiempo de ejecución. salida: "Microsoft Visual Studio C Runtime Library ha detectado un error fatal en test-fontconfig.exe". – codekiddy

Cuestiones relacionadas