Bug 28491 - Allow matching on FC_FILE

Allow :file=/path/to/font/file on matching
This commit is contained in:
Akira TAGOH 2012-04-09 12:51:12 +09:00
parent 2589207cfd
commit 9231d79ad1
4 changed files with 110 additions and 34 deletions

View File

@ -123,7 +123,7 @@ dnl ==========================================================================
# Checks for header files. # Checks for header files.
AC_HEADER_DIRENT AC_HEADER_DIRENT
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h]) AC_CHECK_HEADERS([fcntl.h regex.h stdlib.h string.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics. # Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST AC_C_CONST
@ -133,7 +133,7 @@ AC_TYPE_PID_T
# Checks for library functions. # Checks for library functions.
AC_FUNC_VPRINTF AC_FUNC_VPRINTF
AC_FUNC_MMAP AC_FUNC_MMAP
AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr strtol getopt getopt_long sysconf ftruncate chsize rand random lrand48 random_r rand_r]) AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr strtol getopt getopt_long sysconf ftruncate chsize rand random lrand48 random_r rand_r regcomp regerror regexec regfree])
# #
# Checks for iconv # Checks for iconv

View File

@ -1009,6 +1009,12 @@ FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
FcPrivate int FcPrivate int
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2); FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
FcPrivate FcBool
FcStrRegexCmp (const FcChar8 *s, const FcChar8 *regex);
FcPrivate FcBool
FcStrRegexCmpIgnoreCase (const FcChar8 *s, const FcChar8 *regex);
FcPrivate const FcChar8 * FcPrivate const FcChar8 *
FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2); FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);

View File

@ -174,6 +174,22 @@ FcCompareSize (FcValue *value1, FcValue *value2)
return v; return v;
} }
static double
FcCompareFilename (FcValue *v1, FcValue *v2)
{
const FcChar8 *s1 = FcValueString (v1), *s2 = FcValueString (v2);
if (FcStrCmp (s1, s2) == 0)
return 0.0;
else if (FcStrCmpIgnoreCase (s1, s2) == 0)
return 1.0;
else if (FcStrRegexCmp (s2, s1))
return 2.0;
else if (FcStrRegexCmpIgnoreCase (s2, s1))
return 3.0;
else
return 4.0;
}
typedef struct _FcMatcher { typedef struct _FcMatcher {
FcObject object; FcObject object;
double (*compare) (FcValue *value1, FcValue *value2); double (*compare) (FcValue *value1, FcValue *value2);
@ -186,40 +202,42 @@ typedef struct _FcMatcher {
* later values * later values
*/ */
static const FcMatcher _FcMatchers [] = { static const FcMatcher _FcMatchers [] = {
{ FC_FOUNDRY_OBJECT, FcCompareString, 0, 0 }, { FC_FILE_OBJECT, FcCompareFilename, 0, 0 },
#define MATCH_FOUNDRY 0 #define MATCH_FILE 0
{ FC_CHARSET_OBJECT, FcCompareCharSet, 1, 1 }, { FC_FOUNDRY_OBJECT, FcCompareString, 1, 1 },
#define MATCH_CHARSET 1 #define MATCH_FOUNDRY 1
{ FC_FAMILY_OBJECT, FcCompareFamily, 2, 4 }, { FC_CHARSET_OBJECT, FcCompareCharSet, 2, 2 },
#define MATCH_FAMILY 2 #define MATCH_CHARSET 2
{ FC_LANG_OBJECT, FcCompareLang, 3, 3 }, { FC_FAMILY_OBJECT, FcCompareFamily, 3, 5 },
#define MATCH_LANG 3 #define MATCH_FAMILY 3
#define MATCH_LANG_INDEX 3 { FC_LANG_OBJECT, FcCompareLang, 4, 4 },
{ FC_SPACING_OBJECT, FcCompareNumber, 5, 5 }, #define MATCH_LANG 4
#define MATCH_SPACING 4 #define MATCH_LANG_INDEX 4
{ FC_PIXEL_SIZE_OBJECT, FcCompareSize, 6, 6 }, { FC_SPACING_OBJECT, FcCompareNumber, 6, 6 },
#define MATCH_PIXEL_SIZE 5 #define MATCH_SPACING 5
{ FC_STYLE_OBJECT, FcCompareString, 7, 7 }, { FC_PIXEL_SIZE_OBJECT, FcCompareSize, 7, 7 },
#define MATCH_STYLE 6 #define MATCH_PIXEL_SIZE 6
{ FC_SLANT_OBJECT, FcCompareNumber, 8, 8 }, { FC_STYLE_OBJECT, FcCompareString, 8, 8 },
#define MATCH_SLANT 7 #define MATCH_STYLE 7
{ FC_WEIGHT_OBJECT, FcCompareNumber, 9, 9 }, { FC_SLANT_OBJECT, FcCompareNumber, 9, 9 },
#define MATCH_WEIGHT 8 #define MATCH_SLANT 8
{ FC_WIDTH_OBJECT, FcCompareNumber, 10, 10 }, { FC_WEIGHT_OBJECT, FcCompareNumber, 10, 10 },
#define MATCH_WIDTH 9 #define MATCH_WEIGHT 9
{ FC_DECORATIVE_OBJECT, FcCompareBool, 11, 11 }, { FC_WIDTH_OBJECT, FcCompareNumber, 11, 11 },
#define MATCH_DECORATIVE 10 #define MATCH_WIDTH 10
{ FC_ANTIALIAS_OBJECT, FcCompareBool, 12, 12 }, { FC_DECORATIVE_OBJECT, FcCompareBool, 12, 12 },
#define MATCH_ANTIALIAS 11 #define MATCH_DECORATIVE 11
{ FC_RASTERIZER_OBJECT, FcCompareString, 13, 13 }, { FC_ANTIALIAS_OBJECT, FcCompareBool, 13, 13 },
#define MATCH_RASTERIZER 12 #define MATCH_ANTIALIAS 12
{ FC_OUTLINE_OBJECT, FcCompareBool, 14, 14 }, { FC_RASTERIZER_OBJECT, FcCompareString, 14, 14 },
#define MATCH_OUTLINE 13 #define MATCH_RASTERIZER 13
{ FC_FONTVERSION_OBJECT, FcCompareNumber, 15, 15 }, { FC_OUTLINE_OBJECT, FcCompareBool, 15, 15 },
#define MATCH_FONTVERSION 14 #define MATCH_OUTLINE 14
{ FC_FONTVERSION_OBJECT, FcCompareNumber, 16, 16 },
#define MATCH_FONTVERSION 15
}; };
#define NUM_MATCH_VALUES 16 #define NUM_MATCH_VALUES 17
static const FcMatcher* static const FcMatcher*
FcObjectToMatcher (FcObject object) FcObjectToMatcher (FcObject object)
@ -228,6 +246,8 @@ FcObjectToMatcher (FcObject object)
i = -1; i = -1;
switch (object) { switch (object) {
case FC_FILE_OBJECT:
i = MATCH_FILE; break;
case FC_FOUNDRY_OBJECT: case FC_FOUNDRY_OBJECT:
i = MATCH_FOUNDRY; break; i = MATCH_FOUNDRY; break;
case FC_FONTVERSION_OBJECT: case FC_FONTVERSION_OBJECT:

View File

@ -26,6 +26,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#ifdef HAVE_REGEX_H
#include <regex.h>
#endif
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#endif #endif
@ -269,6 +272,53 @@ FcStrCmp (const FcChar8 *s1, const FcChar8 *s2)
return (int) c1 - (int) c2; return (int) c1 - (int) c2;
} }
static FcBool
_FcStrRegexCmp (const FcChar8 *s, const FcChar8 *regex, int cflags, int eflags)
{
int ret = -1;
#if defined (HAVE_REGCOMP) && defined (HAVE_REGERROR) && defined (HAVE_REGEXEC) && defined (HAVE_REGFREE)
regex_t reg;
if ((ret = regcomp (&reg, (const char *)regex, cflags)) != 0)
{
if (FcDebug () & FC_DBG_MATCHV)
{
char buf[512];
regerror (ret, &reg, buf, 512);
printf("Regexp compile error: %s\n", buf);
}
return FcFalse;
}
ret = regexec (&reg, (const char *)s, 0, NULL, eflags);
if (ret != 0)
{
if (FcDebug () & FC_DBG_MATCHV)
{
char buf[512];
regerror (ret, &reg, buf, 512);
printf("Regexp exec error: %s\n", buf);
}
}
regfree (&reg);
#endif
return ret == 0 ? FcTrue : FcFalse;
}
FcBool
FcStrRegexCmp (const FcChar8 *s, const FcChar8 *regex)
{
return _FcStrRegexCmp (s, regex, REG_EXTENDED | REG_NOSUB, 0);
}
FcBool
FcStrRegexCmpIgnoreCase (const FcChar8 *s, const FcChar8 *regex)
{
return _FcStrRegexCmp (s, regex, REG_EXTENDED | REG_NOSUB | REG_ICASE, 0);
}
/* /*
* Return a hash value for a string * Return a hash value for a string
*/ */