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()); } } }
// ----------------------------------------- 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 }
static void pk_font_not_found (PangoLanguage *language) { FcPattern *pat = NULL; gchar *tag = NULL; const gchar *lang; g_return_if_fail (language != NULL); /* convert to language */ lang = pango_language_to_string (language); if (lang == NULL || lang[0] == '\0') { g_warning ("failed to convert language to string"); goto out; } /* create the font tag used in as a package provides */ pat = FcPatternCreate (); FcPatternAddString (pat, FC_LANG, (FcChar8 *) lang); tag = (gchar *) FcNameUnparse (pat); if (tag == NULL || tag[0] == '\0') { g_warning ("failed to create font tag: %s", lang); goto out; } /* add to array for processing in idle callback */ queue_install_fonts_tag (tag); out: if (pat != NULL) FcPatternDestroy (pat); if (tag != NULL) free (tag); }
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 }
// 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; }
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; }
FcFontSet *fcinfo_styles_index(const FcChar8 *family, const FcPattern *filter, family_info_t *fi) { FcFontSet *fontset, *result; FcPattern *pattern; pattern = FcPatternDuplicate(filter); FcPatternDel(pattern, FC_FAMILY); /* perhaps shouldn't be needed */ FcPatternAddString(pattern, FC_FAMILY, family); fontset = fcinfo(NULL, pattern, FcFalse, 5, FC_FAMILY, FC_STYLE, FC_LANG,/* fonts like Misc Fixed need to be sorted by LANG (subset-like) */ FC_PIXEL_SIZE, FC_FILE); /* for identifying the best font in FC_LANG terms */ FcPatternDestroy(pattern); if (fontset->nfont == 0) return fontset; result = fcinfo_match(fontset, filter); /* assuming family_info entries all same for each style of family; might not be true always */ if (fi) family_info(result->fonts[0], fi); FcFontSetDestroy(fontset); return result; }
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; }
static AliasStrength strengthOfFirstAlias(const FcPattern& original) { // Ideally there would exist a call like // FcResult FcPatternIsWeak(pattern, object, id, FcBool* isWeak); // // However, there is no such call and as of Fc 2.11.0 even FcPatternEquals ignores the weak bit. // Currently, the only reliable way of finding the weak bit is by its effect on matching. // The weak bit only affects the matching of FC_FAMILY and FC_POSTSCRIPT_NAME object values. // A element with the weak bit is scored after FC_LANG, without the weak bit is scored before. // Note that the weak bit is stored on the element, not on the value it holds. FcValue value; FcResult result = FcPatternGet(&original, FC_FAMILY, 0, &value); if (result != FcResultMatch) return AliasStrength::Done; RefPtr<FcPattern> pattern = adoptRef(FcPatternDuplicate(&original)); FcBool hasMultipleFamilies = true; while (hasMultipleFamilies) hasMultipleFamilies = FcPatternRemove(pattern.get(), FC_FAMILY, 1); // Create a font set with two patterns. // 1. the same FC_FAMILY as pattern and a lang object with only 'nomatchlang'. // 2. a different FC_FAMILY from pattern and a lang object with only 'matchlang'. FcUniquePtr<FcFontSet> fontSet(FcFontSetCreate()); FcUniquePtr<FcLangSet> strongLangSet(FcLangSetCreate()); FcLangSetAdd(strongLangSet.get(), reinterpret_cast<const FcChar8*>("nomatchlang")); // Ownership of this FcPattern will be transferred with FcFontSetAdd. FcPattern* strong = FcPatternDuplicate(pattern.get()); FcPatternAddLangSet(strong, FC_LANG, strongLangSet.get()); FcUniquePtr<FcLangSet> weakLangSet(FcLangSetCreate()); FcLangSetAdd(weakLangSet.get(), reinterpret_cast<const FcChar8*>("matchlang")); // Ownership of this FcPattern will be transferred via FcFontSetAdd. FcPattern* weak = FcPatternCreate(); FcPatternAddString(weak, FC_FAMILY, reinterpret_cast<const FcChar8*>("nomatchstring")); FcPatternAddLangSet(weak, FC_LANG, weakLangSet.get()); FcFontSetAdd(fontSet.get(), strong); FcFontSetAdd(fontSet.get(), weak); // Add 'matchlang' to the copy of the pattern. FcPatternAddLangSet(pattern.get(), FC_LANG, weakLangSet.get()); // Run a match against the copy of the pattern. // If the first element was weak, then we should match the pattern with 'matchlang'. // If the first element was strong, then we should match the pattern with 'nomatchlang'. // Note that this config is only used for FcFontRenderPrepare, which we don't even want. // However, there appears to be no way to match/sort without it. RefPtr<FcConfig> config = adoptRef(FcConfigCreate()); FcFontSet* fontSets[1] = { fontSet.get() }; RefPtr<FcPattern> match = adoptRef(FcFontSetMatch(config.get(), fontSets, 1, pattern.get(), &result)); FcLangSet* matchLangSet; FcPatternGetLangSet(match.get(), FC_LANG, 0, &matchLangSet); return FcLangEqual == FcLangSetHasLang(matchLangSet, reinterpret_cast<const FcChar8*>("matchlang")) ? AliasStrength::Weak : AliasStrength::Strong; }
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; }
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; }
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; }
// ------------------------------------------------------ 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; }
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; }
/** Find a font file from its family name. * @param font_config fontconfig instance * @param font_name name of the font * @return full path to the font file */ gchar* find_font_file (FcConfig* font_config, const gchar* font_name) { const FcChar8* name; FcPattern* search_pattern; FcPattern* font; FcChar8* file; gchar* path; FcObjectSet* font_properties; FcFontSet* fonts; int i; if (font_config == NULL) { g_warning("Font config not loaded."); return NULL; } path = NULL; name = font_name; search_pattern = FcPatternCreate (); FcPatternAddString (search_pattern, FC_FAMILY, name); FcPatternAddBool (search_pattern, FC_SCALABLE, FcTrue); FcPatternAddInteger (search_pattern, FC_WEIGHT, FC_WEIGHT_MEDIUM); FcPatternAddInteger (search_pattern, FC_SLANT, FC_SLANT_ROMAN); font_properties = FcObjectSetBuild (FC_FILE, NULL); fonts = FcFontList (font_config, search_pattern, font_properties); if (fonts->nfont > 0) { for (i = 0; i < fonts->nfont; i++) { font = fonts->fonts[i]; if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) { path = g_strdup ((gchar*) file); break; } } FcPatternDestroy (font); } FcPatternDestroy (search_pattern); return path; }
/* Ask the fontgod for a generic, standard issue "Arial" font */ const char *graph_init_fontconfig(void) { /* Offer fontgod sacrificial pointers to hold his highness */ FcConfig *fc_config = FcInitLoadConfigAndFonts(); FcPattern *fc_pattern = FcPatternCreate(); /* Ask the deity for a user-specified gift of typography */ FcPatternAddString(fc_pattern, FC_FAMILY, (const FcChar8 *)option->fontname); /* Ask fontgod not to blind our eyes for our insolence */ FcPatternAddBool(fc_pattern, FC_ANTIALIAS, 1); /* Summon a fontdemon which shall transmit the gifts of our god */ FcResult fc_result; /* Incantation for our omnipotence to recognize our request: */ FcDefaultSubstitute(fc_pattern); FcConfigSubstitute(fc_config, fc_pattern, FcMatchPattern); /* "We ask you, oh you in the sky, for your attention..." */ FcPattern *fc_font_chosen = FcFontMatch(fc_config, fc_pattern, &fc_result); FcValue fc_value; /* SHOW US YOUR POWER, INVOKE ANCIENT KNOWLEDGE, GIVE US THE LOCATION! */ FcPatternGet(fc_font_chosen, "file", 0, &fc_value); /* Fontgod has given us a sacred filename, hail FONTCONFIG! */ pprintf(PRI_SPAM, "[FC] Font path received = %s\n", (char *)fc_value.u.s); return (const char *)fc_value.u.s; }
int main(int argc, char* argv[]) { msgbuf = malloc(256); msgbuf[0] = 0; currentLayer = 0; cache = true; int longIndex; int opt; do { opt = getopt_long(argc, argv, optString, longOpts, &longIndex); if (opt != -1) { switch( opt ) { case 'l': currentLayer = strtol(optarg, NULL, 10); break; case 'w': extrusionWidth = strtof(optarg, NULL); break; case 'n': printf("DISABLING CACHE\n"); cache = false; break; case 'h': /* fall-through is intentional */ case '?': display_usage(); break; case 0: /* long option without a short arg */ //if( strcmp( "randomize", longOpts[longIndex].name ) == 0 ) { // globalArgs.randomized = 1; //} break; default: /* You won't actually get here. */ break; } } } while (opt != -1); if (optind >= argc) display_usage(); int fd = open(argv[optind], 0); if (fd == -1) die("Open ", argv[optind]); struct stat filestats; if (fstat(fd, &filestats) == -1) die("fstat ", argv[optind]); filesz = filestats.st_size; printf("File is %d long\n", filesz); #ifdef __linux__ gcodefile = mmap(NULL, filesz, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd, 0); #elif defined __APPLE__ gcodefile = mmap(NULL, filesz, PROT_READ, MAP_PRIVATE, fd, 0); #else #error "don't know how to mmap on this system!" #endif if (gcodefile == MAP_FAILED) die("mmap ", argv[optind]); gcodefile_end = &gcodefile[filesz]; busy = BUSY_SCANFILE; scanLines(); if (currentLayer >= layerCount) currentLayer = layerCount - 1; //for (int i = 0; i < layerCount; i++) // printf("Layer %3d starts at %7d and is %7d bytes long\n", i, layer[i].index - gcodefile, layer[i].size); Running = true; Surf_Display = NULL; if (SDL_Init(SDL_INIT_EVERYTHING) < 0) die("SDL_init", ""); if (FcInitLoadConfigAndFonts() == ((void *) FcTrue)) die("FontConfig Init",""); // from http://www.spinics.net/lists/font-config/msg03050.html FcPattern *pat, *match; FcResult result; char *file; int index; pat = FcPatternCreate(); FcPatternAddString(pat, FC_FAMILY, (FcChar8 *) "Mono"); FcConfigSubstitute(NULL, pat, FcMatchPattern); FcDefaultSubstitute(pat); match = FcFontMatch(NULL, pat, &result); FcPatternGetString(match, FC_FILE, 0, (FcChar8 **) &file); FcPatternGetInteger(match, FC_INDEX, 0, &index); font = ftglCreateExtrudeFont(file); if (!font) die("FTGL createFont", ""); FcPatternDestroy (match); FcPatternDestroy (pat); #ifdef OPENGL transX = transY = 0.0; zoomFactor = 1.0; resize(600, 600); #else viewPortL = viewPortT = 0.0; viewPortR = viewPortB = 200.0; zoomFactor = 3.0; resize(viewPortR * zoomFactor, viewPortB * zoomFactor); #endif SDL_WM_SetCaption("gcodeview", 0); drawLayer(currentLayer); layerVelocity = 0; timerIdle = SDL_AddTimer(20, &timerCallback, (void *) TIMER_IDLE); SDL_Event Event; while(Running != false) { if (busy) { Event.type = SDL_NOEVENT; SDL_PollEvent(&Event); } else { if (SDL_WaitEvent(&Event) == 0) die("SDL_WaitEvent", ""); } //SDL_RemoveTimer(timerIdle); switch (Event.type) { case SDL_NOEVENT: if (busy & BUSY_SCANFILE) { // TODO: scan next layer scanLine(); if ((busy & BUSY_SCANFILE) == 0) { if (cache) { printf("File scanned, rendering...\n"); busy = BUSY_RENDER; } else { printf("File scanned.\n"); busy = 0; } } } else if ((busy & BUSY_RENDER) && cache) { bool allRendered = true; int i; // TODO: render next layer in background for (i = 0; i < layerCount; i++) { if (layer[i].glList == 0) { layer[i].glList = glGenLists(1); glNewList(layer[i].glList, GL_COMPILE); glBegin(GL_QUADS); for (int j = SHADOW_LAYERS; j >= 1; j--) { if (i - j > 0) render_layer(i - j, SHADOW_ALPHA - (j - 1) * (SHADOW_ALPHA / SHADOW_LAYERS)); } render_layer(i, 1.0); glEnd(); glEndList(); layer[i].flags |= LD_LISTGENERATED; allRendered = false; break; } } if (allRendered) { printf("All %d layers rendered\n", i); busy &= ~BUSY_RENDER; } } break; case SDL_QUIT: Running = false; break; case SDL_VIDEORESIZE: resize(Event.resize.w, Event.resize.h); break; case SDL_VIDEOEXPOSE: render(); break; case SDL_MOUSEBUTTONDOWN: handle_mousedown(Event.button); break; case SDL_MOUSEBUTTONUP: handle_mouseup(Event.button); break; case SDL_MOUSEMOTION: handle_mousemove(Event.motion); break; case SDL_ACTIVEEVENT: // lose or gain focus break; case SDL_KEYDOWN: handle_keydown(Event.key); break; case SDL_KEYUP: handle_keyup(Event.key); break; case SDL_USEREVENT: handle_userevent(Event.user); break; default: printf("SDL Event %d\n", Event.type); break; } //idle code //if (busy) // timerIdle = SDL_AddTimer(20, &timerCallback, (void *) TIMER_IDLE); } if (timerKeyRepeat) SDL_RemoveTimer(timerKeyRepeat); if (timerDragRender) SDL_RemoveTimer(timerDragRender); free(layer); SDL_FreeSurface(Surf_Display); SDL_Quit(); return 0; }
std::unique_ptr<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()); // Never choose unscalable fonts, as they pixelate when displayed at different sizes. FcPatternAddBool(pattern.get(), FC_SCALABLE, FcTrue); String familyNameString(getFamilyNameStringFromFamily(family)); if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(familyNameString.utf8().data()))) return nullptr; bool italic = fontDescription.italic(); if (!FcPatternAddInteger(pattern.get(), FC_SLANT, italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN)) return nullptr; if (!FcPatternAddInteger(pattern.get(), FC_WEIGHT, fontWeightToFontconfigWeight(fontDescription.weight()))) return nullptr; if (!FcPatternAddDouble(pattern.get(), FC_PIXEL_SIZE, fontDescription.computedPixelSize())) return nullptr; // The strategy is originally from Skia (src/ports/SkFontHost_fontconfig.cpp): // // We do not normally allow fontconfig to substitute one font family for another, since this // would break CSS font family fallback: the website should be in control of fallback. During // normal font matching, the only font family substitution permitted is for generic families // (sans, serif, monospace) or for strongly-aliased fonts (which are to be treated as // effectively identical). This is because the font matching step is designed to always find a // match for the font, which we don't want. // // Fontconfig is used in two stages: (1) configuration and (2) matching. During the // configuration step, before any matching occurs, we allow arbitrary family substitutions, // since this is an exact matter of respecting the user's font configuration. FcConfigSubstitute(nullptr, 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(nullptr, pattern.get(), &fontConfigResult)); if (!resultPattern) // No match. return nullptr; FcChar8* fontConfigFamilyNameAfterMatching; FcPatternGetString(resultPattern.get(), FC_FAMILY, 0, &fontConfigFamilyNameAfterMatching); String familyNameAfterMatching = String::fromUTF8(reinterpret_cast<char*>(fontConfigFamilyNameAfterMatching)); // If Fontconfig gave us 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 exceptions are if // this family name is a commonly-used generic family, or if the families are strongly-aliased. // Checking for a strong alias comes last, since it is slow. if (!equalIgnoringCase(familyNameAfterConfiguration, familyNameAfterMatching) && !(equalIgnoringCase(familyNameString, "sans") || equalIgnoringCase(familyNameString, "sans-serif") || equalIgnoringCase(familyNameString, "serif") || equalIgnoringCase(familyNameString, "monospace") || equalIgnoringCase(familyNameString, "fantasy") || equalIgnoringCase(familyNameString, "cursive")) && !areStronglyAliased(familyNameAfterConfiguration, familyNameAfterMatching)) return nullptr; // 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. auto platformData = std::make_unique<FontPlatformData>(resultPattern.get(), fontDescription); if (!platformData->hasCompatibleCharmap()) return nullptr; return platformData; }
static TTF_Font *search_font_config(astring name, bool bold, bool italic, bool underline, bool &bakedstyles) { TTF_Font *font = (TTF_Font *)NULL; FcConfig *config; FcPattern *pat; FcObjectSet *os; FcFontSet *fontset; FcValue val; config = FcConfigGetCurrent(); pat = FcPatternCreate(); os = FcObjectSetCreate(); FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.cstr()); // try and get a font with the requested styles baked-in if (bold) { if (italic) { FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold Italic"); } else { FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold"); } } else if (italic) { FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Italic"); } else { FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular"); } FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType"); FcObjectSetAdd(os, FC_FILE); fontset = FcFontList(config, pat, os); for (int i = 0; i < fontset->nfont; i++) { if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch) { continue; } if (val.type != FcTypeString) { continue; } mame_printf_verbose("Matching font: %s\n", val.u.s); { astring match_name((const char*)val.u.s); font = TTF_OpenFont_Magic(match_name, POINT_SIZE); } if (font) { bakedstyles = true; break; } } // didn't get a font above? try again with no baked-in styles if (!font) { FcPatternDestroy(pat); FcFontSetDestroy(fontset); pat = FcPatternCreate(); FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.cstr()); FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular"); FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType"); fontset = FcFontList(config, pat, os); for (int i = 0; i < fontset->nfont; i++) { if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch) { continue; } if (val.type != FcTypeString) { continue; } mame_printf_verbose("Matching unstyled font: %s\n", val.u.s); { astring match_name((const char*)val.u.s); font = TTF_OpenFont_Magic(match_name, POINT_SIZE); } if (font) { break; } } } FcPatternDestroy(pat); FcObjectSetDestroy(os); FcFontSetDestroy(fontset); return font; }
nsresult gfxQtPlatform::ResolveFontName(const nsAString& aFontName, FontResolverCallback aCallback, void *aClosure, PRBool& aAborted) { nsAutoString name(aFontName); ToLowerCase(name); nsRefPtr<FontFamily> ff; if (gPlatformFonts->Get(name, &ff) || gPlatformFontAliases->Get(name, &ff)) { aAborted = !(*aCallback)(ff->Name(), aClosure); return NS_OK; } nsCAutoString utf8Name = NS_ConvertUTF16toUTF8(aFontName); FcPattern *npat = FcPatternCreate(); FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get()); FcObjectSet *nos = FcObjectSetBuild(FC_FAMILY, NULL); FcFontSet *nfs = FcFontList(NULL, npat, nos); for (int k = 0; k < nfs->nfont; k++) { FcChar8 *str; if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch) continue; nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))); ToLowerCase(altName); if (gPlatformFonts->Get(altName, &ff)) { printf("Adding alias: %s -> %s\n", utf8Name.get(), str); gPlatformFontAliases->Put(name, ff); aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure); goto DONE; } } FcPatternDestroy(npat); FcObjectSetDestroy(nos); FcFontSetDestroy(nfs); { npat = FcPatternCreate(); FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get()); FcPatternDel(npat, FC_LANG); FcConfigSubstitute(NULL, npat, FcMatchPattern); FcDefaultSubstitute(npat); nos = FcObjectSetBuild(FC_FAMILY, NULL); nfs = FcFontList(NULL, npat, nos); FcResult fresult; FcPattern *match = FcFontMatch(NULL, npat, &fresult); if (match) FcFontSetAdd(nfs, match); for (int k = 0; k < nfs->nfont; k++) { FcChar8 *str; if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch) continue; nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))); ToLowerCase(altName); if (gPlatformFonts->Get(altName, &ff)) { printf("Adding alias: %s -> %s\n", utf8Name.get(), str); gPlatformFontAliases->Put(name, ff); aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure); goto DONE; } } } DONE: FcPatternDestroy(npat); FcObjectSetDestroy(nos); FcFontSetDestroy(nfs); return NS_OK; }
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; }
FcPattern * FcNameParse (const FcChar8 *name) { FcChar8 *save; FcPattern *pat; double d; FcChar8 *e; FcChar8 delim; FcValue v; FcMatrix m; const FcObjectType *t; const FcConstant *c; /* freed below */ save = malloc (strlen ((char *) name) + 1); if (!save) goto bail0; pat = FcPatternCreate (); if (!pat) goto bail1; for (;;) { name = FcNameFindNext (name, "-,:", save, &delim); if (save[0]) { if (!FcPatternAddString (pat, FC_FAMILY, save)) goto bail2; } if (delim != ',') break; } if (delim == '-') { for (;;) { name = FcNameFindNext (name, "-,:", save, &delim); d = strtod ((char *) save, (char **) &e); if (e != save) { if (!FcPatternAddDouble (pat, FC_SIZE, d)) goto bail2; } if (delim != ',') break; } } while (delim == ':') { name = FcNameFindNext (name, "=_:", save, &delim); if (save[0]) { if (delim == '=' || delim == '_') { t = FcNameGetObjectType ((char *) save); for (;;) { name = FcNameFindNext (name, ":,", save, &delim); if (t) { v = FcNameConvert (t->type, save, &m); if (!FcPatternAdd (pat, t->object, v, FcTrue)) { switch (v.type) { case FcTypeCharSet: FcCharSetDestroy ((FcCharSet *) v.u.c); break; case FcTypeLangSet: FcLangSetDestroy ((FcLangSet *) v.u.l); break; default: break; } goto bail2; } switch (v.type) { case FcTypeCharSet: FcCharSetDestroy ((FcCharSet *) v.u.c); break; case FcTypeLangSet: FcLangSetDestroy ((FcLangSet *) v.u.l); break; default: break; } } if (delim != ',') break; } } else { if ((c = FcNameGetConstant (save))) { if (!FcPatternAddInteger (pat, c->object, c->value)) goto bail2; } } } } free (save); return pat; bail2: FcPatternDestroy (pat); bail1: free (save); bail0: return 0; }
FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName) : m_pattern(0) , m_fallbacks(0) , m_size(fontDescription.computedSize()) , m_syntheticBold(false) , m_syntheticOblique(false) , m_scaledFont(0) , m_face(0) { FontPlatformData::init(); CString familyNameString = familyName.string().utf8(); const char* fcfamily = familyNameString.data(); int fcslant = FC_SLANT_ROMAN; // FIXME: Map all FontWeight values to fontconfig weights. int fcweight = FC_WEIGHT_NORMAL; float fcsize = fontDescription.computedSize(); if (fontDescription.italic()) fcslant = FC_SLANT_ITALIC; if (fontDescription.weight() >= FontWeight600) fcweight = FC_WEIGHT_BOLD; FcConfig *config = FcConfigGetCurrent(); //printf("family = %s\n", fcfamily); int type = fontDescription.genericFamily(); FcPattern* pattern = FcPatternCreate(); if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily))) goto freePattern; switch (type) { case FontDescription::SerifFamily: fcfamily = "serif"; break; case FontDescription::SansSerifFamily: fcfamily = "sans-serif"; break; case FontDescription::MonospaceFamily: fcfamily = "monospace"; break; case FontDescription::NoFamily: case FontDescription::StandardFamily: default: fcfamily = "sans-serif"; } if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily))) goto freePattern; if (!FcPatternAddInteger(pattern, FC_SLANT, fcslant)) goto freePattern; if (!FcPatternAddInteger(pattern, FC_WEIGHT, fcweight)) goto freePattern; if (!FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fcsize)) goto freePattern; FcConfigSubstitute(config, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); FcResult fcresult; m_pattern = FcFontMatch(config, pattern, &fcresult); FcPatternReference(m_pattern); // FIXME: should we set some default font? if (!m_pattern) goto freePattern; FcChar8 *fc_filename; char *filename; int id; id = 0; if (FcPatternGetString(m_pattern, FC_FILE, 0, &fc_filename) != FcResultMatch) { LOG(FontEngine, "cannot retrieve font\n"); goto freePattern; } filename = (char *) fc_filename; //use C cast as FcChar is a fontconfig type //printf("filename = %s\n", filename); if (FcPatternGetInteger(m_pattern, FC_INDEX, 0, &id) != FcResultMatch) { LOG(FontEngine, "cannot retrieve font index\n"); goto freePattern; } if (FT_Error error = FT_New_Face(m_library, filename, id, &m_face)) { //if (FT_Error error = FT_New_Face(m_library, too, id, &m_face)) { LOG(FontEngine, "fail to open fonti %s with index %d (error = 0x%x)\n", filename, id, error); m_face = 0; goto freePattern; } FT_Set_Pixel_Sizes(m_face, 0, static_cast<uint> (fontDescription.computedSize())); //DBGML(MODULE_FONTS, LEVEL_INFO, "open font %s with size %d\n", filename, static_cast<uint> (fontDescription.specifiedSize())); freePattern: FcPatternDestroy(pattern); FcConfigDestroy(config); }
fz_error * pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection) { fz_error *error; FcResult fcerr; int fterr; char fontname[200]; FcPattern *searchpat; FcPattern *matchpat; FT_Face face; char *style; char *file; int index; error = initfontlibs(); if (error) return error; /* parse windows-style font name descriptors Font,Style */ /* TODO: reliable way to split style from Font-Style type names */ strlcpy(fontname, basefont, sizeof fontname); style = strchr(fontname, ','); if (style) *style++ = 0; searchpat = FcPatternCreate(); if (!searchpat) return fz_outofmem; error = fz_outofmem; if (!FcPatternAddString(searchpat, FC_FAMILY, fontname)) goto cleanup; if (collection) { if (!strcmp(collection, "Adobe-GB1")) if (!FcPatternAddString(searchpat, FC_LANG, "zh-TW")) goto cleanup; if (!strcmp(collection, "Adobe-CNS1")) if (!FcPatternAddString(searchpat, FC_LANG, "zh-CN")) goto cleanup; if (!strcmp(collection, "Adobe-Japan1")) if (!FcPatternAddString(searchpat, FC_LANG, "ja")) goto cleanup; if (!strcmp(collection, "Adobe-Japan2")) if (!FcPatternAddString(searchpat, FC_LANG, "ja")) goto cleanup; if (!strcmp(collection, "Adobe-Korea1")) if (!FcPatternAddString(searchpat, FC_LANG, "ko")) goto cleanup; } if (style) if (!FcPatternAddString(searchpat, FC_STYLE, style)) goto cleanup; if (font->flags & FD_SERIF) FcPatternAddString(searchpat, FC_FAMILY, "serif"); else FcPatternAddString(searchpat, FC_FAMILY, "sans-serif"); if (font->flags & FD_ITALIC) FcPatternAddString(searchpat, FC_STYLE, "Italic"); if (font->flags & FD_FORCEBOLD) FcPatternAddString(searchpat, FC_STYLE, "Bold"); if (!FcPatternAddBool(searchpat, FC_OUTLINE, 1)) goto cleanup; file = FcNameUnparse(searchpat); pdf_logfont("fontconfig0 %s\n", file); free(file); fcerr = FcResultMatch; /* FcDefaultSubstitute(searchpat); */ FcConfigSubstitute(fclib, searchpat, FcMatchPattern); file = FcNameUnparse(searchpat); pdf_logfont("fontconfig1 %s\n", file); free(file); matchpat = FcFontMatch(fclib, searchpat, &fcerr); if (fcerr != FcResultMatch) return fz_throw("fontconfig could not find font %s", basefont); fcerr = FcPatternGetString(matchpat, FC_FAMILY, 0, (FcChar8**)&file); if (file && strcmp(fontname, file)) font->substitute = 1; fcerr = FcPatternGetString(matchpat, FC_STYLE, 0, (FcChar8**)&file); if (file && style && strcmp(style, file)) font->substitute = 1; fcerr = FcPatternGetString(matchpat, FC_FILE, 0, (FcChar8**)&file); if (fcerr != FcResultMatch) return fz_throw("fontconfig could not find font %s", basefont); 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) { FcPatternDestroy(matchpat); FcPatternDestroy(searchpat); return fz_throw("freetype could not load font file '%s': %s", file, pdf_fterrorstring(fterr)); } FcPatternDestroy(matchpat); FcPatternDestroy(searchpat); font->ftface = face; return nil; cleanup: FcPatternDestroy(searchpat); return error; }
bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[], SkTypeface::Style style, FontIdentity* outIdentity, SkString* outFamilyName, SkTypeface::Style* outStyle) { SkString familyStr(familyName ? familyName : ""); if (familyStr.size() > kMaxFontFamilyLength) { return false; } SkAutoMutexAcquire ac(mutex_); FcPattern* pattern = FcPatternCreate(); if (familyName) { FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); } FcPatternAddInteger(pattern, FC_WEIGHT, (style & SkTypeface::kBold) ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL); FcPatternAddInteger(pattern, FC_SLANT, (style & SkTypeface::kItalic) ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); FcConfigSubstitute(NULL, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); // Font matching: // CSS often specifies a fallback list of families: // font-family: a, b, c, serif; // However, fontconfig will always do its best to find *a* font when asked // for something so we need a way to tell if the match which it has found is // "good enough" for us. Otherwise, we can return NULL which gets piped up // and lets WebKit know to try the next CSS family name. However, fontconfig // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we // wish to support that. // // Thus, if a specific family is requested we set @family_requested. Then we // record two strings: the family name after config processing and the // family name after resolving. If the two are equal, it's a good match. // // So consider the case where a user has mapped Arial to Helvetica in their // config. // requested family: "Arial" // post_config_family: "Helvetica" // post_match_family: "Helvetica" // -> good match // // and for a missing font: // requested family: "Monaco" // post_config_family: "Monaco" // post_match_family: "Times New Roman" // -> BAD match // // However, we special-case fallback fonts; see IsFallbackFontAllowed(). const char* post_config_family = get_name(pattern, FC_FAMILY); if (!post_config_family) { // we can just continue with an empty name, e.g. default font post_config_family = ""; } FcResult result; FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result); if (!font_set) { FcPatternDestroy(pattern); return false; } FcPattern* match = MatchFont(font_set, post_config_family, familyStr); if (!match) { FcPatternDestroy(pattern); FcFontSetDestroy(font_set); return false; } FcPatternDestroy(pattern); // From here out we just extract our results from 'match' post_config_family = get_name(match, FC_FAMILY); if (!post_config_family) { FcFontSetDestroy(font_set); return false; } const char* c_filename = get_name(match, FC_FILE); if (!c_filename) { FcFontSetDestroy(font_set); return false; } int face_index; if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) { FcFontSetDestroy(font_set); return false; } FcFontSetDestroy(font_set); if (outIdentity) { outIdentity->fTTCIndex = face_index; outIdentity->fString.set(c_filename); } if (outFamilyName) { outFamilyName->set(post_config_family); } if (outStyle) { *outStyle = GetFontStyle(match); } return true; }
static cairo_status_t create_scaled_font (cairo_t * cr, cairo_scaled_font_t **out) { 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; cairo_status_t status; double pixel_size; font_options = cairo_font_options_create (); cairo_get_font_options (cr, font_options); pattern = FcPatternCreate (); if (pattern == NULL) return CAIRO_STATUS_NO_MEMORY; FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *)CAIRO_TEST_FONT_FAMILY " 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); if (resolved == NULL) { FcPatternDestroy (pattern); return CAIRO_STATUS_NO_MEMORY; } /* 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); status = cairo_scaled_font_status (scaled_font); if (status) { cairo_scaled_font_destroy (scaled_font); return status; } *out = scaled_font; return CAIRO_STATUS_SUCCESS; }
bool SkFontConfigInterfaceDirect::matchFamilySet(const char inFamilyName[], SkString* outFamilyName, SkTArray<FontIdentity>* ids) { SkAutoMutexAcquire ac(mutex_); #if 0 SkString familyStr(familyName ? familyName : ""); if (familyStr.size() > kMaxFontFamilyLength) { return false; } SkAutoMutexAcquire ac(mutex_); FcPattern* pattern = FcPatternCreate(); if (familyName) { FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); } FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); FcConfigSubstitute(NULL, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); // Font matching: // CSS often specifies a fallback list of families: // font-family: a, b, c, serif; // However, fontconfig will always do its best to find *a* font when asked // for something so we need a way to tell if the match which it has found is // "good enough" for us. Otherwise, we can return NULL which gets piped up // and lets WebKit know to try the next CSS family name. However, fontconfig // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we // wish to support that. // // Thus, if a specific family is requested we set @family_requested. Then we // record two strings: the family name after config processing and the // family name after resolving. If the two are equal, it's a good match. // // So consider the case where a user has mapped Arial to Helvetica in their // config. // requested family: "Arial" // post_config_family: "Helvetica" // post_match_family: "Helvetica" // -> good match // // and for a missing font: // requested family: "Monaco" // post_config_family: "Monaco" // post_match_family: "Times New Roman" // -> BAD match // // However, we special-case fallback fonts; see IsFallbackFontAllowed(). const char* post_config_family = get_name(pattern, FC_FAMILY); FcResult result; FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result); if (!font_set) { FcPatternDestroy(pattern); return false; } FcPattern* match = MatchFont(font_set, post_config_family, familyStr); if (!match) { FcPatternDestroy(pattern); FcFontSetDestroy(font_set); return false; } FcPatternDestroy(pattern); // From here out we just extract our results from 'match' if (FcPatternGetString(match, FC_FAMILY, 0, &post_config_family) != FcResultMatch) { FcFontSetDestroy(font_set); return false; } FcChar8* c_filename; if (FcPatternGetString(match, FC_FILE, 0, &c_filename) != FcResultMatch) { FcFontSetDestroy(font_set); return false; } int face_index; if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) { FcFontSetDestroy(font_set); return false; } FcFontSetDestroy(font_set); if (outIdentity) { outIdentity->fTTCIndex = face_index; outIdentity->fString.set((const char*)c_filename); } if (outFamilyName) { outFamilyName->set((const char*)post_config_family); } if (outStyle) { *outStyle = GetFontStyle(match); } return true; //////////////////// int count; FcPattern** match = MatchFont(font_set, post_config_family, &count); if (!match) { FcPatternDestroy(pattern); FcFontSetDestroy(font_set); return NULL; } FcPatternDestroy(pattern); SkTDArray<FcPattern*> trimmedMatches; for (int i = 0; i < count; ++i) { const char* justName = find_just_name(get_name(match[i], FC_FILE)); if (!is_lower(*justName)) { *trimmedMatches.append() = match[i]; } } SkFontStyleSet_FC* sset = new SkFontStyleSet_FC (trimmedMatches.begin(), trimmedMatches.count()); #endif return false; }
QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::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); Q_ASSERT(uint(script) < QChar::ScriptCount); if (*specialLanguages[script] != '\0') { FcLangSet *ls = FcLangSetCreate(); FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]); FcPatternAddLangSet(pattern, FC_LANG, ls); FcLangSetDestroy(ls); } else if (!family.isEmpty()) { // If script is Common or Han, then it may include languages like CJK, // we should attach system default language set to the pattern // to obtain correct font fallback list (i.e. if LANG=zh_CN // then we normally want to use a Chinese font for CJK text; // while a Japanese font should be used for that if LANG=ja) FcPattern *dummy = FcPatternCreate(); FcDefaultSubstitute(dummy); FcChar8 *lang = 0; FcResult res = FcPatternGetString(dummy, FC_LANG, 0, &lang); if (res == FcResultMatch) FcPatternAddString(pattern, FC_LANG, lang); FcPatternDestroy(dummy); } const char *stylehint = getFcFamilyForStyleHint(styleHint); if (stylehint) { value.u.s = (const FcChar8 *)stylehint; FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue); } FcConfigSubstitute(0, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); FcResult result = FcResultMatch; FcFontSet *fontSet = FcFontSort(0,pattern,FcFalse,0,&result); FcPatternDestroy(pattern); if (fontSet) { 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) && familyName.compare(family, Qt::CaseInsensitive)) { fallbackFamilies << familyName; } } FcFontSetDestroy(fontSet); } // qDebug() << "fallbackFamilies for:" << family << style << styleHint << script << fallbackFamilies; return fallbackFamilies; }