2012-05-10 22 views
7

Tôi nghe rằng fontconfig là tùy chọn tốt nhất để nhận phông chữ trong linux. Thật không may, tôi đã xem qua tài liệu dành cho nhà phát triển của họ và tôi hoàn toàn không biết tôi đang làm gì. Nó sẽ xuất hiện không có chức năng đơn giản để có được một danh sách các phông chữ hệ thống. Tôi phải thực hiện tìm kiếm mẫu thay vì ... phải không?Cách sử dụng fontconfig để lấy danh sách phông chữ (C/C++)?

Tóm lại, cách tốt nhất để có được danh sách phông chữ đúng kiểu (gia đình, khuôn mặt và thư mục) của họ với fontconfig là gì? Tất nhiên, nếu có điều gì đó tốt hơn fontconfig, tôi chắc chắn sẽ mở ra các giải pháp khác.

Trả lời

4

Đây không phải chính xác những gì bạn đang yêu cầu, nhưng nó sẽ cung cấp cho bạn danh sách các phông chữ có sẵn.

#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

Tôi có một câu hỏi tương tự và thấy bài đăng này (tài liệu về phông chữ khó có thể vượt qua). Phản hồi của MindaugasJ rất hữu ích, nhưng hãy chú ý đến những dòng phụ gọi những thứ như FcPatternPrint() hoặc in ra các kết quả của FcNameUnparse(). Ngoài ra, bạn cần phải thêm đối số FC_FILE vào danh sách các đối số được chuyển đến FcObjectSetBuild. Một cái gì đó như thế này:

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); 

Tôi đã có một vấn đề hơi khác nhau để giải quyết trong rằng tôi cần phải tìm tập tin phông chữ để vượt qua để FC_New_Face() chức năng freetype của đưa ra một số font "tên". Mã này có thể sử dụng fontconfig để tìm tệp phù hợp nhất với tên:

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

Có lỗi chính tả trong mã của bạn: FcChar8 * tệp, kiểu, gia đình; Bạn quên thêm * cho phong cách và gia đình. Segfaults. –

+0

Tôi sẽ upvote nếu khiếu nại của Mislav đã được giải quyết. –

+0

Cảm ơn cả hai cho những người viết mã của bạn, nhưng khi tôi chạy nó, tôi đã nhận được xác nhận thời gian chạy. đầu ra: "Microsoft Visual Studio C thư viện thời gian chạy đã phát hiện một lỗi nghiêm trọng trong test-fontconfig.exe." – codekiddy

Các vấn đề liên quan