[packages/fontconfig] add regression fixes from upstream; rel 2
atler
atler at pld-linux.org
Thu May 28 19:32:57 CEST 2026
commit 0a442c7f751503ec88e0bafc214cf4cb26aa6ebe
Author: Jan Palus <atler at pld-linux.org>
Date: Thu May 28 19:31:23 2026 +0200
add regression fixes from upstream; rel 2
https://gitlab.freedesktop.org/fontconfig/fontconfig/-/merge_requests/520
https://gitlab.freedesktop.org/fontconfig/fontconfig/-/merge_requests/521
https://gitlab.freedesktop.org/fontconfig/fontconfig/-/merge_requests/522
https://gitlab.freedesktop.org/fontconfig/fontconfig/-/merge_requests/524
fixes.patch | 1138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
fontconfig.spec | 4 +-
2 files changed, 1141 insertions(+), 1 deletion(-)
---
diff --git a/fontconfig.spec b/fontconfig.spec
index d467ed5..de69b15 100644
--- a/fontconfig.spec
+++ b/fontconfig.spec
@@ -9,7 +9,7 @@ Summary(pl.UTF-8): Narzędzia do konfigurowania fontów
Summary(pt_BR.UTF-8): Ferramentas para configuração e customização do acesso a fontes
Name: fontconfig
Version: 2.18.0
-Release: 1
+Release: 2
Epoch: 1
License: MIT
Group: Libraries
@@ -22,6 +22,7 @@ Source0: https://gitlab.freedesktop.org/api/v4/projects/890/packages/generic/fon
Source1: %{name}-lcd-filter.conf
Patch0: %{name}-bitstream-cyberbit.patch
Patch1: disable-tests.patch
+Patch2: fixes.patch
URL: http://fontconfig.org/
BuildRequires: autoconf >= 2.71
BuildRequires: automake >= 1:1.11
@@ -143,6 +144,7 @@ Este pacote contém a biblioteca estática do fontconfig
%setup -q
%patch -P0 -p1
%patch -P1 -p1
+%patch -P2 -p1
# bwrap: No permissions to creating new namespace, likely because the kernel does not allow non-privileged user namespaces...
sed -i -e 's#BWRAP=.*#BWRAP=#g' test/run-test-map.sh
diff --git a/fixes.patch b/fixes.patch
new file mode 100644
index 0000000..f2cd1a7
--- /dev/null
+++ b/fixes.patch
@@ -0,0 +1,1138 @@
+From ec3ac5609a95d9338744d2e39af3a29c6349d2d5 Mon Sep 17 00:00:00 2001
+From: Akira TAGOH <akira at tagoh.org>
+Date: Fri, 22 May 2026 08:07:00 +0900
+Subject: [PATCH] Fix not matching with a font family name
+
+Give higher priority to FC_FAMILY with the strong binding more than
+FC_GENERIC_FAMILY. So even if we add a default value for
+genericfamily in 49-sansserif.conf, a font that is actually
+available on the system will be picked up when it matches a query.
+
+https://gitlab.freedesktop.org/fontconfig/fontconfig/-/work_items/520
+
+Changelog: fixed
+---
+ src/fcmatch.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/fcmatch.c b/src/fcmatch.c
+index e0ab9503..ea6c2243 100644
+--- a/src/fcmatch.c
++++ b/src/fcmatch.c
+@@ -330,8 +330,8 @@ typedef enum _FcMatcherPriority {
+ PRI1 (COLOR),
+ PRI1 (FOUNDRY),
+ PRI1 (CHARSET),
+- PRI1 (GENERIC_FAMILY),
+ PRI_FAMILY_STRONG,
++ PRI1 (GENERIC_FAMILY),
+ PRI_POSTSCRIPT_NAME_STRONG,
+ PRI1 (LANG),
+ PRI_FAMILY_WEAK,
+--
+GitLab
+
+From 56a2f98298642ce34311a02f1299b0282f89a46b Mon Sep 17 00:00:00 2001
+From: Marcus Spencer <marcus at marcusspencer.us>
+Date: Fri, 22 May 2026 01:28:46 -0500
+Subject: [PATCH] Fix a null pointer dereference when computing a pattern from
+ a FreeType face that has no family name
+
+Changelog: fixed
+---
+ src/fcfreetype.c | 39 +++++++++++++++++++++------------------
+ 1 file changed, 21 insertions(+), 18 deletions(-)
+
+diff --git a/src/fcfreetype.c b/src/fcfreetype.c
+index c57f9b33..05c2e8a0 100644
+--- a/src/fcfreetype.c
++++ b/src/fcfreetype.c
+@@ -2080,28 +2080,31 @@ FcFreeTypeQueryFaceInternal (const FT_Face face,
+ int generic_family = FC_FAMILY_UNKNOWN;
+
+ elt = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT);
+- for (l = FcPatternEltValues (elt); l; l = FcValueListNext (l)) {
+- FcValue v = FcValueCanonicalize (&l->value);
++ if (elt) {
++ for (l = FcPatternEltValues (elt); l; l = FcValueListNext (l)) {
++ FcValue v = FcValueCanonicalize (&l->value);
+
+- if (v.type == FcTypeString) {
+- if (FcStrStrIgnoreCase (v.u.s, (FcChar8 *)"mono")) {
+- generic_family = FC_FAMILY_MONO;
+- break;
+- } else if (FcStrStrIgnoreCase (v.u.s, (FcChar8 *)"sans")) {
+- generic_family = FC_FAMILY_SANS;
+- break;
+- } else if (FcStrStrIgnoreCase (v.u.s, (FcChar8 *)"serif")) {
+- generic_family = FC_FAMILY_SERIF;
+- break;
+- } else if (FcStrStrIgnoreCase (v.u.s, (FcChar8 *)"emoji")) {
+- generic_family = FC_FAMILY_EMOJI;
+- break;
+- } else if (FcStrStrIgnoreCase (v.u.s, (FcChar8 *)"math")) {
+- generic_family = FC_FAMILY_MATH;
+- break;
++ if (v.type == FcTypeString) {
++ if (FcStrStrIgnoreCase (v.u.s, (FcChar8 *)"mono")) {
++ generic_family = FC_FAMILY_MONO;
++ break;
++ } else if (FcStrStrIgnoreCase (v.u.s, (FcChar8 *)"sans")) {
++ generic_family = FC_FAMILY_SANS;
++ break;
++ } else if (FcStrStrIgnoreCase (v.u.s, (FcChar8 *)"serif")) {
++ generic_family = FC_FAMILY_SERIF;
++ break;
++ } else if (FcStrStrIgnoreCase (v.u.s, (FcChar8 *)"emoji")) {
++ generic_family = FC_FAMILY_EMOJI;
++ break;
++ } else if (FcStrStrIgnoreCase (v.u.s, (FcChar8 *)"math")) {
++ generic_family = FC_FAMILY_MATH;
++ break;
++ }
+ }
+ }
+ }
++
+ FcPatternObjectAddInteger(pat, FC_GENERIC_FAMILY_OBJECT, generic_family);
+ }
+
+--
+GitLab
+
+From 661fb663fd37be1ff637f1eed9832a388981191e Mon Sep 17 00:00:00 2001
+From: Akira TAGOH <akira at tagoh.org>
+Date: Wed, 27 May 2026 13:24:33 +0900
+Subject: [PATCH 1/3] test-conf: Add a feature to load a certain config for
+ testing
+
+---
+ test/Makefile.am | 2 +-
+ test/meson.build | 3 ++-
+ test/test-conf.c | 60 ++++++++++++++++++++++++++++++++++++++++++++----
+ 3 files changed, 58 insertions(+), 7 deletions(-)
+
+diff --git a/test/Makefile.am b/test/Makefile.am
+index 4b6fd1e4..f6dcf2d3 100644
+--- a/test/Makefile.am
++++ b/test/Makefile.am
+@@ -104,7 +104,7 @@ TESTS += test-name-parse
+
+ if ENABLE_JSONC
+ check_PROGRAMS += test-conf
+-test_conf_CFLAGS = $(JSONC_CFLAGS)
++test_conf_CFLAGS = $(JSONC_CFLAGS) -DSRCDIR="\"$(abs_srcdir)\""
+ test_conf_LDADD = $(top_builddir)/src/libfontconfig.la $(JSONC_LIBS)
+ endif
+
+diff --git a/test/meson.build b/test/meson.build
+index 64d0035c..8bc31646 100644
+--- a/test/meson.build
++++ b/test/meson.build
+@@ -112,7 +112,8 @@ endif
+
+ if jsonc_dep.found()
+ test_conf = executable('test-conf', 'test-conf.c',
+- dependencies: [fontconfig_dep, jsonc_dep])
++ dependencies: [fontconfig_dep, jsonc_dep],
++ c_args: ['-DSRCDIR="@0@"'.format(meson.current_source_dir())])
+ endif
+
+ test_const_name = executable('test_const_name', test_const_name_c,
+diff --git a/test/test-conf.c b/test/test-conf.c
+index 8dcc367d..8709f509 100644
+--- a/test/test-conf.c
++++ b/test/test-conf.c
+@@ -53,9 +53,9 @@ int
+ setenv (const char *name, const char *value, int overwrite)
+ {
+ if (!overwrite) {
+- char *s = getenv (name);
+- if (s)
+- return 0;
++ char *s = getenv (name);
++ if (s)
++ return 0;
+ }
+ return _putenv_s (name, value);
+ }
+@@ -110,6 +110,48 @@ build_env (FcConfig *config, json_object *root)
+ return FcTrue;
+ }
+
++static FcBool
++build_config (FcConfig *config, json_object *obj)
++{
++ int n, i;
++ FcBool ret = FcTrue;
++
++ n = json_object_array_length (obj);
++ for (i = 0; i < n; i++) {
++ json_object *o = json_object_array_get_idx (obj, i);
++ char *allocated = NULL;
++ const char *s;
++ const FcChar8 *m;
++
++ if (json_object_get_type (o) != json_type_string) {
++ fprintf (stderr, "W: Invalid config item\n");
++ continue;
++ }
++ s = json_object_get_string (o);
++ if ((m = FcStrStr ((const FcChar8 *)s, (const FcChar8 *)"%test%")) != 0) {
++ size_t root_len = strlen (SRCDIR);
++ size_t len = strlen (s);
++
++ allocated = malloc (root_len + len);
++ if (!allocated)
++ return FcFalse;
++ strcpy (allocated, SRCDIR);
++ allocated[root_len] = '/';
++ strcpy (&allocated[root_len + 1], (const char *)&m[6]);
++ s = allocated;
++ }
++ ret = FcConfigParseAndLoad (config, (const FcChar8 *)s, FcTrue);
++ if (allocated) {
++ free (allocated);
++ allocated = NULL;
++ }
++ if (!ret)
++ goto bail;
++ }
++bail:
++ return ret;
++}
++
+ static FcPattern *
+ build_pattern (json_object *obj)
+ {
+@@ -416,7 +458,7 @@ bail:
+ static FcBool
+ build_fonts (FcConfig *config, json_object *root)
+ {
+- json_object *fonts, *filter, *appfonts;
++ json_object *fonts, *filter, *appfonts, *cfg_xml;
+ FcFontSet *fs;
+ FcPattern *filterpat;
+
+@@ -448,6 +490,14 @@ build_fonts (FcConfig *config, json_object *root)
+ FcFontSetDestroy (config->fonts[FcSetApplication]);
+ config->fonts[FcSetApplication] = fs;
+ }
++ if (json_object_object_get_ex (root, "load_xml", &cfg_xml)) {
++ if (json_object_get_type (cfg_xml) != json_type_array) {
++ fprintf (stderr, "W: Invalid load_xml defined\n");
++ return FcFalse;
++ }
++ if (!build_config (config, cfg_xml))
++ return FcFalse;
++ }
+
+ return FcTrue;
+ }
+@@ -695,7 +745,7 @@ process_pattern (FcConfig *config,
+ }
+ }
+ } while (FcPatternIterNext (result, &iter2));
+- bail:
++bail:
+ return fail;
+ }
+
+--
+GitLab
+
+
+From 466454b59b4110dda237001deba30be3ff77a603 Mon Sep 17 00:00:00 2001
+From: Akira TAGOH <akira at tagoh.org>
+Date: Wed, 27 May 2026 13:29:44 +0900
+Subject: [PATCH 2/3] test: Add comprehensive documentation for test-conf JSON
+ format
+
+Document the JSON schema used by test-conf for defining test scenarios,
+including all top-level fields (env, fonts, appfonts, filter, load_xml,
+tests), pattern value types, test methods, and common fontconfig properties.
+
+Assisted-By: Claude Sonnet 4.5 <noreply at anthropic.com>
+---
+ test/TEST-JSON-FORMAT.md | 482 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 482 insertions(+)
+ create mode 100644 test/TEST-JSON-FORMAT.md
+
+diff --git a/test/TEST-JSON-FORMAT.md b/test/TEST-JSON-FORMAT.md
+new file mode 100644
+index 00000000..1a1cfc14
+--- /dev/null
++++ b/test/TEST-JSON-FORMAT.md
+@@ -0,0 +1,482 @@
++# Fontconfig Test JSON Format Documentation
++
++This document describes the JSON format used by the `test-conf` test harness for testing fontconfig behavior.
++
++## Overview
++
++The test JSON format allows you to define:
++- A mock font database with specific font properties
++- Environment variables and configuration files to load
++- Test queries and expected results
++
++## Top-Level Structure
++
++```json
++{
++ "env": { ... },
++ "fonts": [ ... ],
++ "appfonts": [ ... ],
++ "filter": { ... },
++ "load_xml": [ ... ],
++ "tests": [ ... ]
++}
++```
++
++### Fields
++
++#### `env` (optional)
++Type: Object
++
++Environment variables to set before running tests. Special key `"locale"` calls `setlocale()` instead of `setenv()`.
++
++**Example:**
++```json
++{
++ "env": {
++ "locale": "de_DE.UTF-8",
++ "FC_DEBUG": "1"
++ }
++}
++```
++
++#### `fonts` (required)
++Type: Array of Pattern objects
++
++Defines the system font database. Each entry represents a font with its properties.
++
++**Example:**
++```json
++{
++ "fonts": [
++ {
++ "family": "Noto Sans",
++ "style": "Regular",
++ "file": "/path/to/NotoSans.ttf",
++ "fontversion": 1
++ }
++ ]
++}
++```
++
++#### `appfonts` (optional)
++Type: Array of Pattern objects
++
++Defines application-level fonts, which can take precedence over system fonts depending on configuration.
++
++**Example:**
++```json
++{
++ "appfonts": [
++ {
++ "family": "Custom Font",
++ "file": "/app/path/to/CustomFont.ttf",
++ "fontversion": 2
++ }
++ ]
++}
++```
++
++#### `filter` (optional)
++Type: Pattern object
++
++A pattern used to filter which fonts from the `fonts` array are actually included in the font set. Only fonts matching all properties in the filter pattern are included.
++
++**Example:**
++```json
++{
++ "filter": {
++ "fontwrapper": "SFNT"
++ }
++}
++```
++
++#### `load_xml` (optional)
++Type: Array of strings
++
++List of fontconfig XML configuration files to load and apply. Use `%test%` as a placeholder for the test directory (defined by SRCDIR).
++
++**Example:**
++```json
++{
++ "load_xml": [
++ "conf.d/48-guessfamily.conf",
++ "conf.d/49-sansserif.conf",
++ "%test%/test-custom.conf"
++ ]
++}
++```
++
++#### `tests` (required)
++Type: Array of Test objects
++
++Test cases to execute against the configured fontconfig instance.
++
++## Pattern Object Format
++
++Patterns are used in `fonts`, `appfonts`, `filter`, test `query`, and test `result` objects. A pattern is a JSON object where keys are fontconfig property names and values specify the property values.
++
++### Value Types
++
++#### String Values
++
++Simple string properties:
++```json
++{
++ "family": "Noto Sans",
++ "style": "Regular",
++ "file": "/path/to/font.ttf"
++}
++```
++
++For properties that expect constants (like `weight`, `slant`, `width`), you can use constant names:
++```json
++{
++ "weight": "bold",
++ "slant": "italic",
++ "width": "condensed"
++}
++```
++
++Special string value:
++- `"DontCare"`: Represents the FcDontCare boolean value
++
++#### Numeric Values
++
++Integer or double values:
++```json
++{
++ "fontversion": 1,
++ "size": 12.5,
++ "weight": 200,
++ "index": 0
++}
++```
++
++#### Boolean Values
++
++```json
++{
++ "scalable": true,
++ "variable": false,
++ "namedinstance": false,
++ "embolden": true
++}
++```
++
++#### Null Values
++
++```json
++{
++ "embolden": null
++}
++```
++
++#### Array Values
++
++Arrays are interpreted based on the property type and array content:
++
++**String Arrays** (for properties like `family`, `style`):
++```json
++{
++ "family": ["Noto Sans", "sans-serif"],
++ "style": ["Regular", "Normal"]
++}
++```
++
++**Charset Arrays** (for `charset` property):
++Each element is a single UTF-8 character (codepoint):
++```json
++{
++ "charset": ["a", "b", "c", "あ", "😀"]
++}
++```
++
++**LangSet Arrays** (for `lang` property):
++Each element is a language code:
++```json
++{
++ "lang": ["en", "de", "ja"]
++}
++```
++
++**Integer Arrays** (for properties like `weight` when multiple values needed):
++```json
++{
++ "weight": [80, 100, 200]
++}
++```
++Can also use constant names:
++```json
++{
++ "weight": ["light", "medium", "bold"]
++}
++```
++
++**Double Arrays** (for properties expecting multiple double values):
++```json
++{
++ "dpi": [96.0, 120.0]
++}
++```
++
++**Range Arrays** (2-element numeric array):
++```json
++{
++ "size": [8.0, 48.0]
++}
++```
++
++**Matrix Arrays** (4-element numeric array `[xx, xy, yx, yy]`):
++```json
++{
++ "matrix": [1.0, 0.0, 0.0, 1.0]
++}
++```
++
++## Test Object Format
++
++```json
++{
++ "method": "match",
++ "config": { ... },
++ "query": { ... },
++ "result": { ... },
++ "result_fs": [ ... ],
++ "$comment": "Optional comment"
++}
++```
++
++### Fields
++
++#### `method` (required)
++Type: String
++
++The test method to use. Valid values:
++- `"match"`: Test `FcFontMatch()` - find the best matching font
++- `"list"`: Test `FcFontList()` - list all fonts matching a pattern
++- `"sort"`: Test `FcFontSort()` with trimming - sorted list of matching fonts (trimmed)
++- `"sort_all"`: Test `FcFontSort()` without trimming - sorted list of all matching fonts
++- `"pattern"`: Test `FcConfigSubstitute()` - pattern substitution without font matching
++
++#### `config` (optional)
++Type: Object
++
++Per-test configuration options applied before running the test.
++
++**Supported options:**
++- `"prefer_app_font"`: Boolean - whether to prefer application fonts over system fonts
++
++**Example:**
++```json
++{
++ "config": {
++ "prefer_app_font": true
++ }
++}
++```
++
++#### `query` (required)
++Type: Pattern object
++
++The input pattern for the query.
++
++**Example:**
++```json
++{
++ "query": {
++ "family": "Noto Sans",
++ "weight": "bold",
++ "size": 12.0
++ }
++}
++```
++
++#### `result` (required for `match` and `pattern` methods)
++Type: Pattern object
++
++The expected result pattern. The test verifies that all properties specified in this pattern match the corresponding properties in the actual result.
++
++**Example:**
++```json
++{
++ "result": {
++ "family": "Noto Sans",
++ "file": "/path/to/NotoSans-Bold.ttf",
++ "weight": 200
++ }
++}
++```
++
++#### `result_fs` (required for `list`, `sort`, and `sort_all` methods)
++Type: Array of Pattern objects
++
++The expected result font set. The test verifies:
++1. The number of results matches
++2. Each result pattern matches the expected pattern at the same index
++
++**Example:**
++```json
++{
++ "result_fs": [
++ {
++ "family": "Noto Sans",
++ "file": "/path/to/NotoSans-Regular.ttf"
++ },
++ {
++ "family": "Noto Sans",
++ "file": "/path/to/NotoSans-Bold.ttf"
++ }
++ ]
++}
++```
++
++#### `$comment` (optional)
++Type: String
++
++A comment field that is ignored by the test runner. Use for documentation purposes.
++
++**Example:**
++```json
++{
++ "$comment": "This test verifies that bold synthesis works correctly"
++}
++```
++
++## Common Pattern Properties
++
++Here are commonly used fontconfig properties you can use in patterns:
++
++### Font Identification
++- `family`: String or Array - Font family name(s)
++- `style`: String or Array - Font style name(s)
++- `fullname`: String - Full font name
++- `file`: String - Font file path
++- `index`: Integer - Font index in collection
++
++### Font Attributes
++- `weight`: Integer or Constant - Font weight (0-215, or "thin", "light", "medium", "bold", "black", etc.)
++- `slant`: Integer or Constant - Font slant ("roman", "italic", "oblique")
++- `width`: Integer or Constant - Font width ("condensed", "normal", "expanded", etc.)
++- `size`: Double or Range - Font size in points
++- `pixelsize`: Double or Range - Font size in pixels
++- `fontversion`: Integer - Font version number
++
++### Font Capabilities
++- `scalable`: Boolean - Whether font is scalable
++- `outline`: Boolean - Whether font has outlines
++- `color`: Boolean - Whether font has color glyphs
++- `variable`: Boolean - Whether font is a variable font
++- `namedinstance`: Boolean - Whether font is a named instance
++
++### Character Support
++- `charset`: Array of characters - Supported characters
++- `lang`: String or Array - Supported language(s)
++
++### Typography
++- `spacing`: Integer or Constant - Character spacing ("proportional", "mono", "charcell")
++- `fontformat`: String - Font format ("TrueType", "Type 1", "CFF", etc.)
++- `fontwrapper`: String - Font wrapper format ("SFNT", "CFF", "WOFF", etc.)
++
++### Rendering
++- `antialias`: Boolean - Whether to antialias
++- `hinting`: Boolean - Whether to hint
++- `hintstyle`: Integer or Constant - Hint style ("none", "slight", "medium", "full")
++- `rgba`: Integer or Constant - Subpixel order ("none", "rgb", "bgr", "vrgb", "vbgr")
++- `embolden`: Boolean or Null - Whether to embolden (synthetic bold)
++- `matrix`: Array[4] - Transformation matrix
++
++### Advanced
++- `dpi`: Double - DPI setting
++- `genericfamily`: Integer or Constant - Generic family ("serif", "sans-serif", "monospace", etc.)
++- `fontvariations`: String - Font variation settings (e.g., "wght=400,wdth=100")
++
++## Complete Example
++
++```json
++{
++ "env": {
++ "locale": "en_US.UTF-8"
++ },
++ "fonts": [
++ {
++ "family": "Noto Sans",
++ "style": "Regular",
++ "file": "/path/to/NotoSans-Regular.ttf",
++ "weight": 80,
++ "slant": "roman",
++ "fontversion": 1,
++ "scalable": true,
++ "outline": true
++ },
++ {
++ "family": "Noto Sans",
++ "style": "Bold",
++ "file": "/path/to/NotoSans-Bold.ttf",
++ "weight": 200,
++ "slant": "roman",
++ "fontversion": 1,
++ "scalable": true,
++ "outline": true
++ }
++ ],
++ "load_xml": [
++ "conf.d/10-autohint.conf",
++ "conf.d/10-hinting-slight.conf"
++ ],
++ "tests": [
++ {
++ "$comment": "Test that bold weight request matches bold font",
++ "method": "match",
++ "query": {
++ "family": "Noto Sans",
++ "weight": "bold"
++ },
++ "result": {
++ "family": "Noto Sans",
++ "file": "/path/to/NotoSans-Bold.ttf",
++ "weight": 200
++ }
++ },
++ {
++ "$comment": "Test that listing returns all Noto Sans variants",
++ "method": "list",
++ "query": {
++ "family": "Noto Sans"
++ },
++ "result_fs": [
++ {
++ "family": "Noto Sans",
++ "file": "/path/to/NotoSans-Regular.ttf"
++ },
++ {
++ "family": "Noto Sans",
++ "file": "/path/to/NotoSans-Bold.ttf"
++ }
++ ]
++ }
++ ]
++}
++```
++
++## Usage
++
++To run a test:
++
++```bash
++test-conf <config-file> <test-json-file>
++```
++
++Where:
++- `<config-file>`: Base fontconfig configuration file (XML format)
++- `<test-json-file>`: Test scenario file (JSON format described in this document)
++
++The test harness will:
++1. Create a fontconfig configuration instance
++2. Load the base config file
++3. Set environment variables from `env`
++4. Build the mock font database from `fonts` and `appfonts`
++5. Apply the `filter` if specified
++6. Load additional config files from `load_xml`
++7. Execute each test in `tests` and verify results
++
++Exit code is 0 if all tests pass, non-zero otherwise.
+--
+GitLab
+
+
+From e17806afda817cf8ba2fe6e0d063617994dcdc0f Mon Sep 17 00:00:00 2001
+From: Akira TAGOH <akira at tagoh.org>
+Date: Wed, 27 May 2026 13:36:49 +0900
+Subject: [PATCH 3/3] Fix another font matching issue
+
+Do not score genericfamily by difference. it isn't like other properties.
+If it doesn't match, the matching decision should simply leaves to the next
+property.
+So we can't use FcCompareNumber for this.
+
+Fixes https://gitlab.freedesktop.org/fontconfig/fontconfig/-/work_items/525
+
+Changelog: fixed
+---
+ src/fcmatch.c | 36 ++++++++++++++++++++++++++++++++++++
+ src/fcobjs.h | 2 +-
+ test/test-issue-525.conf | 8 ++++++++
+ test/test-issue-525.json | 38 ++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 83 insertions(+), 1 deletion(-)
+ create mode 100644 test/test-issue-525.conf
+ create mode 100644 test/test-issue-525.json
+
+diff --git a/src/fcmatch.c b/src/fcmatch.c
+index ea6c2243..1adbbdc2 100644
+--- a/src/fcmatch.c
++++ b/src/fcmatch.c
+@@ -164,6 +164,41 @@ FcCompareBool (const FcValue *v1, const FcValue *v2, FcValue *bestValue)
+ return (double)((v2->u.b ^ v1->u.b) == 1);
+ }
+
++static double
++FcCompareEqual (const FcValue *value1, const FcValue *value2, FcValue *bestValue)
++{
++ double v1, v2, v;
++
++ switch ((int)value1->type) {
++ case FcTypeInteger:
++ v1 = (double)value1->u.i;
++ break;
++ case FcTypeDouble:
++ v1 = value1->u.d;
++ break;
++ case FcTypeBool:
++ return FcCompareBool (value1, value2, bestValue);
++ default:
++ return -1.0;
++ }
++ switch ((int)value2->type) {
++ case FcTypeInteger:
++ v2 = (double)value2->u.i;
++ break;
++ case FcTypeDouble:
++ v2 = value2->u.d;
++ break;
++ case FcTypeBool:
++ return FcCompareBool (value1, value2, bestValue);
++ default:
++ return -1.0;
++ }
++ v = !(v1 == v2);
++ *bestValue = FcValueCanonicalize (value2);
++
++ return v;
++}
++
+ static double
+ FcCompareCharSet (const FcValue *v1, const FcValue *v2, FcValue *bestValue)
+ {
+@@ -296,6 +331,7 @@ FcCompareFilename (const FcValue *v1, const FcValue *v2, FcValue *bestValue)
+ #define PRI_FcCompareFamily(n) PRI1 (n)
+ #define PRI_FcCompareString(n) PRI1 (n)
+ #define PRI_FcCompareNumber(n) PRI1 (n)
++#define PRI_FcCompareEqual(n) PRI1 (n)
+ #define PRI_FcCompareBool(n) PRI1 (n)
+ #define PRI_FcCompareFilename(n) PRI1 (n)
+ #define PRI_FcCompareCharSet(n) PRI1 (n)
+diff --git a/src/fcobjs.h b/src/fcobjs.h
+index 1de0ad0e..bace9a96 100644
+--- a/src/fcobjs.h
++++ b/src/fcobjs.h
+@@ -77,5 +77,5 @@ FC_OBJECT (ORDER, FcTypeInteger, FcCompareNumber)
+ FC_OBJECT (DESKTOP_NAME, FcTypeString, NULL)
+ FC_OBJECT (NAMED_INSTANCE, FcTypeBool, FcCompareBool)
+ FC_OBJECT (FONT_WRAPPER, FcTypeString, FcCompareString)
+-FC_OBJECT (GENERIC_FAMILY, FcTypeInteger, FcCompareNumber)
++FC_OBJECT (GENERIC_FAMILY, FcTypeInteger, FcCompareEqual)
+ /* ^-------------- Add new objects here. */
+diff --git a/test/test-issue-525.conf b/test/test-issue-525.conf
+new file mode 100644
+index 00000000..31eb2fd1
+--- /dev/null
++++ b/test/test-issue-525.conf
+@@ -0,0 +1,8 @@
++<fontconfig>
++ <alias>
++ <family>system-ui</family>
++ <prefer>
++ <family>Lato</family>
++ </prefer>
++ </alias>
++</fontconfig>
+diff --git a/test/test-issue-525.json b/test/test-issue-525.json
+new file mode 100644
+index 00000000..86e9890e
+--- /dev/null
++++ b/test/test-issue-525.json
+@@ -0,0 +1,38 @@
++{
++ "fonts": [
++ {
++ "family": "Noto Sans",
++ "style": "Regular",
++ "file": "/path/to/NotoSans.ttf",
++ "fontversion": 1,
++ "genericfamily": 1
++ },
++ {
++ "family": "Lato",
++ "style": "Regular",
++ "file": "/path/to/Lato.ttf",
++ "fontversion": 1,
++ "genericfamily": 0
++ }
++ ],
++ "load_xml": [
++ "conf.d/48-guessfamily.conf",
++ "conf.d/49-sansserif.conf",
++ "conf.d/60-latin.conf",
++ "%test%/test-issue-525.conf",
++ ],
++ "tests": [
++ {
++ "method": "match",
++ "query": {
++ "family": "system-ui"
++ },
++ "result": {
++ "family": "Lato",
++ "style": "Regular",
++ "file": "/path/to/Lato.ttf",
++ "fontversion": 1
++ }
++ }
++ ]
++}
+--
+GitLab
+
+From 66757ccdbd43260bba3195265311cf8ca268f0d4 Mon Sep 17 00:00:00 2001
+From: Akira TAGOH <akira at tagoh.org>
+Date: Thu, 28 May 2026 12:56:25 +0900
+Subject: [PATCH 1/2] Do not set 'sans-serif' for default genericfamily
+
+To allow a custom family name for alias.
+
+Changelog: fixed
+---
+ conf.d/49-sansserif.conf | 21 ---------------------
+ test/test-issue-525-2.conf | 8 ++++++++
+ test/test-issue-525-2.json | 38 ++++++++++++++++++++++++++++++++++++++
+ test/test-issue-525.json | 2 +-
+ 4 files changed, 47 insertions(+), 22 deletions(-)
+ create mode 100644 test/test-issue-525-2.conf
+ create mode 100644 test/test-issue-525-2.json
+
+diff --git a/conf.d/49-sansserif.conf b/conf.d/49-sansserif.conf
+index 8446b235..b6f8f713 100644
+--- a/conf.d/49-sansserif.conf
++++ b/conf.d/49-sansserif.conf
+@@ -45,27 +45,6 @@
+ </edit>
+ </match>
+
+- <!--
+- If the font still has no generic name, add sans-serif
+- -->
+- <match target="pattern">
+- <test qual="all" name="family" compare="not_eq">
+- <string>sans-serif</string>
+- </test>
+- <test qual="all" name="family" compare="not_eq">
+- <string>serif</string>
+- </test>
+- <test qual="all" name="family" compare="not_eq">
+- <string>monospace</string>
+- </test>
+- <test qual="all" name="genericfamily" compare="contains">
+- <const xsi:nil="true" />
+- </test>
+- <edit name="genericfamily" mode="append">
+- <const>sans-serif</const>
+- </edit>
+- </match>
+-
+ <match target="pattern">
+ <test qual="all" name="family" compare="not_eq">
+ <string>sans-serif</string>
+diff --git a/test/test-issue-525-2.conf b/test/test-issue-525-2.conf
+new file mode 100644
+index 00000000..8531931c
+--- /dev/null
++++ b/test/test-issue-525-2.conf
+@@ -0,0 +1,8 @@
++<fontconfig>
++ <alias>
++ <family>-apple-system</family>
++ <prefer>
++ <family>Lato</family>
++ </prefer>
++ </alias>
++</fontconfig>
+diff --git a/test/test-issue-525-2.json b/test/test-issue-525-2.json
+new file mode 100644
+index 00000000..cf410cab
+--- /dev/null
++++ b/test/test-issue-525-2.json
+@@ -0,0 +1,38 @@
++{
++ "fonts": [
++ {
++ "family": "Noto Sans",
++ "style": "Regular",
++ "file": "/path/to/NotoSans.ttf",
++ "fontversion": 1,
++ "genericfamily": 2
++ },
++ {
++ "family": "Lato",
++ "style": "Regular",
++ "file": "/path/to/Lato.ttf",
++ "fontversion": 1,
++ "genericfamily": 0
++ }
++ ],
++ "load_xml": [
++ "conf.d/48-guessfamily.conf",
++ "conf.d/49-sansserif.conf",
++ "%test%/test-issue-525-2.conf",
++ "conf.d/60-latin.conf",
++ ],
++ "tests": [
++ {
++ "method": "match",
++ "query": {
++ "family": "-apple-system",
++ },
++ "result": {
++ "family": "Lato",
++ "style": "Regular",
++ "file": "/path/to/Lato.ttf",
++ "fontversion": 1
++ }
++ }
++ ]
++}
+diff --git a/test/test-issue-525.json b/test/test-issue-525.json
+index 86e9890e..cf61dc19 100644
+--- a/test/test-issue-525.json
++++ b/test/test-issue-525.json
+@@ -18,8 +18,8 @@
+ "load_xml": [
+ "conf.d/48-guessfamily.conf",
+ "conf.d/49-sansserif.conf",
+- "conf.d/60-latin.conf",
+ "%test%/test-issue-525.conf",
++ "conf.d/60-latin.conf",
+ ],
+ "tests": [
+ {
+--
+GitLab
+
+
+From 31d3b16c97f8965eec7e3361015b3cb10910fc12 Mon Sep 17 00:00:00 2001
+From: Akira TAGOH <akira at tagoh.org>
+Date: Thu, 28 May 2026 13:00:06 +0900
+Subject: [PATCH 2/2] test: use const instead of number for genericfamily
+
+---
+ test/test-48-guessfamily.json | 16 ++++++++--------
+ test/test-issue-525-2.json | 2 +-
+ test/test-issue-525.json | 2 +-
+ 3 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/test/test-48-guessfamily.json b/test/test-48-guessfamily.json
+index 7dedbf81..01fe8e1f 100644
+--- a/test/test-48-guessfamily.json
++++ b/test/test-48-guessfamily.json
+@@ -5,28 +5,28 @@
+ "style": "Regular",
+ "file": "/path/to/LiberationMono-Regular.ttf",
+ "fontversion": 1,
+- "genericfamily": 3
++ "genericfamily": "monospace"
+ },
+ {
+ "family": "Liberation Sans",
+ "style": "Regular",
+ "file": "/path/to/LiberationSans-Regular.ttf",
+ "fontversion": 1,
+- "genericfamily": 2
++ "genericfamily": "sans-serif"
+ },
+ {
+ "family": "Liberation Serif",
+ "style": "Regular",
+ "file": "/path/to/LiberationSerif-Regular.ttf",
+ "fontversion": 1,
+- "genericfamily": 1
++ "genericfamily": "serif"
+ },
+ {
+ "family": "Noto Sans Mono",
+ "style": "Regular",
+ "file": "/path/to/NotoSansMono-Regular.ttf",
+ "fontversion": 1,
+- "genericfamily": 3
++ "genericfamily": "monospace"
+ },
+ ],
+ "tests": [
+@@ -40,7 +40,7 @@
+ "style": "Regular",
+ "file": "/path/to/LiberationMono-Regular.ttf",
+ "fontversion": 1,
+- "genericfamily": 3
++ "genericfamily": "monospace"
+ }
+ },
+ {
+@@ -53,7 +53,7 @@
+ "style": "Regular",
+ "file": "/path/to/LiberationSans-Regular.ttf",
+ "fontversion": 1,
+- "genericfamily": 2
++ "genericfamily": "sans-serif"
+ }
+ },
+ {
+@@ -66,7 +66,7 @@
+ "style": "Regular",
+ "file": "/path/to/LiberationSerif-Regular.ttf",
+ "fontversion": 1,
+- "genericfamily": 1
++ "genericfamily": "serif"
+ }
+ },
+ {
+@@ -79,7 +79,7 @@
+ "style": "Regular",
+ "file": "/path/to/LiberationSans-Regular.ttf",
+ "fontversion": 1,
+- "genericfamily": 2
++ "genericfamily": "sans-serif"
+ }
+ },
+ {
+diff --git a/test/test-issue-525-2.json b/test/test-issue-525-2.json
+index cf410cab..ccf0e90f 100644
+--- a/test/test-issue-525-2.json
++++ b/test/test-issue-525-2.json
+@@ -5,7 +5,7 @@
+ "style": "Regular",
+ "file": "/path/to/NotoSans.ttf",
+ "fontversion": 1,
+- "genericfamily": 2
++ "genericfamily": "sans-serif"
+ },
+ {
+ "family": "Lato",
+diff --git a/test/test-issue-525.json b/test/test-issue-525.json
+index cf61dc19..ba8e3332 100644
+--- a/test/test-issue-525.json
++++ b/test/test-issue-525.json
+@@ -5,7 +5,7 @@
+ "style": "Regular",
+ "file": "/path/to/NotoSans.ttf",
+ "fontversion": 1,
+- "genericfamily": 1
++ "genericfamily": "sans-serif"
+ },
+ {
+ "family": "Lato",
+--
+GitLab
+
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/fontconfig.git/commitdiff/0a442c7f751503ec88e0bafc214cf4cb26aa6ebe
More information about the pld-cvs-commit
mailing list