Add FcFreeTypeQueryAll()
Like FcFreeTypeQuery(), but adds patterns for all fonts found, including named instances of variable fonts. If id is -1, then all collection faces are queried. Returns number of fonts added. This merges the same face loop that was in fc-query. and fcdir.c. Needs documentation update.
This commit is contained in:
parent
c524522bb4
commit
27a6a299e0
|
@ -41,7 +41,7 @@ EXTRA_DIST=fc-query.sgml $(BUILT_MANS)
|
||||||
|
|
||||||
CLEANFILES =
|
CLEANFILES =
|
||||||
|
|
||||||
fc_query_LDADD = ${top_builddir}/src/libfontconfig.la $(FREETYPE_LIBS)
|
fc_query_LDADD = ${top_builddir}/src/libfontconfig.la
|
||||||
|
|
||||||
if USEDOCBOOK
|
if USEDOCBOOK
|
||||||
|
|
||||||
|
|
|
@ -98,12 +98,9 @@ usage (char *program, int error)
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
FT_Library ftLibrary;
|
int id = -1;
|
||||||
int index_set = 0;
|
|
||||||
int set_index = 0;
|
|
||||||
int set_face_num = 0;
|
|
||||||
int set_instance_num = 0;
|
|
||||||
int ignore_blanks = 0;
|
int ignore_blanks = 0;
|
||||||
|
FcFontSet *fs;
|
||||||
FcChar8 *format = NULL;
|
FcChar8 *format = NULL;
|
||||||
FcBlanks *blanks = NULL;
|
FcBlanks *blanks = NULL;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -122,8 +119,7 @@ main (int argc, char **argv)
|
||||||
ignore_blanks = 1;
|
ignore_blanks = 1;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
index_set = 1;
|
id = atoi (optarg);
|
||||||
set_index = atoi (optarg);
|
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
format = (FcChar8 *) strdup (optarg);
|
format = (FcChar8 *) strdup (optarg);
|
||||||
|
@ -146,74 +142,42 @@ main (int argc, char **argv)
|
||||||
if (i == argc)
|
if (i == argc)
|
||||||
usage (argv[0], 1);
|
usage (argv[0], 1);
|
||||||
|
|
||||||
if (FT_Init_FreeType (&ftLibrary))
|
fs = FcFontSetCreate ();
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (!ignore_blanks)
|
if (!ignore_blanks)
|
||||||
blanks = FcConfigGetBlanks (NULL);
|
blanks = FcConfigGetBlanks (NULL);
|
||||||
|
|
||||||
for (; i < argc; i++)
|
for (; i < argc; i++)
|
||||||
{
|
{
|
||||||
FT_Face face;
|
if (!FcFreeTypeQueryAll ((FcChar8*) argv[i], id, blanks, NULL, fs))
|
||||||
int num_faces = 0;
|
|
||||||
int num_instances = 0;
|
|
||||||
int face_num = 0;
|
|
||||||
int instance_num = 0;
|
|
||||||
int id;
|
|
||||||
|
|
||||||
if (index_set)
|
|
||||||
{
|
{
|
||||||
face_num = set_face_num = set_index & 0xFFFF;
|
fprintf (stderr, "Can't query face %d of font file %s\n", id, argv[i]);
|
||||||
instance_num = set_instance_num = set_index >> 16;
|
err = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
|
||||||
FcPattern *pat;
|
|
||||||
|
|
||||||
id = ((instance_num << 16) + face_num);
|
|
||||||
if (FT_New_Face (ftLibrary, argv[i], id, &face))
|
|
||||||
break;
|
|
||||||
num_faces = face->num_faces;
|
|
||||||
num_instances = face->style_flags >> 16;
|
|
||||||
pat = FcFreeTypeQueryFace (face, (const FcChar8 *) argv[i], id, blanks);
|
|
||||||
FT_Done_Face (face);
|
|
||||||
|
|
||||||
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", id, argv[i]);
|
|
||||||
err = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instance_num < num_instances && !set_instance_num)
|
|
||||||
instance_num++;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
face_num++;
|
|
||||||
instance_num = 0;
|
|
||||||
}
|
|
||||||
} while (!err && (!index_set || face_num == set_face_num) && face_num < num_faces);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_Done_FreeType (ftLibrary);
|
for (i = 0; i < fs->nfont; i++)
|
||||||
|
{
|
||||||
|
FcPattern *pat = fs->fonts[i];
|
||||||
|
|
||||||
|
if (format)
|
||||||
|
{
|
||||||
|
FcChar8 *s;
|
||||||
|
|
||||||
|
s = FcPatternFormat (pat, format);
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
printf ("%s", s);
|
||||||
|
FcStrFree (s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FcPatternPrint (pat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FcFontSetDestroy (fs);
|
||||||
|
|
||||||
FcFini ();
|
FcFini ();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,9 +150,7 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
for (i = 0; i < fs->nfont; i++)
|
for (i = 0; i < fs->nfont; i++)
|
||||||
{
|
{
|
||||||
FcPattern *pat;
|
FcPattern *pat = fs->fonts[i];
|
||||||
|
|
||||||
pat = fs->fonts[i];
|
|
||||||
|
|
||||||
if (format)
|
if (format)
|
||||||
{
|
{
|
||||||
|
|
|
@ -577,6 +577,9 @@ FcDirCacheUnload (FcCache *cache);
|
||||||
FcPublic FcPattern *
|
FcPublic FcPattern *
|
||||||
FcFreeTypeQuery (const FcChar8 *file, int id, FcBlanks *blanks, int *count);
|
FcFreeTypeQuery (const FcChar8 *file, int id, FcBlanks *blanks, int *count);
|
||||||
|
|
||||||
|
FcPublic unsigned int
|
||||||
|
FcFreeTypeQueryAll(const FcChar8 *file, int id, FcBlanks *blanks, int *count, FcFontSet *set);
|
||||||
|
|
||||||
/* fcfs.c */
|
/* fcfs.c */
|
||||||
|
|
||||||
FcPublic FcFontSet *
|
FcPublic FcFontSet *
|
||||||
|
|
86
src/fcdir.c
86
src/fcdir.c
|
@ -23,9 +23,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "fcint.h"
|
#include "fcint.h"
|
||||||
#include "fcftint.h"
|
|
||||||
#include <ft2build.h>
|
|
||||||
#include FT_FREETYPE_H
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
|
@ -67,47 +64,32 @@ FcFileScanFontConfig (FcFontSet *set,
|
||||||
const FcChar8 *file,
|
const FcChar8 *file,
|
||||||
FcConfig *config)
|
FcConfig *config)
|
||||||
{
|
{
|
||||||
FT_Library ftLibrary;
|
int i;
|
||||||
FT_Face face;
|
|
||||||
FcPattern *font;
|
|
||||||
FcBool ret = FcTrue;
|
FcBool ret = FcTrue;
|
||||||
int num_faces = 0;
|
int old_nfont = set->nfont;
|
||||||
int num_instances = 0;
|
|
||||||
int face_num = 0;
|
|
||||||
int instance_num = 0;
|
|
||||||
int id;
|
|
||||||
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
|
const FcChar8 *sysroot = FcConfigGetSysRoot (config);
|
||||||
|
|
||||||
if (FT_Init_FreeType (&ftLibrary))
|
if (FcDebug () & FC_DBG_SCAN)
|
||||||
|
{
|
||||||
|
printf ("\tScanning file %s...", file);
|
||||||
|
fflush (stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FcFreeTypeQueryAll (file, -1, NULL, NULL, set))
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
do
|
if (FcDebug () & FC_DBG_SCAN)
|
||||||
|
printf ("done\n");
|
||||||
|
|
||||||
|
for (i = old_nfont; i < set->nfont; i++)
|
||||||
{
|
{
|
||||||
font = 0;
|
FcPattern *font = set->fonts[i];
|
||||||
/*
|
|
||||||
* Nothing in the cache, scan the file
|
|
||||||
*/
|
|
||||||
if (FcDebug () & FC_DBG_SCAN)
|
|
||||||
{
|
|
||||||
printf ("\tScanning file %s...", file);
|
|
||||||
fflush (stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
id = ((instance_num << 16) + face_num);
|
|
||||||
if (FT_New_Face (ftLibrary, (char *) file, id, &face))
|
|
||||||
return FcFalse;
|
|
||||||
num_faces = face->num_faces;
|
|
||||||
num_instances = face->style_flags >> 16;
|
|
||||||
font = FcFreeTypeQueryFace (face, file, id, NULL);
|
|
||||||
FT_Done_Face (face);
|
|
||||||
|
|
||||||
if (FcDebug () & FC_DBG_SCAN)
|
|
||||||
printf ("done\n");
|
|
||||||
/*
|
/*
|
||||||
* Get rid of sysroot here so that targeting scan rule may contains FC_FILE pattern
|
* Get rid of sysroot here so that targeting scan rule may contains FC_FILE pattern
|
||||||
* and they should usually expect without sysroot.
|
* and they should usually expect without sysroot.
|
||||||
*/
|
*/
|
||||||
if (font && sysroot)
|
if (sysroot)
|
||||||
{
|
{
|
||||||
size_t len = strlen ((const char *)sysroot);
|
size_t len = strlen ((const char *)sysroot);
|
||||||
FcChar8 *f = NULL;
|
FcChar8 *f = NULL;
|
||||||
|
@ -129,43 +111,15 @@ FcFileScanFontConfig (FcFontSet *set,
|
||||||
/*
|
/*
|
||||||
* Edit pattern with user-defined rules
|
* Edit pattern with user-defined rules
|
||||||
*/
|
*/
|
||||||
if (font && config && !FcConfigSubstitute (config, font, FcMatchScan))
|
if (config && !FcConfigSubstitute (config, font, FcMatchScan))
|
||||||
{
|
|
||||||
FcPatternDestroy (font);
|
|
||||||
font = NULL;
|
|
||||||
ret = FcFalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add the font
|
|
||||||
*/
|
|
||||||
if (font)
|
|
||||||
{
|
|
||||||
if (FcDebug() & FC_DBG_SCANV)
|
|
||||||
{
|
|
||||||
printf ("Final font pattern:\n");
|
|
||||||
FcPatternPrint (font);
|
|
||||||
}
|
|
||||||
if (!FcFontSetAdd (set, font))
|
|
||||||
{
|
|
||||||
FcPatternDestroy (font);
|
|
||||||
font = NULL;
|
|
||||||
ret = FcFalse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ret = FcFalse;
|
ret = FcFalse;
|
||||||
|
|
||||||
if (instance_num < num_instances)
|
if (FcDebug() & FC_DBG_SCANV)
|
||||||
instance_num++;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
face_num++;
|
printf ("Final font pattern:\n");
|
||||||
instance_num = 0;
|
FcPatternPrint (font);
|
||||||
}
|
}
|
||||||
} while (font && ret && face_num < num_faces);
|
}
|
||||||
|
|
||||||
FT_Done_FreeType (ftLibrary);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1980,7 +1980,8 @@ FcFreeTypeQuery(const FcChar8 *file,
|
||||||
if (FT_New_Face (ftLibrary, (char *) file, id, &face))
|
if (FT_New_Face (ftLibrary, (char *) file, id, &face))
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
*count = face->num_faces;
|
if (count)
|
||||||
|
*count = face->num_faces;
|
||||||
|
|
||||||
pat = FcFreeTypeQueryFace (face, file, id, blanks);
|
pat = FcFreeTypeQueryFace (face, file, id, blanks);
|
||||||
|
|
||||||
|
@ -1990,6 +1991,67 @@ bail:
|
||||||
return pat;
|
return pat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
FcFreeTypeQueryAll(const FcChar8 *file,
|
||||||
|
int id,
|
||||||
|
FcBlanks *blanks,
|
||||||
|
int *count,
|
||||||
|
FcFontSet *set)
|
||||||
|
{
|
||||||
|
FT_Face face;
|
||||||
|
FT_Library ftLibrary = NULL;
|
||||||
|
int index_set = id != -1;
|
||||||
|
int set_face_num = index_set ? id & 0xFFFF : 0;
|
||||||
|
int set_instance_num = index_set ? id >> 16 : 0;
|
||||||
|
int face_num = set_face_num;
|
||||||
|
int instance_num = set_instance_num;
|
||||||
|
int num_faces = 0;
|
||||||
|
int num_instances = 0;
|
||||||
|
unsigned int ret = 0;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (FT_Init_FreeType (&ftLibrary))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
FcPattern *pat;
|
||||||
|
|
||||||
|
id = ((instance_num << 16) + face_num);
|
||||||
|
if (FT_New_Face (ftLibrary, (const char *) file, id, &face))
|
||||||
|
break;
|
||||||
|
|
||||||
|
num_faces = face->num_faces;
|
||||||
|
num_instances = face->style_flags >> 16;
|
||||||
|
pat = FcFreeTypeQueryFace (face, (const FcChar8 *) file, id, blanks);
|
||||||
|
FT_Done_Face (face);
|
||||||
|
|
||||||
|
if (pat)
|
||||||
|
{
|
||||||
|
ret++;
|
||||||
|
if (!set || ! FcFontSetAdd (set, pat))
|
||||||
|
FcPatternDestroy (pat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = 1;
|
||||||
|
|
||||||
|
if (instance_num < num_instances && !set_instance_num)
|
||||||
|
instance_num++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
face_num++;
|
||||||
|
instance_num = 0;
|
||||||
|
}
|
||||||
|
} while (!err && (!index_set || face_num == set_face_num) && face_num < num_faces);
|
||||||
|
|
||||||
|
if (count)
|
||||||
|
*count = num_faces;
|
||||||
|
|
||||||
|
FT_Done_FreeType (ftLibrary);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For our purposes, this approximation is sufficient
|
* For our purposes, this approximation is sufficient
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue