コード例 #1
0
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;
}
コード例 #2
0
ファイル: FontCacheFreeType.cpp プロジェクト: nickooms/webkit
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;
}
コード例 #3
0
ファイル: fc-cat.c プロジェクト: Nathan22Miles/SileLectionary
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;
}
コード例 #4
0
ファイル: pattern.c プロジェクト: rlepigre/ocaml-fontconfig
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);
}
コード例 #5
0
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;
}
コード例 #6
0
ファイル: fc-query.c プロジェクト: MiKTeX/miktex
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;
}
コード例 #7
0
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;
}
コード例 #8
0
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;
}
コード例 #9
0
ファイル: font_list.c プロジェクト: felixonmars/dde-daemon
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;
}