static void load_font_from_fontconfig(void) { FcConfig* config = FcInitLoadConfigAndFonts(); FcFontSet* fontset = NULL; // get application fonts fontset = FcConfigGetFonts(config, FcSetApplication); if (fontset) { FcValue fvalue, dvalue; for (int i = 0; i < fontset->nfont; i++) { if (FcResultMatch == FcPatternGet(fontset->fonts[i], FC_FAMILY, 0, &fvalue)) { if (FcResultMatch == FcPatternGet(fontset->fonts[i], FC_FILE, 0, &dvalue)) { font_item* font = get_font_item((const char*)fvalue.u.s, (const char*)dvalue.u.s); g_font_map.add(font); } } } } // get system fonts fontset = FcConfigGetFonts(config, FcSetSystem); if (fontset) { FcValue fvalue, dvalue; for (int i = 0; i < fontset->nfont; i++) { if (FcResultMatch == FcPatternGet(fontset->fonts[i], FC_FAMILY, 0, &fvalue)) { if (FcResultMatch == FcPatternGet(fontset->fonts[i], FC_FILE, 0, &dvalue)) { font_item* font = get_font_item((const char*)fvalue.u.s, (const char*)dvalue.u.s); g_font_map.add(font); } } } } FcConfigDestroy(config); }
VALUE shoes_font_list() { VALUE ary = rb_ary_new(); FcConfig *fc = FcConfigGetCurrent(); FcFontSet *fonts = FcConfigGetFonts(fc, FcSetApplication); if (fonts) shoes_make_font_list(fonts, ary); fonts = FcConfigGetFonts(fc, FcSetSystem); if (fonts) shoes_make_font_list(fonts, ary); return ary; }
FontFileLister::CollectionResult FontConfigFontFileLister::GetFontPaths(std::string const& facename, int bold, bool italic, std::set<wxUniChar> const& characters) { CollectionResult ret; std::string family(facename); if (family[0] == '@') family.erase(0, 1); boost::to_lower(family); int weight = bold == 0 ? 80 : bold == 1 ? 200 : bold; int slant = italic ? 110 : 0; // Create a fontconfig pattern to match the desired weight/slant agi::scoped_holder<FcPattern*> pat(FcPatternCreate(), FcPatternDestroy); if (!pat) return ret; FcPatternAddBool(pat, FC_OUTLINE, true); FcPatternAddInteger(pat, FC_SLANT, slant); FcPatternAddInteger(pat, FC_WEIGHT, weight); FcDefaultSubstitute(pat); if (!FcConfigSubstitute(config, pat, FcMatchPattern)) return ret; // Create a font set with only correctly named fonts // This is needed because the patterns returned by font matching only // include the first family and fullname, so we can't always verify that // we got the actual font we were asking for after the fact agi::scoped_holder<FcFontSet*> fset(FcFontSetCreate(), FcFontSetDestroy); find_font(FcConfigGetFonts(config, FcSetApplication), fset, family); find_font(FcConfigGetFonts(config, FcSetSystem), fset, family); // Get the best match from fontconfig FcResult result; FcFontSet *sets[] = { (FcFontSet*)fset }; agi::scoped_holder<FcPattern*> match(FcFontSetMatch(config, sets, 1, pat, &result), FcPatternDestroy); if (!match) return ret; FcChar8 *file; if(FcPatternGetString(match, FC_FILE, 0, &file) != FcResultMatch) return ret; FcCharSet *charset; if (FcPatternGetCharSet(match, FC_CHARSET, 0, &charset) == FcResultMatch) { for (wxUniChar chr : characters) { if (!FcCharSetHasChar(charset, chr)) ret.missing += chr; } } ret.paths.emplace_back((const char *)file); return ret; }
static PyObject* Py_Config_add_pattern(Py_Config *self, PyObject *args, PyObject *kwds) { PyObject *py_pattern; FcPattern *pattern; FcFontSet *font_set; static char *kwlist[] = {"pattern", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "O:add_pattern", kwlist, &py_pattern)) { return NULL; } if (Py_TYPE(py_pattern) != &Py_Pattern_Type) { PyErr_SetString(PyExc_TypeError, "pattern must be Pattern object"); return NULL; } pattern = FcPatternDuplicate(((Py_Pattern *)py_pattern)->x); font_set = FcConfigGetFonts(self->x, FcSetApplication); if (font_set == NULL) { PyErr_SetString(PyExc_RuntimeError, "couldn't get application FontSet"); return NULL; } if (!FcFontSetAdd(font_set, pattern)) { PyErr_SetString(PyExc_MemoryError, "allocation error"); return NULL; } Py_RETURN_NONE; }
value fcListFonts( value v_add ) { int i; FcFontSet *fonts = FcConfigGetFonts( 0, FcSetSystem ); if( fonts == NULL ) val_throw( alloc_string("Fontconfig couldn't find any fonts") ); for( i=0; i<fonts->nfont; i++ ) { FcPattern *font = fonts->fonts[i]; FcChar8 *familyName; FcChar8 *style; int weight, slant; bool outline; FcPatternGetBool( font, FC_OUTLINE, 0, &outline ); if( outline ) { FcPatternGetString( font, FC_FAMILY, 0, &familyName ); FcPatternGetString( font, FC_STYLE, 0, &style); FcPatternGetInteger( font, FC_WEIGHT, 0, &weight); FcPatternGetInteger( font, FC_SLANT, 0, &slant); // name = FcNameUnparse( font ); // printf("\nFont: %s || %s\n", familyName, style ); // FcPatternPrint( font ); value arg[4] = { alloc_string((const char *)familyName), alloc_string((const char *)style), alloc_int(weight), alloc_int(slant) }; val_callN( v_add, arg, 4 ); } } }
/** * \brief Case-insensitive match ASS/SSA font family against full name. (also * known as "name for humans") * * \param lib library instance * \param priv fontconfig instance * \param family font fullname * \param bold weight attribute * \param italic italic attribute * \return font set */ static FcFontSet * match_fullname(ASS_Library *lib, FCInstance *priv, const char *family, unsigned bold, unsigned italic) { FcFontSet *sets[2]; FcFontSet *result = FcFontSetCreate(); int nsets = 0; int i, fi; if (!result) return NULL; if ((sets[nsets] = FcConfigGetFonts(priv->config, FcSetSystem))) nsets++; if ((sets[nsets] = FcConfigGetFonts(priv->config, FcSetApplication))) nsets++; // Run over font sets and patterns and try to match against full name for (i = 0; i < nsets; i++) { FcFontSet *set = sets[i]; for (fi = 0; fi < set->nfont; fi++) { FcPattern *pat = set->fonts[fi]; char *fullname; int pi = 0, at; FcBool ol; while (FcPatternGetString(pat, FC_FULLNAME, pi++, (FcChar8 **) &fullname) == FcResultMatch) { if (FcPatternGetBool(pat, FC_OUTLINE, 0, &ol) != FcResultMatch || ol != FcTrue) continue; if (FcPatternGetInteger(pat, FC_SLANT, 0, &at) != FcResultMatch || at < italic) continue; if (FcPatternGetInteger(pat, FC_WEIGHT, 0, &at) != FcResultMatch || at < bold) continue; if (strcasecmp(fullname, family) == 0) { FcFontSetAdd(result, FcPatternDuplicate(pat)); break; } } } } return result; }
/** * \brief Process memory font. * \param priv private data * \param library library object * \param ftlibrary freetype library object * \param idx index of the processed font in library->fontdata * * Builds a font pattern in memory via FT_New_Memory_Face/FcFreeTypeQueryFace. */ static void process_fontdata(FCInstance *priv, ASS_Library *library, FT_Library ftlibrary, int idx) { int rc; const char *name = library->fontdata[idx].name; const char *data = library->fontdata[idx].data; int data_size = library->fontdata[idx].size; FT_Face face; FcPattern *pattern; FcFontSet *fset; FcBool res; int face_index, num_faces = 1; for (face_index = 0; face_index < num_faces; ++face_index) { ass_msg(library, MSGL_V, "Adding memory font '%s'", name); rc = FT_New_Memory_Face(ftlibrary, (unsigned char *) data, data_size, face_index, &face); if (rc) { ass_msg(library, MSGL_WARN, "Error opening memory font: %s", name); return; } num_faces = face->num_faces; pattern = FcFreeTypeQueryFace(face, (unsigned char *) name, face_index, FcConfigGetBlanks(priv->config)); if (!pattern) { ass_msg(library, MSGL_WARN, "%s failed", "FcFreeTypeQueryFace"); FT_Done_Face(face); return; } fset = FcConfigGetFonts(priv->config, FcSetSystem); // somehow it failes when asked for FcSetApplication if (!fset) { ass_msg(library, MSGL_WARN, "%s failed", "FcConfigGetFonts"); FT_Done_Face(face); return; } res = FcFontSetAdd(fset, pattern); if (!res) { ass_msg(library, MSGL_WARN, "%s failed", "FcFontSetAdd"); FT_Done_Face(face); return; } FT_Done_Face(face); } }
void QtTestSupport::initializeTestFonts() { QFontDatabase::removeAllApplicationFonts(); #if HAVE(FONTCONFIG) static int numFonts = -1; FcInit(); // Some test cases may add or remove application fonts (via @font-face). // Make sure to re-initialize the font set if necessary. FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication); if (appFontSet && numFonts >= 0 && appFontSet->nfont == numFonts) return; QByteArray fontDir = getenv("WEBKIT_TESTFONTS"); if (fontDir.isEmpty() || !QDir(QString::fromLatin1(fontDir)).exists()) { qFatal("\n\n" "----------------------------------------------------------------------\n" "WEBKIT_TESTFONTS environment variable is not set correctly.\n" "This variable has to point to the directory containing the fonts\n" "you can clone from git://gitorious.org/qtwebkit/testfonts.git\n" "----------------------------------------------------------------------\n" ); } QByteArray configFile = fontDir + "/fonts.conf"; FcConfig* config = FcConfigCreate(); if (!FcConfigParseAndLoad(config, reinterpret_cast<const FcChar8*>(configFile.constData()), FcTrue)) qFatal("Couldn't load font configuration file"); if (!FcConfigAppFontAddDir(config, reinterpret_cast<const FcChar8*>(fontDir.data()))) qFatal("Couldn't add font dir!"); FcConfigSetCurrent(config); appFontSet = FcConfigGetFonts(config, FcSetApplication); numFonts = appFontSet->nfont; WebCore::fontCache()->invalidate(); #endif }
void activateFonts() { #if defined(Q_WS_X11) static int numFonts = -1; // Some test cases may add or remove application fonts (via @font-face). // Make sure to re-initialize the font set if necessary. FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication); if (appFontSet && numFonts >= 0 && appFontSet->nfont == numFonts) return; QByteArray fontDir = getenv("WEBKIT_TESTFONTS"); if (fontDir.isEmpty() || !QDir(fontDir).exists()) { fprintf(stderr, "\n\n" "----------------------------------------------------------------------\n" "WEBKIT_TESTFONTS environment variable is not set correctly.\n" "This variable has to point to the directory containing the fonts\n" "you can clone from git://gitorious.org/qtwebkit/testfonts.git\n" "----------------------------------------------------------------------\n" ); exit(1); } char currentPath[PATH_MAX+1]; if (!getcwd(currentPath, PATH_MAX)) qFatal("Couldn't get current working directory"); QByteArray configFile = currentPath; FcConfig* config = FcConfigCreate(); configFile += "/WebKitTools/DumpRenderTree/qt/fonts.conf"; if (!FcConfigParseAndLoad (config, (FcChar8*) configFile.data(), true)) qFatal("Couldn't load font configuration file"); if (!FcConfigAppFontAddDir (config, (FcChar8*) fontDir.data())) qFatal("Couldn't add font dir!"); FcConfigSetCurrent(config); appFontSet = FcConfigGetFonts(config, FcSetApplication); numFonts = appFontSet->nfont; #endif }
void initializeFontConfigSetting() { if (g_getenv("WEBKIT_SKIP_WEBKITTESTRUNNER_FONTCONFIG_INITIALIZATION")) return; FcInit(); // If a test resulted a font being added or removed via the @font-face rule, then // we want to reset the FontConfig configuration to prevent it from affecting other tests. static int numFonts = 0; FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication); if (appFontSet && numFonts && appFontSet->nfont == numFonts) return; // Load our configuration file, which sets up proper aliases for family // names like sans, serif and monospace. FcConfig* config = FcConfigCreate(); GUniquePtr<gchar> fontConfigFilename(g_build_filename(FONTS_CONF_DIR, "fonts.conf", nullptr)); if (!g_file_test(fontConfigFilename.get(), G_FILE_TEST_IS_REGULAR)) g_error("Cannot find fonts.conf at %s\n", fontConfigFilename.get()); if (!FcConfigParseAndLoad(config, reinterpret_cast<FcChar8*>(fontConfigFilename.get()), true)) g_error("Couldn't load font configuration file from: %s", fontConfigFilename.get()); CString fontsPath = getFontsPath(); if (fontsPath.isNull()) g_error("Could not locate test fonts at %s. Is WEBKIT_TOP_LEVEL set?", fontsPath.data()); GUniquePtr<GDir> fontsDirectory(g_dir_open(fontsPath.data(), 0, nullptr)); while (const char* directoryEntry = g_dir_read_name(fontsDirectory.get())) { if (!g_str_has_suffix(directoryEntry, ".ttf") && !g_str_has_suffix(directoryEntry, ".otf")) continue; GUniquePtr<gchar> fontPath(g_build_filename(fontsPath.data(), directoryEntry, nullptr)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<const FcChar8*>(fontPath.get()))) g_error("Could not load font at %s!", fontPath.get()); } // Ahem is used by many layout tests. GUniquePtr<gchar> ahemFontFilename(g_build_filename(FONTS_CONF_DIR, "AHEM____.TTF", nullptr)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(ahemFontFilename.get()))) g_error("Could not load font at %s!", ahemFontFilename.get()); static const char* fontFilenames[] = { "WebKitWeightWatcher100.ttf", "WebKitWeightWatcher200.ttf", "WebKitWeightWatcher300.ttf", "WebKitWeightWatcher400.ttf", "WebKitWeightWatcher500.ttf", "WebKitWeightWatcher600.ttf", "WebKitWeightWatcher700.ttf", "WebKitWeightWatcher800.ttf", "WebKitWeightWatcher900.ttf", 0 }; for (size_t i = 0; fontFilenames[i]; ++i) { GUniquePtr<gchar> fontFilename(g_build_filename(FONTS_CONF_DIR, "..", "..", "fonts", fontFilenames[i], nullptr)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontFilename.get()))) g_error("Could not load font at %s!", fontFilename.get()); } // A font with no valid Fontconfig encoding to test https://bugs.webkit.org/show_bug.cgi?id=47452 GUniquePtr<gchar> fontWithNoValidEncodingFilename(g_build_filename(FONTS_CONF_DIR, "FontWithNoValidEncoding.fon", nullptr)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontWithNoValidEncodingFilename.get()))) g_error("Could not load font at %s!", fontWithNoValidEncodingFilename.get()); if (!FcConfigSetCurrent(config)) g_error("Could not set the current font configuration!"); numFonts = FcConfigGetFonts(config, FcSetApplication)->nfont; }
/** * \brief Process memory font. * \param priv private data * \param library library object * \param ftlibrary freetype library object * \param idx index of the processed font in library->fontdata * With FontConfig >= 2.4.2, builds a font pattern in memory via FT_New_Memory_Face/FcFreeTypeQueryFace. * With older FontConfig versions, save the font to ~/.mplayer/fonts. */ static void process_fontdata(fc_instance_t* priv, ass_library_t* library, FT_Library ftlibrary, int idx) { int rc; const char* name = library->fontdata[idx].name; const char* data = library->fontdata[idx].data; int data_size = library->fontdata[idx].size; #if (FC_VERSION < 20402) struct stat st; char* fname; const char* fonts_dir = library->fonts_dir; char buf[1000]; FILE* fp = 0; if (!fonts_dir) return; rc = stat(fonts_dir, &st); if (rc) { int res; #ifndef __MINGW32__ res = mkdir(fonts_dir, 0700); #else res = mkdir(fonts_dir); #endif if (res) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FailedToCreateDirectory, fonts_dir); } } else if (!S_ISDIR(st.st_mode)) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_NotADirectory, fonts_dir); } fname = validate_fname((char*)name); snprintf(buf, 1000, "%s/%s", fonts_dir, fname); free(fname); fp = fopen(buf, "wb"); if (!fp) return; fwrite(data, data_size, 1, fp); fclose(fp); #else // (FC_VERSION >= 20402) FT_Face face; FcPattern* pattern; FcFontSet* fset; FcBool res; rc = FT_New_Memory_Face(ftlibrary, (unsigned char*)data, data_size, 0, &face); if (rc) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningMemoryFont, name); return; } pattern = FcFreeTypeQueryFace(face, (unsigned char*)name, 0, FcConfigGetBlanks(priv->config)); if (!pattern) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcFreeTypeQueryFace"); FT_Done_Face(face); return; } fset = FcConfigGetFonts(priv->config, FcSetSystem); // somehow it failes when asked for FcSetApplication if (!fset) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcConfigGetFonts"); FT_Done_Face(face); return; } res = FcFontSetAdd(fset, pattern); if (!res) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcFontSetAdd"); FT_Done_Face(face); return; } FT_Done_Face(face); #endif }
void inititializeFontConfigSetting() { FcInit(); // If a test resulted a font being added or removed via the @font-face rule, then // we want to reset the FontConfig configuration to prevent it from affecting other tests. static int numFonts = 0; FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication); if (appFontSet && numFonts && appFontSet->nfont == numFonts) return; // Load our configuration file, which sets up proper aliases for family // names like sans, serif and monospace. FcConfig* config = FcConfigCreate(); GOwnPtr<gchar> fontConfigFilename(g_build_filename(FONTS_CONF_DIR, "fonts.conf", NULL)); if (!g_file_test(fontConfigFilename.get(), G_FILE_TEST_IS_REGULAR)) g_error("Cannot find fonts.conf at %s\n", fontConfigFilename.get()); if (!FcConfigParseAndLoad(config, reinterpret_cast<FcChar8*>(fontConfigFilename.get()), true)) g_error("Couldn't load font configuration file from: %s", fontConfigFilename.get()); static const char *const fontDirectories[] = { "/usr/share/fonts/truetype/liberation", "/usr/share/fonts/truetype/ttf-liberation", "/usr/share/fonts/liberation", "/usr/share/fonts/truetype/ttf-dejavu", "/usr/share/fonts/dejavu", "/usr/share/fonts/opentype/stix", "/usr/share/fonts/stix" }; static const char *const fontPaths[] = { "LiberationMono-BoldItalic.ttf", "LiberationMono-Bold.ttf", "LiberationMono-Italic.ttf", "LiberationMono-Regular.ttf", "LiberationSans-BoldItalic.ttf", "LiberationSans-Bold.ttf", "LiberationSans-Italic.ttf", "LiberationSans-Regular.ttf", "LiberationSerif-BoldItalic.ttf", "LiberationSerif-Bold.ttf", "LiberationSerif-Italic.ttf", "LiberationSerif-Regular.ttf", "DejaVuSans.ttf", "DejaVuSerif.ttf", // MathML tests require the STIX fonts. "STIXGeneral.otf", "STIXGeneralBolIta.otf", "STIXGeneralBol.otf", "STIXGeneralItalic.otf" }; // TODO: Some tests use Lucida. We should load these as well, once it becomes // clear how to install these fonts easily on Fedora. for (size_t font = 0; font < G_N_ELEMENTS(fontPaths); font++) { bool found = false; for (size_t path = 0; path < G_N_ELEMENTS(fontDirectories); path++) { GOwnPtr<gchar> fullPath(g_build_filename(fontDirectories[path], fontPaths[font], NULL)); if (g_file_test(fullPath.get(), G_FILE_TEST_EXISTS)) { found = true; if (!FcConfigAppFontAddFile(config, reinterpret_cast<const FcChar8*>(fullPath.get()))) g_error("Could not load font at %s!", fullPath.get()); else break; } } if (!found) { GOwnPtr<gchar> directoriesDescription; for (size_t path = 0; path < G_N_ELEMENTS(fontDirectories); path++) directoriesDescription.set(g_strjoin(":", directoriesDescription.release(), fontDirectories[path], NULL)); g_error("Could not find font %s in %s. Either install this font or file a bug " "at http://bugs.webkit.org if it is installed in another location.", fontPaths[font], directoriesDescription.get()); } } // Ahem is used by many layout tests. GOwnPtr<gchar> ahemFontFilename(g_build_filename(FONTS_CONF_DIR, "AHEM____.TTF", NULL)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(ahemFontFilename.get()))) g_error("Could not load font at %s!", ahemFontFilename.get()); static const char* fontFilenames[] = { "WebKitWeightWatcher100.ttf", "WebKitWeightWatcher200.ttf", "WebKitWeightWatcher300.ttf", "WebKitWeightWatcher400.ttf", "WebKitWeightWatcher500.ttf", "WebKitWeightWatcher600.ttf", "WebKitWeightWatcher700.ttf", "WebKitWeightWatcher800.ttf", "WebKitWeightWatcher900.ttf", 0 }; for (size_t i = 0; fontFilenames[i]; ++i) { GOwnPtr<gchar> fontFilename(g_build_filename(FONTS_CONF_DIR, "..", "..", "fonts", fontFilenames[i], NULL)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontFilename.get()))) g_error("Could not load font at %s!", fontFilename.get()); } // A font with no valid Fontconfig encoding to test https://bugs.webkit.org/show_bug.cgi?id=47452 GOwnPtr<gchar> fontWithNoValidEncodingFilename(g_build_filename(FONTS_CONF_DIR, "FontWithNoValidEncoding.fon", NULL)); if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontWithNoValidEncodingFilename.get()))) g_error("Could not load font at %s!", fontWithNoValidEncodingFilename.get()); if (!FcConfigSetCurrent(config)) g_error("Could not set the current font configuration!"); numFonts = FcConfigGetFonts(config, FcSetApplication)->nfont; }