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 Vector<String> patternToFamilies(FcPattern& pattern) { char* patternChars = reinterpret_cast<char*>(FcPatternFormat(&pattern, reinterpret_cast<const FcChar8*>("%{family}"))); String patternString = String::fromUTF8(patternChars); free(patternChars); Vector<String> results; patternString.split(',', results); return results; }
static FcBool cache_print_set (FcFontSet *set, FcStrSet *dirs, const FcChar8 *base_name, FcBool verbose) { FcChar8 *dir; const FcChar8 *base; int n; int ndir = 0; FcStrList *list; list = FcStrListCreate (dirs); if (!list) goto bail2; while ((dir = FcStrListNext (list))) { base = file_base_name (base_name, dir); if (!write_string (stdout, base)) goto bail3; if (PUTC (' ', stdout) == EOF) goto bail3; if (!write_int (stdout, 0)) goto bail3; if (PUTC (' ', stdout) == EOF) goto bail3; if (!write_string (stdout, FC_FONT_FILE_DIR)) goto bail3; if (PUTC ('\n', stdout) == EOF) goto bail3; ndir++; } for (n = 0; n < set->nfont; n++) { FcPattern *font = set->fonts[n]; FcChar8 *s; s = FcPatternFormat (font, (const FcChar8 *) "%{=fccat}\n"); if (s) { printf ("%s", s); FcStrFree (s); } } if (verbose && !set->nfont && !ndir) printf ("<empty>\n"); FcStrListDone (list); return FcTrue; bail3: FcStrListDone (list); bail2: return FcFalse; }
CAMLprim value pattern_format(value pat, value format) { CAMLparam0(); CAMLlocal1(res); char *str_res = (char *)FcPatternFormat(FcPattern_val(pat), (FcChar8 *) String_val(format)); if(str_res == NULL) { caml_invalid_argument("pattern format"); } else { res = caml_copy_string(str_res); free(str_res); } CAMLreturn(res); }
int main (int argc, char **argv) { int brief = 0; FcChar8 *format = NULL; int i; FcFontSet *fs; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; setlocale (LC_ALL, ""); #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "bf:Vh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "bf:Vh")) != -1) #endif { switch (c) { case 'b': brief = 1; break; case 'f': format = (FcChar8 *) strdup (optarg); break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); exit (0); case 'h': usage (argv[0], 0); default: usage (argv[0], 1); } } i = optind; #else i = 1; #endif if (i == argc) usage (argv[0], 1); fs = FcFontSetCreate (); for (; i < argc; i++) { const FcChar8 *file = (FcChar8*) argv[i]; if (!FcFileIsDir (file)) FcFileScan (fs, NULL, NULL, NULL, file, FcTrue); else { FcStrSet *dirs = FcStrSetCreate (); FcStrList *strlist = FcStrListCreate (dirs); do { FcDirScan (fs, dirs, NULL, NULL, file, FcTrue); } while ((file = FcStrListNext (strlist))); FcStrListDone (strlist); FcStrSetDestroy (dirs); } } for (i = 0; i < fs->nfont; i++) { FcPattern *pat = fs->fonts[i]; if (brief) { FcPatternDel (pat, FC_CHARSET); FcPatternDel (pat, FC_LANG); } if (format) { FcChar8 *s; s = FcPatternFormat (pat, format); if (s) { printf ("%s", s); FcStrFree (s); } } else { FcPatternPrint (pat); } } FcFontSetDestroy (fs); FcFini (); return i > 0 ? 0 : 1; }
int main (int argc, char **argv) { unsigned int id = (unsigned int) -1; int brief = 0; FcFontSet *fs; FcChar8 *format = NULL; int err = 0; int i; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; setlocale (LC_ALL, ""); #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "i:bf:Vh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "i:bf:Vh")) != -1) #endif { switch (c) { case 'i': id = (unsigned int) strtol (optarg, NULL, 0); /* strtol() To handle -1. */ break; case 'b': brief = 1; break; case 'f': format = (FcChar8 *) strdup (optarg); break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); exit (0); case 'h': usage (argv[0], 0); default: usage (argv[0], 1); } } i = optind; #else i = 1; #endif if (i == argc) usage (argv[0], 1); fs = FcFontSetCreate (); #if defined(MIKTEX_WINDOWS) _setmode(_fileno(stdout), _O_BINARY); #endif for (; i < argc; i++) { if (!FcFreeTypeQueryAll ((FcChar8*) argv[i], id, NULL, NULL, fs)) { fprintf (stderr, _("Can't query face %u of font file %s\n"), id, argv[i]); err = 1; } } for (i = 0; i < fs->nfont; i++) { FcPattern *pat = fs->fonts[i]; if (brief) { FcPatternDel (pat, FC_CHARSET); FcPatternDel (pat, FC_LANG); } if (format) { FcChar8 *s; s = FcPatternFormat (pat, format); if (s) { printf ("%s", s); FcStrFree (s); } } else { FcPatternPrint (pat); } } FcFontSetDestroy (fs); FcFini (); return err; }
int main (int argc, char **argv) { int index_set = 0; int set_index = 0; FcChar8 *format = NULL; int err = 0; int i; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "i:f:Vh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "i:f:Vh")) != -1) #endif { switch (c) { case 'i': index_set = 1; set_index = atoi (optarg); break; case 'f': format = (FcChar8 *) strdup (optarg); break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); exit (0); case 'h': usage (argv[0], 0); default: usage (argv[0], 1); } } i = optind; #else i = 1; #endif if (i == argc) usage (argv[0], 1); for (; i < argc; i++) { int index; int count = 0; index = set_index; do { FcPattern *pat; pat = FcFreeTypeQuery ((FcChar8 *) argv[i], index, NULL, &count); if (pat) { if (format) { FcChar8 *s; s = FcPatternFormat (pat, format); if (s) { printf ("%s", s); FcStrFree (s); } } else { FcPatternPrint (pat); } FcPatternDestroy (pat); } else { fprintf (stderr, "Can't query face %d of font file %s\n", index, argv[i]); err = 1; } index++; } while (!index_set && index < count); } FcFini (); return err; }
int main (int argc, char **argv) { int verbose = 0; int sort = 0, all = 0; const FcChar8 *format = NULL; int i; FcObjectSet *os = 0; FcFontSet *fs; FcPattern *pat; FcResult result; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "asvf:Vh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "asvf:Vh")) != -1) #endif { switch (c) { case 'a': all = 1; break; case 's': sort = 1; break; case 'v': verbose = 1; break; case 'f': format = (FcChar8 *) strdup (optarg); break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); exit (0); case 'h': usage (argv[0], 0); default: usage (argv[0], 1); } } i = optind; #else i = 1; #endif if (!FcInit ()) { fprintf (stderr, "Can't init font config library\n"); return 1; } if (argv[i]) { pat = FcNameParse ((FcChar8 *) argv[i]); while (argv[++i]) { if (!os) os = FcObjectSetCreate (); FcObjectSetAdd (os, argv[i]); } } else pat = FcPatternCreate (); if (!pat) return 1; FcConfigSubstitute (0, pat, FcMatchPattern); FcDefaultSubstitute (pat); fs = FcFontSetCreate (); if (sort || all) { FcFontSet *font_patterns; int j; font_patterns = FcFontSort (0, pat, all ? FcFalse : FcTrue, 0, &result); if (!font_patterns || font_patterns->nfont == 0) { fputs("No fonts installed on the system\n", stderr); return 1; } for (j = 0; j < font_patterns->nfont; j++) { FcPattern *font_pattern; font_pattern = FcFontRenderPrepare (NULL, pat, font_patterns->fonts[j]); if (font_pattern) FcFontSetAdd (fs, font_pattern); } FcFontSetSortDestroy (font_patterns); } else { FcPattern *match; match = FcFontMatch (0, pat, &result); if (match) FcFontSetAdd (fs, match); } FcPatternDestroy (pat); if (!format) { if (os) format = (const FcChar8 *) "%{=unparse}\n"; else format = (const FcChar8 *) "%{=fcmatch}\n"; } if (fs) { int j; for (j = 0; j < fs->nfont; j++) { FcPattern *font; font = FcPatternFilter (fs->fonts[j], os); if (verbose) { FcPatternPrint (font); } else { FcChar8 *s; s = FcPatternFormat (font, format); if (s) { printf ("%s", s); free (s); } } FcPatternDestroy (font); } FcFontSetDestroy (fs); } if (os) FcObjectSetDestroy (os); FcFini (); return 0; }
FontInfo * get_font_info_list (int *num) { FcInit(); *num = -1; FcPattern *pat = FcPatternCreate(); if (!pat) { fprintf(stderr, "Create FcPattern Failed\n"); return NULL; } FcObjectSet *os = FcObjectSetBuild( FC_FAMILY, FC_FAMILYLANG, FC_STYLE, FC_FILE, FC_LANG, FC_SPACING, NULL); if (!os) { fprintf(stderr, "Build FcObjectSet Failed\n"); FcPatternDestroy(pat); return NULL; } FcFontSet *fs = FcFontList(0, pat, os); FcObjectSetDestroy(os); FcPatternDestroy(pat); if (!fs) { fprintf(stderr, "List Font Failed\n"); return NULL; } int i; int cnt = 0; FontInfo *list = NULL; for (i = 0; i < fs->nfont; i++) { FontInfo *info = calloc(1, sizeof(FontInfo)); if (!info) { fprintf(stderr, "Alloc memory failed"); continue; } info->family = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{family}"); info->familylang = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{familylang}"); info->style = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{style}"); info->filename = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{file}"); info->lang = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{lang}"); info->spacing = (char*)FcPatternFormat(fs->fonts[i], (FcChar8*)"%{spacing}"); if (!info->family || !info->familylang || !info->style || !info->filename || !info->lang || !info->spacing) { font_info_free(info); continue; } FontInfo *tmp = malloc((cnt+1) * sizeof(FontInfo)); if (!tmp) { fprintf(stderr, "Alloc memory failed\n"); font_info_free(info); continue; } memcpy(tmp+cnt, info, sizeof(FontInfo)); free(info); if (cnt != 0 ) { memcpy(tmp, list, cnt * sizeof(FontInfo)); free(list); list = NULL; } list = tmp; tmp = NULL; cnt++; } FcFontSetDestroy(fs); FcFini(); // Error: FcCacheFini *num = cnt; return list; }