summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira TAGOH <akira@tagoh.org>2012-04-09 12:51:12 +0900
committerAkira TAGOH <akira@tagoh.org>2012-04-11 16:36:36 +0900
commit9231d79ad180f992f9bbef4f3127576870a75075 (patch)
treea3d6899c28418360ca01b84c499bbd3f26f08bfb
parent2589207cfd4c7e948a4b50d7c07c13a3a52fe0aa (diff)
Bug 28491 - Allow matching on FC_FILE
Allow :file=/path/to/font/file on matching
-rw-r--r--configure.in4
-rw-r--r--src/fcint.h6
-rw-r--r--src/fcmatch.c84
-rw-r--r--src/fcstr.c50
4 files changed, 110 insertions, 34 deletions
diff --git a/configure.in b/configure.in
index c3476d3..39ae5a9 100644
--- a/configure.in
+++ b/configure.in
@@ -123,7 +123,7 @@ dnl ==========================================================================
# Checks for header files.
AC_HEADER_DIRENT
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.
AC_C_CONST
@@ -133,7 +133,7 @@ AC_TYPE_PID_T
# Checks for library functions.
AC_FUNC_VPRINTF
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
diff --git a/src/fcint.h b/src/fcint.h
index 56f77ef..fd60e7a 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -1009,6 +1009,12 @@ FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
FcPrivate int
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 *
FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
diff --git a/src/fcmatch.c b/src/fcmatch.c
index 92e4a66..655e62c 100644
--- a/src/fcmatch.c
+++ b/src/fcmatch.c
@@ -174,6 +174,22 @@ FcCompareSize (FcValue *value1, FcValue *value2)
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 {
FcObject object;
double (*compare) (FcValue *value1, FcValue *value2);
@@ -186,40 +202,42 @@ typedef struct _FcMatcher {
* later values
*/
static const FcMatcher _FcMatchers [] = {
- { FC_FOUNDRY_OBJECT, FcCompareString, 0, 0 },
-#define MATCH_FOUNDRY 0
- { FC_CHARSET_OBJECT, FcCompareCharSet, 1, 1 },
-#define MATCH_CHARSET 1
- { FC_FAMILY_OBJECT, FcCompareFamily, 2, 4 },
-#define MATCH_FAMILY 2
- { FC_LANG_OBJECT, FcCompareLang, 3, 3 },
-#define MATCH_LANG 3
-#define MATCH_LANG_INDEX 3
- { FC_SPACING_OBJECT, FcCompareNumber, 5, 5 },
-#define MATCH_SPACING 4
- { FC_PIXEL_SIZE_OBJECT, FcCompareSize, 6, 6 },
-#define MATCH_PIXEL_SIZE 5
- { FC_STYLE_OBJECT, FcCompareString, 7, 7 },
-#define MATCH_STYLE 6
- { FC_SLANT_OBJECT, FcCompareNumber, 8, 8 },
-#define MATCH_SLANT 7
- { FC_WEIGHT_OBJECT, FcCompareNumber, 9, 9 },
-#define MATCH_WEIGHT 8
- { FC_WIDTH_OBJECT, FcCompareNumber, 10, 10 },
-#define MATCH_WIDTH 9
- { FC_DECORATIVE_OBJECT, FcCompareBool, 11, 11 },
-#define MATCH_DECORATIVE 10
- { FC_ANTIALIAS_OBJECT, FcCompareBool, 12, 12 },
-#define MATCH_ANTIALIAS 11
- { FC_RASTERIZER_OBJECT, FcCompareString, 13, 13 },
-#define MATCH_RASTERIZER 12
- { FC_OUTLINE_OBJECT, FcCompareBool, 14, 14 },
-#define MATCH_OUTLINE 13
- { FC_FONTVERSION_OBJECT, FcCompareNumber, 15, 15 },
-#define MATCH_FONTVERSION 14
+ { FC_FILE_OBJECT, FcCompareFilename, 0, 0 },
+#define MATCH_FILE 0
+ { FC_FOUNDRY_OBJECT, FcCompareString, 1, 1 },
+#define MATCH_FOUNDRY 1
+ { FC_CHARSET_OBJECT, FcCompareCharSet, 2, 2 },
+#define MATCH_CHARSET 2
+ { FC_FAMILY_OBJECT, FcCompareFamily, 3, 5 },
+#define MATCH_FAMILY 3
+ { FC_LANG_OBJECT, FcCompareLang, 4, 4 },
+#define MATCH_LANG 4
+#define MATCH_LANG_INDEX 4
+ { FC_SPACING_OBJECT, FcCompareNumber, 6, 6 },
+#define MATCH_SPACING 5
+ { FC_PIXEL_SIZE_OBJECT, FcCompareSize, 7, 7 },
+#define MATCH_PIXEL_SIZE 6
+ { FC_STYLE_OBJECT, FcCompareString, 8, 8 },
+#define MATCH_STYLE 7
+ { FC_SLANT_OBJECT, FcCompareNumber, 9, 9 },
+#define MATCH_SLANT 8
+ { FC_WEIGHT_OBJECT, FcCompareNumber, 10, 10 },
+#define MATCH_WEIGHT 9
+ { FC_WIDTH_OBJECT, FcCompareNumber, 11, 11 },
+#define MATCH_WIDTH 10
+ { FC_DECORATIVE_OBJECT, FcCompareBool, 12, 12 },
+#define MATCH_DECORATIVE 11
+ { FC_ANTIALIAS_OBJECT, FcCompareBool, 13, 13 },
+#define MATCH_ANTIALIAS 12
+ { FC_RASTERIZER_OBJECT, FcCompareString, 14, 14 },
+#define MATCH_RASTERIZER 13
+ { FC_OUTLINE_OBJECT, FcCompareBool, 15, 15 },
+#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*
FcObjectToMatcher (FcObject object)
@@ -228,6 +246,8 @@ FcObjectToMatcher (FcObject object)
i = -1;
switch (object) {
+ case FC_FILE_OBJECT:
+ i = MATCH_FILE; break;
case FC_FOUNDRY_OBJECT:
i = MATCH_FOUNDRY; break;
case FC_FONTVERSION_OBJECT:
diff --git a/src/fcstr.c b/src/fcstr.c
index b712e5d..9484d46 100644
--- a/src/fcstr.c
+++ b/src/fcstr.c
@@ -26,6 +26,9 @@
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
+#ifdef HAVE_REGEX_H
+#include <regex.h>
+#endif
#ifdef _WIN32
#include <windows.h>
#endif
@@ -269,6 +272,53 @@ FcStrCmp (const FcChar8 *s1, const FcChar8 *s2)
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
*/