/** * 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); }
// ----------------------------------------- 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 }
// 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; }
MenuGraphic::MenuGraphic(Menu* menu) : menu_(menu) { const char* fontFamily = "Anonymous Pro"; const char* fontStyle = "Bold"; const char* fontSpacing = "Monospace"; char* font; FcPattern* fontPattern = FcPatternCreate(); FcResult fontResult = FcResultMatch; int fontSize = 74; FcPatternAddString(fontPattern, FC_FAMILY, (const FcChar8*) fontFamily); FcPatternAddDouble(fontPattern, FC_SIZE, fontSize); FcPatternAddString(fontPattern, FC_SPACING, (const FcChar8*) fontSpacing); FcPatternAddString(fontPattern, FC_STYLE, (const FcChar8*) fontStyle); FcDefaultSubstitute(fontPattern); FcPattern* fontMatch = FcFontMatch(NULL, fontPattern, &fontResult); FcPatternGetString(fontMatch, FC_FILE, 0, (FcChar8**) &font); for (int i = 0; i < Menu::NUM_MENU; ++i) { // Create a new SubmenuGraphic for each Submenu menuGraphics_[i] = new SubmenuGraphic(menu->getMenu(i)); Submenu* submenu = menu->getMenu(i); // Add buttons and labels for (std::vector<GuiElement*>::iterator j = submenu->buttons.begin(); j < submenu->buttons.end(); ++j) { labels_.push_back(new Label(font, ((Button*) (*j))->getText(), fontSize, .5, .1)); menuGraphics_[i]->addButton((*j), labels_.back(), (*j)->isSelected()); } } }
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); }
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; }
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; }
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; }
FcFontSet *fcinfo_fontformat_family_index(const FcChar8 *format, const FcPattern *filter) { FcFontSet *fontset, *result; FcPattern *pattern; FcPattern *font; FcResult r; int f; pattern = FcPatternDuplicate(filter); FcPatternAddString(pattern, FC_FONTFORMAT, format); fontset = fcinfo(NULL, pattern, FcTrue, 1, FC_FAMILY); result = FcFontSetCreate(); for (f = 0; f < fontset->nfont; f++) { font = FcFontMatch(NULL, fontset->fonts[f], &r); assert(r == FcResultMatch); /* don't add ethio16f-uni.pcf, johabg16.pcf and similar with reported empty charset */ /* could be done with fcinfo_match(), but that is superfluous there like for fcinfo_language_font_index() - it will be needed when we will need to display some kind of specimen in fontformat index */ if (!empty_charset(font)) FcFontSetAdd(result, FcPatternDuplicate(fontset->fonts[f])); FcPatternDestroy(font); } FcPatternDestroy(pattern); FcFontSetDestroy(fontset); return result; }
static PyObject* Py_Config_match(Py_Config *self, PyObject *args, PyObject *kwds) { PyObject *py_pattern; FcPattern *match = NULL; FcResult result; static char *kwlist[] = {"pattern", NULL}; if (!PyArg_ParseTupleAndKeywords( args, kwds, "O:match", kwlist, &py_pattern)) { return NULL; } if (Py_TYPE(py_pattern) != &Py_Pattern_Type) { PyErr_SetString(PyExc_TypeError, "pattern must be Pattern object"); return NULL; } match = FcFontMatch(self->x, ((Py_Pattern *)py_pattern)->x, &result); if (result == FcResultMatch) { return Py_Pattern_cnew(match); } else { FcPatternDestroy(match); fcpy_result_to_exception(result); return NULL; } }
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; }
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; }
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; }
RefPtr<Font> FontCache::systemFallbackForCharacters(const FontDescription& description, const Font* originalFontData, bool, const UChar* characters, unsigned length) { RefPtr<FcPattern> pattern = createFontConfigPatternForCharacters(characters, length); const FontPlatformData& fontData = originalFontData->platformData(); RefPtr<FcPattern> fallbackPattern = findBestFontGivenFallbacks(fontData, pattern.get()); if (fallbackPattern) { FontPlatformData alternateFontData(fallbackPattern.get(), description); return fontForPlatformData(alternateFontData); } FcResult fontConfigResult; RefPtr<FcPattern> resultPattern = adoptRef(FcFontMatch(nullptr, pattern.get(), &fontConfigResult)); if (!resultPattern) return nullptr; FontPlatformData alternateFontData(resultPattern.get(), description); return fontForPlatformData(alternateFontData); }
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); }
PassRefPtr<SimpleFontData> FontCache::systemFallbackForCharacters(const FontDescription& description, const SimpleFontData* originalFontData, bool, const UChar* characters, int length) { RefPtr<FcPattern> pattern = adoptRef(createFontConfigPatternForCharacters(characters, length)); const FontPlatformData& fontData = originalFontData->platformData(); RefPtr<FcPattern> fallbackPattern = adoptRef(findBestFontGivenFallbacks(fontData, pattern.get())); if (fallbackPattern) { FontPlatformData alternateFontData(fallbackPattern.get(), description); return getCachedFontData(&alternateFontData, DoNotRetain); } FcResult fontConfigResult; RefPtr<FcPattern> resultPattern = adoptRef(FcFontMatch(0, pattern.get(), &fontConfigResult)); if (!resultPattern) return 0; FontPlatformData alternateFontData(resultPattern.get(), description); return getCachedFontData(&alternateFontData, DoNotRetain); }
PassRefPtr<SimpleFontData> FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) { RefPtr<FcPattern> pattern = adoptRef(createFontConfigPatternForCharacters(characters, length)); const FontPlatformData& fontData = font.primaryFont()->platformData(); RefPtr<FcPattern> fallbackPattern = adoptRef(findBestFontGivenFallbacks(fontData, pattern.get())); if (fallbackPattern) { FontPlatformData alternateFontData(fallbackPattern.get(), font.fontDescription()); return getCachedFontData(&alternateFontData, DoNotRetain); } FcResult fontConfigResult; RefPtr<FcPattern> resultPattern = adoptRef(FcFontMatch(0, pattern.get(), &fontConfigResult)); if (!resultPattern) return 0; FontPlatformData alternateFontData(resultPattern.get(), font.fontDescription()); return getCachedFontData(&alternateFontData, DoNotRetain); }
/** * using fontconfig for just getting the font file name by a wanted font name and style. */ char *get_font_filename(const char *family, const char *style) { //initialize fontconfig if (!FcInit()) { throw util::Error{MSG(err) << "Failed to initialize fontconfig."}; } //FcPattern *font_pattern = FcNameParse((const unsigned char *)"DejaVu Serif:style=Book"); FcPattern *font_pattern = FcPatternBuild(nullptr, FC_FAMILY, FcTypeString, family, nullptr); FcPatternBuild(font_pattern, FC_STYLE, FcTypeString, style, nullptr); //debug output: display above pattern as parsable string. FcChar8 *query_string = FcNameUnparse(font_pattern); log::log(MSG(info) << "Font queried: " << query_string); free(query_string); //tell fontconfig to find the best match FcResult font_match_result; FcPattern *font_match = FcFontMatch(nullptr, font_pattern, &font_match_result); /* //debug output: display matching font pattern as parsable string FcChar8 *match_string = FcNameUnparse(font_match); log::dbg2("resulting font: %s", match_string); free(match_string); */ //get attibute FC_FILE (= filename) of best-matched font FcChar8 *font_filename_tmp; if (FcPatternGetString(font_match, FC_FILE, 0, &font_filename_tmp) != FcResultMatch) { throw util::Error(MSG(err) << "Fontconfig could not provide font " << family << " " << style); } //copy the font filename because it will be freed when the pattern is destroyed. char *font_filename = util::copy((const char *)font_filename_tmp); log::log(MSG(info) << "Font file: " << font_filename); //deinitialize fontconfig. FcPatternDestroy(font_match); FcPatternDestroy(font_pattern); FcFini(); return font_filename; }
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; }
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; }
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); }
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; }
void SkScalerContext_CairoFT::resolvePattern(FcPattern* pattern) { if (!pattern) { return; } FcValue value; if (FcPatternGet(pattern, FC_PIXEL_SIZE, 0, &value) == FcResultNoMatch) { SkAutoTUnref<FcPattern> scalePattern(FcPatternDuplicate(pattern)); if (scalePattern && FcPatternAddDouble(scalePattern, FC_PIXEL_SIZE, fScaleY) && FcConfigSubstitute(nullptr, scalePattern, FcMatchPattern)) { FcDefaultSubstitute(scalePattern); FcResult result; SkAutoTUnref<FcPattern> resolved(FcFontMatch(nullptr, scalePattern, &result)); if (resolved) { parsePattern(resolved); return; } } } parsePattern(pattern); }
static int find_font(info_rec* info, char* family, char* path) { FcPattern* pattern; FcPattern* matchedPattern; FcResult result; FcChar8* s; pattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, family, (char*) NULL); if (pattern == NULL) return YUV_fontconfig; if (FcConfigSubstitute(info->config, pattern, FcMatchPattern) != FcTrue) return YUV_fontconfig; FcDefaultSubstitute(pattern); matchedPattern = FcFontMatch(info->config, pattern, &result); FcPatternDestroy(pattern); if (FcPatternGetString(matchedPattern, FC_FILE, 0, &s) != FcResultMatch) return YUV_fontconfig; strcpy(path, (char*)s); FcPatternDestroy(matchedPattern); return YUV_OK; }