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; }
static string linuxFontPathByName(string fontname){ string filename; FcPattern * pattern = FcNameParse((const FcChar8*)fontname.c_str()); FcBool ret = FcConfigSubstitute(0,pattern,FcMatchPattern); if(!ret){ ofLogError() << "linuxFontPathByName(): couldn't find font file or system font with name \"" << fontname << "\""; return ""; } FcDefaultSubstitute(pattern); FcResult result; FcPattern * fontMatch=NULL; fontMatch = FcFontMatch(0,pattern,&result); if(!fontMatch){ ofLogError() << "linuxFontPathByName(): couldn't match font file or system font with name \"" << fontname << "\""; return ""; } FcChar8 *file; if (FcPatternGetString (fontMatch, FC_FILE, 0, &file) == FcResultMatch){ filename = (const char*)file; }else{ ofLogError() << "linuxFontPathByName(): couldn't find font match for \"" << fontname << "\""; return ""; } return filename; }
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; }
// also handle an xlfd with %d for size? static char* makeFontOfSize(char *font, int size, char *fallback) { FcPattern *pattern; char *result; if (font[0]=='-') { char *fname; fname = fixXLFD(font, size); pattern = XftXlfdParse(fname, False, False); wfree(fname); } else { pattern = FcNameParse(font); } //FcPatternPrint(pattern); if (size > 0) { FcPatternDel(pattern, "pixelsize"); FcPatternAddDouble(pattern, "pixelsize", (double)size); } else if (size==0 && !hasProperty(pattern, "size") && !hasProperty(pattern, "pixelsize")) { FcPatternAddDouble(pattern, "pixelsize", (double)DEFAULT_SIZE); } if (fallback && !hasPropertyWithStringValue(pattern, "family", fallback)) { FcPatternAddString(pattern, "family", fallback); } result = FcNameUnparse(pattern); FcPatternDestroy(pattern); return result; }
// Thanks to http://stackoverflow.com/a/14634033/1447751 const std::string get_font_path(const std::string &name) { std::string path; const FcChar8 *fcname = reinterpret_cast<const FcChar8 *>(name.c_str()); FcConfig *config = FcInitLoadConfigAndFonts(); // configure the search pattern, // assume "name" is a std::string with the desired font name in it FcPattern *pat = FcNameParse(fcname); FcConfigSubstitute(config, pat, FcMatchPattern); FcDefaultSubstitute(pat); FcResult result; // find the font FcPattern *font = FcFontMatch(config, pat, &result); if (font) { FcChar8 *fcpath = NULL; FcChar8 *fcfamily = NULL; if (FcPatternGetString(font, FC_FAMILY, 0, &fcfamily) == FcResultMatch && (name.empty() || !FcStrCmpIgnoreCase(fcname, fcfamily)) // Empty name means searching for default font, otherwise make // sure the returned font is exactly what we searched for && FcPatternGetString(font, FC_FILE, 0, &fcpath) == FcResultMatch) path = std::string(reinterpret_cast<char *>(fcpath)); FcPatternDestroy(font); } FcPatternDestroy(pat); return path; }
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; }
std::string FindDefaultFont() { std::string answer("/usr/share/fonts/liberation/LiberationSans-Regular.ttf"); FcFontSet *fs; FcPattern *pat; FcResult result; if (!FcInit()) { return answer; } pat = FcNameParse((FcChar8 *)"LiberationSans-Regular.ttf"); FcConfigSubstitute(0, pat, FcMatchPattern); FcDefaultSubstitute(pat); fs = FcFontSetCreate(); FcPattern *match; match = FcFontMatch(0, pat, &result); if (match) { FcChar8 *file; if (FcPatternGetString(match, FC_FILE, 0, &file) == FcResultMatch) { answer = (const char *)file; } FcPatternDestroy(match); } FcPatternDestroy(pat); FcFini(); return answer; }
/** * Match and create font from given fontconfig pattern */ decltype(auto) make_font(cairo_t* cairo, string&& fontname, double offset, double dpi_x, double dpi_y) { static bool fc_init{false}; if (!fc_init && !(fc_init = FcInit())) { throw application_error("Could not load fontconfig"); } else if (FT_Init_FreeType(&g_ftlib) != FT_Err_Ok) { throw application_error("Could not load FreeType"); } static auto fc_cleanup = scope_util::make_exit_handler([] { FT_Done_FreeType(g_ftlib); FcFini(); }); auto pattern = FcNameParse((FcChar8*)fontname.c_str()); FcDefaultSubstitute(pattern); FcConfigSubstitute(nullptr, pattern, FcMatchPattern); FcResult result; FcPattern* match = FcFontMatch(nullptr, pattern, &result); FcPatternDestroy(pattern); if (match == nullptr) { throw application_error("Could not load font \"" + fontname + "\""); } #ifdef DEBUG_FONTCONFIG FcPatternPrint(match); #endif return make_shared<font_fc>(cairo, match, offset, dpi_x, dpi_y); }
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; }
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; }
fz_error * pdf_loadbuiltinfont(pdf_font *font, char *basefont) { fz_error *error; FcResult fcerr; int fterr; FcPattern *searchpat; FcPattern *matchpat; FT_Face face; char *pattern; char *file; int index; int i; error = initfontlibs(); if (error) return error; pattern = basefont; for (i = 0; i < 14; i++) if (!strcmp(basefont, basenames[i])) pattern = basepatterns[i]; pdf_logfont("load builtin %s\n", pattern); fcerr = FcResultMatch; searchpat = FcNameParse(pattern); FcDefaultSubstitute(searchpat); FcConfigSubstitute(fclib, searchpat, FcMatchPattern); matchpat = FcFontMatch(fclib, searchpat, &fcerr); if (fcerr != FcResultMatch) return fz_throw("fontconfig could not find font %s", pattern); fcerr = FcPatternGetString(matchpat, FC_FILE, 0, (FcChar8**)&file); if (fcerr != FcResultMatch) return fz_throw("fontconfig could not find font %s", pattern); index = 0; fcerr = FcPatternGetInteger(matchpat, FC_INDEX, 0, &index); pdf_logfont("load font file %s %d\n", file, index); fterr = FT_New_Face(ftlib, file, index, &face); if (fterr) return fz_throw("freetype could not load font file '%s': %s", file, pdf_fterrorstring(fterr)); FcPatternDestroy(matchpat); FcPatternDestroy(searchpat); font->ftface = face; return nil; }
/* This function is an implementation detail. Library users should use * drw_font_create instead. */ static Fnt * drw_font_xcreate(Drw *drw, const char *fontname, FcPattern *fontpattern) { Fnt *font; if (!(fontname || fontpattern)) die("No font specified.\n"); if (!(font = (Fnt *)calloc(1, sizeof(Fnt)))) return NULL; if (fontname) { /* Using the pattern found at font->xfont->pattern does not yield same * the same substitution results as using the pattern returned by * FcNameParse; using the latter results in the desired fallback * behaviour whereas the former just results in * missing-character-rectangles being drawn, at least with some fonts. */ if (!(font->xfont = XftFontOpenName(drw->dpy, drw->screen, fontname)) || !(font->pattern = FcNameParse((FcChar8 *) fontname))) { if (font->xfont) { XftFontClose(drw->dpy, font->xfont); font->xfont = NULL; } fprintf(stderr, "error, cannot load font: '%s'\n", fontname); } } else if (fontpattern) { if (!(font->xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { fprintf(stderr, "error, cannot load font pattern.\n"); } else { font->pattern = NULL; } } if (!font->xfont) { free(font); return NULL; } font->ascent = font->xfont->ascent; font->descent = font->xfont->descent; font->h = font->ascent + font->descent; font->dpy = drw->dpy; return font; }
void Rcairo_set_font(int i, const char *fcname){ FcFontSet *fs; FcPattern *pat, *match; FcResult result; FcChar8 *file; int j; if (Rcairo_fonts[i].face != NULL){ cairo_font_face_destroy(Rcairo_fonts[i].face); Rcairo_fonts[i].face = NULL; } pat = FcNameParse((FcChar8 *)fcname); if (!pat){ error("Problem with font config library in Rcairo_set_font\n"); return; } FcConfigSubstitute (0, pat, FcMatchPattern); FcDefaultSubstitute (pat); fs = FcFontSetCreate (); match = FcFontMatch (0, pat, &result); FcPatternDestroy (pat); if (match) { FcFontSetAdd (fs, match); } else { error("No font found in Rcairo_set_font"); FcFontSetDestroy (fs); return; } /* should be at least one font face in fontset */ if (fs) { for (j = 0; j < fs->nfont; j++) { /* Need to make sure a real font file exists */ if (FcPatternGetString (fs->fonts[j], FC_FILE, 0, &file) == FcResultMatch){ Rcairo_fonts[i].face = Rcairo_set_font_face(i,(const char *)file); break; } } FcFontSetDestroy (fs); Rcairo_fonts[i].updated = 1; } else { error("No font found Rcairo_set_font"); } }
const std::string find_font(const char* name) { std::string font_file; FcConfig* config = FcInitLoadConfigAndFonts(); FcPattern* pattern = FcNameParse((const FcChar8*) (name)); FcConfigSubstitute(config, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); FcPattern* font = FcFontMatch(config, pattern, NULL); if (font) { FcChar8* file = NULL; if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) font_file = std::string((char*) file); FcPatternDestroy(font); } FcPatternDestroy(pattern); return font_file; }
FcPattern *fcinfo_name_parse(const FcChar8 *pattern) { FcChar8 sanitized_pattern[2*strlen((char *)pattern)]; int c1, c2; c1 = c2 = 0; while (pattern[c1]) { if (pattern[c1] == '-') /* escape dash */ sanitized_pattern[c2++] = '\\'; sanitized_pattern[c2++] = pattern[c1++]; } sanitized_pattern[c2] = '\0'; //fprintf(stdout, "name: %s\n", (char *)sanitized_pattern); return FcNameParse(sanitized_pattern); }
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; }
static void test_match(int thr_num,int test_num) { FcPattern *pat; FcPattern *match; FcResult result; FcInit(); pat = FcNameParse((const FcChar8 *)"New Century Schoolbook"); FcConfigSubstitute(0,pat,FcMatchPattern); FcDefaultSubstitute(pat); match = FcFontMatch(0,pat,&result); FcPatternDestroy(pat); FcPatternDestroy(match); }
WMFont* WMCopyFontWithStyle(WMScreen *scrPtr, WMFont *font, WMFontStyle style) { FcPattern *pattern; WMFont *copy; char *name; if (!font) return NULL; pattern = FcNameParse(WMGetFontName(font)); switch (style) { case WFSNormal: FcPatternDel(pattern, "weight"); FcPatternDel(pattern, "slant"); FcPatternAddString(pattern, "weight", "regular"); FcPatternAddString(pattern, "weight", "medium"); FcPatternAddString(pattern, "slant", "roman"); break; case WFSBold: FcPatternDel(pattern, "weight"); FcPatternAddString(pattern, "weight", "bold"); break; case WFSEmphasized: FcPatternDel(pattern, "slant"); FcPatternAddString(pattern, "slant", "italic"); FcPatternAddString(pattern, "slant", "oblique"); break; case WFSBoldEmphasized: FcPatternDel(pattern, "weight"); FcPatternDel(pattern, "slant"); FcPatternAddString(pattern, "weight", "bold"); FcPatternAddString(pattern, "slant", "italic"); FcPatternAddString(pattern, "slant", "oblique"); break; } name = FcNameUnparse(pattern); copy = WMCreateFont(scrPtr, name); FcPatternDestroy(pattern); wfree(name); return copy; }
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size) { assert(buffer != NULL); assert(font != NULL); log_verbose("Looking for font %s with FontConfig.", font->font_name); FcConfig* config = FcInitLoadConfigAndFonts(); if (!config) { log_error("Failed to initialize FontConfig library"); FcFini(); return false; } FcPattern* pat = FcNameParse((const FcChar8*) font->font_name); FcConfigSubstitute(config, pat, FcMatchPattern); FcDefaultSubstitute(pat); bool found = false; FcResult result = FcResultNoMatch; FcPattern* match = FcFontMatch(config, pat, &result); if (match) { FcChar8* filename = NULL; if (FcPatternGetString(match, FC_FILE, 0, &filename) == FcResultMatch) { found = true; safe_strcpy(buffer, (utf8*) filename, size); log_verbose("FontConfig provided font %s", filename); } FcPatternDestroy(match); } else { log_warning("Failed to find required font."); } FcPatternDestroy(pat); FcConfigDestroy(config); FcFini(); return found; }
value fcFindFont( value _familyName, value _weight, value _slant, value _size ) { val_check(_familyName,string); val_check(_weight,number); val_check(_slant,number); val_check(_size,number); const char *familyName = val_string(_familyName); int weight = val_number(_weight); int slant = val_number(_slant); float size = val_number(_size); FcPattern *pattern; pattern = FcNameParse( (FcChar8*)familyName ); FcDefaultSubstitute( pattern ); FcConfigSubstitute( FcConfigGetCurrent(), pattern, FcMatchPattern ); FcResult result; FcPattern *match = FcFontMatch( 0, pattern, &result ); FcPatternDestroy( pattern ); if( !match ) val_throw(alloc_string("Could not find font")); FcChar8 *temp; int id; pattern = FcPatternDuplicate(match); if( FcPatternGetString( pattern, FC_FILE, 0, &temp ) != FcResultMatch || FcPatternGetInteger( pattern, FC_INDEX, 0, &id ) != FcResultMatch ) { val_throw(alloc_string("Could not load font")); } value ret = alloc_string((const char *)temp); FcPatternDestroy( pattern ); FcPatternDestroy( match ); return ret; }
TTF_Font *load_font(const char *font_spec) { int font_size; char *font_name; /* figure out font size from name, or default to 24 */ char *sep = strchr(font_spec, ':'); if(sep) { font_name = strndup(font_spec, sep - font_spec); font_size = strtol(sep+1, NULL, 10); } else { font_name = strdup(font_spec); font_size = 24; } FcConfig *cfg = FcInitLoadConfigAndFonts(); FcPattern *pattern = FcNameParse((const FcChar8*)font_name); FcConfigSubstitute(cfg, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); TTF_Font *ret = NULL; FcResult result = FcResultNoMatch; FcPattern* font = FcFontMatch(cfg, pattern, &result); if (font) { FcChar8 *path = NULL; if (FcPatternGetString(font, FC_FILE, 0, &path) == FcResultMatch) { ret = TTF_OpenFont((char*)path, font_size); } FcPatternDestroy(font); } FcPatternDestroy(pattern); FcConfigDestroy(cfg); free(font_name); return ret; }
/** * @brief Tries to find a system font. */ static char *gl_fontFind( const char *fname ) { FcConfig* config; FcPattern *pat, *font; FcResult result; FcChar8* file; char *fontFile; config = FcInitLoadConfigAndFonts(); pat = FcNameParse( (const FcChar8*)fname ); FcConfigSubstitute( config, pat, FcMatchPattern ); FcDefaultSubstitute(pat); font = FcFontMatch(config, pat, &result); if (font) { file = NULL; if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) { fontFile = strdup( (char*)file ); FcPatternDestroy(pat); return fontFile; } } FcPatternDestroy(pat); return NULL; }
void load_font(FcChar8 *font_str) { FcPattern *pattern, *match; FcResult result; if (font_str[0] == '-') pattern = XftXlfdParse(font_str, False, False); else pattern = FcNameParse((FcChar8 *) font_str); if (!pattern) die("Failed to get font pattern"); match = FcFontMatch(NULL, pattern, &result); if (!match) die("Failed to get font match"); if (!(font = XftFontOpenPattern(display, match))) { FcPatternDestroy(match); die("Failed to open font"); } ascent = font->ascent; descent = font->descent; }
void font_impl::loadSystemFont(const char* const pName, int pFontSize) { //TODO do error checking once it is working std::string ttf_file_path; #ifndef OS_WIN // use fontconfig to get the file FcConfig* config = FcInitLoadConfigAndFonts(); if (!config) { FT_THROW_ERROR("fontconfig initilization failed", fg::FG_ERR_FREETYPE_ERROR); } // configure the search pattern, FcPattern* pat = FcNameParse((const FcChar8*)(pName)); if (!pat) { FT_THROW_ERROR("fontconfig pattern creation failed", fg::FG_ERR_FREETYPE_ERROR); } FcConfigSubstitute(config, pat, FcMatchPattern); FcDefaultSubstitute(pat); // find the font FcResult res; FcPattern* font = FcFontMatch(config, pat, &res); FcConfigSubstitute(config, pat, FcMatchPattern); if (font) { FcChar8* file = NULL; if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) { // save the file to another std::string ttf_file_path = (char*)file; } FcPatternDestroy(font); } // destroy fontconfig pattern object FcPatternDestroy(pat); #else char buf[512]; GetWindowsDirectory(buf, 512); std::regex fontRegex(std::string(pName), std::regex_constants::egrep | std::regex_constants::icase); std::vector<std::string> fontFiles; std::vector<std::string> matchedFontFiles; getFontFilePaths(fontFiles, std::string(buf)+"\\Fonts\\", std::string("ttf")); for (const auto &fontName : fontFiles) { if (std::regex_search(fontName, fontRegex)) { matchedFontFiles.push_back(fontName); } } /* out of all the possible matches, we choose the first possible match for given input font name parameter */ if (matchedFontFiles.size()==0) FT_THROW_ERROR("loadSystemFont failed to find the given font name", fg::FG_ERR_FREETYPE_ERROR); ttf_file_path = buf; ttf_file_path += "\\Fonts\\"; ttf_file_path += matchedFontFiles[0]; #endif loadFont(ttf_file_path.c_str(), pFontSize); }
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; }
static int load_font_fontconfig(AVFilterContext *ctx) { DrawTextContext *s = ctx->priv; FcConfig *fontconfig; FcPattern *pat, *best; FcResult result = FcResultMatch; FcChar8 *filename; int index; double size; int err = AVERROR(ENOENT); fontconfig = FcInitLoadConfigAndFonts(); if (!fontconfig) { av_log(ctx, AV_LOG_ERROR, "impossible to init fontconfig\n"); return AVERROR_UNKNOWN; } pat = FcNameParse(s->fontfile ? s->fontfile : (uint8_t *)(intptr_t)"default"); if (!pat) { av_log(ctx, AV_LOG_ERROR, "could not parse fontconfig pat"); return AVERROR(EINVAL); } FcPatternAddString(pat, FC_FAMILY, s->font); if (s->fontsize) FcPatternAddDouble(pat, FC_SIZE, (double)s->fontsize); FcDefaultSubstitute(pat); if (!FcConfigSubstitute(fontconfig, pat, FcMatchPattern)) { av_log(ctx, AV_LOG_ERROR, "could not substitue fontconfig options"); /* very unlikely */ FcPatternDestroy(pat); return AVERROR(ENOMEM); } best = FcFontMatch(fontconfig, pat, &result); FcPatternDestroy(pat); if (!best || result != FcResultMatch) { av_log(ctx, AV_LOG_ERROR, "Cannot find a valid font for the family %s\n", s->font); goto fail; } if ( FcPatternGetInteger(best, FC_INDEX, 0, &index ) != FcResultMatch || FcPatternGetDouble (best, FC_SIZE, 0, &size ) != FcResultMatch) { av_log(ctx, AV_LOG_ERROR, "impossible to find font information"); return AVERROR(EINVAL); } if (FcPatternGetString(best, FC_FILE, 0, &filename) != FcResultMatch) { av_log(ctx, AV_LOG_ERROR, "No file path for %s\n", s->font); goto fail; } av_log(ctx, AV_LOG_INFO, "Using \"%s\"\n", filename); if (!s->fontsize) s->fontsize = size + 0.5; err = load_font_file(ctx, filename, index); if (err) return err; FcConfigDestroy(fontconfig); fail: FcPatternDestroy(best); return err; }
XftPattern * XftNameParse (const char *name) { return FcNameParse ((const FcChar8 *) name); }
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); /* 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; 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; } /* 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) continue; /* Do not use those that explicitly say they're slanted. */ FcPatternGetInteger(font, FC_SLANT, 0, &value); if (value != 0) continue; /* We want the fatter font as they look better at small sizes. */ FcPatternGetInteger(font, FC_WEIGHT, 0, &value); if (value <= best_weight) continue; callback->SetFontNames(settings, (const char*)file); bool missing = callback->FindMissingGlyphs(NULL); DEBUG(freetype, 1, "Font \"%s\" misses%s glyphs", file, missing ? "" : " no"); if (!missing) { best_weight = value; best_font = (const char *)file; } } if (best_font != NULL) { ret = true; callback->SetFontNames(settings, best_font); InitFreeType(callback->Monospace()); } /* Clean up the list of filenames. */ FcFontSetDestroy(fs); } FcFini(); return ret; }
/* ======================================================================================== * FontConfig (unix) support * ======================================================================================== */ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) { FT_Error err = FT_Err_Cannot_Open_Resource; if (!FcInit()) { ShowInfoF("Unable to load font configuration"); } else { FcPattern *match; FcPattern *pat; FcFontSet *fs; FcResult result; char *font_style; char *font_family; /* Split & strip the font's style */ font_family = stredup(font_name); font_style = strchr(font_family, ','); if (font_style != NULL) { font_style[0] = '\0'; font_style++; while (*font_style == ' ' || *font_style == '\t') font_style++; } /* Resolve the name and populate the information structure */ pat = FcNameParse((FcChar8*)font_family); if (font_style != NULL) FcPatternAddString(pat, FC_STYLE, (FcChar8*)font_style); FcConfigSubstitute(0, pat, FcMatchPattern); FcDefaultSubstitute(pat); fs = FcFontSetCreate(); match = FcFontMatch(0, pat, &result); if (fs != NULL && match != NULL) { int i; FcChar8 *family; FcChar8 *style; FcChar8 *file; FcFontSetAdd(fs, match); for (i = 0; err != FT_Err_Ok && i < fs->nfont; i++) { /* Try the new filename */ if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, &file) == FcResultMatch && FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) == FcResultMatch && FcPatternGetString(fs->fonts[i], FC_STYLE, 0, &style) == FcResultMatch) { /* The correct style? */ if (font_style != NULL && strcasecmp(font_style, (char*)style) != 0) continue; /* Font config takes the best shot, which, if the family name is spelled * wrongly a 'random' font, so check whether the family name is the * same as the supplied name */ if (strcasecmp(font_family, (char*)family) == 0) { err = FT_New_Face(_library, (char *)file, 0, face); } } } } free(font_family); FcPatternDestroy(pat); FcFontSetDestroy(fs); FcFini(); } return err; }
/** * \brief Low-level font selection. * \param priv private data * \param family font family * \param treat_family_as_pattern treat family as fontconfig pattern * \param bold font weight value * \param italic font slant value * \param index out: font index inside a file * \param code: the character that should be present in the font, can be 0 * \return font file path */ static char *select_font(ASS_Library *library, FCInstance *priv, const char *family, int treat_family_as_pattern, unsigned bold, unsigned italic, int *index, uint32_t code) { FcBool rc; FcResult result; FcPattern *pat = NULL, *rpat = NULL; int r_index, r_slant, r_weight; FcChar8 *r_family, *r_style, *r_file, *r_fullname; FcBool r_outline, r_embolden; FcCharSet *r_charset; FcFontSet *ffullname = NULL, *fsorted = NULL, *fset = NULL; int curf; char *retval = NULL; int family_cnt = 0; *index = 0; if (treat_family_as_pattern) pat = FcNameParse((const FcChar8 *) family); else pat = FcPatternCreate(); if (!pat) goto error; if (!treat_family_as_pattern) { FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *) family); // In SSA/ASS fonts are sometimes referenced by their "full name", // which is usually a concatenation of family name and font // style (ex. Ottawa Bold). Full name is available from // FontConfig pattern element FC_FULLNAME, but it is never // used for font matching. // Therefore, I'm removing words from the end of the name one // by one, and adding shortened names to the pattern. It seems // that the first value (full name in this case) has // precedence in matching. // An alternative approach could be to reimplement FcFontSort // using FC_FULLNAME instead of FC_FAMILY. family_cnt = 1; { char *s = strdup(family); char *p = s + strlen(s); while (--p > s) if (*p == ' ' || *p == '-') { *p = '\0'; FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *) s); ++family_cnt; } free(s); } } FcPatternAddBool(pat, FC_OUTLINE, FcTrue); FcPatternAddInteger(pat, FC_SLANT, italic); FcPatternAddInteger(pat, FC_WEIGHT, bold); FcDefaultSubstitute(pat); rc = FcConfigSubstitute(priv->config, pat, FcMatchPattern); if (!rc) goto error; /* Fontconfig defaults include a language setting, which it sets based on * some environment variables or defaults to "en". Unset this as we don't * know the real language, and because some some attached fonts lack * non-ascii characters included in fontconfig's list of characters * required for English support and therefore don't match the lang=en * criterion. */ FcPatternDel(pat, "lang"); fsorted = FcFontSort(priv->config, pat, FcTrue, NULL, &result); ffullname = match_fullname(library, priv, family, bold, italic); if (!fsorted || !ffullname) goto error; fset = FcFontSetCreate(); for (curf = 0; curf < ffullname->nfont; ++curf) { FcPattern *curp = ffullname->fonts[curf]; FcPatternReference(curp); FcFontSetAdd(fset, curp); } for (curf = 0; curf < fsorted->nfont; ++curf) { FcPattern *curp = fsorted->fonts[curf]; FcPatternReference(curp); FcFontSetAdd(fset, curp); } for (curf = 0; curf < fset->nfont; ++curf) { FcPattern *curp = fset->fonts[curf]; result = FcPatternGetBool(curp, FC_OUTLINE, 0, &r_outline); if (result != FcResultMatch) continue; if (r_outline != FcTrue) continue; if (!code) break; result = FcPatternGetCharSet(curp, FC_CHARSET, 0, &r_charset); if (result != FcResultMatch) continue; if (FcCharSetHasChar(r_charset, code)) break; } if (curf >= fset->nfont) goto error; if (!treat_family_as_pattern) { // Remove all extra family names from original pattern. // After this, FcFontRenderPrepare will select the most relevant family // name in case there are more than one of them. for (; family_cnt > 1; --family_cnt) FcPatternRemove(pat, FC_FAMILY, family_cnt - 1); } rpat = FcFontRenderPrepare(priv->config, pat, fset->fonts[curf]); if (!rpat) goto error; result = FcPatternGetInteger(rpat, FC_INDEX, 0, &r_index); if (result != FcResultMatch) goto error; *index = r_index; result = FcPatternGetString(rpat, FC_FILE, 0, &r_file); if (result != FcResultMatch) goto error; retval = strdup((const char *) r_file); result = FcPatternGetString(rpat, FC_FAMILY, 0, &r_family); if (result != FcResultMatch) r_family = NULL; result = FcPatternGetString(rpat, FC_FULLNAME, 0, &r_fullname); if (result != FcResultMatch) r_fullname = NULL; if (!treat_family_as_pattern && !(r_family && strcasecmp((const char *) r_family, family) == 0) && !(r_fullname && strcasecmp((const char *) r_fullname, family) == 0)) { char *fallback = (char *) (r_fullname ? r_fullname : r_family); if (code) { ass_msg(library, MSGL_WARN, "fontconfig: cannot find glyph U+%04X in font '%s', falling back to '%s'", (unsigned int)code, family, fallback); } else { ass_msg(library, MSGL_WARN, "fontconfig: cannot find font '%s', falling back to '%s'", family, fallback); } } result = FcPatternGetString(rpat, FC_STYLE, 0, &r_style); if (result != FcResultMatch) r_style = NULL; result = FcPatternGetInteger(rpat, FC_SLANT, 0, &r_slant); if (result != FcResultMatch) r_slant = 0; result = FcPatternGetInteger(rpat, FC_WEIGHT, 0, &r_weight); if (result != FcResultMatch) r_weight = 0; result = FcPatternGetBool(rpat, FC_EMBOLDEN, 0, &r_embolden); if (result != FcResultMatch) r_embolden = 0; ass_msg(library, MSGL_V, "Font info: family '%s', style '%s', fullname '%s'," " slant %d, weight %d%s", (const char *) r_family, (const char *) r_style, (const char *) r_fullname, r_slant, r_weight, r_embolden ? ", embolden" : ""); error: if (pat) FcPatternDestroy(pat); if (rpat) FcPatternDestroy(rpat); if (fsorted) FcFontSetDestroy(fsorted); if (ffullname) FcFontSetDestroy(ffullname); if (fset) FcFontSetDestroy(fset); return retval; }