Bool XftConfigSubstitute (XftPattern *p) { FcConfigSubstitute (0, p, FcMatchPattern); FcConfigSubstitute (0, p, FcMatchFont); return True; }
QStringList QFontconfigDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const { QStringList fallbackFamilies; FcPattern *pattern = FcPatternCreate(); if (!pattern) return fallbackFamilies; FcValue value; value.type = FcTypeString; QByteArray cs = family.toUtf8(); value.u.s = (const FcChar8 *)cs.data(); FcPatternAdd(pattern,FC_FAMILY,value,true); int slant_value = FC_SLANT_ROMAN; if (style == QFont::StyleItalic) slant_value = FC_SLANT_ITALIC; else if (style == QFont::StyleOblique) slant_value = FC_SLANT_OBLIQUE; FcPatternAddInteger(pattern, FC_SLANT, slant_value); if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') { Q_ASSERT(script < QUnicodeTables::ScriptCount); FcLangSet *ls = FcLangSetCreate(); FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]); FcPatternAddLangSet(pattern, FC_LANG, ls); FcLangSetDestroy(ls); } const char *stylehint = getFcFamilyForStyleHint(styleHint); if (stylehint) { value.u.s = (const FcChar8 *)stylehint; FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue); } FcConfigSubstitute(0, pattern, FcMatchPattern); FcConfigSubstitute(0, pattern, FcMatchFont); FcResult result = FcResultMatch; FcFontSet *fontSet = FcFontSort(0,pattern,FcFalse,0,&result); if (fontSet && result == FcResultMatch) { for (int i = 0; i < fontSet->nfont; i++) { FcChar8 *value = 0; if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch) continue; // capitalize(value); QString familyName = QString::fromUtf8((const char *)value); if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive)) { fallbackFamilies << familyName; } } } // qDebug() << "fallbackFamilies for:" << family << fallbackFamilies; return fallbackFamilies; }
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; }
FcPattern *fcinfo_get_font(const FcChar8 *request) { FcPattern *pattern, *match; FcResult r; FcChar8 *string; int integer; double double_num; pattern = fcinfo_name_parse((FcChar8 *) request); if (FcPatternGetString(pattern, FC_FAMILY, 0, &string) != FcResultMatch) FcPatternAddString(pattern, FC_FAMILY, (FcChar8 *)"sans-serif"); if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &double_num) != FcResultMatch) FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12.0); if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &integer) != FcResultMatch) FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR); if (FcPatternGetInteger(pattern, FC_SLANT, 0, &integer) != FcResultMatch) FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); if (FcPatternGetInteger(pattern, FC_WIDTH, 0, &integer) != FcResultMatch) FcPatternAddInteger(pattern, FC_WIDTH, FC_WIDTH_NORMAL); FcConfigSubstitute(NULL, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); match = FcFontMatch(0, pattern, &r); assert(r == FcResultMatch); FcPatternDestroy(pattern); return match; }
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; }
claro_font_t * claro_ft2_load_font(claro_font_backend_t * backend, claro_font_pattern_t * pattern, const char * lang_id) { claro_ft2_backend * ft2_backend = (claro_ft2_backend *)backend; FcPattern * real_pattern = NULL, * test_pattern; int res; claro_font_t * font; g_return_val_if_fail(ft2_backend != NULL, NULL); g_return_val_if_fail(pattern != NULL, NULL); // lang_id can be unspecified test_pattern = (FcPattern *)pattern->native; if(lang_id) FcPatternAddString (test_pattern, FC_LANG, lang_id); g_return_val_if_fail(FcConfigSubstitute(ft2_backend->config, test_pattern, FcMatchPattern), NULL); FcDefaultSubstitute(test_pattern); //TODO this sets res to "134524017" wtf? real_pattern = FcFontMatch(ft2_backend->config, test_pattern, NULL); if(res != FcResultMatch) { printf("%s: res = %d\n", __FUNCTION__, res); FcPatternDestroy(real_pattern); return NULL; } font = _claro_ft2_make_font(real_pattern); return font; }
bool sui_font_fromfc(sui_font *font, sui_library *l, char **error, FcPattern *pattern) { FcResult res; FcConfig *config = FcConfigGetCurrent(); if (!FcConfigSubstitute(config, pattern, FcMatchFont)) { *error = sui_aprintf("FcConfigSubstitute: Allocation failure"); return false; } FcDefaultSubstitute(pattern); FcPattern *match = FcFontMatch(config, pattern, &res); if (res != FcResultMatch) { *error = sui_aprintf("FcFontMatch: %s", sui_result_name(res)); return false; } FcChar8 *file; int index; res = FcPatternGetString(match, FC_FILE, 0, &file); if (res != FcResultMatch) { *error = sui_aprintf("FcPatternGetString FC_FILE: %s", sui_result_name(res)); return false; } res = FcPatternGetInteger(match, FC_INDEX, 0, &index); if (res != FcResultMatch) { *error = sui_aprintf("FcPatternGetInteger FC_INDEX: %s", sui_result_name(res)); return false; } FT_Error fterr; if ((fterr = FT_New_Face(l->library, (const char*)file, index, &font->face))) { *error = sui_aprintf("FT_New_Face: Error code %i", fterr); return false; } return font_fromfont(font, l, error, font->face); }
// ----------------------------------------- font_manager_match_description --- char * font_manager_match_description( font_manager_t * self, const char * family, const float size, const int bold, const int italic ) { // Use of fontconfig is disabled by default. #if 1 return 0; #else # if defined _WIN32 || defined _WIN64 fprintf( stderr, "\"font_manager_match_description\" not implemented for windows.\n" ); return 0; # endif char *filename = 0; int weight = FC_WEIGHT_REGULAR; int slant = FC_SLANT_ROMAN; if ( bold ) { weight = FC_WEIGHT_BOLD; } if( italic ) { slant = FC_SLANT_ITALIC; } FcInit(); FcPattern *pattern = FcPatternCreate(); FcPatternAddDouble( pattern, FC_SIZE, size ); FcPatternAddInteger( pattern, FC_WEIGHT, weight ); FcPatternAddInteger( pattern, FC_SLANT, slant ); FcPatternAddString( pattern, FC_FAMILY, (FcChar8*) family ); FcConfigSubstitute( 0, pattern, FcMatchPattern ); FcDefaultSubstitute( pattern ); FcResult result; FcPattern *match = FcFontMatch( 0, pattern, &result ); FcPatternDestroy( pattern ); if ( !match ) { fprintf( stderr, "fontconfig error: could not match family '%s'", family ); return 0; } else { FcValue value; FcResult result = FcPatternGet( match, FC_FILE, 0, &value ); if ( result ) { fprintf( stderr, "fontconfig error: could not match family '%s'", family ); } else { filename = strdup( (char *)(value.u.s) ); } } FcPatternDestroy( match ); return filename; #endif }
/** * 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); }
static void initfonts(void) { FcResult result; FcPattern *pat = FcPatternCreate(); FcPatternAddString(pat, FC_FAMILY, (uint8_t*)"Roboto"); FcConfigSubstitute(0, pat, FcMatchPattern); FcDefaultSubstitute(pat); fs = FcFontSort(NULL, pat, 0, &charset, &result); FcPatternDestroy(pat); #define F(x) (x * SCALE / 2.0) font[FONT_TEXT][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(12.0), NULL); font[FONT_TITLE][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(12.0), XFT_WEIGHT, XftTypeInteger, FC_WEIGHT_BOLD, NULL); font[FONT_SELF_NAME][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(14.0), XFT_WEIGHT, XftTypeInteger, FC_WEIGHT_BOLD, NULL); font[FONT_STATUS][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(11.0), NULL); font[FONT_LIST_NAME][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(12.0), NULL); font[FONT_MSG][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(11.0), XFT_WEIGHT, XftTypeInteger, FC_WEIGHT_LIGHT, NULL); font[FONT_MSG_NAME][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(10.0), XFT_WEIGHT, XftTypeInteger, FC_WEIGHT_LIGHT, NULL); font[FONT_MISC][0] = XftFontOpen(display, screen, XFT_FAMILY, XftTypeString, "Roboto", XFT_PIXEL_SIZE, XftTypeDouble, F(10.0), NULL); font[FONT_MSG_LINK][0] = font[FONT_MSG][0]; #undef F }
// 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; }
CAMLprim value pattern_font_sort(value plist, value trim) { CAMLparam0(); CAMLlocal2(res, nres); FcPattern *pat; FcFontSet *match; FcResult result; int i; pat = FcPattern_val(plist); FcConfigSubstitute(NULL, pat, FcMatchPattern); FcDefaultSubstitute(pat); match = FcFontSort(NULL, pat, Bool_val(trim) ? FcTrue : FcFalse, NULL, &result); /* Reconstruire la belle liste */ res = Val_int(0); /* empty list */ for(i = match->nfont; i >= 0; i--) { nres = caml_alloc(2, 0); Store_field(nres, 0, caml_copy_pattern(match->fonts[i])); Store_field(nres, 1, res); res = nres; } FcFontSetDestroy(match); FcPatternDestroy(pat); CAMLreturn(res); }
static PyObject* Py_Config_substitute(Py_Config *self, PyObject *args, PyObject *kwds) { PyObject *py_pattern; static char *kwlist[] = {"pattern", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "O:substitute", kwlist, &py_pattern)) { return NULL; } if (Py_TYPE(py_pattern) != &Py_Pattern_Type) { PyErr_SetString(PyExc_TypeError, "pattern must be Pattern object"); return NULL; } if (!FcConfigSubstitute(self->x, ((Py_Pattern *)py_pattern)->x, FcMatchFont)) { PyErr_SetString(PyExc_MemoryError, "Out of memory"); return NULL; } Py_RETURN_NONE; }
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) { // The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm) // says that we must find an exact match for font family, slant (italic or oblique can be used) // and font weight (we only match bold/non-bold here). RefPtr<FcPattern> pattern = adoptRef(FcPatternCreate()); String familyNameString(getFamilyNameStringFromFontDescriptionAndFamily(fontDescription, family)); if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(familyNameString.utf8().data()))) return 0; bool italic = fontDescription.italic(); if (!FcPatternAddInteger(pattern.get(), FC_SLANT, italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN)) return 0; if (!FcPatternAddInteger(pattern.get(), FC_WEIGHT, fontWeightToFontconfigWeight(fontDescription.weight()))) return 0; if (!FcPatternAddDouble(pattern.get(), FC_PIXEL_SIZE, fontDescription.computedPixelSize())) return 0; // The strategy is originally from Skia (src/ports/SkFontHost_fontconfig.cpp): // Allow Fontconfig to do pre-match substitution. Unless we are accessing a "fallback" // family like "sans," this is the only time we allow Fontconfig to substitute one // family name for another (i.e. if the fonts are aliased to each other). FcConfigSubstitute(0, pattern.get(), FcMatchPattern); FcDefaultSubstitute(pattern.get()); FcChar8* fontConfigFamilyNameAfterConfiguration; FcPatternGetString(pattern.get(), FC_FAMILY, 0, &fontConfigFamilyNameAfterConfiguration); String familyNameAfterConfiguration = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterConfiguration)); FcResult fontConfigResult; RefPtr<FcPattern> resultPattern = adoptRef(FcFontMatch(0, pattern.get(), &fontConfigResult)); if (!resultPattern) // No match. return 0; FcChar8* fontConfigFamilyNameAfterMatching; FcPatternGetString(resultPattern.get(), FC_FAMILY, 0, &fontConfigFamilyNameAfterMatching); String familyNameAfterMatching = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterMatching)); // If Fontconfig gave use a different font family than the one we requested, we should ignore it // and allow WebCore to give us the next font on the CSS fallback list. The only exception is if // this family name is a commonly used generic family. if (!equalIgnoringCase(familyNameAfterConfiguration, familyNameAfterMatching) && !(equalIgnoringCase(familyNameString, "sans") || equalIgnoringCase(familyNameString, "sans-serif") || equalIgnoringCase(familyNameString, "serif") || equalIgnoringCase(familyNameString, "monospace") || equalIgnoringCase(familyNameString, "fantasy") || equalIgnoringCase(familyNameString, "cursive"))) return 0; // Verify that this font has an encoding compatible with Fontconfig. Fontconfig currently // supports three encodings in FcFreeTypeCharIndex: Unicode, Symbol and AppleRoman. // If this font doesn't have one of these three encodings, don't select it. FontPlatformData* platformData = new FontPlatformData(resultPattern.get(), fontDescription); if (!platformData->hasCompatibleCharmap()) { delete platformData; return 0; } return platformData; }
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; }
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; }
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; }
std::string FontConfig::match_font(const std::string &typeface_name, const FontDescription &desc) const { FcPattern * fc_pattern = nullptr; FcPattern * fc_match = nullptr; try { int weight = static_cast<int>(desc.get_weight()); // Build font matching pattern. fc_pattern = FcPatternBuild(nullptr, FC_FAMILY, FcTypeString, typeface_name.c_str(), FC_PIXEL_SIZE, FcTypeDouble, (double)std::abs(desc.get_height()), FC_WEIGHT, FcTypeInteger, (weight > 0) ? (int)(weight * (FC_WEIGHT_HEAVY / 900.0)) : FC_WEIGHT_NORMAL, FC_SLANT, FcTypeInteger, (desc.get_style() == clan::FontStyle::italic) ? FC_SLANT_ITALIC : ((desc.get_style() == clan::FontStyle::oblique) ? FC_SLANT_OBLIQUE : FC_SLANT_ROMAN), FC_SPACING, FcTypeInteger, FC_PROPORTIONAL, (char*) nullptr ); if (!fc_pattern) { throw Exception("CL_FontConfig: Building FontConfig pattern failed."); } // Execute any needed param substitutions required by the system config. if (FcTrue != FcConfigSubstitute(fc_config, fc_pattern, FcMatchPattern)) { throw Exception("CL_FontConfig: Font config substitutions failed."); } // Supply default values for underspecified font patterns. Never fails. FcDefaultSubstitute(fc_pattern); // Find best match for pattern and extract filename. FcResult match_result; // Doesn't appear to be actually updated. fc_match = FcFontMatch(fc_config, fc_pattern, &match_result); FcChar8 * fc_font_file_path = nullptr; if (FcResultMatch != FcPatternGetString(fc_match, FC_FILE, 0, &fc_font_file_path)) { throw Exception("CL_FontConfig: Could not resolve font pattern to a font file."); } // Release resources and return results. std::string cl_font_file_path((char*)fc_font_file_path); FcPatternDestroy(fc_match); FcPatternDestroy(fc_pattern); return cl_font_file_path; } catch (...) { // If any exceptions thrown, ensure fontconfig resources are released. if (fc_match) FcPatternDestroy(fc_match); if (fc_pattern) FcPatternDestroy(fc_pattern); throw; } }
static String getFontFamilyForCharacters(const UChar* characters, size_t numCharacters) { FcCharSet* cset = FcCharSetCreate(); for (size_t i = 0; i < numCharacters; ++i) { if (U16_IS_SURROGATE(characters[i]) && U16_IS_SURROGATE_LEAD(characters[i]) && i != numCharacters - 1 && U16_IS_TRAIL(characters[i + 1])) { if (FcCharSetAddChar(cset, U16_GET_SUPPLEMENTARY(characters[i], characters[i+1])) == FcFalse) return String(); i++; } else if (FcCharSetAddChar(cset, characters[i]) == FcFalse) return String(); } FcPattern *pattern = FcPatternCreate(); FcPatternAddCharSet(pattern, FC_CHARSET, cset); FcConfigSubstitute(0, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); FcResult result; FcPattern *match = FcFontMatch(0, pattern, &result); FcChar8 *filename; if (FcPatternGetString(match, FC_FILE, 0, &filename) != FcResultMatch) { FcCharSetDestroy(cset); FcPatternDestroy(match); FcPatternDestroy(pattern); return String(); } FcChar8* family; if (FcPatternGetString(match, FC_FAMILY, 0, &family) == FcResultMatch) { FcCharSetDestroy(cset); FcPatternDestroy(match); FcPatternDestroy(pattern); const char* charFamily = reinterpret_cast<char*>(family); return String(charFamily); } FcPatternDestroy(match); FcCharSetDestroy(cset); FcPatternDestroy(pattern); return String(); }
static cairo_scaled_font_t * create_scaled_font (cairo_t * cr) { FcPattern *pattern, *resolved; FcResult result; cairo_font_face_t *font_face; cairo_scaled_font_t *scaled_font; cairo_font_options_t *font_options; cairo_matrix_t font_matrix, ctm; double pixel_size; font_options = cairo_font_options_create (); cairo_get_font_options (cr, font_options); pattern = FcPatternCreate (); FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *)"Bitstream Vera Sans"); FcPatternAddDouble (pattern, FC_PIXEL_SIZE, TEXT_SIZE); FcConfigSubstitute (NULL, pattern, FcMatchPattern); cairo_ft_font_options_substitute (font_options, pattern); FcDefaultSubstitute (pattern); resolved = FcFontMatch (NULL, pattern, &result); /* set layout to vertical */ FcPatternDel (resolved, FC_VERTICAL_LAYOUT); FcPatternAddBool (resolved, FC_VERTICAL_LAYOUT, FcTrue); FcPatternGetDouble (resolved, FC_PIXEL_SIZE, 0, &pixel_size); font_face = cairo_ft_font_face_create_for_pattern (resolved); cairo_matrix_init_translate (&font_matrix, 10, 30); cairo_matrix_rotate (&font_matrix, M_PI_2/3); cairo_matrix_scale (&font_matrix, pixel_size, pixel_size); cairo_get_matrix (cr, &ctm); scaled_font = cairo_scaled_font_create (font_face, &font_matrix, &ctm, font_options); cairo_font_options_destroy (font_options); cairo_font_face_destroy (font_face); FcPatternDestroy (pattern); FcPatternDestroy (resolved); return scaled_font; }
// ------------------------------------------------------ match_description --- char * //match_description( char * description ) match_description( const char * face, bool bold=false, bool italic=false ) { #if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) fprintf( stderr, "\"font_manager_match_description\" " "not implemented for windows.\n" ); return 0; #endif char *filename = 0; FcInit(); //FcPattern *pattern = FcNameParse((const FcChar8*)description); FcPattern *pattern = FcPatternCreate(); if(!pattern) { fprintf( stderr, "fontconfig error: could not match face '%s'", face ); return 0; } FcPatternAddString(pattern, FC_FAMILY, (const FcChar8*)face); FcPatternAddInteger(pattern, FC_WEIGHT, bold?FC_WEIGHT_BOLD:FC_WEIGHT_REGULAR); FcPatternAddInteger(pattern, FC_SLANT, italic?FC_SLANT_ITALIC:FC_SLANT_ROMAN); FcConfigSubstitute( 0, pattern, FcMatchPattern ); FcDefaultSubstitute( pattern ); FcResult result; FcPattern *match = FcFontMatch( 0, pattern, &result ); FcPatternDestroy( pattern ); if ( !match ) { fprintf( stderr, "fontconfig error: could not match face '%s'", face ); return 0; } else { FcValue value; FcResult result = FcPatternGet( match, FC_FILE, 0, &value ); if ( result ) { fprintf( stderr, "fontconfig error: could not match face '%s'", face ); } else { filename = strdup( (char *)(value.u.s) ); } } FcPatternDestroy( match ); return filename; }
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; }
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); }
static RefPtr<FcPattern> createFontConfigPatternForCharacters(const UChar* characters, int bufferLength) { RefPtr<FcPattern> pattern = adoptRef(FcPatternCreate()); FcUniquePtr<FcCharSet> fontConfigCharSet(FcCharSetCreate()); UTF16UChar32Iterator iterator(characters, bufferLength); UChar32 character = iterator.next(); while (character != iterator.end()) { FcCharSetAddChar(fontConfigCharSet.get(), character); character = iterator.next(); } FcPatternAddCharSet(pattern.get(), FC_CHARSET, fontConfigCharSet.get()); FcPatternAddBool(pattern.get(), FC_SCALABLE, FcTrue); FcConfigSubstitute(nullptr, pattern.get(), FcMatchPattern); FcDefaultSubstitute(pattern.get()); return pattern; }
FcPattern *CreateFcPattern(Font font) { LTIMING("CreateXftFont"); int hg = abs(font.GetHeight()); if(hg == 0) hg = 10; String face = font.GetFaceName(); FcPattern *p = FcPatternCreate(); FcPatternAddString(p, FC_FAMILY, (FcChar8*)~face); FcPatternAddInteger(p, FC_SLANT, font.IsItalic() ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); FcPatternAddInteger(p, FC_PIXEL_SIZE, hg); FcPatternAddInteger(p, FC_WEIGHT, font.IsBold() ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL); FcPatternAddBool(p, FC_MINSPACE, 1); FcConfigSubstitute(0, p, FcMatchPattern); FcDefaultSubstitute(p); FcResult result; FcPattern *m = FcFontMatch(0, p, &result); FcPatternDestroy(p); return m; }
FcPattern* createFontConfigPatternForCharacters(const UChar* characters, int bufferLength) { FcPattern* pattern = FcPatternCreate(); FcCharSet* fontConfigCharSet = FcCharSetCreate(); UTF16UChar32Iterator iterator(characters, bufferLength); UChar32 character = iterator.next(); while (character != iterator.end()) { FcCharSetAddChar(fontConfigCharSet, character); character = iterator.next(); } FcPatternAddCharSet(pattern, FC_CHARSET, fontConfigCharSet); FcCharSetDestroy(fontConfigCharSet); FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); FcConfigSubstitute(0, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); return pattern; }
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; }
FcPattern* createFontConfigPatternForCharacters(const UChar* characters, int length) { FcPattern* pattern = FcPatternCreate(); FcCharSet* fontConfigCharSet = FcCharSetCreate(); for (int i = 0; i < length; ++i) { if (U16_IS_SURROGATE(characters[i]) && U16_IS_SURROGATE_LEAD(characters[i]) && i != length - 1 && U16_IS_TRAIL(characters[i + 1])) { FcCharSetAddChar(fontConfigCharSet, U16_GET_SUPPLEMENTARY(characters[i], characters[i+1])); i++; } else FcCharSetAddChar(fontConfigCharSet, characters[i]); } FcPatternAddCharSet(pattern, FC_CHARSET, fontConfigCharSet); FcCharSetDestroy(fontConfigCharSet); FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); FcConfigSubstitute(0, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); return pattern; }
CAMLprim value pattern_find_font(value plist) { CAMLparam0(); CAMLlocal1(res); FcPattern *pat, *match; FcResult result = FcResultMatch; pat = FcPattern_val(plist); FcConfigSubstitute(NULL, pat, FcMatchPattern); FcDefaultSubstitute(pat); match = FcFontMatch(NULL, pat, &result); if(result == FcResultMatch) { res = caml_box_fcpattern(match); } else { caml_raise_constant(*caml_named_value("not_found exception")); } CAMLreturn(res); }