Merge branch 'varfonts2'
https://lists.freedesktop.org/archives/fontconfig/2017-September/006048.html
This commit is contained in:
commit
1580593ecc
|
@ -40,11 +40,11 @@
|
||||||
<match target="font">
|
<match target="font">
|
||||||
<!-- check to see if the font is just regular -->
|
<!-- check to see if the font is just regular -->
|
||||||
<test name="weight" compare="less_eq">
|
<test name="weight" compare="less_eq">
|
||||||
<const>medium</const>
|
<const>regular</const>
|
||||||
</test>
|
</test>
|
||||||
<!-- check to see if the pattern requests bold -->
|
<!-- check to see if the pattern requests bold -->
|
||||||
<test target="pattern" name="weight" compare="more">
|
<test target="pattern" name="weight" compare="more_eq">
|
||||||
<const>medium</const>
|
<const>bold</const>
|
||||||
</test>
|
</test>
|
||||||
<!--
|
<!--
|
||||||
set the embolden flag
|
set the embolden flag
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
const struct option longopts[] = {
|
const struct option longopts[] = {
|
||||||
{"verbose", 0, 0, 'v'},
|
{"verbose", 0, 0, 'v'},
|
||||||
|
{"brief", 0, 0, 'b'},
|
||||||
{"format", 1, 0, 'f'},
|
{"format", 1, 0, 'f'},
|
||||||
{"quiet", 0, 0, 'q'},
|
{"quiet", 0, 0, 'q'},
|
||||||
{"version", 0, 0, 'V'},
|
{"version", 0, 0, 'V'},
|
||||||
|
@ -67,22 +68,24 @@ usage (char *program, int error)
|
||||||
{
|
{
|
||||||
FILE *file = error ? stderr : stdout;
|
FILE *file = error ? stderr : stdout;
|
||||||
#if HAVE_GETOPT_LONG
|
#if HAVE_GETOPT_LONG
|
||||||
fprintf (file, "usage: %s [-vqVh] [-f FORMAT] [--verbose] [--format=FORMAT] [--quiet] [--version] [--help] [pattern] {element ...} \n",
|
fprintf (file, "usage: %s [-vbqVh] [-f FORMAT] [--verbose] [--brief] [--format=FORMAT] [--quiet] [--version] [--help] [pattern] {element ...} \n",
|
||||||
program);
|
program);
|
||||||
#else
|
#else
|
||||||
fprintf (file, "usage: %s [-vqVh] [-f FORMAT] [pattern] {element ...} \n",
|
fprintf (file, "usage: %s [-vbqVh] [-f FORMAT] [pattern] {element ...} \n",
|
||||||
program);
|
program);
|
||||||
#endif
|
#endif
|
||||||
fprintf (file, "List fonts matching [pattern]\n");
|
fprintf (file, "List fonts matching [pattern]\n");
|
||||||
fprintf (file, "\n");
|
fprintf (file, "\n");
|
||||||
#if HAVE_GETOPT_LONG
|
#if HAVE_GETOPT_LONG
|
||||||
fprintf (file, " -v, --verbose display entire font pattern verbosely\n");
|
fprintf (file, " -v, --verbose display entire font pattern verbosely\n");
|
||||||
|
fprintf (file, " -b, --brief display entire font pattern briefly\n");
|
||||||
fprintf (file, " -f, --format=FORMAT use the given output format\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, " -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, " -V, --version display font config version and exit\n");
|
||||||
fprintf (file, " -h, --help display this help and exit\n");
|
fprintf (file, " -h, --help display this help and exit\n");
|
||||||
#else
|
#else
|
||||||
fprintf (file, " -v (verbose) display entire font pattern verbosely\n");
|
fprintf (file, " -v (verbose) display entire font pattern verbosely\n");
|
||||||
|
fprintf (file, " -b (brief) display entire font pattern briefly\n");
|
||||||
fprintf (file, " -f FORMAT (format) use the given output format\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, " -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, " -V (version) display font config version and exit\n");
|
||||||
|
@ -95,6 +98,7 @@ int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
|
int brief = 0;
|
||||||
int quiet = 0;
|
int quiet = 0;
|
||||||
const FcChar8 *format = NULL;
|
const FcChar8 *format = NULL;
|
||||||
int nfont = 0;
|
int nfont = 0;
|
||||||
|
@ -106,15 +110,18 @@ main (int argc, char **argv)
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
#if HAVE_GETOPT_LONG
|
#if HAVE_GETOPT_LONG
|
||||||
while ((c = getopt_long (argc, argv, "vf:qVh", longopts, NULL)) != -1)
|
while ((c = getopt_long (argc, argv, "vbf:qVh", longopts, NULL)) != -1)
|
||||||
#else
|
#else
|
||||||
while ((c = getopt (argc, argv, "vf:qVh")) != -1)
|
while ((c = getopt (argc, argv, "vbf:qVh")) != -1)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose = 1;
|
verbose = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'b':
|
||||||
|
brief = 1;
|
||||||
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
format = (FcChar8 *) strdup (optarg);
|
format = (FcChar8 *) strdup (optarg);
|
||||||
break;
|
break;
|
||||||
|
@ -155,7 +162,7 @@ main (int argc, char **argv)
|
||||||
pat = FcPatternCreate ();
|
pat = FcPatternCreate ();
|
||||||
if (quiet && !os)
|
if (quiet && !os)
|
||||||
os = FcObjectSetCreate ();
|
os = FcObjectSetCreate ();
|
||||||
if (!verbose && !format && !os)
|
if (!verbose && !brief && !format && !os)
|
||||||
os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_FILE, (char *) 0);
|
os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_FILE, (char *) 0);
|
||||||
if (!format)
|
if (!format)
|
||||||
format = (const FcChar8 *) "%{=fclist}\n";
|
format = (const FcChar8 *) "%{=fclist}\n";
|
||||||
|
@ -171,8 +178,13 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
for (j = 0; j < fs->nfont; j++)
|
for (j = 0; j < fs->nfont; j++)
|
||||||
{
|
{
|
||||||
if (verbose)
|
if (verbose || brief)
|
||||||
{
|
{
|
||||||
|
if (brief)
|
||||||
|
{
|
||||||
|
FcPatternDel (fs->fonts[j], FC_CHARSET);
|
||||||
|
FcPatternDel (fs->fonts[j], FC_LANG);
|
||||||
|
}
|
||||||
FcPatternPrint (fs->fonts[j]);
|
FcPatternPrint (fs->fonts[j]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -52,6 +52,7 @@ static const struct option longopts[] = {
|
||||||
{"sort", 0, 0, 's'},
|
{"sort", 0, 0, 's'},
|
||||||
{"all", 0, 0, 'a'},
|
{"all", 0, 0, 'a'},
|
||||||
{"verbose", 0, 0, 'v'},
|
{"verbose", 0, 0, 'v'},
|
||||||
|
{"brief", 0, 0, 'b'},
|
||||||
{"format", 1, 0, 'f'},
|
{"format", 1, 0, 'f'},
|
||||||
{"version", 0, 0, 'V'},
|
{"version", 0, 0, 'V'},
|
||||||
{"help", 0, 0, 'h'},
|
{"help", 0, 0, 'h'},
|
||||||
|
@ -69,7 +70,7 @@ usage (char *program, int error)
|
||||||
{
|
{
|
||||||
FILE *file = error ? stderr : stdout;
|
FILE *file = error ? stderr : stdout;
|
||||||
#if HAVE_GETOPT_LONG
|
#if HAVE_GETOPT_LONG
|
||||||
fprintf (file, "usage: %s [-savVh] [-f FORMAT] [--sort] [--all] [--verbose] [--format=FORMAT] [--version] [--help] [pattern] {element...}\n",
|
fprintf (file, "usage: %s [-savbVh] [-f FORMAT] [--sort] [--all] [--verbose] [--brief] [--format=FORMAT] [--version] [--help] [pattern] {element...}\n",
|
||||||
program);
|
program);
|
||||||
#else
|
#else
|
||||||
fprintf (file, "usage: %s [-savVh] [-f FORMAT] [pattern] {element...}\n",
|
fprintf (file, "usage: %s [-savVh] [-f FORMAT] [pattern] {element...}\n",
|
||||||
|
@ -81,6 +82,7 @@ usage (char *program, int error)
|
||||||
fprintf (file, " -s, --sort display sorted list of matches\n");
|
fprintf (file, " -s, --sort display sorted list of matches\n");
|
||||||
fprintf (file, " -a, --all display unpruned 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, " -v, --verbose display entire font pattern verbosely\n");
|
||||||
|
fprintf (file, " -b, --brief display entire font pattern briefly\n");
|
||||||
fprintf (file, " -f, --format=FORMAT use the given output format\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, " -V, --version display font config version and exit\n");
|
||||||
fprintf (file, " -h, --help display this help and exit\n");
|
fprintf (file, " -h, --help display this help and exit\n");
|
||||||
|
@ -88,6 +90,7 @@ usage (char *program, int error)
|
||||||
fprintf (file, " -s, (sort) display sorted list of matches\n");
|
fprintf (file, " -s, (sort) display sorted list of matches\n");
|
||||||
fprintf (file, " -a (all) display unpruned 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, " -v (verbose) display entire font pattern verbosely\n");
|
||||||
|
fprintf (file, " -b (brief) display entire font pattern briefly\n");
|
||||||
fprintf (file, " -f FORMAT (format) use the given output format\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, " -V (version) display font config version and exit\n");
|
||||||
fprintf (file, " -h (help) display this help and exit\n");
|
fprintf (file, " -h (help) display this help and exit\n");
|
||||||
|
@ -99,6 +102,7 @@ int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
|
int brief = 0;
|
||||||
int sort = 0, all = 0;
|
int sort = 0, all = 0;
|
||||||
const FcChar8 *format = NULL;
|
const FcChar8 *format = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
@ -110,9 +114,9 @@ main (int argc, char **argv)
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
#if HAVE_GETOPT_LONG
|
#if HAVE_GETOPT_LONG
|
||||||
while ((c = getopt_long (argc, argv, "asvf:Vh", longopts, NULL)) != -1)
|
while ((c = getopt_long (argc, argv, "asvbf:Vh", longopts, NULL)) != -1)
|
||||||
#else
|
#else
|
||||||
while ((c = getopt (argc, argv, "asvf:Vh")) != -1)
|
while ((c = getopt (argc, argv, "asvbf:Vh")) != -1)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
@ -125,6 +129,9 @@ main (int argc, char **argv)
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose = 1;
|
verbose = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'b':
|
||||||
|
brief = 1;
|
||||||
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
format = (FcChar8 *) strdup (optarg);
|
format = (FcChar8 *) strdup (optarg);
|
||||||
break;
|
break;
|
||||||
|
@ -218,8 +225,13 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
font = FcPatternFilter (fs->fonts[j], os);
|
font = FcPatternFilter (fs->fonts[j], os);
|
||||||
|
|
||||||
if (verbose)
|
if (verbose || brief)
|
||||||
{
|
{
|
||||||
|
if (brief)
|
||||||
|
{
|
||||||
|
FcPatternDel (font, FC_CHARSET);
|
||||||
|
FcPatternDel (font, FC_LANG);
|
||||||
|
}
|
||||||
FcPatternPrint (font);
|
FcPatternPrint (font);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -52,8 +52,8 @@
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
static const struct option longopts[] = {
|
static const struct option longopts[] = {
|
||||||
{"ignore-blanks", 0, 0, 'b'},
|
|
||||||
{"index", 1, 0, 'i'},
|
{"index", 1, 0, 'i'},
|
||||||
|
{"brief", 0, 0, 'b'},
|
||||||
{"format", 1, 0, 'f'},
|
{"format", 1, 0, 'f'},
|
||||||
{"version", 0, 0, 'V'},
|
{"version", 0, 0, 'V'},
|
||||||
{"help", 0, 0, 'h'},
|
{"help", 0, 0, 'h'},
|
||||||
|
@ -71,23 +71,23 @@ usage (char *program, int error)
|
||||||
{
|
{
|
||||||
FILE *file = error ? stderr : stdout;
|
FILE *file = error ? stderr : stdout;
|
||||||
#if HAVE_GETOPT_LONG
|
#if HAVE_GETOPT_LONG
|
||||||
fprintf (file, "usage: %s [-Vbh] [-i index] [-f FORMAT] [--ignore-blanks] [--index index] [--format FORMAT] [--version] [--help] font-file...\n",
|
fprintf (file, "usage: %s [-bVh] [-i index] [-f FORMAT] [--index index] [--brief] [--format FORMAT] [--version] [--help] font-file...\n",
|
||||||
program);
|
program);
|
||||||
#else
|
#else
|
||||||
fprintf (file, "usage: %s [-Vbh] [-i index] [-f FORMAT] font-file...\n",
|
fprintf (file, "usage: %s [-bVh] [-i index] [-f FORMAT] font-file...\n",
|
||||||
program);
|
program);
|
||||||
#endif
|
#endif
|
||||||
fprintf (file, "Query font files and print resulting pattern(s)\n");
|
fprintf (file, "Query font files and print resulting pattern(s)\n");
|
||||||
fprintf (file, "\n");
|
fprintf (file, "\n");
|
||||||
#if HAVE_GETOPT_LONG
|
#if HAVE_GETOPT_LONG
|
||||||
fprintf (file, " -b, --ignore-blanks ignore blanks to compute langauges\n");
|
|
||||||
fprintf (file, " -i, --index INDEX display the INDEX face of each font file only\n");
|
fprintf (file, " -i, --index INDEX display the INDEX face of each font file only\n");
|
||||||
|
fprintf (file, " -b, --brief display font pattern briefly\n");
|
||||||
fprintf (file, " -f, --format=FORMAT use the given output format\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, " -V, --version display font config version and exit\n");
|
||||||
fprintf (file, " -h, --help display this help and exit\n");
|
fprintf (file, " -h, --help display this help and exit\n");
|
||||||
#else
|
#else
|
||||||
fprintf (file, " -b (ignore-blanks) ignore blanks to compute languages\n");
|
|
||||||
fprintf (file, " -i INDEX (index) display the INDEX face of each font file only\n");
|
fprintf (file, " -i INDEX (index) display the INDEX face of each font file only\n");
|
||||||
|
fprintf (file, " -b (brief) display font pattern briefly\n");
|
||||||
fprintf (file, " -f FORMAT (format) use the given output format\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, " -V (version) display font config version and exit\n");
|
||||||
fprintf (file, " -h (help) display this help and exit\n");
|
fprintf (file, " -h (help) display this help and exit\n");
|
||||||
|
@ -98,28 +98,27 @@ usage (char *program, int error)
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int id = -1;
|
unsigned int id = (unsigned int) -1;
|
||||||
int ignore_blanks = 0;
|
int brief = 0;
|
||||||
FcFontSet *fs;
|
FcFontSet *fs;
|
||||||
FcChar8 *format = NULL;
|
FcChar8 *format = NULL;
|
||||||
FcBlanks *blanks = NULL;
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int i;
|
int i;
|
||||||
#if HAVE_GETOPT_LONG || HAVE_GETOPT
|
#if HAVE_GETOPT_LONG || HAVE_GETOPT
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
#if HAVE_GETOPT_LONG
|
#if HAVE_GETOPT_LONG
|
||||||
while ((c = getopt_long (argc, argv, "bi:f:Vh", longopts, NULL)) != -1)
|
while ((c = getopt_long (argc, argv, "i:bf:Vh", longopts, NULL)) != -1)
|
||||||
#else
|
#else
|
||||||
while ((c = getopt (argc, argv, "bi:f:Vh")) != -1)
|
while ((c = getopt (argc, argv, "i:bf:Vh")) != -1)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'b':
|
|
||||||
ignore_blanks = 1;
|
|
||||||
break;
|
|
||||||
case 'i':
|
case 'i':
|
||||||
id = atoi (optarg);
|
id = (unsigned int) strtol (optarg, NULL, 0); /* strtol() To handle -1. */
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
brief = 1;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
format = (FcChar8 *) strdup (optarg);
|
format = (FcChar8 *) strdup (optarg);
|
||||||
|
@ -143,14 +142,12 @@ main (int argc, char **argv)
|
||||||
usage (argv[0], 1);
|
usage (argv[0], 1);
|
||||||
|
|
||||||
fs = FcFontSetCreate ();
|
fs = FcFontSetCreate ();
|
||||||
if (!ignore_blanks)
|
|
||||||
blanks = FcConfigGetBlanks (NULL);
|
|
||||||
|
|
||||||
for (; i < argc; i++)
|
for (; i < argc; i++)
|
||||||
{
|
{
|
||||||
if (!FcFreeTypeQueryAll ((FcChar8*) argv[i], id, blanks, NULL, fs))
|
if (!FcFreeTypeQueryAll ((FcChar8*) argv[i], id, NULL, NULL, fs))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Can't query face %d of font file %s\n", id, argv[i]);
|
fprintf (stderr, "Can't query face %u of font file %s\n", id, argv[i]);
|
||||||
err = 1;
|
err = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,6 +156,12 @@ main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
FcPattern *pat = fs->fonts[i];
|
FcPattern *pat = fs->fonts[i];
|
||||||
|
|
||||||
|
if (brief)
|
||||||
|
{
|
||||||
|
FcPatternDel (pat, FC_CHARSET);
|
||||||
|
FcPatternDel (pat, FC_LANG);
|
||||||
|
}
|
||||||
|
|
||||||
if (format)
|
if (format)
|
||||||
{
|
{
|
||||||
FcChar8 *s;
|
FcChar8 *s;
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
static const struct option longopts[] = {
|
static const struct option longopts[] = {
|
||||||
|
{"brief", 0, 0, 'b'},
|
||||||
{"format", 1, 0, 'f'},
|
{"format", 1, 0, 'f'},
|
||||||
{"version", 0, 0, 'V'},
|
{"version", 0, 0, 'V'},
|
||||||
{"help", 0, 0, 'h'},
|
{"help", 0, 0, 'h'},
|
||||||
|
@ -69,19 +70,21 @@ usage (char *program, int error)
|
||||||
{
|
{
|
||||||
FILE *file = error ? stderr : stdout;
|
FILE *file = error ? stderr : stdout;
|
||||||
#if HAVE_GETOPT_LONG
|
#if HAVE_GETOPT_LONG
|
||||||
fprintf (file, "usage: %s [-Vh] [-f FORMAT] [--format FORMAT] [--version] [--help] font-file...\n",
|
fprintf (file, "usage: %s [-bVh] [-f FORMAT] [--brief] [--format FORMAT] [--version] [--help] font-file...\n",
|
||||||
program);
|
program);
|
||||||
#else
|
#else
|
||||||
fprintf (file, "usage: %s [-Vh] [-f FORMAT] font-file...\n",
|
fprintf (file, "usage: %s [-bVh] [-f FORMAT] font-file...\n",
|
||||||
program);
|
program);
|
||||||
#endif
|
#endif
|
||||||
fprintf (file, "Scan font files and directories, and print resulting pattern(s)\n");
|
fprintf (file, "Scan font files and directories, and print resulting pattern(s)\n");
|
||||||
fprintf (file, "\n");
|
fprintf (file, "\n");
|
||||||
#if HAVE_GETOPT_LONG
|
#if HAVE_GETOPT_LONG
|
||||||
|
fprintf (file, " -b, --brief display font pattern briefly\n");
|
||||||
fprintf (file, " -f, --format=FORMAT use the given output format\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, " -V, --version display font config version and exit\n");
|
||||||
fprintf (file, " -h, --help display this help and exit\n");
|
fprintf (file, " -h, --help display this help and exit\n");
|
||||||
#else
|
#else
|
||||||
|
fprintf (file, " -b (brief) display font pattern briefly\n");
|
||||||
fprintf (file, " -f FORMAT (format) use the given output format\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, " -V (version) display font config version and exit\n");
|
||||||
fprintf (file, " -h (help) display this help and exit\n");
|
fprintf (file, " -h (help) display this help and exit\n");
|
||||||
|
@ -92,6 +95,7 @@ usage (char *program, int error)
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
int brief = 0;
|
||||||
FcChar8 *format = NULL;
|
FcChar8 *format = NULL;
|
||||||
int i;
|
int i;
|
||||||
FcFontSet *fs;
|
FcFontSet *fs;
|
||||||
|
@ -105,6 +109,9 @@ main (int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'b':
|
||||||
|
brief = 1;
|
||||||
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
format = (FcChar8 *) strdup (optarg);
|
format = (FcChar8 *) strdup (optarg);
|
||||||
break;
|
break;
|
||||||
|
@ -152,6 +159,12 @@ main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
FcPattern *pat = fs->fonts[i];
|
FcPattern *pat = fs->fonts[i];
|
||||||
|
|
||||||
|
if (brief)
|
||||||
|
{
|
||||||
|
FcPatternDel (pat, FC_CHARSET);
|
||||||
|
FcPatternDel (pat, FC_LANG);
|
||||||
|
}
|
||||||
|
|
||||||
if (format)
|
if (format)
|
||||||
{
|
{
|
||||||
FcChar8 *s;
|
FcChar8 *s;
|
||||||
|
|
|
@ -51,7 +51,7 @@ FcPatternAddFTFace (FcPattern *p, const char *object, const FT_Face f);
|
||||||
FcPublic FcPattern *
|
FcPublic FcPattern *
|
||||||
FcFreeTypeQueryFace (const FT_Face face,
|
FcFreeTypeQueryFace (const FT_Face face,
|
||||||
const FcChar8 *file,
|
const FcChar8 *file,
|
||||||
int id,
|
unsigned int id,
|
||||||
FcBlanks *blanks);
|
FcBlanks *blanks);
|
||||||
|
|
||||||
_FCFUNCPROTOEND
|
_FCFUNCPROTOEND
|
||||||
|
|
|
@ -72,8 +72,9 @@ typedef int FcBool;
|
||||||
#define _FC_STRINGIFY(s) _FC_STRINGIFY_(s)
|
#define _FC_STRINGIFY(s) _FC_STRINGIFY_(s)
|
||||||
#define FC_CACHE_VERSION _FC_STRINGIFY(FC_CACHE_VERSION_NUMBER)
|
#define FC_CACHE_VERSION _FC_STRINGIFY(FC_CACHE_VERSION_NUMBER)
|
||||||
|
|
||||||
#define FcTrue 1
|
|
||||||
#define FcFalse 0
|
#define FcFalse 0
|
||||||
|
#define FcTrue 1
|
||||||
|
#define FcDontCare 2
|
||||||
|
|
||||||
#define FC_FAMILY "family" /* String */
|
#define FC_FAMILY "family" /* String */
|
||||||
#define FC_STYLE "style" /* String */
|
#define FC_STYLE "style" /* String */
|
||||||
|
@ -99,6 +100,7 @@ typedef int FcBool;
|
||||||
#define FC_OUTLINE "outline" /* Bool */
|
#define FC_OUTLINE "outline" /* Bool */
|
||||||
#define FC_SCALABLE "scalable" /* Bool */
|
#define FC_SCALABLE "scalable" /* Bool */
|
||||||
#define FC_COLOR "color" /* Bool */
|
#define FC_COLOR "color" /* Bool */
|
||||||
|
#define FC_VARIABLE "variable" /* Bool */
|
||||||
#define FC_SCALE "scale" /* double (deprecated) */
|
#define FC_SCALE "scale" /* double (deprecated) */
|
||||||
#define FC_SYMBOL "symbol" /* Bool */
|
#define FC_SYMBOL "symbol" /* Bool */
|
||||||
#define FC_DPI "dpi" /* double */
|
#define FC_DPI "dpi" /* double */
|
||||||
|
@ -119,6 +121,7 @@ typedef int FcBool;
|
||||||
#define FC_DECORATIVE "decorative" /* Bool - true if style is a decorative variant */
|
#define FC_DECORATIVE "decorative" /* Bool - true if style is a decorative variant */
|
||||||
#define FC_LCD_FILTER "lcdfilter" /* Int */
|
#define FC_LCD_FILTER "lcdfilter" /* Int */
|
||||||
#define FC_FONT_FEATURES "fontfeatures" /* String */
|
#define FC_FONT_FEATURES "fontfeatures" /* String */
|
||||||
|
#define FC_FONT_VARIATIONS "fontvariations" /* String */
|
||||||
#define FC_NAMELANG "namelang" /* String RFC 3866 langs */
|
#define FC_NAMELANG "namelang" /* String RFC 3866 langs */
|
||||||
#define FC_PRGNAME "prgname" /* String */
|
#define FC_PRGNAME "prgname" /* String */
|
||||||
#define FC_HASH "hash" /* String (deprecated) */
|
#define FC_HASH "hash" /* String (deprecated) */
|
||||||
|
@ -575,10 +578,10 @@ FcDirCacheUnload (FcCache *cache);
|
||||||
|
|
||||||
/* fcfreetype.c */
|
/* fcfreetype.c */
|
||||||
FcPublic FcPattern *
|
FcPublic FcPattern *
|
||||||
FcFreeTypeQuery (const FcChar8 *file, int id, FcBlanks *blanks, int *count);
|
FcFreeTypeQuery (const FcChar8 *file, unsigned int id, FcBlanks *blanks, int *count);
|
||||||
|
|
||||||
FcPublic unsigned int
|
FcPublic unsigned int
|
||||||
FcFreeTypeQueryAll(const FcChar8 *file, int id, FcBlanks *blanks, int *count, FcFontSet *set);
|
FcFreeTypeQueryAll(const FcChar8 *file, unsigned int id, FcBlanks *blanks, int *count, FcFontSet *set);
|
||||||
|
|
||||||
/* fcfs.c */
|
/* fcfs.c */
|
||||||
|
|
||||||
|
|
22
src/fccfg.c
22
src/fccfg.c
|
@ -796,14 +796,30 @@ FcConfigCompareValue (const FcValue *left_o,
|
||||||
case FcTypeBool:
|
case FcTypeBool:
|
||||||
switch ((int) op) {
|
switch ((int) op) {
|
||||||
case FcOpEqual:
|
case FcOpEqual:
|
||||||
case FcOpContains:
|
|
||||||
case FcOpListing:
|
|
||||||
ret = left.u.b == right.u.b;
|
ret = left.u.b == right.u.b;
|
||||||
break;
|
break;
|
||||||
|
case FcOpContains:
|
||||||
|
case FcOpListing:
|
||||||
|
ret = left.u.b == right.u.b || left.u.b == FcDontCare;
|
||||||
|
break;
|
||||||
case FcOpNotEqual:
|
case FcOpNotEqual:
|
||||||
case FcOpNotContains:
|
|
||||||
ret = left.u.b != right.u.b;
|
ret = left.u.b != right.u.b;
|
||||||
break;
|
break;
|
||||||
|
case FcOpNotContains:
|
||||||
|
ret = !(left.u.b == right.u.b || left.u.b == FcDontCare);
|
||||||
|
break;
|
||||||
|
case FcOpLess:
|
||||||
|
ret = left.u.b != right.u.b && right.u.b == FcDontCare;
|
||||||
|
break;
|
||||||
|
case FcOpLessEqual:
|
||||||
|
ret = left.u.b == right.u.b || right.u.b == FcDontCare;
|
||||||
|
break;
|
||||||
|
case FcOpMore:
|
||||||
|
ret = left.u.b != right.u.b && left.u.b == FcDontCare;
|
||||||
|
break;
|
||||||
|
case FcOpMoreEqual:
|
||||||
|
ret = left.u.b == right.u.b || left.u.b == FcDontCare;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,10 @@ _FcValuePrintFile (FILE *f, const FcValue v)
|
||||||
fprintf (f, "\"%s\"", v.u.s);
|
fprintf (f, "\"%s\"", v.u.s);
|
||||||
break;
|
break;
|
||||||
case FcTypeBool:
|
case FcTypeBool:
|
||||||
fprintf (f, "%s", v.u.b ? "True" : "False");
|
fprintf (f,
|
||||||
|
v.u.b == FcTrue ? (FcChar8 *) "True" :
|
||||||
|
v.u.b == FcFalse ? (FcChar8 *) "False" :
|
||||||
|
(FcChar8 *) "DontCare", 0);
|
||||||
break;
|
break;
|
||||||
case FcTypeMatrix:
|
case FcTypeMatrix:
|
||||||
fprintf (f, "[%g %g; %g %g]", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
|
fprintf (f, "[%g %g; %g %g]", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
|
||||||
|
@ -62,7 +65,7 @@ _FcValuePrintFile (FILE *f, const FcValue v)
|
||||||
fprintf (f, "face");
|
fprintf (f, "face");
|
||||||
break;
|
break;
|
||||||
case FcTypeRange:
|
case FcTypeRange:
|
||||||
fprintf (f, "[%g %g)", v.u.r->begin, v.u.r->end);
|
fprintf (f, "[%g %g]", v.u.r->begin, v.u.r->end);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ static const struct {
|
||||||
{ FC_EMBEDDED_BITMAP_OBJECT, FcTrue }, /* !FC_LOAD_NO_BITMAP */
|
{ FC_EMBEDDED_BITMAP_OBJECT, FcTrue }, /* !FC_LOAD_NO_BITMAP */
|
||||||
{ FC_DECORATIVE_OBJECT, FcFalse },
|
{ FC_DECORATIVE_OBJECT, FcFalse },
|
||||||
{ FC_SYMBOL_OBJECT, FcFalse },
|
{ FC_SYMBOL_OBJECT, FcFalse },
|
||||||
|
{ FC_VARIABLE_OBJECT, FcFalse },
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_FC_BOOL_DEFAULTS (int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0])
|
#define NUM_FC_BOOL_DEFAULTS (int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0])
|
||||||
|
@ -255,7 +256,14 @@ FcDefaultSubstitute (FcPattern *pattern)
|
||||||
FcPatternObjectAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value);
|
FcPatternObjectAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value);
|
||||||
|
|
||||||
if (FcPatternObjectGetDouble (pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch)
|
if (FcPatternObjectGetDouble (pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch)
|
||||||
|
{
|
||||||
|
FcRange *r;
|
||||||
|
double b, e;
|
||||||
|
if (FcPatternObjectGetRange (pattern, FC_SIZE_OBJECT, 0, &r) == FcResultMatch && FcRangeGetDouble (r, &b, &e))
|
||||||
|
size = (b + e) * .5;
|
||||||
|
else
|
||||||
size = 12.0L;
|
size = 12.0L;
|
||||||
|
}
|
||||||
if (FcPatternObjectGetDouble (pattern, FC_SCALE_OBJECT, 0, &scale) != FcResultMatch)
|
if (FcPatternObjectGetDouble (pattern, FC_SCALE_OBJECT, 0, &scale) != FcResultMatch)
|
||||||
scale = 1.0;
|
scale = 1.0;
|
||||||
if (FcPatternObjectGetDouble (pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch)
|
if (FcPatternObjectGetDouble (pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch)
|
||||||
|
|
527
src/fcfreetype.c
527
src/fcfreetype.c
|
@ -558,6 +558,9 @@ static const FcMacRomanFake fcMacRomanFake[] = {
|
||||||
static FcChar8 *
|
static FcChar8 *
|
||||||
FcFontCapabilities(FT_Face face);
|
FcFontCapabilities(FT_Face face);
|
||||||
|
|
||||||
|
static int
|
||||||
|
FcFreeTypeSpacing (FT_Face face);
|
||||||
|
|
||||||
#define NUM_FC_MAC_ROMAN_FAKE (int) (sizeof (fcMacRomanFake) / sizeof (fcMacRomanFake[0]))
|
#define NUM_FC_MAC_ROMAN_FAKE (int) (sizeof (fcMacRomanFake) / sizeof (fcMacRomanFake[0]))
|
||||||
|
|
||||||
|
|
||||||
|
@ -1133,6 +1136,7 @@ static const FT_UShort platform_order[] = {
|
||||||
TT_PLATFORM_MICROSOFT,
|
TT_PLATFORM_MICROSOFT,
|
||||||
TT_PLATFORM_APPLE_UNICODE,
|
TT_PLATFORM_APPLE_UNICODE,
|
||||||
TT_PLATFORM_MACINTOSH,
|
TT_PLATFORM_MACINTOSH,
|
||||||
|
TT_PLATFORM_ISO,
|
||||||
};
|
};
|
||||||
#define NUM_PLATFORM_ORDER (sizeof (platform_order) / sizeof (platform_order[0]))
|
#define NUM_PLATFORM_ORDER (sizeof (platform_order) / sizeof (platform_order[0]))
|
||||||
|
|
||||||
|
@ -1154,17 +1158,49 @@ static const FT_UShort nameid_order[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_NAMEID_ORDER (sizeof (nameid_order) / sizeof (nameid_order[0]))
|
#define NUM_NAMEID_ORDER (sizeof (nameid_order) / sizeof (nameid_order[0]))
|
||||||
FcPattern *
|
|
||||||
FcFreeTypeQueryFace (const FT_Face face,
|
static FcBool
|
||||||
|
FcFreeTypeGetName (const FT_Face face,
|
||||||
|
unsigned int platform,
|
||||||
|
unsigned int nameid,
|
||||||
|
FT_SfntName *sname)
|
||||||
|
{
|
||||||
|
int min = 0, max = (int) FT_Get_Sfnt_Name_Count (face) - 1;
|
||||||
|
|
||||||
|
while (min <= max)
|
||||||
|
{
|
||||||
|
int mid = (min + max) / 2;
|
||||||
|
|
||||||
|
if (FT_Get_Sfnt_Name (face, mid, sname) != 0)
|
||||||
|
return FcFalse;
|
||||||
|
|
||||||
|
if (platform < sname->platform_id || (platform == sname->platform_id && nameid < sname->name_id))
|
||||||
|
max = mid - 1;
|
||||||
|
else if (platform > sname->platform_id || (platform == sname->platform_id && nameid > sname->name_id))
|
||||||
|
min = mid + 1;
|
||||||
|
else
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FcFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FcPattern *
|
||||||
|
FcFreeTypeQueryFaceInternal (const FT_Face face,
|
||||||
const FcChar8 *file,
|
const FcChar8 *file,
|
||||||
int id,
|
unsigned int id,
|
||||||
FcBlanks *blanks FC_UNUSED)
|
FcCharSet **cs_share,
|
||||||
|
FcLangSet **ls_share)
|
||||||
{
|
{
|
||||||
FcPattern *pat;
|
FcPattern *pat;
|
||||||
int slant = -1;
|
int slant = -1;
|
||||||
int weight = -1;
|
int weight = -1;
|
||||||
int width = -1;
|
int width = -1;
|
||||||
FcBool decorative = FcFalse;
|
FcBool decorative = FcFalse;
|
||||||
|
FcBool variable = FcFalse;
|
||||||
|
FcBool variable_weight = FcFalse;
|
||||||
|
FcBool variable_width = FcFalse;
|
||||||
|
FcBool variable_size = FcFalse;
|
||||||
FcCharSet *cs;
|
FcCharSet *cs;
|
||||||
FcLangSet *ls;
|
FcLangSet *ls;
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -1189,8 +1225,6 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
#endif
|
#endif
|
||||||
TT_Header *head;
|
TT_Header *head;
|
||||||
const FcChar8 *exclusiveLang = 0;
|
const FcChar8 *exclusiveLang = 0;
|
||||||
FT_SfntName sname;
|
|
||||||
FT_UInt snamei, snamec;
|
|
||||||
|
|
||||||
int nfamily = 0;
|
int nfamily = 0;
|
||||||
int nfamily_lang = 0;
|
int nfamily_lang = 0;
|
||||||
|
@ -1199,14 +1233,9 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
int nfullname = 0;
|
int nfullname = 0;
|
||||||
int nfullname_lang = 0;
|
int nfullname_lang = 0;
|
||||||
unsigned int p, n;
|
unsigned int p, n;
|
||||||
int platform, nameid;
|
|
||||||
|
|
||||||
FcChar8 *style = 0;
|
FcChar8 *style = 0;
|
||||||
int st;
|
int st;
|
||||||
char psname[256];
|
|
||||||
const char *tmp;
|
|
||||||
|
|
||||||
FcRange *r = NULL;
|
|
||||||
|
|
||||||
FcBool symbol = FcFalse;
|
FcBool symbol = FcFalse;
|
||||||
|
|
||||||
|
@ -1238,19 +1267,78 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
|
|
||||||
if (id >> 16)
|
if (id >> 16)
|
||||||
{
|
{
|
||||||
if (!FT_Get_MM_Var (face, &master))
|
if (FT_Get_MM_Var (face, &master))
|
||||||
instance = &master->namedstyle[(id >> 16) - 1];
|
goto bail1;
|
||||||
|
|
||||||
if (instance)
|
if (id >> 16 == 0x8000)
|
||||||
|
{
|
||||||
|
/* Query variable font itself. */
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < master->num_axis; i++)
|
||||||
|
{
|
||||||
|
double min_value = master->axis[i].minimum / (double) (1 << 16);
|
||||||
|
double def_value = master->axis[i].def / (double) (1 << 16);
|
||||||
|
double max_value = master->axis[i].maximum / (double) (1 << 16);
|
||||||
|
const char *elt = NULL;
|
||||||
|
|
||||||
|
if (min_value > def_value || def_value > max_value || min_value == max_value)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (master->axis[i].tag)
|
||||||
|
{
|
||||||
|
case FT_MAKE_TAG ('w','g','h','t'):
|
||||||
|
elt = FC_WEIGHT;
|
||||||
|
min_value = FcWeightFromOpenType (min_value);
|
||||||
|
max_value = FcWeightFromOpenType (max_value);
|
||||||
|
variable_weight = FcTrue;
|
||||||
|
weight = 0; /* To stop looking for weight. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FT_MAKE_TAG ('w','d','t','h'):
|
||||||
|
elt = FC_WIDTH;
|
||||||
|
/* Values in 'wdth' match Fontconfig FC_WIDTH_* scheme directly. */
|
||||||
|
variable_width = FcTrue;
|
||||||
|
width = 0; /* To stop looking for width. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FT_MAKE_TAG ('o','p','s','z'):
|
||||||
|
elt = FC_SIZE;
|
||||||
|
/* Values in 'opsz' match Fontconfig FC_SIZE, both are in points. */
|
||||||
|
variable_size = FcTrue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elt)
|
||||||
|
{
|
||||||
|
FcRange *r = FcRangeCreateDouble (min_value, max_value);
|
||||||
|
if (!FcPatternAddRange (pat, elt, r))
|
||||||
|
{
|
||||||
|
FcRangeDestroy (r);
|
||||||
|
goto bail1;
|
||||||
|
}
|
||||||
|
FcRangeDestroy (r);
|
||||||
|
variable = FcTrue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!variable)
|
||||||
|
goto bail1;
|
||||||
|
|
||||||
|
id &= 0xFFFF;
|
||||||
|
}
|
||||||
|
else if ((id >> 16) - 1 < master->num_namedstyles)
|
||||||
{
|
{
|
||||||
/* Pull out weight and width from named-instance. */
|
/* Pull out weight and width from named-instance. */
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
instance = &master->namedstyle[(id >> 16) - 1];
|
||||||
|
|
||||||
for (i = 0; i < master->num_axis; i++)
|
for (i = 0; i < master->num_axis; i++)
|
||||||
{
|
{
|
||||||
double value = instance->coords[i] / (double) (1 << 16);
|
double value = instance->coords[i] / (double) (1 << 16);
|
||||||
double default_value = master->axis[i].def / (double) (1 << 16);
|
double default_value = master->axis[i].def / (double) (1 << 16);
|
||||||
double mult = value / default_value;
|
double mult = default_value ? value / default_value : 1;
|
||||||
//printf ("named-instance, axis %d tag %lx value %g\n", i, master->axis[i].tag, value);
|
//printf ("named-instance, axis %d tag %lx value %g\n", i, master->axis[i].tag, value);
|
||||||
switch (master->axis[i].tag)
|
switch (master->axis[i].tag)
|
||||||
{
|
{
|
||||||
|
@ -1262,11 +1350,18 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
width_mult = mult;
|
width_mult = mult;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* TODO optical size! */
|
case FT_MAKE_TAG ('o','p','s','z'):
|
||||||
|
if (!FcPatternAddDouble (pat, FC_SIZE, value))
|
||||||
|
goto bail1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
goto bail1;
|
||||||
}
|
}
|
||||||
|
if (!FcPatternAddBool (pat, FC_VARIABLE, variable))
|
||||||
|
goto bail1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the OS/2 table
|
* Get the OS/2 table
|
||||||
|
@ -1299,13 +1394,9 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
* and style names. FreeType makes quite a hash
|
* and style names. FreeType makes quite a hash
|
||||||
* of them
|
* of them
|
||||||
*/
|
*/
|
||||||
snamec = FT_Get_Sfnt_Name_Count (face);
|
for (p = 0; p < NUM_PLATFORM_ORDER; p++)
|
||||||
for (p = 0; p <= NUM_PLATFORM_ORDER; p++)
|
|
||||||
{
|
{
|
||||||
if (p < NUM_PLATFORM_ORDER)
|
int platform = platform_order[p];
|
||||||
platform = platform_order[p];
|
|
||||||
else
|
|
||||||
platform = 0xffff;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Order nameids so preferred names appear first
|
* Order nameids so preferred names appear first
|
||||||
|
@ -1313,60 +1404,32 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
*/
|
*/
|
||||||
for (n = 0; n < NUM_NAMEID_ORDER; n++)
|
for (n = 0; n < NUM_NAMEID_ORDER; n++)
|
||||||
{
|
{
|
||||||
nameid = nameid_order[n];
|
FT_SfntName sname;
|
||||||
|
|
||||||
for (snamei = 0; snamei < snamec; snamei++)
|
|
||||||
{
|
|
||||||
FcChar8 *utf8, *pp;
|
|
||||||
const FcChar8 *lang;
|
const FcChar8 *lang;
|
||||||
const char *elt = 0, *eltlang = 0;
|
const char *elt = 0, *eltlang = 0;
|
||||||
int *np = 0, *nlangp = 0;
|
int *np = 0, *nlangp = 0;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
int nameid, lookupid;
|
||||||
|
|
||||||
if (FT_Get_Sfnt_Name (face, snamei, &sname) != 0)
|
nameid = lookupid = nameid_order[n];
|
||||||
continue;
|
|
||||||
|
|
||||||
if (instance)
|
if (instance)
|
||||||
{
|
{
|
||||||
/* For named-instances, we regular style nameIDs,
|
/* For named-instances, we skip regular style nameIDs,
|
||||||
* and map the instance's strid to FONT_SUBFAMILY. */
|
* and treat the instance's nameid as FONT_SUBFAMILY.
|
||||||
if (sname.name_id == TT_NAME_ID_WWS_SUBFAMILY ||
|
* Postscript name is automatically handled by FreeType. */
|
||||||
sname.name_id == TT_NAME_ID_PREFERRED_SUBFAMILY ||
|
if (nameid == TT_NAME_ID_WWS_SUBFAMILY ||
|
||||||
sname.name_id == TT_NAME_ID_FONT_SUBFAMILY)
|
nameid == TT_NAME_ID_PREFERRED_SUBFAMILY)
|
||||||
continue;
|
continue;
|
||||||
if (sname.name_id == instance->strid)
|
|
||||||
sname.name_id = TT_NAME_ID_FONT_SUBFAMILY;
|
if (nameid == TT_NAME_ID_FONT_SUBFAMILY)
|
||||||
|
lookupid = instance->strid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sname.name_id != nameid)
|
if (!FcFreeTypeGetName (face, platform, lookupid, &sname))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
switch (nameid) {
|
||||||
* Sort platforms in preference order, accepting
|
|
||||||
* all other platforms last
|
|
||||||
*/
|
|
||||||
if (p < NUM_PLATFORM_ORDER)
|
|
||||||
{
|
|
||||||
if (sname.platform_id != platform)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned int sp;
|
|
||||||
|
|
||||||
for (sp = 0; sp < NUM_PLATFORM_ORDER; sp++)
|
|
||||||
if (sname.platform_id == platform_order[sp])
|
|
||||||
break;
|
|
||||||
if (sp != NUM_PLATFORM_ORDER)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
utf8 = FcSfntNameTranscode (&sname);
|
|
||||||
lang = FcSfntNameLanguage (&sname);
|
|
||||||
|
|
||||||
if (!utf8)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (sname.name_id) {
|
|
||||||
#ifdef TT_NAME_ID_WWS_FAMILY
|
#ifdef TT_NAME_ID_WWS_FAMILY
|
||||||
case TT_NAME_ID_WWS_FAMILY:
|
case TT_NAME_ID_WWS_FAMILY:
|
||||||
#endif
|
#endif
|
||||||
|
@ -1376,10 +1439,9 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
case TT_NAME_ID_UNIQUE_ID:
|
case TT_NAME_ID_UNIQUE_ID:
|
||||||
#endif
|
#endif
|
||||||
if (FcDebug () & FC_DBG_SCANV)
|
if (FcDebug () & FC_DBG_SCANV)
|
||||||
printf ("found family (n %2d p %d e %d l 0x%04x) %s\n",
|
printf ("found family (n %2d p %d e %d l 0x%04x)",
|
||||||
sname.name_id, sname.platform_id,
|
sname.name_id, sname.platform_id,
|
||||||
sname.encoding_id, sname.language_id,
|
sname.encoding_id, sname.language_id);
|
||||||
utf8);
|
|
||||||
|
|
||||||
elt = FC_FAMILY;
|
elt = FC_FAMILY;
|
||||||
eltlang = FC_FAMILYLANG;
|
eltlang = FC_FAMILYLANG;
|
||||||
|
@ -1389,10 +1451,9 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
case TT_NAME_ID_MAC_FULL_NAME:
|
case TT_NAME_ID_MAC_FULL_NAME:
|
||||||
case TT_NAME_ID_FULL_NAME:
|
case TT_NAME_ID_FULL_NAME:
|
||||||
if (FcDebug () & FC_DBG_SCANV)
|
if (FcDebug () & FC_DBG_SCANV)
|
||||||
printf ("found full (n %2d p %d e %d l 0x%04x) %s\n",
|
printf ("found full (n %2d p %d e %d l 0x%04x)",
|
||||||
sname.name_id, sname.platform_id,
|
sname.name_id, sname.platform_id,
|
||||||
sname.encoding_id, sname.language_id,
|
sname.encoding_id, sname.language_id);
|
||||||
utf8);
|
|
||||||
|
|
||||||
elt = FC_FULLNAME;
|
elt = FC_FULLNAME;
|
||||||
eltlang = FC_FULLNAMELANG;
|
eltlang = FC_FULLNAMELANG;
|
||||||
|
@ -1404,23 +1465,12 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
#endif
|
#endif
|
||||||
case TT_NAME_ID_PREFERRED_SUBFAMILY:
|
case TT_NAME_ID_PREFERRED_SUBFAMILY:
|
||||||
case TT_NAME_ID_FONT_SUBFAMILY:
|
case TT_NAME_ID_FONT_SUBFAMILY:
|
||||||
if (utf8)
|
if (variable)
|
||||||
{
|
break;
|
||||||
pp = utf8;
|
|
||||||
while (*pp == ' ')
|
|
||||||
pp++;
|
|
||||||
len = strlen ((const char *) pp);
|
|
||||||
memmove (utf8, pp, len + 1);
|
|
||||||
pp = utf8 + len - 1;
|
|
||||||
while (*pp == ' ')
|
|
||||||
pp--;
|
|
||||||
*(pp + 1) = 0;
|
|
||||||
}
|
|
||||||
if (FcDebug () & FC_DBG_SCANV)
|
if (FcDebug () & FC_DBG_SCANV)
|
||||||
printf ("found style (n %2d p %d e %d l 0x%04x) %s\n",
|
printf ("found style (n %2d p %d e %d l 0x%04x) ",
|
||||||
sname.name_id, sname.platform_id,
|
sname.name_id, sname.platform_id,
|
||||||
sname.encoding_id, sname.language_id,
|
sname.encoding_id, sname.language_id);
|
||||||
utf8);
|
|
||||||
|
|
||||||
elt = FC_STYLE;
|
elt = FC_STYLE;
|
||||||
eltlang = FC_STYLELANG;
|
eltlang = FC_STYLELANG;
|
||||||
|
@ -1431,11 +1481,38 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
case TT_NAME_ID_MANUFACTURER:
|
case TT_NAME_ID_MANUFACTURER:
|
||||||
/* If the foundry wasn't found in the OS/2 table, look here */
|
/* If the foundry wasn't found in the OS/2 table, look here */
|
||||||
if(!foundry)
|
if(!foundry)
|
||||||
|
{
|
||||||
|
FcChar8 *utf8;
|
||||||
|
utf8 = FcSfntNameTranscode (&sname);
|
||||||
foundry = FcNoticeFoundry((FT_String *) utf8);
|
foundry = FcNoticeFoundry((FT_String *) utf8);
|
||||||
|
free (utf8);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (elt)
|
if (elt)
|
||||||
{
|
{
|
||||||
|
FcChar8 *utf8, *pp;
|
||||||
|
|
||||||
|
utf8 = FcSfntNameTranscode (&sname);
|
||||||
|
lang = FcSfntNameLanguage (&sname);
|
||||||
|
|
||||||
|
if (FcDebug () & FC_DBG_SCANV)
|
||||||
|
printf ("%s\n", utf8);
|
||||||
|
|
||||||
|
if (!utf8)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Trim surrounding whitespace. */
|
||||||
|
pp = utf8;
|
||||||
|
while (*pp == ' ')
|
||||||
|
pp++;
|
||||||
|
len = strlen ((const char *) pp);
|
||||||
|
memmove (utf8, pp, len + 1);
|
||||||
|
pp = utf8 + len;
|
||||||
|
while (pp > utf8 && *(pp - 1) == ' ')
|
||||||
|
pp--;
|
||||||
|
*pp = 0;
|
||||||
|
|
||||||
if (FcStringInPatternElement (pat, elt, utf8))
|
if (FcStringInPatternElement (pat, elt, utf8))
|
||||||
{
|
{
|
||||||
free (utf8);
|
free (utf8);
|
||||||
|
@ -1464,9 +1541,6 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
}
|
}
|
||||||
++*np;
|
++*np;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
free (utf8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1482,11 +1556,12 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
++nfamily;
|
++nfamily;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nstyle && face->style_name &&
|
if (!variable && !nstyle && face->style_name &&
|
||||||
FcStrCmpIgnoreBlanksAndCase ((FcChar8 *) face->style_name, (FcChar8 *) "") != 0)
|
FcStrCmpIgnoreBlanksAndCase ((FcChar8 *) face->style_name, (FcChar8 *) "") != 0)
|
||||||
{
|
{
|
||||||
if (FcDebug () & FC_DBG_SCANV)
|
if (FcDebug () & FC_DBG_SCANV)
|
||||||
printf ("using FreeType style \"%s\"\n", face->style_name);
|
printf ("using FreeType style \"%s\"\n", face->style_name);
|
||||||
|
|
||||||
if (!FcPatternAddString (pat, FC_STYLE, (FcChar8 *) face->style_name))
|
if (!FcPatternAddString (pat, FC_STYLE, (FcChar8 *) face->style_name))
|
||||||
goto bail1;
|
goto bail1;
|
||||||
if (!FcPatternAddString (pat, FC_STYLELANG, (FcChar8 *) "en"))
|
if (!FcPatternAddString (pat, FC_STYLELANG, (FcChar8 *) "en"))
|
||||||
|
@ -1523,6 +1598,10 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the PostScript name into the cache */
|
/* Add the PostScript name into the cache */
|
||||||
|
if (!variable)
|
||||||
|
{
|
||||||
|
char psname[256];
|
||||||
|
const char *tmp;
|
||||||
tmp = FT_Get_Postscript_Name (face);
|
tmp = FT_Get_Postscript_Name (face);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
{
|
{
|
||||||
|
@ -1569,6 +1648,7 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
}
|
}
|
||||||
if (!FcPatternAddString (pat, FC_POSTSCRIPT_NAME, (const FcChar8 *)psname))
|
if (!FcPatternAddString (pat, FC_POSTSCRIPT_NAME, (const FcChar8 *)psname))
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
}
|
||||||
|
|
||||||
if (file && *file && !FcPatternAddString (pat, FC_FILE, file))
|
if (file && *file && !FcPatternAddString (pat, FC_FILE, file))
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
@ -1679,14 +1759,22 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (HAVE_TT_OS2_USUPPEROPTICALPOINTSIZE) && defined (HAVE_TT_OS2_USLOWEROPTICALPOINTSIZE)
|
#if defined (HAVE_TT_OS2_USUPPEROPTICALPOINTSIZE) && defined (HAVE_TT_OS2_USLOWEROPTICALPOINTSIZE)
|
||||||
if (os2 && os2->version >= 0x0005 && os2->version != 0xffff)
|
if (!variable_size && os2 && os2->version >= 0x0005 && os2->version != 0xffff)
|
||||||
{
|
{
|
||||||
double lower_size, upper_size;
|
double lower_size, upper_size;
|
||||||
|
FcRange *r;
|
||||||
|
|
||||||
/* usLowerPointSize and usUpperPointSize is actually twips */
|
/* usLowerPointSize and usUpperPointSize is actually twips */
|
||||||
lower_size = os2->usLowerOpticalPointSize / 20.0L;
|
lower_size = os2->usLowerOpticalPointSize / 20.0L;
|
||||||
upper_size = os2->usUpperOpticalPointSize / 20.0L;
|
upper_size = os2->usUpperOpticalPointSize / 20.0L;
|
||||||
|
|
||||||
|
if (lower_size == upper_size)
|
||||||
|
{
|
||||||
|
if (!FcPatternAddDouble (pat, FC_SIZE, lower_size))
|
||||||
|
goto bail1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
r = FcRangeCreateDouble (lower_size, upper_size);
|
r = FcRangeCreateDouble (lower_size, upper_size);
|
||||||
if (!FcPatternAddRange (pat, FC_SIZE, r))
|
if (!FcPatternAddRange (pat, FC_SIZE, r))
|
||||||
{
|
{
|
||||||
|
@ -1695,6 +1783,7 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
}
|
}
|
||||||
FcRangeDestroy (r);
|
FcRangeDestroy (r);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1835,10 +1924,10 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
if (!FcPatternAddInteger (pat, FC_SLANT, slant))
|
if (!FcPatternAddInteger (pat, FC_SLANT, slant))
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
|
||||||
if (!FcPatternAddInteger (pat, FC_WEIGHT, weight))
|
if (!variable_weight && !FcPatternAddInteger (pat, FC_WEIGHT, weight))
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
|
||||||
if (!FcPatternAddInteger (pat, FC_WIDTH, width))
|
if (!variable_width && !FcPatternAddInteger (pat, FC_WIDTH, width))
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
|
||||||
if (!FcPatternAddString (pat, FC_FOUNDRY, foundry))
|
if (!FcPatternAddString (pat, FC_FOUNDRY, foundry))
|
||||||
|
@ -1851,15 +1940,23 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
/*
|
/*
|
||||||
* Compute the unicode coverage for the font
|
* Compute the unicode coverage for the font
|
||||||
*/
|
*/
|
||||||
cs = FcFreeTypeCharSetAndSpacing (face, blanks, &spacing);
|
if (cs_share && *cs_share)
|
||||||
|
cs = FcCharSetCopy (*cs_share);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cs = FcFreeTypeCharSet (face, NULL);
|
||||||
|
if (cs_share)
|
||||||
|
*cs_share = FcCharSetCopy (cs);
|
||||||
|
}
|
||||||
if (!cs)
|
if (!cs)
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
|
||||||
/* The FcFreeTypeCharSetAndSpacing() chose the encoding; test it for symbol. */
|
/* The FcFreeTypeCharSet() chose the encoding; test it for symbol. */
|
||||||
symbol = face->charmap && face->charmap->encoding == FT_ENCODING_MS_SYMBOL;
|
symbol = face->charmap && face->charmap->encoding == FT_ENCODING_MS_SYMBOL;
|
||||||
if (!FcPatternAddBool (pat, FC_SYMBOL, symbol))
|
if (!FcPatternAddBool (pat, FC_SYMBOL, symbol))
|
||||||
goto bail1;
|
goto bail1;
|
||||||
|
|
||||||
|
spacing = FcFreeTypeSpacing (face);
|
||||||
#if HAVE_FT_GET_BDF_PROPERTY
|
#if HAVE_FT_GET_BDF_PROPERTY
|
||||||
/* For PCF fonts, override the computed spacing with the one from
|
/* For PCF fonts, override the computed spacing with the one from
|
||||||
the property */
|
the property */
|
||||||
|
@ -1893,8 +1990,15 @@ FcFreeTypeQueryFace (const FT_Face face,
|
||||||
goto bail2;
|
goto bail2;
|
||||||
|
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
|
{
|
||||||
|
if (ls_share && *ls_share)
|
||||||
|
ls = FcLangSetCopy (*ls_share);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
ls = FcFreeTypeLangSet (cs, exclusiveLang);
|
ls = FcFreeTypeLangSet (cs, exclusiveLang);
|
||||||
|
if (ls_share)
|
||||||
|
*ls_share = FcLangSetCopy (ls);
|
||||||
|
}
|
||||||
if (!ls)
|
if (!ls)
|
||||||
goto bail2;
|
goto bail2;
|
||||||
}
|
}
|
||||||
|
@ -1964,10 +2068,19 @@ bail0:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FcPattern *
|
||||||
|
FcFreeTypeQueryFace (const FT_Face face,
|
||||||
|
const FcChar8 *file,
|
||||||
|
unsigned int id,
|
||||||
|
FcBlanks *blanks FC_UNUSED)
|
||||||
|
{
|
||||||
|
return FcFreeTypeQueryFaceInternal (face, file, id, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
FcPattern *
|
FcPattern *
|
||||||
FcFreeTypeQuery(const FcChar8 *file,
|
FcFreeTypeQuery(const FcChar8 *file,
|
||||||
int id,
|
unsigned int id,
|
||||||
FcBlanks *blanks,
|
FcBlanks *blanks FC_UNUSED,
|
||||||
int *count)
|
int *count)
|
||||||
{
|
{
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
|
@ -1977,13 +2090,13 @@ FcFreeTypeQuery(const FcChar8 *file,
|
||||||
if (FT_Init_FreeType (&ftLibrary))
|
if (FT_Init_FreeType (&ftLibrary))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (FT_New_Face (ftLibrary, (char *) file, id, &face))
|
if (FT_New_Face (ftLibrary, (char *) file, id & 0x7FFFFFFFF, &face))
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
if (count)
|
if (count)
|
||||||
*count = face->num_faces;
|
*count = face->num_faces;
|
||||||
|
|
||||||
pat = FcFreeTypeQueryFace (face, file, id, blanks);
|
pat = FcFreeTypeQueryFaceInternal (face, file, id, NULL, NULL);
|
||||||
|
|
||||||
FT_Done_Face (face);
|
FT_Done_Face (face);
|
||||||
bail:
|
bail:
|
||||||
|
@ -1993,59 +2106,112 @@ bail:
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
FcFreeTypeQueryAll(const FcChar8 *file,
|
FcFreeTypeQueryAll(const FcChar8 *file,
|
||||||
int id,
|
unsigned int id,
|
||||||
FcBlanks *blanks,
|
FcBlanks *blanks,
|
||||||
int *count,
|
int *count,
|
||||||
FcFontSet *set)
|
FcFontSet *set)
|
||||||
{
|
{
|
||||||
FT_Face face;
|
FT_Face face = NULL;
|
||||||
FT_Library ftLibrary = NULL;
|
FT_Library ftLibrary = NULL;
|
||||||
int index_set = id != -1;
|
FcCharSet *cs = NULL;
|
||||||
int set_face_num = index_set ? id & 0xFFFF : 0;
|
FcLangSet *ls = NULL;
|
||||||
int set_instance_num = index_set ? id >> 16 : 0;
|
FT_MM_Var *mm_var = NULL;
|
||||||
int face_num = set_face_num;
|
FcBool index_set = id != (unsigned int) -1;
|
||||||
int instance_num = set_instance_num;
|
unsigned int set_face_num = index_set ? id & 0xFFFF : 0;
|
||||||
int num_faces = 0;
|
unsigned int set_instance_num = index_set ? id >> 16 : 0;
|
||||||
int num_instances = 0;
|
unsigned int face_num = set_face_num;
|
||||||
|
unsigned int instance_num = set_instance_num;
|
||||||
|
unsigned int num_faces = 0;
|
||||||
|
unsigned int num_instances = 0;
|
||||||
unsigned int ret = 0;
|
unsigned int ret = 0;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
if (count)
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
if (FT_Init_FreeType (&ftLibrary))
|
if (FT_Init_FreeType (&ftLibrary))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
do {
|
if (FT_New_Face (ftLibrary, (const char *) file, face_num, &face))
|
||||||
FcPattern *pat;
|
goto bail;
|
||||||
|
|
||||||
id = ((instance_num << 16) + face_num);
|
|
||||||
if (FT_New_Face (ftLibrary, (const char *) file, id, &face))
|
|
||||||
break;
|
|
||||||
|
|
||||||
num_faces = face->num_faces;
|
num_faces = face->num_faces;
|
||||||
num_instances = face->style_flags >> 16;
|
num_instances = face->style_flags >> 16;
|
||||||
pat = FcFreeTypeQueryFace (face, (const FcChar8 *) file, id, blanks);
|
if (num_instances && (!index_set || instance_num))
|
||||||
FT_Done_Face (face);
|
|
||||||
|
|
||||||
if (pat)
|
|
||||||
{
|
{
|
||||||
ret++;
|
FT_Get_MM_Var (face, &mm_var);
|
||||||
if (!set || ! FcFontSetAdd (set, pat))
|
assert (mm_var);
|
||||||
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)
|
if (count)
|
||||||
*count = num_faces;
|
*count = num_faces;
|
||||||
|
|
||||||
|
do {
|
||||||
|
FcPattern *pat = NULL;
|
||||||
|
|
||||||
|
if (instance_num == 0x8000 || instance_num > num_instances)
|
||||||
|
FT_Set_Var_Design_Coordinates (face, 0, NULL); /* Reset variations. */
|
||||||
|
else if (instance_num)
|
||||||
|
{
|
||||||
|
FT_Var_Named_Style *instance = &mm_var->namedstyle[instance_num - 1];
|
||||||
|
FT_Fixed *coords = instance->coords;
|
||||||
|
FcBool nonzero;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
/* Skip named-instance that coincides with base instance. */
|
||||||
|
nonzero = FcFalse;
|
||||||
|
for (i = 0; i < mm_var->num_axis; i++)
|
||||||
|
if (coords[i] != mm_var->axis[i].def)
|
||||||
|
{
|
||||||
|
nonzero = FcTrue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!nonzero)
|
||||||
|
goto skip;
|
||||||
|
|
||||||
|
FT_Set_Var_Design_Coordinates (face, mm_var->num_axis, coords);
|
||||||
|
}
|
||||||
|
|
||||||
|
id = ((instance_num << 16) + face_num);
|
||||||
|
pat = FcFreeTypeQueryFaceInternal (face, (const FcChar8 *) file, id, &cs, &ls);
|
||||||
|
|
||||||
|
if (pat)
|
||||||
|
{
|
||||||
|
|
||||||
|
ret++;
|
||||||
|
if (!set || ! FcFontSetAdd (set, pat))
|
||||||
|
FcPatternDestroy (pat);
|
||||||
|
}
|
||||||
|
else if (instance_num != 0x8000)
|
||||||
|
err = 1;
|
||||||
|
|
||||||
|
skip:
|
||||||
|
if (!index_set && instance_num < num_instances)
|
||||||
|
instance_num++;
|
||||||
|
else if (!index_set && instance_num == num_instances)
|
||||||
|
instance_num = 0x8000; /* variable font */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FcLangSetDestroy (ls);
|
||||||
|
ls = NULL;
|
||||||
|
FcCharSetDestroy (cs);
|
||||||
|
cs = NULL;
|
||||||
|
FT_Done_Face (face);
|
||||||
|
face = NULL;
|
||||||
|
|
||||||
|
face_num++;
|
||||||
|
instance_num = set_instance_num;
|
||||||
|
|
||||||
|
if (FT_New_Face (ftLibrary, (const char *) file, face_num, &face))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (!err && (!index_set || face_num == set_face_num) && face_num < num_faces);
|
||||||
|
|
||||||
|
bail:
|
||||||
|
FcLangSetDestroy (ls);
|
||||||
|
FcCharSetDestroy (cs);
|
||||||
|
if (face)
|
||||||
|
FT_Done_Face (face);
|
||||||
FT_Done_FreeType (ftLibrary);
|
FT_Done_FreeType (ftLibrary);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -2134,18 +2300,13 @@ static inline int fc_max (int a, int b) { return a >= b ? a : b; }
|
||||||
static inline FcBool fc_approximately_equal (int x, int y)
|
static inline FcBool fc_approximately_equal (int x, int y)
|
||||||
{ return abs (x - y) * 33 <= fc_max (abs (x), abs (y)); }
|
{ return abs (x - y) * 33 <= fc_max (abs (x), abs (y)); }
|
||||||
|
|
||||||
FcCharSet *
|
static int
|
||||||
FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks FC_UNUSED, int *spacing)
|
FcFreeTypeSpacing (FT_Face face)
|
||||||
{
|
{
|
||||||
FcCharSet *fcs;
|
|
||||||
int o;
|
|
||||||
FT_Int load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
|
FT_Int load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
|
||||||
FT_Pos advances[3];
|
FT_Pos advances[3] = {};
|
||||||
unsigned int num_advances = 0;
|
unsigned int num_advances = 0;
|
||||||
|
int o;
|
||||||
fcs = FcCharSetCreate ();
|
|
||||||
if (!fcs)
|
|
||||||
goto bail0;
|
|
||||||
|
|
||||||
/* When using scalable fonts, only report those glyphs
|
/* When using scalable fonts, only report those glyphs
|
||||||
* which can be scaled; otherwise those fonts will
|
* which can be scaled; otherwise those fonts will
|
||||||
|
@ -2170,11 +2331,58 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks FC_UNUSED, int *spac
|
||||||
strike_index = i;
|
strike_index = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FT_Select_Size (face, strike_index) != FT_Err_Ok)
|
FT_Select_Size (face, strike_index);
|
||||||
goto bail1;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
for (o = 0; o < NUM_DECODE; o++)
|
||||||
|
{
|
||||||
|
FcChar32 ucs4;
|
||||||
|
FT_UInt glyph;
|
||||||
|
|
||||||
|
if (FT_Select_Charmap (face, fcFontEncodings[o]) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ucs4 = FT_Get_First_Char (face, &glyph);
|
||||||
|
while (glyph != 0 && num_advances < 3)
|
||||||
|
{
|
||||||
|
FT_Pos advance = 0;
|
||||||
|
if (!FT_Get_Advance (face, glyph, load_flags, &advance) && advance)
|
||||||
|
{
|
||||||
|
unsigned int j;
|
||||||
|
for (j = 0; j < num_advances; j++)
|
||||||
|
if (fc_approximately_equal (advance, advances[j]))
|
||||||
|
break;
|
||||||
|
if (j == num_advances)
|
||||||
|
advances[num_advances++] = advance;
|
||||||
|
}
|
||||||
|
|
||||||
|
ucs4 = FT_Get_Next_Char (face, ucs4, &glyph);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_advances <= 1)
|
||||||
|
return FC_MONO;
|
||||||
|
else if (num_advances == 2 &&
|
||||||
|
fc_approximately_equal (fc_min (advances[0], advances[1]) * 2,
|
||||||
|
fc_max (advances[0], advances[1])))
|
||||||
|
return FC_DUAL;
|
||||||
|
else
|
||||||
|
return FC_PROPORTIONAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcCharSet *
|
||||||
|
FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks FC_UNUSED)
|
||||||
|
{
|
||||||
|
const FT_Int load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
|
||||||
|
FcCharSet *fcs;
|
||||||
|
int o;
|
||||||
|
|
||||||
|
fcs = FcCharSetCreate ();
|
||||||
|
if (!fcs)
|
||||||
|
goto bail;
|
||||||
|
|
||||||
#ifdef CHECK
|
#ifdef CHECK
|
||||||
printf ("Family %s style %s\n", face->family_name, face->style_name);
|
printf ("Family %s style %s\n", face->family_name, face->style_name);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2206,26 +2414,13 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks FC_UNUSED, int *spac
|
||||||
|
|
||||||
if (good)
|
if (good)
|
||||||
{
|
{
|
||||||
if (num_advances < 3)
|
FcCharSetAddChar (fcs, ucs4);
|
||||||
{
|
|
||||||
FT_Pos advance = 0;
|
|
||||||
if (!FT_Get_Advance (face, glyph, load_flags, &advance) && advance)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
for (i = 0; i < num_advances; i++)
|
|
||||||
if (fc_approximately_equal (advance, advances[i]))
|
|
||||||
break;
|
|
||||||
if (i == num_advances)
|
|
||||||
advances[num_advances++] = advance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ucs4 >> 8) != page)
|
if ((ucs4 >> 8) != page)
|
||||||
{
|
{
|
||||||
page = (ucs4 >> 8);
|
page = (ucs4 >> 8);
|
||||||
leaf = FcCharSetFindLeafCreate (fcs, ucs4);
|
leaf = FcCharSetFindLeafCreate (fcs, ucs4);
|
||||||
if (!leaf)
|
if (!leaf)
|
||||||
goto bail1;
|
goto bail;
|
||||||
}
|
}
|
||||||
off = ucs4 & 0xff;
|
off = ucs4 & 0xff;
|
||||||
leaf->map[off >> 5] |= (1 << (off & 0x1f));
|
leaf->map[off >> 5] |= (1 << (off & 0x1f));
|
||||||
|
@ -2265,27 +2460,21 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks FC_UNUSED, int *spac
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (num_advances <= 1)
|
|
||||||
*spacing = FC_MONO;
|
|
||||||
else if (num_advances == 2 &&
|
|
||||||
fc_approximately_equal (fc_min (advances[0], advances[1]) * 2,
|
|
||||||
fc_max (advances[0], advances[1])))
|
|
||||||
*spacing = FC_DUAL;
|
|
||||||
else
|
|
||||||
*spacing = FC_PROPORTIONAL;
|
|
||||||
return fcs;
|
return fcs;
|
||||||
bail1:
|
bail:
|
||||||
FcCharSetDestroy (fcs);
|
FcCharSetDestroy (fcs);
|
||||||
bail0:
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FcCharSet *
|
FcCharSet *
|
||||||
FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks FC_UNUSED)
|
FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks FC_UNUSED, int *spacing)
|
||||||
{
|
{
|
||||||
int spacing;
|
|
||||||
|
|
||||||
return FcFreeTypeCharSetAndSpacing (face, blanks, &spacing);
|
if (spacing)
|
||||||
|
*spacing = FcFreeTypeSpacing (face);
|
||||||
|
|
||||||
|
return FcFreeTypeCharSet (face, blanks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -485,6 +485,9 @@ FcLangSetCreate (void)
|
||||||
void
|
void
|
||||||
FcLangSetDestroy (FcLangSet *ls)
|
FcLangSetDestroy (FcLangSet *ls)
|
||||||
{
|
{
|
||||||
|
if (!ls)
|
||||||
|
return;
|
||||||
|
|
||||||
if (ls->extra)
|
if (ls->extra)
|
||||||
FcStrSetDestroy (ls->extra);
|
FcStrSetDestroy (ls->extra);
|
||||||
free (ls);
|
free (ls);
|
||||||
|
@ -495,6 +498,9 @@ FcLangSetCopy (const FcLangSet *ls)
|
||||||
{
|
{
|
||||||
FcLangSet *new;
|
FcLangSet *new;
|
||||||
|
|
||||||
|
if (!ls)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
new = FcLangSetCreate ();
|
new = FcLangSetCreate ();
|
||||||
if (!new)
|
if (!new)
|
||||||
goto bail0;
|
goto bail0;
|
||||||
|
|
177
src/fcmatch.c
177
src/fcmatch.c
|
@ -25,7 +25,7 @@
|
||||||
#include "fcint.h"
|
#include "fcint.h"
|
||||||
|
|
||||||
static double
|
static double
|
||||||
FcCompareNumber (FcValue *value1, FcValue *value2)
|
FcCompareNumber (const FcValue *value1, const FcValue *value2, FcValue *bestValue)
|
||||||
{
|
{
|
||||||
double v1, v2, v;
|
double v1, v2, v;
|
||||||
|
|
||||||
|
@ -52,23 +52,27 @@ FcCompareNumber (FcValue *value1, FcValue *value2)
|
||||||
v = v2 - v1;
|
v = v2 - v1;
|
||||||
if (v < 0)
|
if (v < 0)
|
||||||
v = -v;
|
v = -v;
|
||||||
|
*bestValue = FcValueCanonicalize (value2);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
FcCompareString (FcValue *v1, FcValue *v2)
|
FcCompareString (const FcValue *v1, const FcValue *v2, FcValue *bestValue)
|
||||||
{
|
{
|
||||||
|
*bestValue = FcValueCanonicalize (v2);
|
||||||
return (double) FcStrCmpIgnoreCase (FcValueString(v1), FcValueString(v2)) != 0;
|
return (double) FcStrCmpIgnoreCase (FcValueString(v1), FcValueString(v2)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
FcCompareFamily (FcValue *v1, FcValue *v2)
|
FcCompareFamily (const FcValue *v1, const FcValue *v2, FcValue *bestValue)
|
||||||
{
|
{
|
||||||
/* rely on the guarantee in FcPatternObjectAddWithBinding that
|
/* rely on the guarantee in FcPatternObjectAddWithBinding that
|
||||||
* families are always FcTypeString. */
|
* families are always FcTypeString. */
|
||||||
const FcChar8* v1_string = FcValueString(v1);
|
const FcChar8* v1_string = FcValueString(v1);
|
||||||
const FcChar8* v2_string = FcValueString(v2);
|
const FcChar8* v2_string = FcValueString(v2);
|
||||||
|
|
||||||
|
*bestValue = FcValueCanonicalize (v2);
|
||||||
|
|
||||||
if (FcToLower(*v1_string) != FcToLower(*v2_string) &&
|
if (FcToLower(*v1_string) != FcToLower(*v2_string) &&
|
||||||
*v1_string != ' ' && *v2_string != ' ')
|
*v1_string != ' ' && *v2_string != ' ')
|
||||||
return 1.0;
|
return 1.0;
|
||||||
|
@ -77,13 +81,15 @@ FcCompareFamily (FcValue *v1, FcValue *v2)
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
FcComparePostScript (FcValue *v1, FcValue *v2)
|
FcComparePostScript (const FcValue *v1, const FcValue *v2, FcValue *bestValue)
|
||||||
{
|
{
|
||||||
const FcChar8 *v1_string = FcValueString (v1);
|
const FcChar8 *v1_string = FcValueString (v1);
|
||||||
const FcChar8 *v2_string = FcValueString (v2);
|
const FcChar8 *v2_string = FcValueString (v2);
|
||||||
int n;
|
int n;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
*bestValue = FcValueCanonicalize (v2);
|
||||||
|
|
||||||
if (FcToLower (*v1_string) != FcToLower (*v2_string) &&
|
if (FcToLower (*v1_string) != FcToLower (*v2_string) &&
|
||||||
*v1_string != ' ' && *v2_string != ' ')
|
*v1_string != ' ' && *v2_string != ' ')
|
||||||
return 1.0;
|
return 1.0;
|
||||||
|
@ -95,7 +101,7 @@ FcComparePostScript (FcValue *v1, FcValue *v2)
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
FcCompareLang (FcValue *v1, FcValue *v2)
|
FcCompareLang (const FcValue *v1, const FcValue *v2, FcValue *bestValue)
|
||||||
{
|
{
|
||||||
FcLangResult result;
|
FcLangResult result;
|
||||||
FcValue value1 = FcValueCanonicalize(v1), value2 = FcValueCanonicalize(v2);
|
FcValue value1 = FcValueCanonicalize(v1), value2 = FcValueCanonicalize(v2);
|
||||||
|
@ -130,6 +136,7 @@ FcCompareLang (FcValue *v1, FcValue *v2)
|
||||||
default:
|
default:
|
||||||
return -1.0;
|
return -1.0;
|
||||||
}
|
}
|
||||||
|
*bestValue = FcValueCanonicalize (v2);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case FcLangEqual:
|
case FcLangEqual:
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -142,99 +149,134 @@ FcCompareLang (FcValue *v1, FcValue *v2)
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
FcCompareBool (FcValue *v1, FcValue *v2)
|
FcCompareBool (const FcValue *v1, const FcValue *v2, FcValue *bestValue)
|
||||||
{
|
{
|
||||||
if (v2->type != FcTypeBool || v1->type != FcTypeBool)
|
if (v2->type != FcTypeBool || v1->type != FcTypeBool)
|
||||||
return -1.0;
|
return -1.0;
|
||||||
return (double) v2->u.b != v1->u.b;
|
|
||||||
|
if (v2->u.b != FcDontCare)
|
||||||
|
*bestValue = FcValueCanonicalize (v2);
|
||||||
|
else
|
||||||
|
*bestValue = FcValueCanonicalize (v1);
|
||||||
|
|
||||||
|
return (double) ((v2->u.b ^ v1->u.b) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
FcCompareCharSet (FcValue *v1, FcValue *v2)
|
FcCompareCharSet (const FcValue *v1, const FcValue *v2, FcValue *bestValue)
|
||||||
{
|
{
|
||||||
|
*bestValue = FcValueCanonicalize (v2); /* TODO Improve. */
|
||||||
return (double) FcCharSetSubtractCount (FcValueCharSet(v1), FcValueCharSet(v2));
|
return (double) FcCharSetSubtractCount (FcValueCharSet(v1), FcValueCharSet(v2));
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
FcCompareSize (FcValue *value1, FcValue *value2)
|
FcCompareRange (const FcValue *v1, const FcValue *v2, FcValue *bestValue)
|
||||||
{
|
|
||||||
double v1, v2, v;
|
|
||||||
|
|
||||||
switch ((int) value1->type) {
|
|
||||||
case FcTypeInteger:
|
|
||||||
v1 = value1->u.i;
|
|
||||||
break;
|
|
||||||
case FcTypeDouble:
|
|
||||||
v1 = value1->u.d;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
switch ((int) value2->type) {
|
|
||||||
case FcTypeInteger:
|
|
||||||
v2 = value2->u.i;
|
|
||||||
break;
|
|
||||||
case FcTypeDouble:
|
|
||||||
v2 = value2->u.d;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (v2 == 0)
|
|
||||||
return 0;
|
|
||||||
v = v2 - v1;
|
|
||||||
if (v < 0)
|
|
||||||
v = -v;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static double
|
|
||||||
FcCompareSizeRange (FcValue *v1, FcValue *v2)
|
|
||||||
{
|
{
|
||||||
FcValue value1 = FcValueCanonicalize (v1);
|
FcValue value1 = FcValueCanonicalize (v1);
|
||||||
FcValue value2 = FcValueCanonicalize (v2);
|
FcValue value2 = FcValueCanonicalize (v2);
|
||||||
FcRange *r1 = NULL, *r2 = NULL;
|
double b1, e1, b2, e2, d;
|
||||||
double ret = -1.0;
|
|
||||||
|
|
||||||
switch ((int) value1.type) {
|
switch ((int) value1.type) {
|
||||||
|
case FcTypeInteger:
|
||||||
|
b1 = e1 = value1.u.i;
|
||||||
|
break;
|
||||||
case FcTypeDouble:
|
case FcTypeDouble:
|
||||||
r1 = FcRangeCreateDouble (value1.u.d, value1.u.d);
|
b1 = e1 = value1.u.d;
|
||||||
break;
|
break;
|
||||||
case FcTypeRange:
|
case FcTypeRange:
|
||||||
r1 = FcRangeCopy (value1.u.r);
|
abort();
|
||||||
|
b1 = value1.u.r->begin;
|
||||||
|
e1 = value1.u.r->end;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto bail;
|
return -1;
|
||||||
}
|
}
|
||||||
switch ((int) value2.type) {
|
switch ((int) value2.type) {
|
||||||
|
case FcTypeInteger:
|
||||||
|
b2 = e2 = value2.u.i;
|
||||||
|
break;
|
||||||
case FcTypeDouble:
|
case FcTypeDouble:
|
||||||
r2 = FcRangeCreateDouble (value2.u.d, value2.u.d);
|
b2 = e2 = value2.u.d;
|
||||||
break;
|
break;
|
||||||
case FcTypeRange:
|
case FcTypeRange:
|
||||||
r2 = FcRangeCopy (value2.u.r);
|
b2 = value2.u.r->begin;
|
||||||
|
e2 = value2.u.r->end;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto bail;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FcRangeIsInRange (r1, r2))
|
if (e1 < b2)
|
||||||
ret = 0.0;
|
d = b2;
|
||||||
|
else if (e2 < b1)
|
||||||
|
d = e2;
|
||||||
else
|
else
|
||||||
ret = FC_MIN (fabs (r1->end - r2->begin), fabs (r1->begin - r2->end));
|
d = (FC_MAX (b1, b2) + FC_MIN (e1, e2)) * .5;
|
||||||
|
|
||||||
bail:
|
bestValue->type = FcTypeDouble;
|
||||||
if (r1)
|
bestValue->u.d = d;
|
||||||
FcRangeDestroy (r1);
|
|
||||||
if (r2)
|
|
||||||
FcRangeDestroy (r2);
|
|
||||||
|
|
||||||
return ret;
|
/* If the ranges overlap, it's a match, otherwise return closest distance. */
|
||||||
|
if (e1 < b2 || e2 < b1)
|
||||||
|
return FC_MIN (fabs (b2 - e1), fabs (b1 - e2));
|
||||||
|
else
|
||||||
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
FcCompareFilename (FcValue *v1, FcValue *v2)
|
FcCompareSize (const FcValue *v1, const FcValue *v2, FcValue *bestValue)
|
||||||
|
{
|
||||||
|
FcValue value1 = FcValueCanonicalize (v1);
|
||||||
|
FcValue value2 = FcValueCanonicalize (v2);
|
||||||
|
double b1, e1, b2, e2;
|
||||||
|
|
||||||
|
switch ((int) value1.type) {
|
||||||
|
case FcTypeInteger:
|
||||||
|
b1 = e1 = value1.u.i;
|
||||||
|
break;
|
||||||
|
case FcTypeDouble:
|
||||||
|
b1 = e1 = value1.u.d;
|
||||||
|
break;
|
||||||
|
case FcTypeRange:
|
||||||
|
abort();
|
||||||
|
b1 = value1.u.r->begin;
|
||||||
|
e1 = value1.u.r->end;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
switch ((int) value2.type) {
|
||||||
|
case FcTypeInteger:
|
||||||
|
b2 = e2 = value2.u.i;
|
||||||
|
break;
|
||||||
|
case FcTypeDouble:
|
||||||
|
b2 = e2 = value2.u.d;
|
||||||
|
break;
|
||||||
|
case FcTypeRange:
|
||||||
|
b2 = value2.u.r->begin;
|
||||||
|
e2 = value2.u.r->end;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bestValue->type = FcTypeDouble;
|
||||||
|
bestValue->u.d = (b1 + e1) * .5;
|
||||||
|
|
||||||
|
/* If the ranges overlap, it's a match, otherwise return closest distance. */
|
||||||
|
if (e1 < b2 || e2 < b1)
|
||||||
|
return FC_MIN (fabs (b2 - e1), fabs (b1 - e2));
|
||||||
|
if (b2 != e2 && b1 == e2) /* Semi-closed interval. */
|
||||||
|
return 1e-15;
|
||||||
|
else
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double
|
||||||
|
FcCompareFilename (const FcValue *v1, const FcValue *v2, FcValue *bestValue)
|
||||||
{
|
{
|
||||||
const FcChar8 *s1 = FcValueString (v1), *s2 = FcValueString (v2);
|
const FcChar8 *s1 = FcValueString (v1), *s2 = FcValueString (v2);
|
||||||
|
*bestValue = FcValueCanonicalize (v2);
|
||||||
if (FcStrCmp (s1, s2) == 0)
|
if (FcStrCmp (s1, s2) == 0)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
else if (FcStrCmpIgnoreCase (s1, s2) == 0)
|
else if (FcStrCmpIgnoreCase (s1, s2) == 0)
|
||||||
|
@ -255,13 +297,13 @@ FcCompareFilename (FcValue *v1, FcValue *v2)
|
||||||
#define PRI_FcCompareFamily(n) PRI1(n)
|
#define PRI_FcCompareFamily(n) PRI1(n)
|
||||||
#define PRI_FcCompareString(n) PRI1(n)
|
#define PRI_FcCompareString(n) PRI1(n)
|
||||||
#define PRI_FcCompareNumber(n) PRI1(n)
|
#define PRI_FcCompareNumber(n) PRI1(n)
|
||||||
#define PRI_FcCompareSize(n) PRI1(n)
|
|
||||||
#define PRI_FcCompareBool(n) PRI1(n)
|
#define PRI_FcCompareBool(n) PRI1(n)
|
||||||
#define PRI_FcCompareFilename(n) PRI1(n)
|
#define PRI_FcCompareFilename(n) PRI1(n)
|
||||||
#define PRI_FcCompareCharSet(n) PRI1(n)
|
#define PRI_FcCompareCharSet(n) PRI1(n)
|
||||||
#define PRI_FcCompareLang(n) PRI1(n)
|
#define PRI_FcCompareLang(n) PRI1(n)
|
||||||
#define PRI_FcComparePostScript(n) PRI1(n)
|
#define PRI_FcComparePostScript(n) PRI1(n)
|
||||||
#define PRI_FcCompareSizeRange(n) PRI1(n)
|
#define PRI_FcCompareRange(n) PRI1(n)
|
||||||
|
#define PRI_FcCompareSize(n) PRI1(n)
|
||||||
|
|
||||||
#define FC_OBJECT(NAME, Type, Cmp) PRI_##Cmp(NAME)
|
#define FC_OBJECT(NAME, Type, Cmp) PRI_##Cmp(NAME)
|
||||||
|
|
||||||
|
@ -283,6 +325,7 @@ typedef enum _FcMatcherPriorityDummy {
|
||||||
typedef enum _FcMatcherPriority {
|
typedef enum _FcMatcherPriority {
|
||||||
PRI1(FILE),
|
PRI1(FILE),
|
||||||
PRI1(FONTFORMAT),
|
PRI1(FONTFORMAT),
|
||||||
|
PRI1(VARIABLE),
|
||||||
PRI1(SCALABLE),
|
PRI1(SCALABLE),
|
||||||
PRI1(COLOR),
|
PRI1(COLOR),
|
||||||
PRI1(FOUNDRY),
|
PRI1(FOUNDRY),
|
||||||
|
@ -312,7 +355,7 @@ typedef enum _FcMatcherPriority {
|
||||||
|
|
||||||
typedef struct _FcMatcher {
|
typedef struct _FcMatcher {
|
||||||
FcObject object;
|
FcObject object;
|
||||||
double (*compare) (FcValue *value1, FcValue *value2);
|
double (*compare) (const FcValue *v1, const FcValue *v2, FcValue *bestValue);
|
||||||
int strong, weak;
|
int strong, weak;
|
||||||
} FcMatcher;
|
} FcMatcher;
|
||||||
|
|
||||||
|
@ -382,7 +425,8 @@ FcCompareValueList (FcObject object,
|
||||||
{
|
{
|
||||||
for (v2 = v2orig, k = 0; v2; v2 = FcValueListNext(v2), k++)
|
for (v2 = v2orig, k = 0; v2; v2 = FcValueListNext(v2), k++)
|
||||||
{
|
{
|
||||||
v = (match->compare) (&v1->value, &v2->value);
|
FcValue matchValue;
|
||||||
|
v = (match->compare) (&v1->value, &v2->value, &matchValue);
|
||||||
if (v < 0)
|
if (v < 0)
|
||||||
{
|
{
|
||||||
*result = FcResultTypeMismatch;
|
*result = FcResultTypeMismatch;
|
||||||
|
@ -392,7 +436,7 @@ FcCompareValueList (FcObject object,
|
||||||
if (v < best)
|
if (v < best)
|
||||||
{
|
{
|
||||||
if (bestValue)
|
if (bestValue)
|
||||||
*bestValue = FcValueCanonicalize(&v2->value);
|
*bestValue = matchValue;
|
||||||
best = v;
|
best = v;
|
||||||
pos = k;
|
pos = k;
|
||||||
}
|
}
|
||||||
|
@ -1017,7 +1061,8 @@ FcFontSetSort (FcConfig *config FC_UNUSED,
|
||||||
FcPatternGet (p, FC_LANG, i, &patternLang) == FcResultMatch &&
|
FcPatternGet (p, FC_LANG, i, &patternLang) == FcResultMatch &&
|
||||||
FcPatternGet (nodeps[f]->pattern, FC_LANG, 0, &nodeLang) == FcResultMatch)
|
FcPatternGet (nodeps[f]->pattern, FC_LANG, 0, &nodeLang) == FcResultMatch)
|
||||||
{
|
{
|
||||||
double compare = FcCompareLang (&patternLang, &nodeLang);
|
FcValue matchValue;
|
||||||
|
double compare = FcCompareLang (&patternLang, &nodeLang, &matchValue);
|
||||||
if (compare >= 0 && compare < 2)
|
if (compare >= 0 && compare < 2)
|
||||||
{
|
{
|
||||||
if (FcDebug () & FC_DBG_MATCHV)
|
if (FcDebug () & FC_DBG_MATCHV)
|
||||||
|
|
19
src/fcname.c
19
src/fcname.c
|
@ -258,6 +258,11 @@ FcNameBool (const FcChar8 *v, FcBool *result)
|
||||||
*result = FcFalse;
|
*result = FcFalse;
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
if (c0 == 'd' || c0 == 'x' || c0 == '2')
|
||||||
|
{
|
||||||
|
*result = FcDontCare;
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
if (c0 == 'o')
|
if (c0 == 'o')
|
||||||
{
|
{
|
||||||
c1 = v[1];
|
c1 = v[1];
|
||||||
|
@ -272,6 +277,11 @@ FcNameBool (const FcChar8 *v, FcBool *result)
|
||||||
*result = FcFalse;
|
*result = FcFalse;
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
if (c1 == 'r')
|
||||||
|
{
|
||||||
|
*result = FcDontCare;
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
}
|
}
|
||||||
|
@ -318,7 +328,7 @@ FcNameConvert (FcType type, FcChar8 *string)
|
||||||
v.type = FcTypeVoid;
|
v.type = FcTypeVoid;
|
||||||
break;
|
break;
|
||||||
case FcTypeRange:
|
case FcTypeRange:
|
||||||
if (sscanf ((char *) string, "[%lg %lg)", &b, &e) != 2)
|
if (sscanf ((char *) string, "[%lg %lg]", &b, &e) != 2)
|
||||||
{
|
{
|
||||||
v.u.d = strtod ((char *) string, &p);
|
v.u.d = strtod ((char *) string, &p);
|
||||||
if (p != NULL && p[0] != 0)
|
if (p != NULL && p[0] != 0)
|
||||||
|
@ -514,7 +524,10 @@ FcNameUnparseValue (FcStrBuf *buf,
|
||||||
case FcTypeString:
|
case FcTypeString:
|
||||||
return FcNameUnparseString (buf, v.u.s, escape);
|
return FcNameUnparseString (buf, v.u.s, escape);
|
||||||
case FcTypeBool:
|
case FcTypeBool:
|
||||||
return FcNameUnparseString (buf, v.u.b ? (FcChar8 *) "True" : (FcChar8 *) "False", 0);
|
return FcNameUnparseString (buf,
|
||||||
|
v.u.b == FcTrue ? (FcChar8 *) "True" :
|
||||||
|
v.u.b == FcFalse ? (FcChar8 *) "False" :
|
||||||
|
(FcChar8 *) "DontCare", 0);
|
||||||
case FcTypeMatrix:
|
case FcTypeMatrix:
|
||||||
sprintf ((char *) temp, "%g %g %g %g",
|
sprintf ((char *) temp, "%g %g %g %g",
|
||||||
v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
|
v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy);
|
||||||
|
@ -526,7 +539,7 @@ FcNameUnparseValue (FcStrBuf *buf,
|
||||||
case FcTypeFTFace:
|
case FcTypeFTFace:
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
case FcTypeRange:
|
case FcTypeRange:
|
||||||
sprintf ((char *) temp, "[%g %g)", v.u.r->begin, v.u.r->end);
|
sprintf ((char *) temp, "[%g %g]", v.u.r->begin, v.u.r->end);
|
||||||
return FcNameUnparseString (buf, temp, 0);
|
return FcNameUnparseString (buf, temp, 0);
|
||||||
}
|
}
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
10
src/fcobjs.h
10
src/fcobjs.h
|
@ -29,11 +29,11 @@ FC_OBJECT (STYLELANG, FcTypeString, NULL)
|
||||||
FC_OBJECT (FULLNAME, FcTypeString, NULL)
|
FC_OBJECT (FULLNAME, FcTypeString, NULL)
|
||||||
FC_OBJECT (FULLNAMELANG, FcTypeString, NULL)
|
FC_OBJECT (FULLNAMELANG, FcTypeString, NULL)
|
||||||
FC_OBJECT (SLANT, FcTypeInteger, FcCompareNumber)
|
FC_OBJECT (SLANT, FcTypeInteger, FcCompareNumber)
|
||||||
FC_OBJECT (WEIGHT, FcTypeInteger, FcCompareNumber)
|
FC_OBJECT (WEIGHT, FcTypeRange, FcCompareRange)
|
||||||
FC_OBJECT (WIDTH, FcTypeInteger, FcCompareNumber)
|
FC_OBJECT (WIDTH, FcTypeRange, FcCompareRange)
|
||||||
FC_OBJECT (SIZE, FcTypeRange, FcCompareSizeRange)
|
FC_OBJECT (SIZE, FcTypeRange, FcCompareSize)
|
||||||
FC_OBJECT (ASPECT, FcTypeDouble, NULL)
|
FC_OBJECT (ASPECT, FcTypeDouble, NULL)
|
||||||
FC_OBJECT (PIXEL_SIZE, FcTypeDouble, FcCompareSize)
|
FC_OBJECT (PIXEL_SIZE, FcTypeDouble, FcCompareNumber)
|
||||||
FC_OBJECT (SPACING, FcTypeInteger, FcCompareNumber)
|
FC_OBJECT (SPACING, FcTypeInteger, FcCompareNumber)
|
||||||
FC_OBJECT (FOUNDRY, FcTypeString, FcCompareString)
|
FC_OBJECT (FOUNDRY, FcTypeString, FcCompareString)
|
||||||
FC_OBJECT (ANTIALIAS, FcTypeBool, FcCompareBool)
|
FC_OBJECT (ANTIALIAS, FcTypeBool, FcCompareBool)
|
||||||
|
@ -70,4 +70,6 @@ FC_OBJECT (HASH, FcTypeString, NULL) /* deprecated */
|
||||||
FC_OBJECT (POSTSCRIPT_NAME, FcTypeString, FcComparePostScript)
|
FC_OBJECT (POSTSCRIPT_NAME, FcTypeString, FcComparePostScript)
|
||||||
FC_OBJECT (COLOR, FcTypeBool, FcCompareBool)
|
FC_OBJECT (COLOR, FcTypeBool, FcCompareBool)
|
||||||
FC_OBJECT (SYMBOL, FcTypeBool, FcCompareBool)
|
FC_OBJECT (SYMBOL, FcTypeBool, FcCompareBool)
|
||||||
|
FC_OBJECT (FONT_VARIATIONS, FcTypeString, NULL)
|
||||||
|
FC_OBJECT (VARIABLE, FcTypeBool, FcCompareBool)
|
||||||
/* ^-------------- Add new objects here. */
|
/* ^-------------- Add new objects here. */
|
||||||
|
|
|
@ -1113,6 +1113,9 @@ FcPatternDuplicate (const FcPattern *orig)
|
||||||
int i;
|
int i;
|
||||||
FcValueListPtr l;
|
FcValueListPtr l;
|
||||||
|
|
||||||
|
if (!orig)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
new = FcPatternCreate ();
|
new = FcPatternCreate ();
|
||||||
if (!new)
|
if (!new)
|
||||||
goto bail0;
|
goto bail0;
|
||||||
|
|
|
@ -96,9 +96,6 @@ FcRangePromote (double v, FcValuePromotionBuffer *vbuf)
|
||||||
FcBool
|
FcBool
|
||||||
FcRangeIsInRange (const FcRange *a, const FcRange *b)
|
FcRangeIsInRange (const FcRange *a, const FcRange *b)
|
||||||
{
|
{
|
||||||
if (!a || !b)
|
|
||||||
return FcFalse;
|
|
||||||
|
|
||||||
return a->begin >= b->begin && a->end <= b->end;
|
return a->begin >= b->begin && a->end <= b->end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,20 +104,22 @@ FcRangeCompare (FcOp op, const FcRange *a, const FcRange *b)
|
||||||
{
|
{
|
||||||
switch ((int) op) {
|
switch ((int) op) {
|
||||||
case FcOpEqual:
|
case FcOpEqual:
|
||||||
|
return a->begin == b->begin && a->end == b->end;
|
||||||
case FcOpContains:
|
case FcOpContains:
|
||||||
case FcOpListing:
|
case FcOpListing:
|
||||||
return FcRangeIsInRange (a, b);
|
return FcRangeIsInRange (a, b);
|
||||||
case FcOpNotEqual:
|
case FcOpNotEqual:
|
||||||
|
return a->begin != b->begin || a->end != b->end;
|
||||||
case FcOpNotContains:
|
case FcOpNotContains:
|
||||||
return !FcRangeIsInRange (a, b);
|
return !FcRangeIsInRange (a, b);
|
||||||
case FcOpLess:
|
case FcOpLess:
|
||||||
return a->begin < b->begin;
|
return a->end < b->begin;
|
||||||
case FcOpLessEqual:
|
case FcOpLessEqual:
|
||||||
return a->begin <= b->begin;
|
return a->end <= b->begin;
|
||||||
case FcOpMore:
|
case FcOpMore:
|
||||||
return a->end > b->end;
|
return a->begin > b->end;
|
||||||
case FcOpMoreEqual:
|
case FcOpMoreEqual:
|
||||||
return a->end >= b->end;
|
return a->begin >= b->end;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue