Hey,
I have two issues with matching patterns with fontconfig.
1. Something seems wrong with FcFontSort in some cases. I've tried it
both with fc-match and with code.
If I run "fc-match :spacing=100" it finds the default font (doesn't have
spacing=100), however if I run fc-list with the same parameter, I get a
filtered result that doesn't include the default system font.
It seems that fc-match is misbehaving, or am I missing something?
2. Both FcFontSort and FcFontList don't work for me with "ftface" as a
filtering parameter.
Testing:
Use either of the attached c programs (modified versions of fc-match and
fc-list) and try running them. I hard-coded a font path there (which
correctly loads, I verified that), you might need to change that to a
different path depending on your system (Arch here).
compile with:
gcc fc-list.c `pkg-config --cflags --libs fontconfig freetype2` list
I would expect it to filter according to the FT_Face, but it doesn't,
any ideas?
If that's not what it's meant to do, what's the best way to load a list
of "most similar to ftface" fonts available on the system? Do I have no
analyse the face and create the pattern on my own?
I'm unsure if it's some misconfiguration here that's causing the havoc,
or an actual issue with fontconfig. Looking forward to hear what you
guys have to say.
Thanks,
Tom.
/*
* fontconfig/fc-list/fc-list.c
*
* Copyright 짤 2002 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the author(s) not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. The authors make no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <fontconfig/fontconfig.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#else
#ifdef linux
#define HAVE_GETOPT_LONG 1
#endif
#define HAVE_GETOPT 1
#endif
#include <ft2build.h>
#include FT_FREETYPE_H
#ifndef HAVE_GETOPT
#define HAVE_GETOPT 0
#endif
#ifndef HAVE_GETOPT_LONG
#define HAVE_GETOPT_LONG 0
#endif
#if HAVE_GETOPT_LONG
#undef _GNU_SOURCE
#define _GNU_SOURCE
#include <getopt.h>
const struct option longopts[] = {
{"verbose", 0, 0, 'v'},
{"format", 1, 0, 'f'},
{"quiet", 0, 0, 'q'},
{"version", 0, 0, 'V'},
{"help", 0, 0, 'h'},
{NULL,0,0,0},
};
#else
#if HAVE_GETOPT
extern char *optarg;
extern int optind, opterr, optopt;
#endif
#endif
static void
usage (char *program, int error)
{
FILE *file = error ? stderr : stdout;
#if HAVE_GETOPT_LONG
fprintf (file, "usage: %s [-vqVh] [-f FORMAT] [--verbose] [--format=FORMAT] [--quiet] [--version] [--help] [pattern] {element ...} \n",
program);
#else
fprintf (file, "usage: %s [-vqVh] [-f FORMAT] [pattern] {element ...} \n",
program);
#endif
fprintf (file, "List fonts matching [pattern]\n");
fprintf (file, "\n");
#if HAVE_GETOPT_LONG
fprintf (file, " -v, --verbose display entire font pattern verbosely\n");
fprintf (file, " -f, --format=FORMAT use the given output format\n");
fprintf (file, " -q, --quiet suppress all normal output, exit 1 if no fonts matched\n");
fprintf (file, " -V, --version display font config version and exit\n");
fprintf (file, " -h, --help display this help and exit\n");
#else
fprintf (file, " -v (verbose) display entire font pattern verbosely\n");
fprintf (file, " -f FORMAT (format) use the given output format\n");
fprintf (file, " -q, (quiet) suppress all normal output, exit 1 if no fonts matched\n");
fprintf (file, " -V (version) display font config version and exit\n");
fprintf (file, " -h (help) display this help and exit\n");
#endif
exit (error);
}
int
main (int argc, char **argv)
{
int verbose = 0;
int quiet = 0;
const FcChar8 *format = NULL;
int nfont = 0;
int i;
FcObjectSet *os = 0;
FcFontSet *fs;
FcPattern *pat;
#if HAVE_GETOPT_LONG || HAVE_GETOPT
int c;
#if HAVE_GETOPT_LONG
while ((c = getopt_long (argc, argv, "vf:qVh", longopts, NULL)) != -1)
#else
while ((c = getopt (argc, argv, "vf:qVh")) != -1)
#endif
{
switch (c) {
case 'v':
verbose = 1;
break;
case 'f':
format = (FcChar8 *) strdup (optarg);
break;
case 'q':
quiet = 1;
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
{
FT_Library library;
FT_Face face;
FT_Init_FreeType( &library );
FT_New_Face( library, "/usr/share/fonts/TTF/DejaVuSans-Bold.ttf", 0, &face );
pat = FcPatternBuild(NULL,
FC_FT_FACE, FcTypeFTFace, face,
NULL);
}
if (quiet && !os)
os = FcObjectSetCreate ();
if (!verbose && !format && !os)
os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_FILE, (char *) 0);
if (!format)
format = (const FcChar8 *) "%{=fclist}\n";
fs = FcFontList (0, pat, os);
if (os)
FcObjectSetDestroy (os);
if (pat)
FcPatternDestroy (pat);
if (!quiet && fs)
{
int j;
for (j = 0; j < fs->nfont; j++)
{
if (verbose)
{
FcPatternPrint (fs->fonts[j]);
}
else
{
FcChar8 *s;
s = FcPatternFormat (fs->fonts[j], format);
if (s)
{
printf ("%s", s);
FcStrFree (s);
}
}
}
}
if (fs) {
nfont = fs->nfont;
FcFontSetDestroy (fs);
}
FcFini ();
return quiet ? (nfont == 0 ? 1 : 0) : 0;
}
/*
* fontconfig/fc-match/fc-match.c
*
* Copyright 짤 2003 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the author(s) not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. The authors make no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#else
#ifdef linux
#define HAVE_GETOPT_LONG 1
#endif
#define HAVE_GETOPT 1
#endif
#include <fontconfig/fontconfig.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#ifndef HAVE_GETOPT
#define HAVE_GETOPT 0
#endif
#ifndef HAVE_GETOPT_LONG
#define HAVE_GETOPT_LONG 0
#endif
#if HAVE_GETOPT_LONG
#undef _GNU_SOURCE
#define _GNU_SOURCE
#include <getopt.h>
static const struct option longopts[] = {
{"sort", 0, 0, 's'},
{"all", 0, 0, 'a'},
{"verbose", 0, 0, 'v'},
{"format", 1, 0, 'f'},
{"version", 0, 0, 'V'},
{"help", 0, 0, 'h'},
{NULL,0,0,0},
};
#else
#if HAVE_GETOPT
extern char *optarg;
extern int optind, opterr, optopt;
#endif
#endif
static void
usage (char *program, int error)
{
FILE *file = error ? stderr : stdout;
#if HAVE_GETOPT_LONG
fprintf (file, "usage: %s [-savVh] [-f FORMAT] [--sort] [--all] [--verbose] [--format=FORMAT] [--version] [--help] [pattern] {element...}\n",
program);
#else
fprintf (file, "usage: %s [-savVh] [-f FORMAT] [pattern] {element...}\n",
program);
#endif
fprintf (file, "List best font matching [pattern]\n");
fprintf (file, "\n");
#if HAVE_GETOPT_LONG
fprintf (file, " -s, --sort display sorted list of matches\n");
fprintf (file, " -a, --all display unpruned sorted list of matches\n");
fprintf (file, " -v, --verbose display entire font pattern verbosely\n");
fprintf (file, " -f, --format=FORMAT use the given output format\n");
fprintf (file, " -V, --version display font config version and exit\n");
fprintf (file, " -h, --help display this help and exit\n");
#else
fprintf (file, " -s, (sort) display sorted list of matches\n");
fprintf (file, " -a (all) display unpruned sorted list of matches\n");
fprintf (file, " -v (verbose) display entire font pattern verbosely\n");
fprintf (file, " -f FORMAT (format) use the given output format\n");
fprintf (file, " -V (version) display font config version and exit\n");
fprintf (file, " -h (help) display this help and exit\n");
#endif
exit (error);
}
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
{
FT_Library library;
FT_Face face;
FT_Init_FreeType( &library );
FT_New_Face( library, "/usr/share/fonts/TTF/DejaVuSans-Bold.ttf", 0, &face );
pat = FcPatternBuild(NULL,
FC_FT_FACE, FcTypeFTFace, face,
NULL);
}
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);
FcStrFree (s);
}
}
FcPatternDestroy (font);
}
FcFontSetDestroy (fs);
}
if (os)
FcObjectSetDestroy (os);
FcFini ();
return 0;
}
_______________________________________________
Fontconfig mailing list
Fontconfig@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/fontconfig