[Fontconfig] fontconfig: Branch 'master' - 4 commits
Akira TAGOH
tagoh at kemper.freedesktop.org
Fri May 11 13:18:18 UTC 2018
conf.d/90-synthetic.conf | 4
configure.ac | 9 +
doc/fcpattern.fncs | 111 ++++++++++++++
fontconfig/fontconfig.h | 33 ++++
src/fcdbg.c | 15 --
src/fcdefault.c | 32 ++--
src/fcformat.c | 22 --
src/fcint.h | 9 +
src/fcpat.c | 233 +++++++++++++++++++++++++------
test/Makefile.am | 16 +-
test/run-test-conf.sh | 36 ++++
test/test-90-synthetic.json | 68 +++++++++
test/test-conf.c | 328 ++++++++++++++++++++++++++++++++++++++++++++
13 files changed, 829 insertions(+), 87 deletions(-)
New commits:
commit af964f789762df0b023c8cfd7ea622045892cb54
Author: Akira TAGOH <akira at tagoh.org>
Date: Fri May 11 22:15:39 2018 +0900
Add a test case for 90-synthetic.conf
diff --git a/test/Makefile.am b/test/Makefile.am
index 117ba01..48ec3ce 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -13,7 +13,12 @@ BUILT_SOURCES = $(builddir)/out.expected
SH_LOG_COMPILER = sh
TESTS=run-test.sh
-TESTDATA=4x6.pcf 8x16.pcf fonts.conf.in
+TESTDATA = \
+ 4x6.pcf \
+ 8x16.pcf \
+ fonts.conf.in \
+ test-90-synthetic.json \
+ $(NULL)
if FREETYPE_PCF_LONG_FAMILY_NAMES
$(builddir)/out.expected: $(srcdir)/out.expected-long-family-names Makefile
@@ -63,10 +68,10 @@ if ENABLE_JSONC
check_PROGRAMS += test-conf
test_conf_CFLAGS = $(JSONC_CFLAGS)
test_conf_LDADD = $(top_builddir)/src/libfontconfig.la $(JSONC_LIBS)
-TESTS += test-conf.sh
+TESTS += run-test-conf.sh
endif
-EXTRA_DIST=run-test.sh $(TESTDATA) out.expected-long-family-names out.expected-no-long-family-names
+EXTRA_DIST=run-test.sh run-test-conf.sh $(TESTDATA) out.expected-long-family-names out.expected-no-long-family-names
CLEANFILES=out fonts.conf out.expected
diff --git a/test/run-test-conf.sh b/test/run-test-conf.sh
new file mode 100644
index 0000000..4bcc29c
--- /dev/null
+++ b/test/run-test-conf.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+# test/run-test-conf.sh
+#
+# Copyright © 2000 Keith Packard
+# Copyright © 2018 Akira TAGOH
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of the author(s) not be used in
+# advertising or publicity pertaining to distribution of the software without
+# specific, written prior permission. The authors make no
+# representations about the suitability of this software for any purpose. It
+# is provided "as is" without express or implied warranty.
+#
+# THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+# EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+set -eu
+
+case "$OSTYPE" in
+ msys ) MyPWD=`pwd -W` ;; # On Msys/MinGW, returns a MS Windows style path.
+ * ) MyPWD=`pwd` ;; # On any other platforms, returns a Unix style path.
+esac
+
+TESTDIR=${srcdir-"$MyPWD"}
+BUILDTESTDIR=${builddir-"$MyPWD"}
+
+RUNNER=../test/test-conf$EXEEXT
+
+$RUNNER $TESTDIR/../conf.d/90-synthetic.conf $TESTDIR/test-90-synthetic.json
diff --git a/test/test-90-synthetic.json b/test/test-90-synthetic.json
new file mode 100644
index 0000000..4205402
--- /dev/null
+++ b/test/test-90-synthetic.json
@@ -0,0 +1,68 @@
+{
+ "fonts": [
+ {
+ "family": "Foo",
+ "style": "Medium",
+ "weight": 100
+ },
+ {
+ "family": "Bar",
+ "style": "Regular",
+ "weight": 80
+ },
+ {
+ "family": "Baz",
+ "style": "Bold",
+ "weight": 200
+ }
+ ],
+ "tests": [
+ {
+ "method": "match",
+ "query": {
+ "family": "Foo",
+ "weight": 200
+ },
+ "result": {
+ "family": "Foo",
+ "weight": 200,
+ "embolden": true
+ }
+ },
+ {
+ "method": "match",
+ "query": {
+ "family": "Bar",
+ "weight": 102
+ },
+ "result": {
+ "family": "Bar",
+ "weight": 80
+ }
+ },
+ {
+ "method": "match",
+ "query": {
+ "family": "Bar",
+ "weight": 200
+ },
+ "result": {
+ "family": "Bar",
+ "weight": 200,
+ "embolden": true
+ }
+ },
+ {
+ "method": "match",
+ "query": {
+ "family": "Baz",
+ "weight": 200
+ },
+ "result": {
+ "family": "Baz",
+ "weight": 200,
+ "embolden": null
+ }
+ }
+ ]
+}
commit f665852df90cd5a28c3040af8f484999ca3dfa4e
Author: Akira TAGOH <akira at tagoh.org>
Date: Fri May 11 21:39:50 2018 +0900
Add a testrunner for conf
diff --git a/configure.ac b/configure.ac
index 557d151..3e37663 100644
--- a/configure.ac
+++ b/configure.ac
@@ -474,6 +474,15 @@ if test "$enable_libxml2" = "yes"; then
fi
#
+# Check json-c
+#
+PKG_CHECK_MODULES([JSONC], [json-c], [use_jsonc=yes], [use_jsonc=no])
+
+AM_CONDITIONAL(ENABLE_JSONC, test "x$use_jsonc" = "xyes")
+AC_SUBST(JSONC_CFLAGS)
+AC_SUBST(JSONC_LIBS)
+
+#
# Set default hinting
#
diff --git a/test/Makefile.am b/test/Makefile.am
index e5b8626..117ba01 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -59,6 +59,13 @@ check_PROGRAMS += test-name-parse
test_name_parse_LDADD = $(top_builddir)/src/libfontconfig.la
TESTS += test-name-parse
+if ENABLE_JSONC
+check_PROGRAMS += test-conf
+test_conf_CFLAGS = $(JSONC_CFLAGS)
+test_conf_LDADD = $(top_builddir)/src/libfontconfig.la $(JSONC_LIBS)
+TESTS += test-conf.sh
+endif
+
EXTRA_DIST=run-test.sh $(TESTDATA) out.expected-long-family-names out.expected-no-long-family-names
CLEANFILES=out fonts.conf out.expected
diff --git a/test/test-conf.c b/test/test-conf.c
new file mode 100644
index 0000000..6619ea7
--- /dev/null
+++ b/test/test-conf.c
@@ -0,0 +1,328 @@
+/*
+ * fontconfig/test/test-conf.c
+ *
+ * Copyright © 2000 Keith Packard
+ * Copyright © 2018 Akira TAGOH
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <fontconfig/fontconfig.h>
+#include <json.h>
+
+struct _FcConfig {
+ FcStrSet *configDirs; /* directories to scan for fonts */
+ FcStrSet *fontDirs;
+ FcStrSet *cacheDirs;
+ FcStrSet *configFiles; /* config files loaded */
+ void *subst[FcMatchKindEnd];
+ int maxObjects; /* maximum number of tests in all substs */
+ FcStrSet *acceptGlobs;
+ FcStrSet *rejectGlobs;
+ FcFontSet *acceptPatterns;
+ FcFontSet *rejectPatterns;
+ FcFontSet *fonts[FcSetApplication + 1];
+};
+
+static FcPattern *
+build_pattern (json_object *obj)
+{
+ json_object_iter iter;
+ FcPattern *pat = FcPatternCreate ();
+
+ json_object_object_foreachC (obj, iter)
+ {
+ FcValue v;
+
+ if (json_object_get_type (iter.val) == json_type_boolean)
+ {
+ v.type = FcTypeBool;
+ v.u.b = json_object_get_boolean (iter.val);
+ }
+ else if (json_object_get_type (iter.val) == json_type_double)
+ {
+ v.type = FcTypeDouble;
+ v.u.d = json_object_get_double (iter.val);
+ }
+ else if (json_object_get_type (iter.val) == json_type_int)
+ {
+ v.type = FcTypeInteger;
+ v.u.i = json_object_get_int (iter.val);
+ }
+ else if (json_object_get_type (iter.val) == json_type_string)
+ {
+ v.type = FcTypeString;
+ v.u.s = json_object_get_string (iter.val);
+ }
+ else if (json_object_get_type (iter.val) == json_type_null)
+ {
+ v.type = FcTypeVoid;
+ }
+ else
+ {
+ fprintf (stderr, "W: unexpected object to build a pattern: (%s %s)", iter.key, json_type_to_name (json_object_get_type (iter.val)));
+ continue;
+ }
+ FcPatternAdd (pat, iter.key, v, FcTrue);
+ }
+ return pat;
+}
+
+static FcBool
+build_fonts (FcConfig *config, json_object *root)
+{
+ json_object *fonts;
+ FcFontSet *fs;
+ int i, n;
+
+ if (!json_object_object_get_ex (root, "fonts", &fonts) ||
+ json_object_get_type (fonts) != json_type_array)
+ {
+ fprintf (stderr, "W: No fonts defined\n");
+ return FcFalse;
+ }
+ fs = FcFontSetCreate ();
+ n = json_object_array_length (fonts);
+ for (i = 0; i < n; i++)
+ {
+ json_object *obj = json_object_array_get_idx (fonts, i);
+ FcPattern *pat;
+
+ if (json_object_get_type (obj) != json_type_object)
+ continue;
+ pat = build_pattern (obj);
+ FcFontSetAdd (fs, pat);
+ }
+ /* FcConfigSetFonts (config, fs, FcSetSystem); */
+ if (config->fonts[FcSetSystem])
+ FcFontSetDestroy (config->fonts[FcSetSystem]);
+ config->fonts[FcSetSystem] = fs;
+
+ return FcTrue;
+}
+
+static FcBool
+run_test (FcConfig *config, json_object *root)
+{
+ json_object *tests;
+ FcFontSet *fs;
+ int i, n, fail = 0;
+
+ if (!json_object_object_get_ex (root, "tests", &tests) ||
+ json_object_get_type (tests) != json_type_array)
+ {
+ fprintf (stderr, "W: No test cases defined\n");
+ return FcFalse;
+ }
+ fs = FcFontSetCreate ();
+ n = json_object_array_length (tests);
+ for (i = 0; i < n; i++)
+ {
+ json_object *obj = json_object_array_get_idx (tests, i);
+ json_object_iter iter;
+ FcPattern *query, *result;
+ const char *method;
+
+ if (json_object_get_type (obj) != json_type_object)
+ continue;
+ json_object_object_foreachC (obj, iter)
+ {
+ if (strcmp (iter.key, "method") == 0)
+ {
+ if (json_object_get_type (iter.val) != json_type_string)
+ {
+ fprintf (stderr, "W: invalid type of method: (%s)\n", json_type_to_name (json_object_get_type (iter.val)));
+ continue;
+ }
+ method = json_object_get_string (iter.val);
+ }
+ else if (strcmp (iter.key, "query") == 0)
+ {
+ if (json_object_get_type (iter.val) != json_type_object)
+ {
+ fprintf (stderr, "W: invalid type of query: (%s)\n", json_type_to_name (json_object_get_type (iter.val)));
+ continue;
+ }
+ query = build_pattern (iter.val);
+ }
+ else if (strcmp (iter.key, "result") == 0)
+ {
+ if (json_object_get_type (iter.val) != json_type_object)
+ {
+ fprintf (stderr, "W: invalid type of result: (%s)\n", json_type_to_name (json_object_get_type (iter.val)));
+ continue;
+ }
+ result = build_pattern (iter.val);
+ }
+ else
+ {
+ fprintf (stderr, "W: unknown object: %s\n", iter.key);
+ }
+ }
+ if (strcmp (method, "match") == 0)
+ {
+ FcPattern *match;
+ FcResult res;
+
+ FcConfigSubstitute (config, query, FcMatchPattern);
+ FcDefaultSubstitute (query);
+ match = FcFontMatch (config, query, &res);
+ if (match)
+ {
+ FcPatternIter iter;
+ int x, vc;
+
+ FcPatternIterStart (result, &iter);
+ do
+ {
+ vc = FcPatternIterValueCount (result, &iter);
+ for (x = 0; x < vc; x++)
+ {
+ FcValue vr, vm;
+
+ if (FcPatternIterGetValue (result, &iter, x, &vr, NULL) != FcResultMatch)
+ {
+ fprintf (stderr, "E: unable to obtain a value from the expected result\n");
+ fail++;
+ goto bail;
+ }
+ if (FcPatternGet (match, FcPatternIterGetObject (result, &iter), x, &vm) != FcResultMatch)
+ {
+ vm.type = FcTypeVoid;
+ }
+ if (!FcValueEqual (vm, vr))
+ {
+ printf ("E: failed to compare %s:\n", FcPatternIterGetObject (result, &iter));
+ printf (" actual result:");
+ FcValuePrint (vm);
+ printf ("\n expected result:");
+ FcValuePrint (vr);
+ printf ("\n");
+ fail++;
+ goto bail;
+ }
+ }
+ } while (FcPatternIterNext (result, &iter));
+ bail:;
+ }
+ else
+ {
+ fprintf (stderr, "E: no match\n");
+ fail++;
+ }
+ }
+ else
+ {
+ fprintf (stderr, "W: unknown testing method: %s\n", method);
+ }
+ }
+
+ return fail == 0;
+}
+
+static FcBool
+run_scenario (FcConfig *config, char *file)
+{
+ FcBool ret = FcTrue;
+ json_object *root, *scenario;
+
+ root = json_object_from_file (file);
+ if (!root)
+ {
+ fprintf (stderr, "E: Unable to read the file: %s\n", file);
+ return FcFalse;
+ }
+ if (!build_fonts (config, root))
+ {
+ ret = FcFalse;
+ goto bail1;
+ }
+ if (!run_test (config, root))
+ {
+ ret = FcFalse;
+ goto bail1;
+ }
+
+bail1:
+ json_object_put (root);
+
+ return ret;
+}
+
+static FcBool
+load_config (FcConfig *config, char *file)
+{
+ FILE *fp;
+ long len;
+ char *buf = NULL;
+ FcBool ret = FcTrue;
+
+ if ((fp = fopen(file, "rb")) == NULL)
+ return FcFalse;
+ fseek (fp, 0L, SEEK_END);
+ len = ftell (fp);
+ fseek (fp, 0L, SEEK_SET);
+ buf = malloc (sizeof (char) * (len + 1));
+ if (!buf)
+ {
+ ret = FcFalse;
+ goto bail1;
+ }
+ fread (buf, (size_t)len, sizeof (char), fp);
+ buf[len] = 0;
+
+ ret = FcConfigParseAndLoadFromMemory (config, buf, FcTrue);
+bail1:
+ fclose (fp);
+ if (buf)
+ free (buf);
+
+ return ret;
+}
+
+int
+main (int argc, char **argv)
+{
+ FcConfig *config;
+ int retval = 0;
+
+ if (argc < 3)
+ {
+ fprintf(stderr, "Usage: %s <conf file> <test scenario>\n", argv[0]);
+ return 1;
+ }
+
+ config = FcConfigCreate ();
+ if (!load_config (config, argv[1]))
+ {
+ fprintf(stderr, "E: Failed to load config\n");
+ retval = 1;
+ goto bail1;
+ }
+ if (!run_scenario (config, argv[2]))
+ {
+ retval = 1;
+ goto bail1;
+ }
+bail1:
+ FcConfigDestroy (config);
+
+ return retval;
+}
commit 307639cff143341cb10273db1a19264ba28b247e
Author: Akira TAGOH <akira at tagoh.org>
Date: Fri May 11 20:48:30 2018 +0900
Bug 43367 - RFE: iterator to peek objects in FcPattern
Add various APIs to obtain things in FcPattern through the iterator
https://bugs.freedesktop.org/show_bug.cgi?id=43367
diff --git a/doc/fcpattern.fncs b/doc/fcpattern.fncs
index 928f0bc..3b13c22 100644
--- a/doc/fcpattern.fncs
+++ b/doc/fcpattern.fncs
@@ -57,6 +57,15 @@ Decrement the pattern reference count. If all references are gone, destroys
the pattern, in the process destroying all related values.
@@
+ at RET@ int
+ at FUNC@ FcPatternObjectCount
+ at TYPE1@ const FcPattern * @ARG1@ p
+ at PURPOSE@ Returns the number of the object
+ at DESC@
+Returns the number of the object <parameter>p</parameter> has.
+ at SINCE@ 2.13.1
+@@
+
@RET@ FcBool
@FUNC@ FcPatternEqual
@TYPE1@ const FcPattern * @ARG1@ pa
@@ -383,7 +392,107 @@ whether the property existed or not.
Removes the value associated with the property `object' at position `id', returning
whether the property existed and had a value at that position or not.
@@
-
+
+ at RET@ void
+ at FUNC@ FcPatternIterStart
+ at TYPE1@ const FcPattern * @ARG1@ p
+ at TYPE2@ FcPatternIter * @ARG2@ iter
+ at PURPOSE@ Initialize the iterator with the first iterator in the pattern
+ at DESC@
+Initialize <parameter>iter</parameter> with the first iterator in <parameter>p</parameter>.
+If there are no objects in <parameter>p</parameter>, <parameter>iter</parameter>
+will not have any valid data.
+ at SINCE@ 2.13.1
+@@
+
+ at RET@ FcBool
+ at FUNC@ FcPatternIterNext
+ at TYPE1@ const FcPattern * @ARG1@ p
+ at TYPE2@ FcPatternIter * @ARG2@ iter
+ at PURPUSE@ Set the iterator to point to the next object in the pattern
+ at DESC@
+Set <parameter>iter</parameter> to point to the next object in <parameter>p</parameter>
+and returns FcTrue if <parameter>iter</parameter> has been changed to the next object.
+returns FcFalse otherwise.
+ at SINCE@ 2.13.1
+@@
+
+ at RET@ FcBool
+ at FUNC@ FcPatternIterEqual
+ at TYPE1@ const FcPattern * @ARG1@ p1
+ at TYPE2@ FcPatternIter * @ARG2@ i1
+ at TYPE3@ const FcPattern * @ARG3@ p2
+ at TYPE4@ FcPatternIter * @ARG4@ i2
+ at PURPOSE@ Compare iterators
+ at DESC@
+Return FcTrue if both <parameter>i1</parameter> and <parameter>i2</parameter>
+point to same object and contains same values. return FcFalse otherwise.
+ at SINCE@ 2.13.1
+@@
+
+ at RET@ FcBool
+ at FUNC@ FcPatternFindIter
+ at TYPE1@ const FcPattern * @ARG1@ p
+ at TYPE2@ FcPatternIter * @ARG2@ iter
+ at TYPE3@ const char * @ARG3@ object
+ at PURPOSE@ Set the iterator to point to the object in the pattern
+ at DESC@
+Set <parameter>iter</parameter> to point to <parameter>object</parameter> in
+<parameter>p</parameter> if any and returns FcTrue. returns FcFalse otherwise.
+ at SINCE@ 2.13.1
+@@
+
+ at RET@ FcBool
+ at FUNC@ FcPatternIterIsValid
+ at TYPE1@ const FcPattern * @ARG1@ p
+ at TYPE2@ FcPatternIter : @ARG2@ iter
+ at PURPOSE@ Check whether the iterator is valid or not
+ at DESC@
+Returns FcTrue if <parameter>iter</parameter> point to the valid entry
+in <parameter>p</parameter>. returns FcFalse otherwise.
+ at SINCE@ 2.13.1
+@@
+
+ at RET@ const char *
+ at FUNC@ FcPatternIterGetObject
+ at TYPE1@ const FcPattern * @ARG1@ p
+ at TYPE2@ FcPatternIter * @ARG2@ iter
+ at PURPOSE@ Returns an object name which the iterator point to
+ at DESC@
+Returns an object name in <parameter>p</parameter> which
+<parameter>iter</parameter> point to. returns NULL if
+<parameter>iter</parameter> isn't valid.
+ at SINCE@ 2.13.1
+@@
+
+ at RET@ int
+ at FUNC@ FcPatternIterValueCount
+ at TYPE1@ const FcPattern * @ARG1@ p
+ at TYPE2@ FcPatternIter * @ARG2@ iter
+ at PURPOSE@ Returns the number of the values which the iterator point to
+ at DESC@
+Returns the number of the values in the object which <parameter>iter</parameter>
+point to. if <parameter>iter</parameter> isn't valid, returns 0.
+ at SINCE@ 2.13.1
+@@
+
+ at RET@ FcResult
+ at FUNC@ FcPatternIterGetValue
+ at TYPE1@ const FcPattern * @ARG1@ p
+ at TYPE2@ FcPatternIter * @ARG2@ iter
+ at TYPE3@ int @ARG3@ id
+ at TYPE4@ FcValue * @ARG4@ v
+ at TYPE5@ FcValueBinding * @ARG5@ b
+ at PURPOSE@ Returns a value which the iterator point to
+ at DESC@
+Returns in <parameter>v</parameter> the <parameter>id</parameter>'th value
+which <parameter>iter</parameter> point to. also binding to <parameter>b</parameter>
+if given.
+The value returned is not a copy, but rather refers to the data stored
+within the pattern directly. Applications must not free this value.
+ at SINCE@ 2.13.1
+@@
+
@RET@ void
@FUNC@ FcPatternPrint
@TYPE1@ const FcPattern * @ARG1@ p
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
index a89b22f..5c04219 100644
--- a/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig.h
@@ -248,6 +248,11 @@ typedef enum _FcValueBinding {
typedef struct _FcPattern FcPattern;
+typedef struct _FcPatternIter {
+ void *dummy1;
+ void *dummy2;
+} FcPatternIter;
+
typedef struct _FcLangSet FcLangSet;
typedef struct _FcRange FcRange;
@@ -861,6 +866,9 @@ FcValueSave (FcValue v);
FcPublic void
FcPatternDestroy (FcPattern *p);
+int
+FcPatternObjectCount (const FcPattern *pat);
+
FcPublic FcBool
FcPatternEqual (const FcPattern *pa, const FcPattern *pb);
@@ -961,6 +969,31 @@ FcRangeCopy (const FcRange *r);
FcPublic FcBool
FcRangeGetDouble(const FcRange *range, double *begin, double *end);
+FcPublic void
+FcPatternIterStart (const FcPattern *pat, FcPatternIter *iter);
+
+FcPublic FcBool
+FcPatternIterNext (const FcPattern *pat, FcPatternIter *iter);
+
+FcPublic FcBool
+FcPatternIterEqual (const FcPattern *p1, FcPatternIter *i1,
+ const FcPattern *p2, FcPatternIter *i2);
+
+FcPublic FcBool
+FcPatternFindIter (const FcPattern *pat, FcPatternIter *iter, const char *object);
+
+FcPublic FcBool
+FcPatternIterIsValid (const FcPattern *pat, FcPatternIter *iter);
+
+FcPublic const char *
+FcPatternIterGetObject (const FcPattern *pat, FcPatternIter *iter);
+
+FcPublic int
+FcPatternIterValueCount (const FcPattern *pat, FcPatternIter *iter);
+
+FcPublic FcResult
+FcPatternIterGetValue (const FcPattern *pat, FcPatternIter *iter, int id, FcValue *v, FcValueBinding *b);
+
/* fcweight.c */
FcPublic int
diff --git a/src/fcdbg.c b/src/fcdbg.c
index 2e16a31..e2c6b56 100644
--- a/src/fcdbg.c
+++ b/src/fcdbg.c
@@ -187,22 +187,21 @@ FcCharSetPrint (const FcCharSet *c)
void
FcPatternPrint (const FcPattern *p)
{
- int i;
- FcPatternElt *e;
+ FcPatternIter iter;
if (!p)
{
printf ("Null pattern\n");
return;
}
- printf ("Pattern has %d elts (size %d)\n", p->num, p->size);
- for (i = 0; i < p->num; i++)
+ printf ("Pattern has %d elts (size %d)\n", FcPatternObjectCount (p), p->size);
+ FcPatternIterStart (p, &iter);
+ do
{
- e = &FcPatternElts(p)[i];
- printf ("\t%s:", FcObjectName(e->object));
- FcValueListPrint (FcPatternEltValues(e));
+ printf ("\t%s:", FcPatternIterGetObject (p, &iter));
+ FcValueListPrint (FcPatternIterGetValues (p, &iter));
printf ("\n");
- }
+ } while (FcPatternIterNext (p, &iter));
printf ("\n");
}
diff --git a/src/fcdefault.c b/src/fcdefault.c
index 35973d7..f3addca 100644
--- a/src/fcdefault.c
+++ b/src/fcdefault.c
@@ -238,21 +238,22 @@ FcDefaultFini (void)
void
FcDefaultSubstitute (FcPattern *pattern)
{
+ FcPatternIter iter;
FcValue v, namelang, v2;
int i;
double dpi, size, scale, pixelsize;
- if (FcPatternObjectGet (pattern, FC_WEIGHT_OBJECT, 0, &v) == FcResultNoMatch )
+ if (!FcPatternFindObjectIter (pattern, &iter, FC_WEIGHT_OBJECT))
FcPatternObjectAddInteger (pattern, FC_WEIGHT_OBJECT, FC_WEIGHT_NORMAL);
- if (FcPatternObjectGet (pattern, FC_SLANT_OBJECT, 0, &v) == FcResultNoMatch)
+ if (!FcPatternFindObjectIter (pattern, &iter, FC_SLANT_OBJECT))
FcPatternObjectAddInteger (pattern, FC_SLANT_OBJECT, FC_SLANT_ROMAN);
- if (FcPatternObjectGet (pattern, FC_WIDTH_OBJECT, 0, &v) == FcResultNoMatch)
+ if (!FcPatternFindObjectIter (pattern, &iter, FC_WIDTH_OBJECT))
FcPatternObjectAddInteger (pattern, FC_WIDTH_OBJECT, FC_WIDTH_NORMAL);
for (i = 0; i < NUM_FC_BOOL_DEFAULTS; i++)
- if (FcPatternObjectGet (pattern, FcBoolDefaults[i].field, 0, &v) == FcResultNoMatch)
+ if (!FcPatternFindObjectIter (pattern, &iter, FcBoolDefaults[i].field))
FcPatternObjectAddBool (pattern, FcBoolDefaults[i].field, FcBoolDefaults[i].value);
if (FcPatternObjectGetDouble (pattern, FC_SIZE_OBJECT, 0, &size) != FcResultMatch)
@@ -269,7 +270,7 @@ FcDefaultSubstitute (FcPattern *pattern)
if (FcPatternObjectGetDouble (pattern, FC_DPI_OBJECT, 0, &dpi) != FcResultMatch)
dpi = 75.0;
- if (FcPatternObjectGet (pattern, FC_PIXEL_SIZE_OBJECT, 0, &v) != FcResultMatch)
+ if (!FcPatternFindObjectIter (pattern, &iter, FC_PIXEL_SIZE_OBJECT))
{
(void) FcPatternObjectDel (pattern, FC_SCALE_OBJECT);
FcPatternObjectAddDouble (pattern, FC_SCALE_OBJECT, scale);
@@ -281,25 +282,22 @@ FcDefaultSubstitute (FcPattern *pattern)
}
else
{
+ FcPatternIterGetValue(pattern, &iter, 0, &v, NULL);
size = v.u.d;
size = size / dpi * 72.0 / scale;
}
(void) FcPatternObjectDel (pattern, FC_SIZE_OBJECT);
FcPatternObjectAddDouble (pattern, FC_SIZE_OBJECT, size);
- if (FcPatternObjectGet (pattern, FC_FONTVERSION_OBJECT, 0, &v) == FcResultNoMatch)
- {
+ if (!FcPatternFindObjectIter (pattern, &iter, FC_FONTVERSION_OBJECT))
FcPatternObjectAddInteger (pattern, FC_FONTVERSION_OBJECT, 0x7fffffff);
- }
- if (FcPatternObjectGet (pattern, FC_HINT_STYLE_OBJECT, 0, &v) == FcResultNoMatch)
- {
+ if (!FcPatternFindObjectIter (pattern, &iter, FC_HINT_STYLE_OBJECT))
FcPatternObjectAddInteger (pattern, FC_HINT_STYLE_OBJECT, FC_HINT_FULL);
- }
- if (FcPatternObjectGet (pattern, FC_NAMELANG_OBJECT, 0, &v) == FcResultNoMatch)
- {
+
+ if (!FcPatternFindObjectIter (pattern, &iter, FC_NAMELANG_OBJECT))
FcPatternObjectAddString (pattern, FC_NAMELANG_OBJECT, FcGetDefaultLang ());
- }
+
/* shouldn't be failed. */
FcPatternObjectGet (pattern, FC_NAMELANG_OBJECT, 0, &namelang);
/* Add a fallback to ensure the english name when the requested language
@@ -315,17 +313,17 @@ FcDefaultSubstitute (FcPattern *pattern)
*/
v2.type = FcTypeString;
v2.u.s = (FcChar8 *) "en-us";
- if (FcPatternObjectGet (pattern, FC_FAMILYLANG_OBJECT, 0, &v) == FcResultNoMatch)
+ if (!FcPatternFindObjectIter (pattern, &iter, FC_FAMILYLANG_OBJECT))
{
FcPatternObjectAdd (pattern, FC_FAMILYLANG_OBJECT, namelang, FcTrue);
FcPatternObjectAddWithBinding (pattern, FC_FAMILYLANG_OBJECT, v2, FcValueBindingWeak, FcTrue);
}
- if (FcPatternObjectGet (pattern, FC_STYLELANG_OBJECT, 0, &v) == FcResultNoMatch)
+ if (!FcPatternFindObjectIter (pattern, &iter, FC_STYLELANG_OBJECT))
{
FcPatternObjectAdd (pattern, FC_STYLELANG_OBJECT, namelang, FcTrue);
FcPatternObjectAddWithBinding (pattern, FC_STYLELANG_OBJECT, v2, FcValueBindingWeak, FcTrue);
}
- if (FcPatternObjectGet (pattern, FC_FULLNAMELANG_OBJECT, 0, &v) == FcResultNoMatch)
+ if (!FcPatternFindObjectIter (pattern, &iter, FC_FULLNAMELANG_OBJECT))
{
FcPatternObjectAdd (pattern, FC_FULLNAMELANG_OBJECT, namelang, FcTrue);
FcPatternObjectAddWithBinding (pattern, FC_FULLNAMELANG_OBJECT, v2, FcValueBindingWeak, FcTrue);
diff --git a/src/fcformat.c b/src/fcformat.c
index 59f8681..c76dc5e 100644
--- a/src/fcformat.c
+++ b/src/fcformat.c
@@ -544,7 +544,7 @@ interpret_count (FcFormatContext *c,
FcStrBuf *buf)
{
int count;
- FcPatternElt *e;
+ FcPatternIter iter;
FcChar8 buf_static[64];
if (!expect_char (c, '#'))
@@ -554,16 +554,9 @@ interpret_count (FcFormatContext *c,
return FcFalse;
count = 0;
- e = FcPatternObjectFindElt (pat,
- FcObjectFromName ((const char *) c->word));
- if (e)
+ if (FcPatternFindIter (pat, &iter, (const char *) c->word))
{
- FcValueListPtr l;
- count++;
- for (l = FcPatternEltValues(e);
- l->next;
- l = l->next)
- count++;
+ count = FcPatternIterValueCount (pat, &iter);
}
snprintf ((char *) buf_static, sizeof (buf_static), "%d", count);
@@ -695,7 +688,7 @@ interpret_simple (FcFormatContext *c,
FcPattern *pat,
FcStrBuf *buf)
{
- FcPatternElt *e;
+ FcPatternIter iter;
FcBool add_colon = FcFalse;
FcBool add_elt_name = FcFalse;
int idx;
@@ -743,9 +736,7 @@ interpret_simple (FcFormatContext *c,
c->word = orig;
}
- e = FcPatternObjectFindElt (pat,
- FcObjectFromName ((const char *) c->word));
- if (e || else_string)
+ if (FcPatternFindIter (pat, &iter, (const char *) c->word) || else_string)
{
FcValueListPtr l = NULL;
@@ -757,8 +748,7 @@ interpret_simple (FcFormatContext *c,
FcStrBufChar (buf, '=');
}
- if (e)
- l = FcPatternEltValues(e);
+ l = FcPatternIterGetValues (pat, &iter);
if (idx != -1)
{
diff --git a/src/fcint.h b/src/fcint.h
index d837a38..a402ca2 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -1150,6 +1150,15 @@ FcPatternAppend (FcPattern *p, FcPattern *s);
FcPrivate int
FcPatternPosition (const FcPattern *p, const char *object);
+FcPrivate FcBool
+FcPatternFindObjectIter (const FcPattern *pat, FcPatternIter *iter, FcObject object);
+
+FcPrivate FcObject
+FcPatternIterGetObjectId (const FcPattern *pat, FcPatternIter *iter);
+
+FcPrivate FcValueListPtr
+FcPatternIterGetValues (const FcPattern *pat, FcPatternIter *iter);
+
FcPrivate FcChar32
FcStringHash (const FcChar8 *s);
diff --git a/src/fcpat.c b/src/fcpat.c
index e624aea..eb534c3 100644
--- a/src/fcpat.c
+++ b/src/fcpat.c
@@ -392,13 +392,23 @@ FcPatternDestroy (FcPattern *p)
return;
elts = FcPatternElts (p);
- for (i = 0; i < p->num; i++)
+ for (i = 0; i < FcPatternObjectCount (p); i++)
FcValueListDestroy (FcPatternEltValues(&elts[i]));
free (elts);
free (p);
}
+int
+FcPatternObjectCount (const FcPattern *pat)
+{
+ if (pat)
+ return pat->num;
+
+ return 0;
+}
+
+
static int
FcPatternObjectPosition (const FcPattern *p, FcObject object)
{
@@ -406,7 +416,7 @@ FcPatternObjectPosition (const FcPattern *p, FcObject object)
FcPatternElt *elts = FcPatternElts(p);
low = 0;
- high = p->num - 1;
+ high = FcPatternObjectCount (p) - 1;
c = 1;
mid = 0;
while (low <= high)
@@ -452,7 +462,7 @@ FcPatternObjectInsertElt (FcPattern *p, FcObject object)
i = -i - 1;
/* reallocate array */
- if (p->num + 1 >= p->size)
+ if (FcPatternObjectCount (p) + 1 >= p->size)
{
int s = p->size + 16;
if (p->size)
@@ -463,7 +473,7 @@ FcPatternObjectInsertElt (FcPattern *p, FcObject object)
{
e = malloc(s * sizeof (FcPatternElt));
if (e)
- memcpy(e, e0, p->num * sizeof (FcPatternElt));
+ memcpy(e, e0, FcPatternObjectCount (p) * sizeof (FcPatternElt));
}
}
else
@@ -484,7 +494,7 @@ FcPatternObjectInsertElt (FcPattern *p, FcObject object)
memmove (e + i + 1,
e + i,
sizeof (FcPatternElt) *
- (p->num - i));
+ (FcPatternObjectCount (p) - i));
/* bump count */
p->num++;
@@ -499,24 +509,26 @@ FcPatternObjectInsertElt (FcPattern *p, FcObject object)
FcBool
FcPatternEqual (const FcPattern *pa, const FcPattern *pb)
{
- int i;
- FcPatternElt *pae, *pbe;
+ FcPatternIter ia, ib;
if (pa == pb)
return FcTrue;
- if (pa->num != pb->num)
+ if (FcPatternObjectCount (pa) != FcPatternObjectCount (pb))
return FcFalse;
- pae = FcPatternElts(pa);
- pbe = FcPatternElts(pb);
- for (i = 0; i < pa->num; i++)
- {
- if (pae[i].object != pbe[i].object)
- return FcFalse;
- if (!FcValueListEqual (FcPatternEltValues(&pae[i]),
- FcPatternEltValues(&pbe[i])))
+ FcPatternIterStart (pa, &ia);
+ FcPatternIterStart (pb, &ib);
+ do {
+ FcBool ra, rb;
+
+ if (!FcPatternIterEqual (pa, &ia, pb, &ib))
return FcFalse;
- }
+ ra = FcPatternIterNext (pa, &ia);
+ rb = FcPatternIterNext (pb, &ib);
+ if (!ra && !rb)
+ break;
+ } while (1);
+
return FcTrue;
}
@@ -527,7 +539,7 @@ FcPatternHash (const FcPattern *p)
FcChar32 h = 0;
FcPatternElt *pe = FcPatternElts(p);
- for (i = 0; i < p->num; i++)
+ for (i = 0; i < FcPatternObjectCount (p); i++)
{
h = (((h << 1) | (h >> 31)) ^
pe[i].object ^
@@ -713,10 +725,10 @@ FcPatternObjectDel (FcPattern *p, FcObject object)
/* shuffle existing ones down */
memmove (e, e+1,
- (FcPatternElts(p) + p->num - (e + 1)) *
+ (FcPatternElts(p) + FcPatternObjectCount (p) - (e + 1)) *
sizeof (FcPatternElt));
p->num--;
- e = FcPatternElts(p) + p->num;
+ e = FcPatternElts(p) + FcPatternObjectCount (p);
e->object = 0;
e->values = NULL;
return FcTrue;
@@ -1115,8 +1127,7 @@ FcPattern *
FcPatternDuplicate (const FcPattern *orig)
{
FcPattern *new;
- FcPatternElt *e;
- int i;
+ FcPatternIter iter;
FcValueListPtr l;
if (!orig)
@@ -1126,20 +1137,18 @@ FcPatternDuplicate (const FcPattern *orig)
if (!new)
goto bail0;
- e = FcPatternElts(orig);
-
- for (i = 0; i < orig->num; i++)
+ FcPatternIterStart (orig, &iter);
+ do
{
- for (l = FcPatternEltValues(e + i); l; l = FcValueListNext(l))
+ for (l = FcPatternIterGetValues (orig, &iter); l; l = FcValueListNext (l))
{
- if (!FcPatternObjectAddWithBinding (new, e[i].object,
+ if (!FcPatternObjectAddWithBinding (new, FcPatternIterGetObjectId (orig, &iter),
FcValueCanonicalize(&l->value),
l->binding,
FcTrue))
goto bail1;
-
}
- }
+ } while (FcPatternIterNext (orig, &iter));
return new;
@@ -1184,21 +1193,21 @@ FcPatternBuild (FcPattern *p, ...)
FcBool
FcPatternAppend (FcPattern *p, FcPattern *s)
{
- int i;
- FcPatternElt *e;
- FcValueListPtr v;
+ FcPatternIter iter;
+ FcValueListPtr v;
- for (i = 0; i < s->num; i++)
+ FcPatternIterStart (s, &iter);
+ do
{
- e = FcPatternElts(s)+i;
- for (v = FcPatternEltValues(e); v; v = FcValueListNext(v))
+ for (v = FcPatternIterGetValues (s, &iter); v; v = FcValueListNext (v))
{
- if (!FcPatternObjectAddWithBinding (p, e->object,
+ if (!FcPatternObjectAddWithBinding (p, FcPatternIterGetObjectId (s, &iter),
FcValueCanonicalize(&v->value),
v->binding, FcTrue))
return FcFalse;
}
- }
+ } while (FcPatternIterNext (s, &iter));
+
return FcTrue;
}
@@ -1239,6 +1248,148 @@ bail0:
return NULL;
}
+typedef struct _FcPatternPrivateIter {
+ FcPatternElt *elt;
+ int pos;
+} FcPatternPrivateIter;
+
+static void
+FcPatternIterSet (const FcPattern *pat, FcPatternPrivateIter *iter)
+{
+ iter->elt = FcPatternObjectCount (pat) > 0 && iter->pos < FcPatternObjectCount (pat) ? &FcPatternElts (pat)[iter->pos] : NULL;
+}
+
+void
+FcPatternIterStart (const FcPattern *pat, FcPatternIter *iter)
+{
+ FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
+
+ priv->pos = 0;
+ FcPatternIterSet (pat, priv);
+}
+
+FcBool
+FcPatternIterNext (const FcPattern *pat, FcPatternIter *iter)
+{
+ FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
+
+ priv->pos++;
+ if (priv->pos >= FcPatternObjectCount (pat))
+ return FcFalse;
+ FcPatternIterSet (pat, priv);
+
+ return FcTrue;
+}
+
+FcBool
+FcPatternIterEqual (const FcPattern *p1, FcPatternIter *i1,
+ const FcPattern *p2, FcPatternIter *i2)
+{
+ FcBool b1 = FcPatternIterIsValid (p1, i1);
+ FcBool b2 = FcPatternIterIsValid (p2, i2);
+
+ if (!i1 && !i2)
+ return FcTrue;
+ if (!b1 || !b2)
+ return FcFalse;
+ if (FcPatternIterGetObjectId (p1, i1) != FcPatternIterGetObjectId (p2, i2))
+ return FcFalse;
+
+ return FcValueListEqual (FcPatternIterGetValues (p1, i1),
+ FcPatternIterGetValues (p2, i2));
+}
+
+FcBool
+FcPatternFindObjectIter (const FcPattern *pat, FcPatternIter *iter, FcObject object)
+{
+ FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
+ int i = FcPatternObjectPosition (pat, object);
+
+ priv->elt = NULL;
+ if (i < 0)
+ return FcFalse;
+
+ priv->pos = i;
+ FcPatternIterSet (pat, priv);
+
+ return FcTrue;
+}
+
+FcBool
+FcPatternFindIter (const FcPattern *pat, FcPatternIter *iter, const char *object)
+{
+ return FcPatternFindObjectIter (pat, iter, FcObjectFromName (object));
+}
+
+FcBool
+FcPatternIterIsValid (const FcPattern *pat, FcPatternIter *iter)
+{
+ FcPatternPrivateIter *priv = (FcPatternPrivateIter *)iter;
+
+ if (priv && priv->elt)
+ return FcTrue;
+
+ return FcFalse;
+}
+
+FcObject
+FcPatternIterGetObjectId (const FcPattern *pat, FcPatternIter *iter)
+{
+ FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
+
+ if (priv && priv->elt)
+ return priv->elt->object;
+
+ return 0;
+}
+
+const char *
+FcPatternIterGetObject (const FcPattern *pat, FcPatternIter *iter)
+{
+ return FcObjectName (FcPatternIterGetObjectId (pat, iter));
+}
+
+FcValueListPtr
+FcPatternIterGetValues (const FcPattern *pat, FcPatternIter *iter)
+{
+ FcPatternPrivateIter *priv = (FcPatternPrivateIter *) iter;
+
+ if (priv && priv->elt)
+ return FcPatternEltValues (priv->elt);
+
+ return NULL;
+}
+
+int
+FcPatternIterValueCount (const FcPattern *pat, FcPatternIter *iter)
+{
+ int count = 0;
+ FcValueListPtr l;
+
+ for (l = FcPatternIterGetValues (pat, iter); l; l = FcValueListNext (l))
+ count++;
+
+ return count;
+}
+
+FcResult
+FcPatternIterGetValue (const FcPattern *pat, FcPatternIter *iter, int id, FcValue *v, FcValueBinding *b)
+{
+ FcValueListPtr l;
+
+ for (l = FcPatternIterGetValues (pat, iter); l; l = FcValueListNext (l))
+ {
+ if (id == 0)
+ {
+ *v = FcValueCanonicalize (&l->value);
+ if (b)
+ *b = l->binding;
+ return FcResultMatch;
+ }
+ id--;
+ }
+ return FcResultNoId;
+}
FcBool
FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat)
@@ -1248,9 +1399,9 @@ FcPatternSerializeAlloc (FcSerialize *serialize, const FcPattern *pat)
if (!FcSerializeAlloc (serialize, pat, sizeof (FcPattern)))
return FcFalse;
- if (!FcSerializeAlloc (serialize, elts, pat->num * sizeof (FcPatternElt)))
+ if (!FcSerializeAlloc (serialize, elts, FcPatternObjectCount (pat) * sizeof (FcPatternElt)))
return FcFalse;
- for (i = 0; i < pat->num; i++)
+ for (i = 0; i < FcPatternObjectCount (pat); i++)
if (!FcValueListSerializeAlloc (serialize, FcPatternEltValues(elts+i)))
return FcFalse;
return FcTrue;
@@ -1269,7 +1420,7 @@ FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat)
if (!pat_serialized)
return NULL;
*pat_serialized = *pat;
- pat_serialized->size = pat->num;
+ pat_serialized->size = FcPatternObjectCount (pat);
FcRefSetConst (&pat_serialized->ref);
elts_serialized = FcSerializePtr (serialize, elts);
@@ -1279,7 +1430,7 @@ FcPatternSerialize (FcSerialize *serialize, const FcPattern *pat)
pat_serialized->elts_offset = FcPtrToOffset (pat_serialized,
elts_serialized);
- for (i = 0; i < pat->num; i++)
+ for (i = 0; i < FcPatternObjectCount (pat); i++)
{
values_serialized = FcValueListSerialize (serialize, FcPatternEltValues (elts+i));
if (!values_serialized)
commit 454923709a1a1e480554c400e053aea9a1ba951a
Author: Akira TAGOH <akira at tagoh.org>
Date: Thu May 10 22:01:29 2018 +0900
Change the emboldening logic again
enable emboldening when request was >= bold and font was <= medium
https://bugs.freedesktop.org/show_bug.cgi?id=106460
diff --git a/conf.d/90-synthetic.conf b/conf.d/90-synthetic.conf
index e344e4a..6b929dd 100644
--- a/conf.d/90-synthetic.conf
+++ b/conf.d/90-synthetic.conf
@@ -42,9 +42,9 @@
-->
<match target="font">
- <!-- check to see if the font is just regular -->
+ <!-- check to see if the weight in the font is less than medium which possibly need emboldening -->
<test name="weight" compare="less_eq">
- <const>regular</const>
+ <const>medium</const>
</test>
<!-- check to see if the pattern requests bold -->
<test target="pattern" name="weight" compare="more_eq">
More information about the Fontconfig
mailing list