// 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; }
static void gimp_font_list_load_names (GimpFontList *list, PangoFontMap *fontmap, PangoContext *context) { FcObjectSet *os; FcPattern *pat; FcFontSet *fontset; gint i; os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_SLANT, FC_WEIGHT, FC_WIDTH, NULL); pat = FcPatternCreate (); fontset = FcFontList (NULL, pat, os); FcPatternDestroy (pat); FcObjectSetDestroy (os); for (i = 0; i < fontset->nfont; i++) { PangoFontDescription *desc; desc = pango_fc_font_description_from_pattern (fontset->fonts[i], FALSE); gimp_font_list_add_font (list, context, desc); pango_font_description_free (desc); } /* only create aliases if there is at least one font available */ if (fontset->nfont > 0) gimp_font_list_load_aliases (list, context); FcFontSetDestroy (fontset); }
nsresult gfxQtPlatform::UpdateFontList() { FcPattern *pat = NULL; FcObjectSet *os = NULL; FcFontSet *fs = NULL; PRInt32 result = -1; pat = FcPatternCreate(); os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_WEIGHT, FC_SLANT, FC_WIDTH, NULL); fs = FcFontList(NULL, pat, os); for (int i = 0; i < fs->nfont; i++) { char *str; if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch) continue; printf("Family: %s\n", str); nsAutoString name(NS_ConvertUTF8toUTF16(nsDependentCString(str)).get()); nsAutoString key(name); ToLowerCase(key); nsRefPtr<FontFamily> ff; if (!gPlatformFonts->Get(key, &ff)) { ff = new FontFamily(name); gPlatformFonts->Put(key, ff); } FontEntry *fe = new FontEntry(ff->Name()); ff->AddFontEntry(fe); if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, (FcChar8 **) &str) == FcResultMatch) { fe->mFilename = nsDependentCString(str); printf(" - file: %s\n", str); } int x; if (FcPatternGetInteger(fs->fonts[i], FC_INDEX, 0, &x) == FcResultMatch) { printf(" - index: %d\n", x); fe->mFTFontIndex = x; } else { fe->mFTFontIndex = 0; } if (FcPatternGetInteger(fs->fonts[i], FC_WEIGHT, 0, &x) == FcResultMatch) { switch(x) { case 0: fe->mWeight = 100; break; case 40: fe->mWeight = 200; break; case 50: fe->mWeight = 300; break; case 75: case 80: fe->mWeight = 400; break; case 100: fe->mWeight = 500; break; case 180: fe->mWeight = 600; break; case 200: fe->mWeight = 700; break; case 205: fe->mWeight = 800; break; case 210: fe->mWeight = 900; break; default: // rough estimate fe->mWeight = (((x * 4) + 100) / 100) * 100; break; } printf(" - weight: %d\n", fe->mWeight); } fe->mItalic = PR_FALSE; if (FcPatternGetInteger(fs->fonts[i], FC_SLANT, 0, &x) == FcResultMatch) { switch (x) { case FC_SLANT_ITALIC: case FC_SLANT_OBLIQUE: fe->mItalic = PR_TRUE; } printf(" - slant: %d\n", x); } if (FcPatternGetInteger(fs->fonts[i], FC_WIDTH, 0, &x) == FcResultMatch) printf(" - width: %d\n", x); // XXX deal with font-stretch stuff later } if (pat) FcPatternDestroy(pat); if (os) FcObjectSetDestroy(os); if (fs) FcFontSetDestroy(fs); return sFontconfigUtils->UpdateFontList(); }
FcFontSet * FcFontSetList (FcConfig *config, FcFontSet **sets, int nsets, FcPattern *p, FcObjectSet *os) { FcFontSet *ret; FcFontSet *s; int f; int set; FcListHashTable table; int i; FcListBucket *bucket; int destroy_os = 0; if (!config) { if (!FcInitBringUptoDate ()) goto bail0; config = FcConfigGetCurrent (); if (!config) goto bail0; } FcListHashTableInit (&table); if (!os) { os = FcObjectGetSet (); destroy_os = 1; } /* * Walk all available fonts adding those that * match to the hash table */ for (set = 0; set < nsets; set++) { s = sets[set]; if (!s) continue; for (f = 0; f < s->nfont; f++) if (FcListPatternMatchAny (p, /* pattern */ s->fonts[f])) /* font */ { FcChar8 *lang; if (FcPatternObjectGetString (p, FC_NAMELANG_OBJECT, 0, &lang) != FcResultMatch) { lang = FcGetDefaultLang (); } if (!FcListAppend (&table, s->fonts[f], os, lang)) goto bail1; } } #if 0 { int max = 0; int full = 0; int ents = 0; int len; for (i = 0; i < FC_LIST_HASH_SIZE; i++) { if ((bucket = table.buckets[i])) { len = 0; for (; bucket; bucket = bucket->next) { ents++; len++; } if (len > max) max = len; full++; } } printf ("used: %d max: %d avg: %g\n", full, max, (double) ents / FC_LIST_HASH_SIZE); } #endif /* * Walk the hash table and build * a font set */ ret = FcFontSetCreate (); if (!ret) goto bail0; for (i = 0; i < FC_LIST_HASH_SIZE; i++) while ((bucket = table.buckets[i])) { if (!FcFontSetAdd (ret, bucket->pattern)) goto bail2; table.buckets[i] = bucket->next; FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket)); free (bucket); } return ret; bail2: FcFontSetDestroy (ret); bail1: FcListHashTableCleanup (&table); bail0: if (destroy_os) FcObjectSetDestroy (os); return 0; }
template <> void deleteOwnedPtr<FcObjectSet>(FcObjectSet* ptr) { if (ptr) FcObjectSetDestroy(ptr); }
void QFontconfigDatabase::populateFontDatabase() { FcFontSet *fonts; QString familyName; FcChar8 *value = 0; int weight_value; int slant_value; int spacing_value; FcChar8 *file_value; int indexValue; FcChar8 *foundry_value; FcChar8 *style_value; FcBool scalable; FcBool antialias; { FcObjectSet *os = FcObjectSetCreate(); FcPattern *pattern = FcPatternCreate(); const char *properties [] = { FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT, FC_SPACING, FC_FILE, FC_INDEX, FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WEIGHT, FC_WIDTH, #if FC_VERSION >= 20297 FC_CAPABILITY, #endif (const char *)0 }; const char **p = properties; while (*p) { FcObjectSetAdd(os, *p); ++p; } fonts = FcFontList(0, pattern, os); FcObjectSetDestroy(os); FcPatternDestroy(pattern); } for (int i = 0; i < fonts->nfont; i++) { if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch) continue; // capitalize(value); familyName = QString::fromUtf8((const char *)value); slant_value = FC_SLANT_ROMAN; weight_value = FC_WEIGHT_REGULAR; spacing_value = FC_PROPORTIONAL; file_value = 0; indexValue = 0; scalable = FcTrue; if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch) slant_value = FC_SLANT_ROMAN; if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch) weight_value = FC_WEIGHT_REGULAR; if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch) spacing_value = FC_PROPORTIONAL; if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch) file_value = 0; if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &indexValue) != FcResultMatch) indexValue = 0; if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch) scalable = FcTrue; if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch) foundry_value = 0; if (FcPatternGetString(fonts->fonts[i], FC_STYLE, 0, &style_value) != FcResultMatch) style_value = 0; if(FcPatternGetBool(fonts->fonts[i],FC_ANTIALIAS,0,&antialias) != FcResultMatch) antialias = true; QSupportedWritingSystems writingSystems; FcLangSet *langset = 0; FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset); if (res == FcResultMatch) { bool hasLang = false; for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) { const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j]; if (lang) { FcLangResult langRes = FcLangSetHasLang(langset, lang); if (langRes != FcLangDifferentLang) { writingSystems.setSupported(QFontDatabase::WritingSystem(j)); hasLang = true; } } } if (!hasLang) // none of our known languages, add it to the other set writingSystems.setSupported(QFontDatabase::Other); } else { // we set Other to supported for symbol fonts. It makes no // sense to merge these with other ones, as they are // special in a way. writingSystems.setSupported(QFontDatabase::Other); } #if FC_VERSION >= 20297 for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) { if (writingSystems.supported(QFontDatabase::WritingSystem(j)) && requiresOpenType(j) && openType[j]) { FcChar8 *cap; res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap); if (res != FcResultMatch || !strstr((const char *)cap, openType[j])) writingSystems.setSupported(QFontDatabase::WritingSystem(j),false); } } #endif FontFile *fontFile = new FontFile; fontFile->fileName = QLatin1String((const char *)file_value); fontFile->indexValue = indexValue; QFont::Style style = (slant_value == FC_SLANT_ITALIC) ? QFont::StyleItalic : ((slant_value == FC_SLANT_OBLIQUE) ? QFont::StyleOblique : QFont::StyleNormal); QFont::Weight weight = QFont::Weight(getFCWeight(weight_value)); double pixel_size = 0; if (!scalable) { int width = 100; FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width); FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size); } bool fixedPitch = spacing_value >= FC_MONO; QFont::Stretch stretch = QFont::Unstretched; QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString(); QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile); // qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size; for (int k = 1; FcPatternGetString(fonts->fonts[i], FC_FAMILY, k, &value) == FcResultMatch; ++k) QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value)); } FcFontSetDestroy (fonts); struct FcDefaultFont { const char *qtname; const char *rawname; bool fixed; }; const FcDefaultFont defaults[] = { { "Serif", "serif", false }, { "Sans Serif", "sans-serif", false }, { "Monospace", "monospace", true }, { 0, 0, false } }; const FcDefaultFont *f = defaults; // aliases only make sense for 'common', not for any of the specials QSupportedWritingSystems ws; ws.setSupported(QFontDatabase::Latin); while (f->qtname) { QString familyQtName = QString::fromLatin1(f->qtname); registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,f->fixed,ws,0); registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,f->fixed,ws,0); registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,f->fixed,ws,0); ++f; } //Lighthouse has very lazy population of the font db. We want it to be initialized when //QApplication is constructed, so that the population procedure can do something like this to //set the default font // const FcDefaultFont *s = defaults; // QFont font("Sans Serif"); // font.setPointSize(9); // QApplication::setFont(font); }
static void SearchFont(VALUE rbFilePathOrName, VALUE* volatile rbRealFilePath, int* ttcIndex) { *rbRealFilePath = Qnil; if (ttcIndex != NULL) { *ttcIndex = -1; } *rbRealFilePath = strb_GetCompletePath(rbFilePathOrName, false); if (!NIL_P(*rbRealFilePath)) { return; } volatile VALUE rbFontNameSymbol = ID2SYM(rb_intern_str(rbFilePathOrName)); FontFileInfo* info = fontFileInfos; while (info) { if (info->rbFontNameSymbol == rbFontNameSymbol) { *rbRealFilePath = rb_str_new2(rb_id2name(SYM2ID(info->rbFileNameSymbol))); #ifdef WIN32 volatile VALUE rbTemp = rb_str_new2(rb_id2name(SYM2ID(rbWindowsFontDirPathSymbol))); *rbRealFilePath = rb_str_concat(rb_str_cat2(rbTemp, "\\"), *rbRealFilePath); #endif if (ttcIndex != NULL) { *ttcIndex = info->ttcIndex; } return; } info = info->next; } #ifdef HAVE_FONTCONFIG_FONTCONFIG_H if (!FcInit()) { FcFini(); rb_raise(strb_GetStarRubyErrorClass(), "can't initialize fontconfig library"); return; } int nameLength = RSTRING_LEN(rbFilePathOrName) + 1; char name[nameLength]; strncpy(name, StringValueCStr(rbFilePathOrName), nameLength); char* delimiter = strchr(name, ','); char* style = NULL; if (delimiter) { *delimiter = '\0'; style = delimiter + 1; char* nameTail = delimiter - 1; while (*nameTail == ' ') { *nameTail = '\0'; nameTail--; } while (*style == ' ') { style++; } } FcPattern* pattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, name, NULL); if (style && 0 < strlen(style)) { FcPatternAddString(pattern, FC_STYLE, (FcChar8*)style); } FcObjectSet* objectSet = FcObjectSetBuild(FC_FAMILY, FC_FILE, NULL); FcFontSet* fontSet = FcFontList(NULL, pattern, objectSet); if (objectSet) { FcObjectSetDestroy(objectSet); } if (pattern) { FcPatternDestroy(pattern); } if (fontSet) { for (int i = 0; i < fontSet->nfont; i++) { FcChar8* fileName = NULL; if (FcPatternGetString(fontSet->fonts[i], FC_FILE, 0, &fileName) == FcResultMatch) { FcChar8* fontName = FcNameUnparse(fontSet->fonts[i]); *rbRealFilePath = rb_str_new2((char*)fileName); volatile VALUE rbFontName = rb_str_new2((char*)fontName); free(fontName); fontName = NULL; if (ttcIndex != NULL && strchr(StringValueCStr(rbFontName), ',')) { *ttcIndex = 0; } } } FcFontSetDestroy(fontSet); } FcFini(); if (!NIL_P(*rbRealFilePath)) { return; } #endif return; }
int BC_Resources::init_fontconfig(const char *search_path) { if( fontlist ) return 0; fontlist = new ArrayList<BC_FontEntry*>; #define get_str(str,sep,ptr,cond) do { char *out = str; \ while( *ptr && !strchr(sep,*ptr) && (cond) ) *out++ = *ptr++; \ *out = 0; \ } while(0) #define skip_str(sep, ptr) do { \ while( *ptr && strchr(sep,*ptr) ) ++ptr; \ } while(0) char find_command[BCTEXTLEN]; sprintf(find_command, "find %s -name 'fonts.dir' -print -exec cat {} \\;", search_path); FILE *in = popen(find_command, "r"); FT_Library freetype_library = 0; // FT_Face freetype_face = 0; // FT_Init_FreeType(&freetype_library); char line[BCTEXTLEN], current_dir[BCTEXTLEN]; current_dir[0] = 0; while( !feof(in) && fgets(line, BCTEXTLEN, in) ) { if(!strlen(line)) break; char *in_ptr = line; // Get current directory if(line[0] == '/') { get_str(current_dir, "\n", in_ptr,1); for( int i=strlen(current_dir); --i>=0 && current_dir[i]!='/'; ) current_dir[i] = 0; continue; } //printf("TitleMain::build_fonts %s\n", line); BC_FontEntry *entry = new BC_FontEntry; char string[BCTEXTLEN]; // Path get_str(string, "\n", in_ptr, in_ptr[0]!=' ' || in_ptr[1]!='-'); entry->path = cstrcat(2, current_dir, string); // Foundary skip_str(" -", in_ptr); get_str(string, " -\n", in_ptr, 1); if( !string[0] ) { delete entry; continue; } entry->foundry = cstrdup(string); if(*in_ptr == '-') in_ptr++; // Family get_str(string, "-\n", in_ptr, 1); if( !string[0] ) { delete entry; continue; } entry->family = cstrdup(string); if(*in_ptr == '-') in_ptr++; // Weight get_str(string, "-\n", in_ptr, 1); entry->weight = cstrdup(string); if(*in_ptr == '-') in_ptr++; // Slant get_str(string, "-\n", in_ptr, 1); entry->slant = cstrdup(string); if(*in_ptr == '-') in_ptr++; // SWidth get_str(string, "-\n", in_ptr, 1); entry->swidth = cstrdup(string); if(*in_ptr == '-') in_ptr++; // Adstyle get_str(string, "-\n", in_ptr, 1); entry->adstyle = cstrdup(string); if(*in_ptr == '-') in_ptr++; // pixelsize get_str(string, "-\n", in_ptr, 1); entry->pixelsize = atol(string); if(*in_ptr == '-') in_ptr++; // pointsize get_str(string, "-\n", in_ptr, 1); entry->pointsize = atol(string); if(*in_ptr == '-') in_ptr++; // xres get_str(string, "-\n", in_ptr, 1); entry->xres = atol(string); if(*in_ptr == '-') in_ptr++; // yres get_str(string, "-\n", in_ptr, 1); entry->yres = atol(string); if(*in_ptr == '-') in_ptr++; // spacing get_str(string, "-\n", in_ptr, 1); entry->spacing = cstrdup(string); if(*in_ptr == '-') in_ptr++; // avg_width get_str(string, "-\n", in_ptr, 1); entry->avg_width = atol(string); if(*in_ptr == '-') in_ptr++; // registry get_str(string, "-\n", in_ptr, 1); entry->registry = cstrdup(string); if(*in_ptr == '-') in_ptr++; // encoding get_str(string, "-\n", in_ptr, 1); entry->encoding = cstrdup(string); if(*in_ptr == '-') in_ptr++; // Add to list //printf("TitleMain::build_fonts 1 %s\n", entry->path); // This takes a real long time to do. Instead just take all fonts // if(!load_freetype_face(freetype_library, // freetype_face, entry->path) ) // Fix parameters sprintf(line, "%s (%s)", entry->family, entry->foundry); entry->displayname = cstrdup(line); if(!strcasecmp(entry->weight, "demibold")) { entry->fixed_style |= BC_FONT_BOLD; entry->style |= FL_WEIGHT_DEMIBOLD; } else if(!strcasecmp(entry->weight, "bold")) { entry->fixed_style |= BC_FONT_BOLD; entry->style |= FL_WEIGHT_BOLD; } else { entry->style |= FL_WEIGHT_NORMAL; } if(!strcasecmp(entry->slant, "r")) { entry->style |= FL_SLANT_ROMAN; } else if(!strcasecmp(entry->slant, "i")) { entry->style |= FL_SLANT_ITALIC; entry->fixed_style |= BC_FONT_ITALIC; } else if(!strcasecmp(entry->slant, "o")) { entry->style |= FL_SLANT_OBLIQUE; entry->fixed_style |= BC_FONT_ITALIC; } if(!strcasecmp(entry->swidth, "normal")) entry->style = FL_WIDTH_NORMAL; else if(!strcasecmp(entry->swidth, "ultracondensed")) entry->style = FL_WIDTH_ULTRACONDENSED; else if(!strcasecmp(entry->swidth, "extracondensed")) entry->style = FL_WIDTH_EXTRACONDENSED; else if(!strcasecmp(entry->swidth, "condensed")) entry->style = FL_WIDTH_CONDENSED; else if(!strcasecmp(entry->swidth, "semicondensed")) entry->style = FL_WIDTH_SEMICONDENSED; else if(!strcasecmp(entry->swidth, "semiexpanded")) entry->style = FL_WIDTH_SEMIEXPANDED; else if(!strcasecmp(entry->swidth, "expanded")) entry->style = FL_WIDTH_EXPANDED; else if(!strcasecmp(entry->swidth, "extraexpanded")) entry->style = FL_WIDTH_EXTRAEXPANDED; else if(!strcasecmp(entry->swidth, "ultraexpanded")) entry->style = FL_WIDTH_ULTRAEXPANDED; else entry->style = FL_WIDTH_NORMAL; fontlist->append(entry); // printf("TitleMain::build_fonts %s: success\n", entry->path); //printf("TitleMain::build_fonts 2\n"); } pclose(in); // Load all the fonts from fontconfig FcPattern *pat; FcFontSet *fs; FcObjectSet *os; FcChar8 *family, *file, *foundry, *style, *format; int slant, spacing, width, weight; int force_style = 0; // if you want limit search to TrueType put 1 int limit_to_trutype = 1; FcConfig *config; int i; char tmpstring[BCTEXTLEN]; if(!FcInit()) return 1; config = FcConfigGetCurrent(); FcConfigSetRescanInterval(config, 0); pat = FcPatternCreate(); os = FcObjectSetBuild ( FC_FAMILY, FC_FILE, FC_FOUNDRY, FC_WEIGHT, FC_WIDTH, FC_SLANT, FC_FONTFORMAT, FC_SPACING, FC_STYLE, (char *) 0); FcPatternAddBool(pat, FC_SCALABLE, true); if(language[0]) { char langstr[LEN_LANG * 3]; strcpy(langstr, language); if(region[0]) { strcat(langstr, "-"); strcat(langstr, region); } FcLangSet *ls = FcLangSetCreate(); if(FcLangSetAdd(ls, (const FcChar8*)langstr)) if(FcPatternAddLangSet(pat, FC_LANG, ls)) FcLangSetDestroy(ls); } fs = FcFontList(config, pat, os); FcPatternDestroy(pat); FcObjectSetDestroy(os); for (i = 0; fs && i < fs->nfont; i++) { FcPattern *font = fs->fonts[i]; force_style = 0; FcPatternGetString(font, FC_FONTFORMAT, 0, &format); //on this point you can limit font search if(limit_to_trutype && strcmp((char *)format, "TrueType")) continue; sprintf(tmpstring, "%s", format); BC_FontEntry *entry = new BC_FontEntry; if(FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) { entry->path = cstrdup((char*)file); } if(FcPatternGetString(font, FC_FOUNDRY, 0, &foundry) == FcResultMatch) { entry->foundry = cstrdup((char*)foundry); } if(FcPatternGetInteger(font, FC_WEIGHT, 0, &weight) == FcResultMatch) { switch(weight) { case FC_WEIGHT_THIN: case FC_WEIGHT_EXTRALIGHT: case FC_WEIGHT_LIGHT: case FC_WEIGHT_BOOK: force_style = 1; entry->weight = cstrdup("medium"); break; case FC_WEIGHT_NORMAL: case FC_WEIGHT_MEDIUM: default: entry->weight = cstrdup("medium"); break; case FC_WEIGHT_BLACK: case FC_WEIGHT_SEMIBOLD: case FC_WEIGHT_BOLD: entry->weight = cstrdup("bold"); entry->fixed_style |= BC_FONT_BOLD; break; case FC_WEIGHT_EXTRABOLD: case FC_WEIGHT_EXTRABLACK: force_style = 1; entry->weight = cstrdup("bold"); entry->fixed_style |= BC_FONT_BOLD; break; } } if(FcPatternGetString(font, FC_FAMILY, 0, &family) == FcResultMatch) entry->family = cstrdup((char*)family); if(FcPatternGetInteger(font, FC_SLANT, 0, &slant) == FcResultMatch) { switch(slant) { case FC_SLANT_ROMAN: default: entry->slant = cstrdup("r"); entry->style |= FL_SLANT_ROMAN; break; case FC_SLANT_ITALIC: entry->slant = cstrdup("i"); entry->style |= FL_SLANT_ITALIC; entry->fixed_style |= BC_FONT_ITALIC; break; case FC_SLANT_OBLIQUE: entry->slant = cstrdup("o"); entry->style |= FL_SLANT_OBLIQUE; entry->fixed_style |= BC_FONT_ITALIC; break; } } if(FcPatternGetInteger(font, FC_WIDTH, 0, &width) == FcResultMatch) { switch(width) { case FC_WIDTH_ULTRACONDENSED: entry->swidth = cstrdup("ultracondensed"); break; case FC_WIDTH_EXTRACONDENSED: entry->swidth = cstrdup("extracondensed"); break; case FC_WIDTH_CONDENSED: entry->swidth = cstrdup("condensed"); break; case FC_WIDTH_SEMICONDENSED: entry->swidth = cstrdup("semicondensed"); break; case FC_WIDTH_NORMAL: default: entry->swidth = cstrdup("normal"); break; case FC_WIDTH_SEMIEXPANDED: entry->swidth = cstrdup("semiexpanded"); break; case FC_WIDTH_EXPANDED: entry->swidth = cstrdup("expanded"); break; case FC_WIDTH_EXTRAEXPANDED: entry->swidth = cstrdup("extraexpanded"); break; case FC_WIDTH_ULTRAEXPANDED: entry->swidth = cstrdup("ultraexpanded"); break; } } if(FcPatternGetInteger(font, FC_SPACING, 0, &spacing) == FcResultMatch) { switch(spacing) { case 0: default: entry->spacing = cstrdup("p"); break; case 90: entry->spacing = cstrdup("d"); break; case 100: entry->spacing = cstrdup("m"); break; case 110: entry->spacing = cstrdup("c"); break; } } // Add fake stuff for compatibility entry->adstyle = cstrdup(" "); entry->pixelsize = 0; entry->pointsize = 0; entry->xres = 0; entry->yres = 0; entry->avg_width = 0; entry->registry = cstrdup("utf"); entry->encoding = cstrdup("8"); if(!FcPatternGetString(font, FC_STYLE, 0, &style) == FcResultMatch) force_style = 0; // If font has a style unmanaged by titler plugin, force style to be displayed on name // in this way we can shown all available fonts styles. if(force_style) { sprintf(tmpstring, "%s (%s)", entry->family, style); entry->displayname = cstrdup(tmpstring); } else { if(strcmp(entry->foundry, "unknown")) { sprintf(tmpstring, "%s (%s)", entry->family, entry->foundry); entry->displayname = cstrdup(tmpstring); } else { sprintf(tmpstring, "%s", entry->family); entry->displayname = cstrdup(tmpstring); } } fontlist->append(entry); } FcFontSetDestroy(fs); if(freetype_library) FT_Done_FreeType(freetype_library); // for(int i = 0; i < fonts->total; i++) // fonts->values[i]->dump(); FcConfigAppFontAddDir(0, (const FcChar8*)search_path); FcConfigSetRescanInterval(0, 0); os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_FOUNDRY, FC_WEIGHT, FC_WIDTH, FC_SLANT, FC_SPACING, FC_STYLE, (char *)0); pat = FcPatternCreate(); FcPatternAddBool(pat, FC_SCALABLE, true); if(language[0]) { char langstr[LEN_LANG * 3]; strcpy(langstr, language); if(region[0]) { strcat(langstr, "-"); strcat(langstr, region); } FcLangSet *ls = FcLangSetCreate(); if(FcLangSetAdd(ls, (const FcChar8*)langstr)) if(FcPatternAddLangSet(pat, FC_LANG, ls)) FcLangSetDestroy(ls); } fs = FcFontList(0, pat, os); FcPatternDestroy(pat); FcObjectSetDestroy(os); for(int i = 0; i < fs->nfont; i++) { FcPattern *font = fs->fonts[i]; BC_FontEntry *entry = new BC_FontEntry; FcChar8 *strvalue; if(FcPatternGetString(font, FC_FILE, 0, &strvalue) == FcResultMatch) { entry->path = new char[strlen((char*)strvalue) + 1]; strcpy(entry->path, (char*)strvalue); } if(FcPatternGetString(font, FC_FOUNDRY, 0, &strvalue) == FcResultMatch) { entry->foundry = new char[strlen((char*)strvalue) + 1]; strcpy(entry->foundry, (char *)strvalue); } if(FcPatternGetString(font, FC_FAMILY, 0, &strvalue) == FcResultMatch) { entry->family = new char[strlen((char*)strvalue) + 2]; strcpy(entry->family, (char*)strvalue); } int intvalue; if(FcPatternGetInteger(font, FC_SLANT, 0, &intvalue) == FcResultMatch) { switch(intvalue) { case FC_SLANT_ROMAN: default: entry->style |= FL_SLANT_ROMAN; break; case FC_SLANT_ITALIC: entry->style |= FL_SLANT_ITALIC; break; case FC_SLANT_OBLIQUE: entry->style |= FL_SLANT_OBLIQUE; break; } } if(FcPatternGetInteger(font, FC_WEIGHT, 0, &intvalue) == FcResultMatch) { switch(intvalue) { case FC_WEIGHT_THIN: entry->style |= FL_WEIGHT_THIN; break; case FC_WEIGHT_EXTRALIGHT: entry->style |= FL_WEIGHT_EXTRALIGHT; break; case FC_WEIGHT_LIGHT: entry->style |= FL_WEIGHT_LIGHT; break; case FC_WEIGHT_BOOK: entry->style |= FL_WEIGHT_BOOK; break; case FC_WEIGHT_NORMAL: default: entry->style |= FL_WEIGHT_NORMAL; break; case FC_WEIGHT_MEDIUM: entry->style |= FL_WEIGHT_MEDIUM; break; case FC_WEIGHT_DEMIBOLD: entry->style |= FL_WEIGHT_DEMIBOLD; break; case FC_WEIGHT_BOLD: entry->style |= FL_WEIGHT_BOLD; break; case FC_WEIGHT_EXTRABOLD: entry->style |= FL_WEIGHT_EXTRABOLD; break; case FC_WEIGHT_BLACK: entry->style |= FL_WEIGHT_BLACK; break; case FC_WEIGHT_EXTRABLACK: entry->style |= FL_WEIGHT_EXTRABLACK; break; } } if(FcPatternGetInteger(font, FC_WIDTH, 0, &intvalue) == FcResultMatch) { switch(intvalue) { case FC_WIDTH_ULTRACONDENSED: entry->style |= FL_WIDTH_ULTRACONDENSED; break; case FC_WIDTH_EXTRACONDENSED: entry->style |= FL_WIDTH_EXTRACONDENSED; break; case FC_WIDTH_CONDENSED: entry->style |= FL_WIDTH_CONDENSED; break; case FC_WIDTH_SEMICONDENSED: entry->style = FL_WIDTH_SEMICONDENSED; break; case FC_WIDTH_NORMAL: default: entry->style |= FL_WIDTH_NORMAL; break; case FC_WIDTH_SEMIEXPANDED: entry->style |= FL_WIDTH_SEMIEXPANDED; break; case FC_WIDTH_EXPANDED: entry->style |= FL_WIDTH_EXPANDED; break; case FC_WIDTH_EXTRAEXPANDED: entry->style |= FL_WIDTH_EXTRAEXPANDED; break; case FC_WIDTH_ULTRAEXPANDED: entry->style |= FL_WIDTH_ULTRAEXPANDED; break; } } if(FcPatternGetInteger(font, FC_SPACING, 0, &intvalue) == FcResultMatch) { switch(intvalue) { case FC_PROPORTIONAL: default: entry->style |= FL_PROPORTIONAL; break; case FC_DUAL: entry->style |= FL_DUAL; break; case FC_MONO: entry->style |= FL_MONO; break; case FC_CHARCELL: entry->style |= FL_CHARCELL; break; } } if(entry->foundry && strcmp(entry->foundry, "unknown")) { char tempstr[BCTEXTLEN]; sprintf(tempstr, "%s (%s)", entry->family, entry->foundry); entry->displayname = new char[strlen(tempstr) + 1]; strcpy(entry->displayname, tempstr); } else { entry->displayname = new char[strlen(entry->family) + 1]; strcpy(entry->displayname, entry->family); } fontlist->append(entry); } FcFontSetDestroy(fs); return 0; }
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) { 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]; seprintf(lang, lastof(lang), ":lang=%s", language_isocode); char *split = strchr(lang, '_'); if (split != NULL) *split = '\0'; /* First create a pattern to match the wanted language. */ //FcPattern *pat = FcNameParse((FcChar8*)lang); FcPattern *pat = FcPatternCreate(); /* We only want to know the filename. */ FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SPACING, FC_SLANT, FC_WEIGHT, NULL); /* Get the list of filenames matching the wanted language. */ FcFontSet *fs = FcFontList(NULL, pat, os); /* We don't need these anymore. */ FcObjectSetDestroy(os); FcPatternDestroy(pat); if (fs != NULL) { int best_weight = -1; const char *best_font = NULL; int best_missing_glypths = 65536; for (int i = 0; i < fs->nfont; i++) { FcPattern *font = fs->fonts[i]; FcChar8 *file = NULL; FcResult res = FcPatternGetString(font, FC_FILE, 0, &file); if (res != FcResultMatch || file == NULL) { continue; } DEBUG(freetype, 1, "Got font %s", file); int missing = 0; /* Get a font with the right spacing .*/ int value = 0; FcPatternGetInteger(font, FC_SPACING, 0, &value); if (callback->Monospace() != (value == FC_MONO) && value != FC_DUAL) missing += 1; /* Do not use those that explicitly say they're slanted. */ FcPatternGetInteger(font, FC_SLANT, 0, &value); if (value != 0) missing += 1; /* We want the fatter font as they look better at small sizes. */ FcPatternGetInteger(font, FC_WEIGHT, 0, &value); if (value <= best_weight) missing += 1; callback->SetFontNames(settings, (const char*)file); missing = callback->FindMissingGlyphs(NULL); DEBUG(freetype, 1, "Font \"%s\" misses %d glyphs for lang %s", file, missing, lang); if (missing < best_missing_glypths) { best_weight = value; best_font = (const char *)file; best_missing_glypths = missing; if (missing == 0) break; } } if (best_font != NULL) { ret = true; callback->SetFontNames(settings, best_font); InitFreeType(callback->Monospace()); DEBUG(freetype, 1, "Selected font %s for lang %s", best_font, lang); } /* Clean up the list of filenames. */ FcFontSetDestroy(fs); } FcFini(); return ret; }
int zaFont::fontconf(const char * charset) { FcFontSet* fs = NULL; FcPattern* pat = NULL; FcObjectSet* os = NULL; //FcChar8* strpat = (FcChar8*)":lang=ja"; string ls = ":lang="; ls.append(charset); FcChar8* strpat = (FcChar8*)ls.c_str(); fprintf(stderr,"zaFont::fontconf charset %s\n",strpat); pat = FcNameParse(strpat); os = FcObjectSetBuild(FC_FAMILY, FC_CHARSET, FC_STYLE,FC_FILE, (char *)0); fs = FcFontList(0, pat, os); if(os) FcObjectSetDestroy(os); os = NULL; FcPatternDestroy(pat); pat = NULL; if(!fs || fs->nfont <= 0) goto nofont; FcChar8 *family; FcChar8 *style; FcChar8 *file; FcCharSet* cs; FcChar32 ch; FcUtf8ToUcs4((FcChar8*)"这", &ch, 3); int i; for(i=0; i<fs->nfont; i++) { if(FcPatternGetCharSet(fs->fonts[i], FC_CHARSET, 0, &cs) != FcResultMatch) { fprintf(stderr, "no match\n"); FcPatternPrint(fs->fonts[i]); goto nofont; } if(FcPatternGetString(fs->fonts[i], FC_FAMILY, 1, &family) != FcResultMatch) if(FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) != FcResultMatch) goto nofont; // fprintf(stderr,"zaFont::fontconf [%d] %s \n", i, (char *)family); if(FcPatternGetString(fs->fonts[i], FC_STYLE, 0, &style) != FcResultMatch) goto nofont; // fprintf(stderr,"zaFont::fontconf [%d] %s \n", i, (char *)style); if(FcPatternGetString(fs->fonts[i], FC_FILE, 0, &file) != FcResultMatch) goto nofont; // fprintf(stderr, "zaFont::fontconf (%s): \n", (char *)file); strcpy(m_charset,charset); strcpy(this->m_path,(char *)file); if(strstr((char*)file,"arial.ttf")) break; // if(FcCharSetHasChar(cs, ch)) // { // puts("Yes"); // }else // { // puts("No"); // } } FcFontSetDestroy(fs); return 0; nofont: return 1; }
/* Constructor of the object : it allocates memory and initializes the member * of the new object. * The user must give the FcPattern of the font or the master (which may be NULL * in which case the character map will be empty). */ __GLCcharMap* __glcCharMapCreate(const __GLCmaster* inMaster, const __GLCcontext* inContext) { __GLCcharMap* This = NULL; assert(inContext); This = (__GLCcharMap*)__glcMalloc(sizeof(__GLCcharMap)); if (!This) { __glcRaiseError(GLC_RESOURCE_ERROR); return NULL; } memset(This, 0, sizeof(__GLCcharMap)); This->charSet = FcCharSetCreate(); if (!This->charSet) { __glcRaiseError(GLC_RESOURCE_ERROR); __glcFree(This); return NULL; } if (inMaster) { FcCharSet* charSet = NULL; FcFontSet* fontSet = NULL; int i = 0; FcObjectSet* objectSet = NULL; FcPattern* pattern = FcPatternCreate(); if (!pattern) { __glcRaiseError(GLC_RESOURCE_ERROR); FcCharSetDestroy(This->charSet); __glcFree(This); return NULL; } objectSet = FcObjectSetBuild(FC_FAMILY, FC_FOUNDRY, FC_SPACING, FC_OUTLINE, FC_CHARSET, NULL); if (!objectSet) { __glcRaiseError(GLC_RESOURCE_ERROR); FcPatternDestroy(pattern); FcCharSetDestroy(This->charSet); __glcFree(This); return NULL; } fontSet = FcFontList(inContext->config, pattern, objectSet); FcObjectSetDestroy(objectSet); FcPatternDestroy(pattern); if (!fontSet) { __glcRaiseError(GLC_RESOURCE_ERROR); FcCharSetDestroy(This->charSet); __glcFree(This); return NULL; } for (i = 0; i < fontSet->nfont; i++) { FcChar8* family = NULL; int fixed = 0; FcChar8* foundry = NULL; FcBool outline = FcFalse; FcBool equal = FcFalse; #ifdef DEBUGMODE FcResult result = FcResultMatch; result = FcPatternGetBool(fontSet->fonts[i], FC_OUTLINE, 0, &outline); assert(result != FcResultTypeMismatch); #else FcPatternGetBool(fontSet->fonts[i], FC_OUTLINE, 0, &outline); #endif /* Check whether the glyphs are outlines */ if (!outline) continue; #ifdef DEBUGMODE result = FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &family); assert(result != FcResultTypeMismatch); result = FcPatternGetString(fontSet->fonts[i], FC_FOUNDRY, 0, &foundry); assert(result != FcResultTypeMismatch); result = FcPatternGetInteger(fontSet->fonts[i], FC_SPACING, 0, &fixed); assert(result != FcResultTypeMismatch); #else FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &family); FcPatternGetString(fontSet->fonts[i], FC_FOUNDRY, 0, &foundry); FcPatternGetInteger(fontSet->fonts[i], FC_SPACING, 0, &fixed); #endif if (foundry) pattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, family, FC_FOUNDRY, FcTypeString, foundry, FC_SPACING, FcTypeInteger, fixed, NULL); else pattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, family, FC_SPACING, FcTypeInteger, fixed, NULL); if (!pattern) { __glcRaiseError(GLC_RESOURCE_ERROR); FcCharSetDestroy(This->charSet); FcFontSetDestroy(fontSet); __glcFree(This); return NULL; } equal = FcPatternEqual(pattern, inMaster->pattern); FcPatternDestroy(pattern); if (equal) { FcCharSet* newCharSet = NULL; #ifdef DEBUGMODE result = FcPatternGetCharSet(fontSet->fonts[i], FC_CHARSET, 0, &charSet); assert(result != FcResultTypeMismatch); #else FcPatternGetCharSet(fontSet->fonts[i], FC_CHARSET, 0, &charSet); #endif newCharSet = FcCharSetUnion(This->charSet, charSet); if (!newCharSet) { __glcRaiseError(GLC_RESOURCE_ERROR); FcCharSetDestroy(This->charSet); FcFontSetDestroy(fontSet); __glcFree(This); return NULL; } FcCharSetDestroy(This->charSet); This->charSet = newCharSet; } } FcFontSetDestroy(fontSet); } /* The array 'map' will contain the actual character map */ This->map = __glcArrayCreate(sizeof(__GLCcharMapElement)); if (!This->map) { FcCharSetDestroy(This->charSet); __glcFree(This); return NULL; } return This; }
int main (int argc, char **argv) { int verbose = 0; int sort = 0, all = 0; const FcChar8 *format = NULL; int i; FcObjectSet *os = 0; FcFontSet *fs; FcPattern *pat; FcResult result; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "asvf:Vh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "asvf:Vh")) != -1) #endif { switch (c) { case 'a': all = 1; break; case 's': sort = 1; break; case 'v': verbose = 1; break; case 'f': format = (FcChar8 *) strdup (optarg); break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); exit (0); case 'h': usage (argv[0], 0); default: usage (argv[0], 1); } } i = optind; #else i = 1; #endif if (!FcInit ()) { fprintf (stderr, "Can't init font config library\n"); return 1; } if (argv[i]) { pat = FcNameParse ((FcChar8 *) argv[i]); while (argv[++i]) { if (!os) os = FcObjectSetCreate (); FcObjectSetAdd (os, argv[i]); } } else pat = FcPatternCreate (); if (!pat) return 1; FcConfigSubstitute (0, pat, FcMatchPattern); FcDefaultSubstitute (pat); fs = FcFontSetCreate (); if (sort || all) { FcFontSet *font_patterns; int j; font_patterns = FcFontSort (0, pat, all ? FcFalse : FcTrue, 0, &result); if (!font_patterns || font_patterns->nfont == 0) { fputs("No fonts installed on the system\n", stderr); return 1; } for (j = 0; j < font_patterns->nfont; j++) { FcPattern *font_pattern; font_pattern = FcFontRenderPrepare (NULL, pat, font_patterns->fonts[j]); if (font_pattern) FcFontSetAdd (fs, font_pattern); } FcFontSetSortDestroy (font_patterns); } else { FcPattern *match; match = FcFontMatch (0, pat, &result); if (match) FcFontSetAdd (fs, match); } FcPatternDestroy (pat); if (!format) { if (os) format = (const FcChar8 *) "%{=unparse}\n"; else format = (const FcChar8 *) "%{=fcmatch}\n"; } if (fs) { int j; for (j = 0; j < fs->nfont; j++) { FcPattern *font; font = FcPatternFilter (fs->fonts[j], os); if (verbose) { FcPatternPrint (font); } else { FcChar8 *s; s = FcPatternFormat (font, format); if (s) { printf ("%s", s); free (s); } } FcPatternDestroy (font); } FcFontSetDestroy (fs); } if (os) FcObjectSetDestroy (os); FcFini (); return 0; }
static XftFont *gui_find_font(winlist_t *win, FcChar32 ucs4) { unsigned int i; int weight, slant, scalable; double font_size; FcFontSet *fontset; XftFont *font = NULL; /* 缺字列表有這個字,那就不用再找啦 */ if (FcCharSetHasChar(gui->missing_chars, ucs4)) { return NULL; } /* 找出 Cache 相符的字型 */ for (i=0 ; i < gui->num_fonts ; i++) { XftPatternGetDouble(gui->xftfonts[i]->pattern, XFT_PIXEL_SIZE, 0, &font_size); if ((int)font_size == win->font_size && FcCharSetHasChar(gui->xftfonts[i]->charset, ucs4)) { return gui->xftfonts[i]; } } /* 列出所有可能的字型 */ FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_CHARSET, NULL); /* 只要標準、非斜體、可縮放字型即可 */ FcPattern *listpat = FcPatternBuild(NULL, FC_SLANT, FcTypeInteger, FC_SLANT_ROMAN, FC_SCALABLE, FcTypeBool, FcTrue, NULL); fontset = FcFontList(NULL, listpat, os); FcPatternDestroy(listpat); FcObjectSetDestroy(os); for (i=0; i< fontset->nfont; i++) { FcPattern *pat = fontset->fonts[i]; FcCharSet *fcs = NULL; if (FcPatternGetCharSet(pat, FC_CHARSET, 0, &fcs) != FcResultMatch) continue; if (!FcCharSetHasChar(fcs, ucs4)) continue; FcResult res; FcPattern *mpat = FcFontMatch(0, pat, &res); if (!mpat) continue; XftPatternAddDouble(mpat, XFT_PIXEL_SIZE, (double)win->font_size); XftFont *chkfont = XftFontOpenPattern(gui->display, mpat); if (chkfont) { gui->num_fonts ++; gui->xftfonts = (XftFont **)oxim_realloc(gui->xftfonts, gui->num_fonts * sizeof(XftFont *)); if (!gui->xftfonts) { FcPatternDestroy(mpat); continue; } gui->xftfonts[gui->num_fonts - 1] = chkfont; font = chkfont; break; } else { FcPatternDestroy(mpat); } } FcFontSetDestroy(fontset); if (!font) FcCharSetAddChar(gui->missing_chars, ucs4); return font; }
bool create(const QString &dir, CFontEngine &fe) { bool root(Misc::root()), added = false; QString fmapDir(Misc::dirSyntax(root ? KFI_ROOT_CFG_DIR : dir)); CFile old(fmapDir); QStringList entries; int i; FcPattern *pat = FcPatternCreate(); FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SCALABLE, (void *)0); FcFontSet *fs = FcFontList(0, pat, os); FcPatternDestroy(pat); FcObjectSetDestroy(os); for(i = 0; i < fs->nfont; i++) { QString fName(Misc::fileSyntax(CFcEngine::getFcString(fs->fonts[i], FC_FILE))); FcBool scalable = FcFalse; if(!fName.isEmpty() && (root || dir.isEmpty() || 0 == fName.find(dir)) && FcResultMatch == FcPatternGetBool(fs->fonts[i], FC_SCALABLE, 0, &scalable) && scalable) { const QStringList *existing = old.getEntries(fName); if(existing && existing->count()) entries += (*existing); else { int face = 0, numFaces = 0; do { if(fe.openFont(fName, face)) { if(fe.hasPsInfo()) { if(0 == numFaces) numFaces = fe.getNumFaces(); // Only really for TTC files... // // Add real addEntry(entries, fe.getPsName(), fName, fmapDir); added = true; // // Add fake entries for X11 generated names switch(fe.getWeight()) { case CFontEngine::WEIGHT_MEDIUM: case CFontEngine::WEIGHT_REGULAR: { QString x11Ps(createX11PsName(fe.getFamilyName())); if(CFontEngine::ITALIC_ITALIC != fe.getItalic() && CFontEngine::ITALIC_OBLIQUE != fe.getItalic()) addAliasEntry(entries, createName(x11Ps, "Roman", getItalicStr(fe.getItalic())), fe.getPsName()); addAliasEntry(entries, createName(x11Ps, NULL, getItalicStr(fe.getItalic())), fe.getPsName()); break; } case CFontEngine::WEIGHT_UNKNOWN: break; default: addAliasEntry(entries, createName(createX11PsName(fe.getFamilyName()), CFontEngine::weightStr(fe.getWeight()), getItalicStr(fe.getItalic())), fe.getPsName()); } } fe.closeFont(); } } while(++face < numFaces); } } } bool status = true; if(added || entries.count() != old.getLineCount()) { KSaveFile out(fmapDir + FONTMAP); QTextStream *stream = out.textStream(); if(stream) { QStringList::Iterator it; for(it = entries.begin(); it != entries.end(); ++it) *stream << *it << endl; } else status = false; } // // Ensure GS's main Fontmap references our file... if(root && status) { static const char *constGhostscriptDirs[] = {"/usr/share/ghostscript/", "/usr/local/share/ghostscript/", "/usr/share/gs-esp/", NULL}; QString gsFile = locateFile(FONTMAP, constGhostscriptDirs); if(!gsFile.isEmpty()) { const int constMaxLineLen = 1024; const char *constRLF = ".runlibfile"; char line[constMaxLineLen]; ifstream in(QFile::encodeName(gsFile)); if(in) { QCString fmap(QFile::encodeName(fmapDir + FONTMAP)); int lineNum = 0, kfiLine = -1, gsLine = -1, ncLine = -1; do { in.getline(line, constMaxLineLen); if(in.good()) { line[constMaxLineLen - 1] = '\0'; if(strstr(line, fmap.data()) != NULL && strstr(line, constRLF) != NULL) kfiLine = lineNum; else if(strstr(line, FONTMAP ".GS") != NULL && strstr(line, constRLF) != NULL) gsLine = lineNum; if(-1 == ncLine && '%' != line[0]) ncLine = lineNum; lineNum++; } } while(!in.eof() && (-1 == kfiLine || -1 == gsLine)); // // If the file doesn't already say to use our Fontmap file, then tell it to! // Also, ensure ours is .runlibfile'd before the main GS one - else problems can occur if(-1 == kfiLine || kfiLine > gsLine) { in.clear(); in.seekg(0, ios::end); int size = (streamoff)in.tellg(); in.seekg(0, ios::beg); char *buffer = new char[size + strlen(fmap) + strlen(constRLF) + 5]; if(buffer) { bool added = false; buffer[0] = '\0'; lineNum = 0; do { in.getline(line, constMaxLineLen); if(in.good()) { line[constMaxLineLen - 1] = '\0'; if(lineNum >= ncLine && !added) { strcat(buffer, "("); strcat(buffer, fmap); strcat(buffer, ") "); strcat(buffer, constRLF); strcat(buffer, "\n"); added = true; } if(lineNum != kfiLine) { strcat(buffer, line); strcat(buffer, "\n"); } lineNum++; } } while(!in.eof()); in.close(); if(added) // Don't re-write GS's Fontmap unless we've actually added something... { KSaveFile out(gsFile); QTextStream *stream = out.textStream(); if(stream) *stream << buffer; } delete[] buffer; } } } } } return status; }
nsresult gfxQtPlatform::ResolveFontName(const nsAString& aFontName, FontResolverCallback aCallback, void *aClosure, PRBool& aAborted) { nsAutoString name(aFontName); ToLowerCase(name); nsRefPtr<FontFamily> ff; if (gPlatformFonts->Get(name, &ff) || gPlatformFontAliases->Get(name, &ff)) { aAborted = !(*aCallback)(ff->Name(), aClosure); return NS_OK; } nsCAutoString utf8Name = NS_ConvertUTF16toUTF8(aFontName); FcPattern *npat = FcPatternCreate(); FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get()); FcObjectSet *nos = FcObjectSetBuild(FC_FAMILY, NULL); FcFontSet *nfs = FcFontList(NULL, npat, nos); for (int k = 0; k < nfs->nfont; k++) { FcChar8 *str; if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch) continue; nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))); ToLowerCase(altName); if (gPlatformFonts->Get(altName, &ff)) { printf("Adding alias: %s -> %s\n", utf8Name.get(), str); gPlatformFontAliases->Put(name, ff); aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure); goto DONE; } } FcPatternDestroy(npat); FcObjectSetDestroy(nos); FcFontSetDestroy(nfs); { npat = FcPatternCreate(); FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get()); FcPatternDel(npat, FC_LANG); FcConfigSubstitute(NULL, npat, FcMatchPattern); FcDefaultSubstitute(npat); nos = FcObjectSetBuild(FC_FAMILY, NULL); nfs = FcFontList(NULL, npat, nos); FcResult fresult; FcPattern *match = FcFontMatch(NULL, npat, &fresult); if (match) FcFontSetAdd(nfs, match); for (int k = 0; k < nfs->nfont; k++) { FcChar8 *str; if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch) continue; nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))); ToLowerCase(altName); if (gPlatformFonts->Get(altName, &ff)) { printf("Adding alias: %s -> %s\n", utf8Name.get(), str); gPlatformFontAliases->Put(name, ff); aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure); goto DONE; } } } DONE: FcPatternDestroy(npat); FcObjectSetDestroy(nos); FcFontSetDestroy(nfs); return NS_OK; }
static TTF_Font *search_font_config(astring name, bool bold, bool italic, bool underline, bool &bakedstyles) { TTF_Font *font = (TTF_Font *)NULL; FcConfig *config; FcPattern *pat; FcObjectSet *os; FcFontSet *fontset; FcValue val; config = FcConfigGetCurrent(); pat = FcPatternCreate(); os = FcObjectSetCreate(); FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.cstr()); // try and get a font with the requested styles baked-in if (bold) { if (italic) { FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold Italic"); } else { FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold"); } } else if (italic) { FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Italic"); } else { FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular"); } FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType"); FcObjectSetAdd(os, FC_FILE); fontset = FcFontList(config, pat, os); for (int i = 0; i < fontset->nfont; i++) { if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch) { continue; } if (val.type != FcTypeString) { continue; } mame_printf_verbose("Matching font: %s\n", val.u.s); { astring match_name((const char*)val.u.s); font = TTF_OpenFont_Magic(match_name, POINT_SIZE); } if (font) { bakedstyles = true; break; } } // didn't get a font above? try again with no baked-in styles if (!font) { FcPatternDestroy(pat); FcFontSetDestroy(fontset); pat = FcPatternCreate(); FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.cstr()); FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular"); FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType"); fontset = FcFontList(config, pat, os); for (int i = 0; i < fontset->nfont; i++) { if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch) { continue; } if (val.type != FcTypeString) { continue; } mame_printf_verbose("Matching unstyled font: %s\n", val.u.s); { astring match_name((const char*)val.u.s); font = TTF_OpenFont_Magic(match_name, POINT_SIZE); } if (font) { break; } } } FcPatternDestroy(pat); FcObjectSetDestroy(os); FcFontSetDestroy(fontset); return font; }
void QFontconfigDatabase::populateFontDatabase() { FcInitReinitialize(); FcFontSet *fonts; { FcObjectSet *os = FcObjectSetCreate(); FcPattern *pattern = FcPatternCreate(); const char *properties [] = { FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT, FC_SPACING, FC_FILE, FC_INDEX, FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WIDTH, #if FC_VERSION >= 20297 FC_CAPABILITY, #endif (const char *)0 }; const char **p = properties; while (*p) { FcObjectSetAdd(os, *p); ++p; } fonts = FcFontList(0, pattern, os); FcObjectSetDestroy(os); FcPatternDestroy(pattern); } for (int i = 0; i < fonts->nfont; i++) populateFromPattern(fonts->fonts[i]); FcFontSetDestroy (fonts); struct FcDefaultFont { const char *qtname; const char *rawname; bool fixed; }; const FcDefaultFont defaults[] = { { "Serif", "serif", false }, { "Sans Serif", "sans-serif", false }, { "Monospace", "monospace", true }, { 0, 0, false } }; const FcDefaultFont *f = defaults; // aliases only make sense for 'common', not for any of the specials QSupportedWritingSystems ws; ws.setSupported(QFontDatabase::Latin); while (f->qtname) { QString familyQtName = QString::fromLatin1(f->qtname); registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,f->fixed,ws,0); registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,f->fixed,ws,0); registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,f->fixed,ws,0); ++f; } //Lighthouse has very lazy population of the font db. We want it to be initialized when //QApplication is constructed, so that the population procedure can do something like this to //set the default font // const FcDefaultFont *s = defaults; // QFont font("Sans Serif"); // font.setPointSize(9); // QApplication::setFont(font); }
MagickExport MagickBooleanType LoadFontConfigFonts(SplayTreeInfo *type_list, ExceptionInfo *exception) { #if !defined(FC_FULLNAME) #define FC_FULLNAME "fullname" #endif char extension[MaxTextExtent], name[MaxTextExtent]; FcChar8 *family, *file, *fullname, *style; FcConfig *font_config; FcFontSet *font_set; FcObjectSet *object_set; FcPattern *pattern; FcResult status; int slant, width, weight; register ssize_t i; TypeInfo *type_info; /* Load system fonts. */ (void) exception; font_config=FcInitLoadConfigAndFonts(); if (font_config == (FcConfig *) NULL) return(MagickFalse); font_set=(FcFontSet *) NULL; object_set=FcObjectSetBuild(FC_FULLNAME,FC_FAMILY,FC_STYLE,FC_SLANT, FC_WIDTH,FC_WEIGHT,FC_FILE,(char *) NULL); if (object_set != (FcObjectSet *) NULL) { pattern=FcPatternCreate(); if (pattern != (FcPattern *) NULL) { font_set=FcFontList(0,pattern,object_set); FcPatternDestroy(pattern); } FcObjectSetDestroy(object_set); } if (font_set == (FcFontSet *) NULL) { FcConfigDestroy(font_config); return(MagickFalse); } for (i=0; i < (ssize_t) font_set->nfont; i++) { status=FcPatternGetString(font_set->fonts[i],FC_FAMILY,0,&family); if (status != FcResultMatch) continue; status=FcPatternGetString(font_set->fonts[i],FC_FILE,0,&file); if (status != FcResultMatch) continue; *extension='\0'; GetPathComponent((const char *) file,ExtensionPath,extension); if ((*extension != '\0') && (LocaleCompare(extension,"gz") == 0)) continue; type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info)); if (type_info == (TypeInfo *) NULL) continue; (void) ResetMagickMemory(type_info,0,sizeof(*type_info)); type_info->path=ConstantString("System Fonts"); type_info->signature=MagickSignature; (void) CopyMagickString(name,"Unknown",MaxTextExtent); status=FcPatternGetString(font_set->fonts[i],FC_FULLNAME,0,&fullname); if ((status == FcResultMatch) && (fullname != (FcChar8 *) NULL)) (void) CopyMagickString(name,(const char *) fullname,MaxTextExtent); else { if (family != (FcChar8 *) NULL) (void) CopyMagickString(name,(const char *) family,MaxTextExtent); status=FcPatternGetString(font_set->fonts[i],FC_STYLE,0,&style); if ((status == FcResultMatch) && (style != (FcChar8 *) NULL) && (LocaleCompare((const char *) style,"Regular") != 0)) { (void) ConcatenateMagickString(name," ",MaxTextExtent); (void) ConcatenateMagickString(name,(const char *) style, MaxTextExtent); } } type_info->name=ConstantString(name); (void) SubstituteString(&type_info->name," ","-"); type_info->family=ConstantString((const char *) family); status=FcPatternGetInteger(font_set->fonts[i],FC_SLANT,0,&slant); type_info->style=NormalStyle; if (slant == FC_SLANT_ITALIC) type_info->style=ItalicStyle; if (slant == FC_SLANT_OBLIQUE) type_info->style=ObliqueStyle; status=FcPatternGetInteger(font_set->fonts[i],FC_WIDTH,0,&width); type_info->stretch=NormalStretch; if (width >= FC_WIDTH_ULTRACONDENSED) type_info->stretch=UltraCondensedStretch; if (width >= FC_WIDTH_EXTRACONDENSED) type_info->stretch=ExtraCondensedStretch; if (width >= FC_WIDTH_CONDENSED) type_info->stretch=CondensedStretch; if (width >= FC_WIDTH_SEMICONDENSED) type_info->stretch=SemiCondensedStretch; if (width >= FC_WIDTH_NORMAL) type_info->stretch=NormalStretch; if (width >= FC_WIDTH_SEMIEXPANDED) type_info->stretch=SemiExpandedStretch; if (width >= FC_WIDTH_EXPANDED) type_info->stretch=ExpandedStretch; if (width >= FC_WIDTH_EXTRAEXPANDED) type_info->stretch=ExtraExpandedStretch; if (width >= FC_WIDTH_ULTRAEXPANDED) type_info->stretch=UltraExpandedStretch; type_info->weight=400; status=FcPatternGetInteger(font_set->fonts[i],FC_WEIGHT,0,&weight); if (weight >= FC_WEIGHT_THIN) type_info->weight=100; if (weight >= FC_WEIGHT_EXTRALIGHT) type_info->weight=200; if (weight >= FC_WEIGHT_LIGHT) type_info->weight=300; if (weight >= FC_WEIGHT_NORMAL) type_info->weight=400; if (weight >= FC_WEIGHT_MEDIUM) type_info->weight=500; if (weight >= FC_WEIGHT_DEMIBOLD) type_info->weight=600; if (weight >= FC_WEIGHT_BOLD) type_info->weight=700; if (weight >= FC_WEIGHT_EXTRABOLD) type_info->weight=800; if (weight >= FC_WEIGHT_BLACK) type_info->weight=900; type_info->glyphs=ConstantString((const char *) file); (void) AddValueToSplayTree(type_list,type_info->name,type_info); } FcFontSetDestroy(font_set); FcConfigDestroy(font_config); return(MagickTrue); }
FontInfo * get_font_info_list (int *num) { FcInit(); *num = -1; FcPattern *pat = FcPatternCreate(); if (!pat) { fprintf(stderr, "Create FcPattern Failed\n"); return NULL; } FcObjectSet *os = FcObjectSetBuild( FC_FAMILY, FC_FAMILYLANG, FC_STYLE, FC_FILE, FC_LANG, FC_SPACING, NULL); if (!os) { fprintf(stderr, "Build FcObjectSet Failed\n"); FcPatternDestroy(pat); return NULL; } FcFontSet *fs = FcFontList(0, pat, os); FcObjectSetDestroy(os); FcPatternDestroy(pat); if (!fs) { fprintf(stderr, "List Font Failed\n"); return NULL; } int i; int cnt = 0; FontInfo *list = NULL; for (i = 0; i < fs->nfont; i++) { FontInfo *info = calloc(1, sizeof(FontInfo)); if (!info) { fprintf(stderr, "Alloc memory failed"); continue; } info->family = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{family}"); info->familylang = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{familylang}"); info->style = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{style}"); info->filename = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{file}"); info->lang = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{lang}"); info->spacing = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{spacing}"); if (!info->family || !info->familylang || !info->style || !info->filename || !info->lang || !info->spacing) { font_info_free(info); continue; } FontInfo *tmp = malloc((cnt+1) * sizeof(FontInfo)); if (!tmp) { fprintf(stderr, "Alloc memory failed\n"); font_info_free(info); continue; } memcpy(tmp+cnt, info, sizeof(FontInfo)); free(info); if (cnt != 0 ) { memcpy(tmp, list, cnt * sizeof(FontInfo)); free(list); list = NULL; } list = tmp; tmp = NULL; cnt++; } FcFontSetDestroy(fs); FcFini(); // Error: FcCacheFini *num = cnt; return list; }