SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() { SkAutoMutexAcquire ac(mutex_); FcPattern* pat = FcPatternCreate(); SkAutoTCallVProc<FcPattern, FcPatternDestroy> autoDestroyPat(pat); if (NULL == pat) { return NULL; } FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, (char *)0); SkAutoTCallVProc<FcObjectSet, FcObjectSetDestroy> autoDestroyOs(os); if (NULL == os) { return NULL; } FcFontSet* fs = FcFontList(NULL, pat, os); SkAutoTCallVProc<FcFontSet, FcFontSetDestroy> autoDestroyFs(fs); if (NULL == fs) { return NULL; } SkTDArray<const char*> names; SkTDArray<size_t> sizes; for (int i = 0; i < fs->nfont; ++i) { FcPattern* match = fs->fonts[i]; const char* famName = get_name(match, FC_FAMILY); if (famName && !find_name(names, famName)) { *names.append() = famName; *sizes.append() = strlen(famName) + 1; } } return SkDataTable::NewCopyArrays((const void*const*)names.begin(), sizes.begin(), names.count()); }
static void findfont(char *fontname, char *fontpath) { FcPattern *p = NULL; FcChar8 *strval = NULL; FcObjectSet *attr = NULL; if (!FcInit()) return; attr = FcObjectSetBuild (FC_FILE, (char *) 0); p = FcNameParse((FcChar8*)fontname); if (p == NULL) return; FcFontSet *fs = FcFontList (0, p, attr); if (fs->nfont == 0) return; if (FcPatternGetString(fs->fonts[0], FC_FILE, 0, &strval) == FcResultTypeMismatch || strval == NULL) return; strcpy(fontpath, strval); FcFontSetDestroy(fs); FcObjectSetDestroy(attr); FcPatternDestroy(p); FcFini(); return; }
void XeTeXFontMgr_FC::initialize() { if (FcInit() == FcFalse) { fprintf(stderr, "fontconfig initialization failed!\n"); exit(9); } if (gFreeTypeLibrary == 0 && FT_Init_FreeType(&gFreeTypeLibrary) != 0) { fprintf(stderr, "FreeType initialization failed!\n"); exit(9); } UErrorCode err = U_ZERO_ERROR; macRomanConv = ucnv_open("macintosh", &err); utf16beConv = ucnv_open("UTF16BE", &err); utf8Conv = ucnv_open("UTF8", &err); if (err != 0) { fprintf(stderr, "internal error; cannot read font names\n"); exit(3); } FcPattern* pat = FcNameParse((const FcChar8*)":outline=true"); FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FILE, FC_INDEX, FC_FULLNAME, FC_WEIGHT, FC_WIDTH, FC_SLANT, NULL); allFonts = FcFontList(FcConfigGetCurrent(), pat, os); FcObjectSetDestroy(os); FcPatternDestroy(pat); cachedAll = false; }
GeeArrayList * FcListFiles(void) { int i; FcPattern * pattern; FcFontSet * fontset; FcObjectSet * objectset = 0; GeeArrayList * filelist = gee_array_list_new(G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free0, NULL, NULL, NULL); g_assert(FcInit()); pattern = FcNameParse((FcChar8 *) ":"); objectset = FcObjectSetBuild (FC_FILE, NULL); fontset = FcFontList(NULL, pattern, objectset); for (i = 0; i < fontset->nfont; i++) { FcChar8 * file; if (FcPatternGetString(fontset->fonts[i], FC_FILE, 0, &file) == FcResultMatch) gee_abstract_collection_add((GeeAbstractCollection *) filelist, file); } if (objectset) FcObjectSetDestroy(objectset); if (pattern) FcPatternDestroy(pattern); if (fontset) FcFontSetDestroy(fontset); return filelist; }
gchar* find_font_with_property (FcConfig* fontconfig, const gchar* characters, const gchar* property) { FcPattern* pattern; FcCharSet* character_set; FcObjectSet* font_properties; FcFontSet* fonts; FcPattern* font; FcChar8* path; gchar* result; gchar* remaining_characters; gunichar character; if (fontconfig == NULL) { g_warning("Font config not loaded."); return NULL; } result = NULL; pattern = FcPatternCreate (); character_set = FcCharSetCreate (); remaining_characters = (gchar*) characters; while (TRUE) { character = g_utf8_get_char (remaining_characters); if (character == '\0') { break; } FcCharSetAddChar(character_set, character); remaining_characters = g_utf8_next_char (remaining_characters); } FcPatternAddCharSet (pattern, FC_CHARSET, character_set); FcCharSetDestroy (character_set); FcPatternAddInteger (pattern, FC_SLANT, FC_SLANT_ROMAN); FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); font_properties = FcObjectSetBuild (property, NULL); fonts = FcFontList (fontconfig, pattern, font_properties); if (fonts && fonts->nfont > 0) { font = fonts->fonts[0]; if (FcPatternGetString(font, property, 0, &path) == FcResultMatch) { result = g_strdup ((gchar*) path); } } if (fonts) { FcFontSetDestroy(fonts); } if (pattern) { FcPatternDestroy(pattern); } return result; }
FcPattern* BC_Resources::find_similar_font(FT_ULong char_code, FcPattern *oldfont) { FcPattern *pat, *font; FcFontSet *fs; FcObjectSet *os; FcCharSet *fcs; FcChar8 *file; double dval; int ival; // Do not search control codes if(char_code < ' ') return 0; fontconfig_lock.lock("BC_Resources::find_similar_font"); pat = FcPatternCreate(); os = FcObjectSetBuild(FC_FILE, FC_CHARSET, FC_SCALABLE, FC_FAMILY, FC_SLANT, FC_WEIGHT, FC_WIDTH, (char *)0); FcPatternAddBool(pat, FC_SCALABLE, true); fcs = FcCharSetCreate(); if(FcCharSetAddChar(fcs, char_code)) FcPatternAddCharSet(pat, FC_CHARSET, fcs); FcCharSetDestroy(fcs); for(int i = 0; i < LEN_FCPROP; i++) { if(FcPatternGetInteger(oldfont, fc_properties[i], 0, &ival) == FcResultMatch) FcPatternAddInteger(pat, fc_properties[i], ival); } fs = FcFontList(0, pat, os); for(int i = LEN_FCPROP - 1; i >= 0 && fs->nfont == 0; i--) { FcFontSetDestroy(fs); FcPatternDel(pat, fc_properties[i]); fs = FcFontList(0, pat, os); } FcPatternDestroy(pat); FcObjectSetDestroy(os); pat = 0; for (int i = 0; i < fs->nfont; i++) { font = fs->fonts[i]; if(FcPatternGetCharSet(font, FC_CHARSET, 0, &fcs) == FcResultMatch) { if(FcCharSetHasChar(fcs, char_code)) { pat = FcPatternDuplicate(font); break; } } } FcFontSetDestroy(fs); fontconfig_lock.unlock(); return pat; }
/* make sure the font list is valid */ static void ensure_font_list (FontViewModel *self) { FcPattern *pat; FcObjectSet *os; gint i; FcChar8 *file; gchar *font_name, *collation_key; GdkPixbuf *pix; if (self->priv->font_list) { FcFontSetDestroy (self->priv->font_list); self->priv->font_list = NULL; } gtk_list_store_clear (GTK_LIST_STORE (self)); /* always reinitialize the font database */ if (!FcInitReinitialize()) return; pat = FcPatternCreate (); os = FcObjectSetBuild (FC_FILE, FC_FAMILY, FC_WEIGHT, FC_SLANT, NULL); self->priv->font_list = FcFontList (NULL, pat, os); FcPatternDestroy (pat); FcObjectSetDestroy (os); if (!self->priv->font_list) return; for (i = 0; i < self->priv->font_list->nfont; i++) { FcPatternGetString (self->priv->font_list->fonts[i], FC_FILE, 0, &file); font_name = font_utils_get_font_name_for_file (self->priv->library, (const gchar *) file); if (!font_name) continue; pix = get_fallback_icon (); collation_key = g_utf8_collate_key (font_name, -1); gtk_list_store_insert_with_values (GTK_LIST_STORE (self), NULL, -1, COLUMN_NAME, font_name, COLUMN_POINTER, self->priv->font_list->fonts[i], COLUMN_PATH, file, COLUMN_ICON, pix, COLUMN_COLLATION_KEY, collation_key, -1); ensure_thumbnail (self, (const gchar *) file); g_free (font_name); g_free (collation_key); g_object_unref (pix); } }
static Vector<String> strongAliasesForFamily(const String& family) { RefPtr<FcPattern> pattern = adoptRef(FcPatternCreate()); if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(family.utf8().data()))) return Vector<String>(); FcConfigSubstitute(nullptr, pattern.get(), FcMatchPattern); FcDefaultSubstitute(pattern.get()); FcUniquePtr<FcObjectSet> familiesOnly(FcObjectSetBuild(FC_FAMILY, nullptr)); RefPtr<FcPattern> minimal = adoptRef(FcPatternFilter(pattern.get(), familiesOnly.get())); // We really want to match strong (preferred) and same (acceptable) only here. // If a family name was specified, assume that any weak matches after the last strong match // are weak (default) and ignore them. // The reason for is that after substitution the pattern for 'sans-serif' looks like // "wwwwwwwwwwwwwwswww" where there are many weak but preferred names, followed by defaults. // So it is possible to have weakly matching but preferred names. // In aliases, bindings are weak by default, so this is easy and common. // If no family name was specified, we'll probably only get weak matches, but that's ok. int lastStrongId = -1; int numIds = 0; for (int id = 0; ; ++id) { AliasStrength result = strengthOfFirstAlias(*minimal); if (result == AliasStrength::Done) { numIds = id; break; } if (result == AliasStrength::Strong) lastStrongId = id; if (!FcPatternRemove(minimal.get(), FC_FAMILY, 0)) return Vector<String>(); } // If they were all weak, then leave the pattern alone. if (lastStrongId < 0) return Vector<String>(); // Remove everything after the last strong. for (int id = lastStrongId + 1; id < numIds; ++id) { if (!FcPatternRemove(pattern.get(), FC_FAMILY, lastStrongId + 1)) { ASSERT_NOT_REACHED(); return Vector<String>(); } } // Take the resulting pattern and remove everything but the families. minimal = adoptRef(FcPatternFilter(pattern.get(), familiesOnly.get())); // Convert the pattern to a string, and cut out the non-family junk that gets added to the end. char* patternChars = reinterpret_cast<char*>(FcPatternFormat(pattern.get(), reinterpret_cast<const FcChar8*>("%{family}"))); String patternString = String::fromUTF8(patternChars); free(patternChars); Vector<String> results; patternString.split(',', results); return results; }
int fontconf() { FcFontSet* fs = NULL; FcPattern* pat = NULL; FcObjectSet* os = NULL; FcChar8* strpat = (FcChar8*) ":lang=ja"; pat = FcNameParse(strpat); os = FcObjectSetBuild(FC_FAMILY, FC_CHARSET, 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 *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; printf("[%d] %s ", i, (char *)family); if(FcPatternGetString(fs->fonts[i], FC_FILE, 0, &file) != FcResultMatch) goto nofont; printf("(%s): ", (char *)file); if(FcCharSetHasChar(cs, ch)){ puts("Yes"); }else{ puts("No"); } } FcFontSetDestroy(fs); return 0; nofont: return 1; }
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, SetFallbackFontCallback *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); /* We only want to know the filename. */ FcObjectSet *os = FcObjectSetBuild(FC_FILE, 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) { 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; } 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)); bool missing = callback(NULL); DEBUG(freetype, 1, "Font \"%s\" misses%s glyphs", file, missing ? "" : " no"); if (!missing) { ret = true; break; } } /* Clean up the list of filenames. */ FcFontSetDestroy(fs); } FcFini(); return ret; }
void *gp_enumerate_fonts_init(gs_memory_t *mem) { #ifdef HAVE_FONTCONFIG unix_fontenum_t *state; FcPattern *pat; FcObjectSet *os; state = (unix_fontenum_t *)malloc(sizeof(unix_fontenum_t)); if (state == NULL) return NULL; /* Failed to allocate state */ state->index = 0; state->fc = NULL; state->font_list = NULL; /* Load the fontconfig library */ state->fc = FcInitLoadConfigAndFonts(); if (state->fc == NULL) { free(state); state = NULL; dlprintf("destroyed state - fontconfig init failed"); return NULL; /* Failed to open fontconfig library */ } /* load the font set that we'll iterate over */ pat = FcPatternBuild(NULL, FC_OUTLINE, FcTypeBool, 1, FC_SCALABLE, FcTypeBool, 1, NULL); os = FcObjectSetBuild(FC_FILE, FC_OUTLINE, FC_FAMILY, FC_WEIGHT, FC_SLANT, NULL); state->font_list = FcFontList(0, pat, os); FcPatternDestroy(pat); FcObjectSetDestroy(os); if (state->font_list == NULL) { free(state); state = NULL; return NULL; /* Failed to generate font list */ } return (void *)state; #else return NULL; #endif }
int lltxplatform_get_installed_fonts_impl(struct lltxplatform_fontinfo **const fonts, unsigned int *const count) { int status = -1; FcPattern *const pattern = FcPatternCreate(); if (pattern != NULL) { FcObjectSet *const objects = FcObjectSetBuild(FC_FULLNAME, FC_FILE, NULL); if (objects != NULL) { FcFontSet *const list = FcFontList(NULL, pattern, objects); if (list != NULL) { if (list->nfont > 0) { const unsigned int cnt = (unsigned int) list->nfont; struct lltxplatform_fontinfo *const array = (struct lltxplatform_fontinfo *) calloc((size_t) cnt, sizeof(struct lltxplatform_fontinfo)); if (array != NULL) { unsigned int i; status = 0; for (i = 0; i < cnt; ++i) { struct lltxplatform_fontinfo *const info = &array[i]; FcPattern *const font = list->fonts[i]; FcChar8 *value; if (FcPatternGetString(font, FC_FULLNAME, 0, &value) == FcResultMatch) { info->name = strdup((char *) value); } else { info->name = NULL; } if (FcPatternGetString(font, FC_FILE, 0, &value) == FcResultMatch) { info->path = strdup((char *) value); } else { info->path = NULL; } } *count = cnt; *fonts = array; } } else { status = 0; *count = 0; *fonts = NULL; } FcFontSetDestroy(list); } FcObjectSetDestroy(objects); } FcPatternDestroy(pattern); } return status; }
GeeArrayList * FcListFonts(gchar * family_name) { int i; FcPattern * pattern; FcFontSet * fontset; FcObjectSet * objectset = 0; GeeArrayList * fontlist = gee_array_list_new(G_TYPE_OBJECT, NULL, NULL, NULL, NULL, NULL); g_assert(FcInit()); if (family_name) pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, family_name, NULL); else pattern = FcNameParse((FcChar8 *) ":"); objectset = FcObjectSetBuild (FC_FILE, FC_INDEX, FC_FAMILY, FC_STYLE, FC_SLANT, FC_WEIGHT, FC_WIDTH, FC_SPACING, NULL); fontset = FcFontList(NULL, pattern, objectset); for (i = 0; i < fontset->nfont; i++) { FontConfigFont * font = font_config_font_new(); get_font_details_from_pattern(font, fontset->fonts[i]); gee_abstract_collection_add((GeeAbstractCollection *) fontlist, font); } if (objectset) FcObjectSetDestroy(objectset); if (pattern) FcPatternDestroy(pattern); if (fontset) FcFontSetDestroy(fontset); return fontlist; }
void configureFontConfig() { if (fontConfigHasBeenInitialized) return ; fontConfigHasBeenInitialized = true; if (!FcInit()) { INCD_ERROR("could not initialize fontconfig."); return ; } fontConfigConfig = FcConfigGetCurrent(); FcConfigSetRescanInterval(fontConfigConfig, 0); fontConfigPattern = FcPatternCreate(); fontConfigObjectSet = FcObjectSetBuild(FC_FAMILY, FC_FILE, (char *)0); fontConfigFontSet = FcFontList(fontConfigConfig, fontConfigPattern, fontConfigObjectSet); }
/** Find a font file from its family name. * @param font_config fontconfig instance * @param font_name name of the font * @return full path to the font file */ gchar* find_font_file (FcConfig* font_config, const gchar* font_name) { const FcChar8* name; FcPattern* search_pattern; FcPattern* font; FcChar8* file; gchar* path; FcObjectSet* font_properties; FcFontSet* fonts; int i; if (font_config == NULL) { g_warning("Font config not loaded."); return NULL; } path = NULL; name = font_name; search_pattern = FcPatternCreate (); FcPatternAddString (search_pattern, FC_FAMILY, name); FcPatternAddBool (search_pattern, FC_SCALABLE, FcTrue); FcPatternAddInteger (search_pattern, FC_WEIGHT, FC_WEIGHT_MEDIUM); FcPatternAddInteger (search_pattern, FC_SLANT, FC_SLANT_ROMAN); font_properties = FcObjectSetBuild (FC_FILE, NULL); fonts = FcFontList (font_config, search_pattern, font_properties); if (fonts->nfont > 0) { for (i = 0; i < fonts->nfont; i++) { font = fonts->fonts[i]; if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) { path = g_strdup ((gchar*) file); break; } } FcPatternDestroy (font); } FcPatternDestroy (search_pattern); return path; }
Vector<String> FontCache::systemFontFamilies() { RefPtr<FcPattern> scalablesOnlyPattern = adoptRef(FcPatternCreate()); FcPatternAddBool(scalablesOnlyPattern.get(), FC_SCALABLE, FcTrue); FcUniquePtr<FcObjectSet> familiesOnly(FcObjectSetBuild(FC_FAMILY, nullptr)); FcUniquePtr<FcFontSet> fontSet(FcFontList(nullptr, scalablesOnlyPattern.get(), familiesOnly.get())); Vector<String> fontFamilies; for (int i = 0; i < fontSet->nfont; i++) { FcPattern* pattern = fontSet->fonts[i]; FcChar8* family = nullptr; FcPatternGetString(pattern, FC_FAMILY, 0, &family); if (family) fontFamilies.appendVector(patternToFamilies(*pattern)); } return fontFamilies; }
FcStrSet *fcinfo_languages(const FcPattern *filter) { FcObjectSet *objectset; FcFontSet *fontset; FcLangSet *union_langset; FcStrSet *result; int f; FcInit(); objectset = FcObjectSetBuild(FC_LANG, NULL); fontset = FcFontList(NULL, (FcPattern *)filter, objectset); FcObjectSetDestroy(objectset); union_langset = FcLangSetCreate(); for (f = 0; f < fontset->nfont; f++) { FcLangSet *langset; FcStrList *strlist; FcChar8 *lang; if (FcPatternGetLangSet(fontset->fonts[f], FC_LANG, 0, &langset) != FcResultMatch) continue; if (! langset) continue; strlist = FcStrListCreate(FcLangSetGetLangs(langset)); while ((lang = FcStrListNext(strlist))) if (FcLangSetHasLang(union_langset, lang)) FcLangSetAdd(union_langset, FcStrCopy(lang)); } result = FcLangSetGetLangs(union_langset); FcFontSetDestroy(fontset); FcLangSetDestroy(union_langset); return result; }
// 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); }
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); }
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 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; }
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(); }
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; }
/* 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 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; }
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; }
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; }
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; }