fontconfig: Branch 'main' - 2 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Nov 27 11:04:40 UTC 2024


 .gitlab-ci.yml                   |   31 +++++++++++++++++++---
 .gitlab-ci/build.sh              |    6 ++--
 .gitlab-ci/config.yml            |    9 ++++++
 .gitlab-ci/other.yml             |   25 +++++++++++++-----
 Cargo.lock                       |   24 +++++++++++++++++
 Cargo.toml                       |   10 +++++++
 fc-fontations-bindgen/Cargo.lock |    7 +++++
 fc-fontations-bindgen/Cargo.toml |   10 +++++++
 fc-fontations-bindgen/build.rs   |   34 +++++++++++++++++++++++++
 fc-fontations/meson.build        |   53 +++++++++++++++++++++++++++++++++++++++
 fc-fontations/mod.rs             |   41 ++++++++++++++++++++++++++++++
 meson.build                      |   15 +++++++++--
 meson_options.txt                |    2 +
 test/meson.build                 |    6 ++++
 14 files changed, 258 insertions(+), 15 deletions(-)

New commits:
commit 712c5be5802790dfd20ac809313878e316cb8396
Merge: 00a779b 3b291c2
Author: Akira TAGOH <akira at tagoh.org>
Date:   Wed Nov 27 11:04:37 2024 +0000

    Merge branch 'optionBindGenBuild' into 'main'
    
    [Fontations] Build bindgen targets, basic Rust test
    
    Closes #435
    
    See merge request fontconfig/fontconfig!349

commit 3b291c2a19e7e51cedd833a2280f699a44b575d7
Author: Dominik Röttsches <drott at chromium.org>
Date:   Tue Nov 26 16:50:07 2024 +0200

    [Fontations] Build bindgen targets, basic Rust test
    
    Define meson bindgen steps that form a bindgen Rust library
    that allows calling back to typical FontConfig functions for
    constructing FcPatterns and adding them to an FcFontSet.
    
    Add a basic Rust test that demonstrates it's possible to
    call back to Fontconfig. Enable execution of this test
    through:
        meson test -C build
    as well as through:
        cargo test
    
    Part of #434.

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ed7bbdc..228fc6e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -41,8 +41,8 @@ variables:
 # changing these will force rebuilding the associated image
 # Note: these tags have no meaning and are not tied to a particular
 # fontconfig version
-  FEDORA_TAG:    '2024-11-13.2-18d71ad2cf03'
-  FREEBSD_TAG:   '2024-11-13.2-c197d92cb6b7'
+  FEDORA_TAG:    '2024-11-13.2-3bd7920ce40a'
+  FREEBSD_TAG:   '2024-11-13.2-f272a7918d7b'
 
   FEDORA_EXEC:   'bash .gitlab-ci/fedora-install.sh'
   FREEBSD_EXEC:  'bash .gitlab-ci/freebsd-install.sh'
@@ -96,7 +96,7 @@ fedora:rawhide at container-prep:
   variables:
     GIT_STRATEGY: none
     FDO_DISTRIBUTION_VERSION: 'rawhide'
-    FDO_DISTRIBUTION_PACKAGES: '@buildsys-build autoconf automake libtool gettext gettext-devel gperf expat-devel libxml2-devel freetype-devel json-c-devel git docbook-utils docbook-utils-pdf bubblewrap ninja-build wget python3-pip mingw64-expat mingw64-gcc mingw64-gettext mingw64-freetype mingw64-libxml2 wine rust cargo'
+    FDO_DISTRIBUTION_PACKAGES: '@buildsys-build autoconf automake clang-devel libtool gettext gettext-devel gperf expat-devel libxml2-devel freetype-devel json-c-devel git docbook-utils docbook-utils-pdf bubblewrap ninja-build wget python3-pip mingw64-expat mingw64-gcc mingw64-gettext mingw64-freetype mingw64-libxml2 wine rust cargo bindgen-cli'
     FDO_DISTRIBUTION_TAG: $FEDORA_TAG
     FDO_DISTRIBUTION_EXEC: $FEDORA_EXEC
 
@@ -106,7 +106,7 @@ fedora:41 at container-prep:
   variables:
     GIT_STRATEGY: none
     FDO_DISTRIBUTION_VERSION: '41'
-    FDO_DISTRIBUTION_PACKAGES: '@buildsys-build autoconf automake libtool gettext gettext-devel gperf expat-devel libxml2-devel freetype-devel json-c-devel git docbook-utils docbook-utils-pdf bubblewrap ninja-build wget python3-pip mingw64-expat mingw64-gcc mingw64-gettext mingw64-freetype mingw64-libxml2 wine rust cargo'
+    FDO_DISTRIBUTION_PACKAGES: '@buildsys-build autoconf automake clang-devel libtool gettext gettext-devel gperf expat-devel libxml2-devel freetype-devel json-c-devel git docbook-utils docbook-utils-pdf bubblewrap ninja-build wget python3-pip mingw64-expat mingw64-gcc mingw64-gettext mingw64-freetype mingw64-libxml2 wine rust cargo bindgen-cli'
     FDO_DISTRIBUTION_TAG: $FEDORA_TAG
     FDO_DISTRIBUTION_EXEC: $FEDORA_EXEC
 
@@ -116,7 +116,7 @@ fedora:40 at container-prep:
   variables:
     GIT_STRATEGY: none
     FDO_DISTRIBUTION_VERSION: '40'
-    FDO_DISTRIBUTION_PACKAGES: '@buildsys-build autoconf automake libtool gettext gettext-devel gperf expat-devel libxml2-devel freetype-devel json-c-devel git docbook-utils docbook-utils-pdf bubblewrap ninja-build wget python3-pip mingw64-expat mingw64-gcc mingw64-gettext mingw64-freetype mingw64-libxml2 wine rust cargo'
+    FDO_DISTRIBUTION_PACKAGES: '@buildsys-build autoconf automake clang-devel libtool gettext gettext-devel gperf expat-devel libxml2-devel freetype-devel json-c-devel git docbook-utils docbook-utils-pdf bubblewrap ninja-build wget python3-pip mingw64-expat mingw64-gcc mingw64-gettext mingw64-freetype mingw64-libxml2 wine rust cargo bindgen-cli'
     FDO_DISTRIBUTION_TAG: $FEDORA_TAG
     FDO_DISTRIBUTION_EXEC: $FEDORA_EXEC
 
@@ -471,6 +471,23 @@ t_fedora:rawhide:mingw meson static expat:
     - 'fedora:rawhide at container-prep'
 
 
+t_fedora:rawhide:meson static libxml2 fontations:
+  extends:
+    - .build at template
+    - .fdo.distribution-image at fedora
+    - .fc_artifacts
+  variables:
+    FC_DISTRO_NAME: fedora
+    FDO_DISTRIBUTION_VERSION: 'rawhide'
+    FDO_DISTRIBUTION_TAG: $FEDORA_TAG
+    FC_BUILDSYS: meson
+    FC_BUILD_TYPE: static
+    FC_XML_BACKEND: libxml2
+    FC_BUILD_ENABLED: fontations
+  needs:
+    - 'fedora:rawhide at container-prep'
+
+
 t_fedora:41:autotools shared expat:
   extends:
     - .build at template
@@ -548,6 +565,8 @@ t_fedora:41:meson shared libxml2:
 
 
 
+
+
 t_fedora:40:autotools shared expat:
   extends:
     - .build at template
@@ -641,6 +660,8 @@ t_fedora:40:mingw autotools static libxml2:
 
 
 
+
+
 t_freebsd:14.1:autotools shared expat:
   extends:
     - .build-in-qemu at template
diff --git a/.gitlab-ci/build.sh b/.gitlab-ci/build.sh
index d568644..932b042 100755
--- a/.gitlab-ci/build.sh
+++ b/.gitlab-ci/build.sh
@@ -106,11 +106,13 @@ if [ x"$buildsys" == "xautotools" ]; then
     fi
 elif [ x"$buildsys" == "xmeson" ]; then
     pip install meson
+#   tomli not required for Python >= 3.11
+    pip install tomli
     for i in "${enable[@]}"; do
-        buildopt+=(-D$i=true)
+        buildopt+=(-D$i=enabled)
     done
     for i in "${disable[@]}"; do
-        buildopt+=(-D$i=false)
+        buildopt+=(-D$i=disabled)
     done
     case x"$backend" in
         'xexpat')
diff --git a/.gitlab-ci/config.yml b/.gitlab-ci/config.yml
index 47a0283..426ea6a 100644
--- a/.gitlab-ci/config.yml
+++ b/.gitlab-ci/config.yml
@@ -72,6 +72,13 @@ distributions:
           FC_BUILD_PLATFORM: mingw
           FC_BUILD_ARCH: linux-mingw-w64-64bit
           FC_BUILD_NO_INSTALL: 1
+      - name: "meson static libxml2 fontations"
+        build_only: "rawhide"
+        variables:
+          FC_BUILDSYS: meson
+          FC_BUILD_TYPE: static
+          FC_XML_BACKEND: libxml2
+          FC_BUILD_ENABLED: "fontations"
   - name: freebsd
     tag: *default_tag
     base_type: freebsd
@@ -113,6 +120,7 @@ packages:
         "@buildsys-build",
         "autoconf",
         "automake",
+        "clang-devel",
         "libtool",
         "gettext",
         "gettext-devel",
@@ -136,6 +144,7 @@ packages:
         "wine",
         "rust",
         "cargo",
+        "bindgen-cli"
       ]
   freebsd:
     needed:
diff --git a/.gitlab-ci/other.yml b/.gitlab-ci/other.yml
index 074146b..b2aad54 100644
--- a/.gitlab-ci/other.yml
+++ b/.gitlab-ci/other.yml
@@ -45,17 +45,18 @@
       - build-*/meson-logs/*txt
       - prefix-*
 
-meson vs2019 amd64:
-  extends: ".build meson windows"
-  variables:
-    ARCH: "amd64"
 
 meson vs2019 x86:
   extends: ".build meson windows"
   variables:
     ARCH: "x86"
+    MESON_ARGS: "-Dfontations=disabled"
 
-meson macos:
+# A Windows Fontations build would currently require
+# libclang and llvm installation which is a several hundred megabyte download.
+# Skip that configuration for now.
+
+.meson macos test:
   stage: "test"
   # See https://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/main/.gitlab-ci.yml
   # As of 2024-11-21, this is a Mac OS 15 Sequia image on Apple silicon.
@@ -83,12 +84,24 @@ meson macos:
     - . "$HOME/.cargo/env"
     # Test Rust availability.
     - rustup update
+    - cargo install bindgen-cli
     - rustc --version
+    - bindgen --version
   script:
-    - CERT_PATH=$(python3 -m certifi) && export SSL_CERT_FILE=${CERT_PATH} && export REQUESTS_CA_BUNDLE=${CERT_PATH} && meson setup -Diconv=enabled build
+    - CERT_PATH=$(python3 -m certifi) && export SSL_CERT_FILE=${CERT_PATH} && export REQUESTS_CA_BUNDLE=${CERT_PATH} && meson setup -Diconv=enabled $MESON_FONTATIONS_ARG build
     - meson compile --verbose -C build
     - meson test -C build
 
+meson macos test:
+  extends: ".meson macos test"
+  variables:
+    MESON_FONTATIONS_ARG: "-Dfontations=disabled"
+
+meson macos test fontations:
+  extends: ".meson macos test"
+  variables:
+    MESON_FONTATIONS_ARG: "-Dfontations=enabled"
+
 # msys infrastructure is a bit broken, disable for now
 meson msys2:
   extends: ".build meson windows"
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..156bffc
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,24 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "fc-fontations"
+version = "0.1.0"
+dependencies = [
+ "fc-fontations-bindgen",
+ "libc",
+]
+
+[[package]]
+name = "fc-fontations-bindgen"
+version = "0.1.0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.165"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcb4d3d38eab6c5239a362fa8bae48c03baf980a6e7079f063942d563ef3533e"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..6feaf0c
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "fc-fontations"
+version = "0.1.0"
+
+[dependencies]
+fc-fontations-bindgen = { path = "./fc-fontations-bindgen" }
+libc = "0.2"
+
+[lib]
+path = "fc-fontations/mod.rs"
diff --git a/fc-fontations-bindgen/Cargo.lock b/fc-fontations-bindgen/Cargo.lock
new file mode 100644
index 0000000..98cf25e
--- /dev/null
+++ b/fc-fontations-bindgen/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "fc-fontations-bindgen"
+version = "0.1.0"
diff --git a/fc-fontations-bindgen/Cargo.toml b/fc-fontations-bindgen/Cargo.toml
new file mode 100644
index 0000000..fafeefc
--- /dev/null
+++ b/fc-fontations-bindgen/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "fc-fontations-bindgen"
+version = "0.1.0"
+links = "fontconfig"
+
+[lib]
+path = "../build/fc-fontations/fontconfig.rs"
+
+[dependencies]
+libc = "0.2"
diff --git a/fc-fontations-bindgen/build.rs b/fc-fontations-bindgen/build.rs
new file mode 100644
index 0000000..50b703d
--- /dev/null
+++ b/fc-fontations-bindgen/build.rs
@@ -0,0 +1,34 @@
+use std::path::PathBuf;
+use std::process::Command;
+
+fn main() {
+    // Directory for the fontconfig build
+    let build_dir = PathBuf::from("build");
+
+    // Configure and build fontconfig using meson
+    let mut meson = Command::new("meson");
+    meson.current_dir("../");
+    meson.arg("setup")
+         .arg(build_dir.to_str().unwrap())
+         .arg("-Dfontations=enabled");
+
+    let status = meson.status().expect("Failed to execute meson");
+    if !status.success() {
+        panic!("Meson setup failed");
+    }
+
+    let mut ninja = Command::new("ninja");
+    ninja.current_dir("../");
+    ninja.arg("-C").arg(build_dir.to_str().unwrap());
+    let status = ninja.status().expect("Failed to execute ninja");
+    if !status.success() {
+        panic!("Ninja build failed");
+    }
+
+    // Tell cargo to look for fontconfig in the build directory
+    println!("cargo:rustc-link-search=native={}", build_dir.join("lib").display());
+    println!("cargo:rustc-link-lib=dylib=fontconfig");
+
+    // Rerun this build script if the fontconfig source code changes
+    println!("cargo:rerun-if-changed=src");
+}
diff --git a/fc-fontations/meson.build b/fc-fontations/meson.build
new file mode 100644
index 0000000..fd06081
--- /dev/null
+++ b/fc-fontations/meson.build
@@ -0,0 +1,53 @@
+fontations = get_option('fontations')
+
+if (fontations.enabled())
+  rust = import('rust')
+
+  generated_fontconfig = rust.bindgen(
+    input : '../fontconfig/fontconfig.h',
+    output : 'fontconfig.rs',
+    include_directories : [ '../' ],
+    args : [
+      '--merge-extern-blocks',
+      '--allowlist-item=(FcCharSet.*|FC_(SLANT|WEIGHT|WIDTH)_.*|FcFontSet(Add|Create|Destroy).*|FcLangSet(Destroy|Copy)|FcWeightFromOpenType.*)',
+      '--raw-line=#![allow(nonstandard_style,unused)]',
+      '--raw-line= ',
+      '--raw-line=pub mod fcint;',
+    ],
+    c_args : ['-DBINDGEN_IGNORE_VISIBILITY=1'],
+  )
+
+  generated_fcint = rust.bindgen(
+    input : '../src/fcint.h',
+    output : 'fcint.rs',
+    include_directories : [ '../' ],
+    args : [
+      '--merge-extern-blocks',
+      '--allowlist-item=(FcPattern.*|FcRange.*|FC_.*_OBJECT|FcCharSet.*|FcFreeTypeLangSet)',
+      '--blocklist-type=(FcCharSet|FcLangSet)',
+      '--raw-line=#![allow(nonstandard_style,unused)]',
+      '--raw-line= ',
+      '--raw-line=pub use FcCharSet; pub use FcLangSet;',
+    ],
+    c_args : ['-DBINDGEN_IGNORE_VISIBILITY=1'],
+  )
+
+  bindgen_lib = static_library(
+    'fc_fontations_bindgen',
+    sources: [generated_fontconfig, generated_fcint],
+    rust_abi : 'rust',
+  )
+
+  fc_fontations = static_library(
+    'fc_fontations',
+    sources: ['mod.rs'],
+    link_with: [bindgen_lib, libfontconfig],
+    rust_abi: 'c',
+    dependencies: [
+      dependency('libc-0.2-rs'),
+
+    ],
+
+  )
+
+endif
\ No newline at end of file
diff --git a/fc-fontations/mod.rs b/fc-fontations/mod.rs
new file mode 100644
index 0000000..a39c814
--- /dev/null
+++ b/fc-fontations/mod.rs
@@ -0,0 +1,41 @@
+extern crate fc_fontations_bindgen;
+
+use fc_fontations_bindgen::{fcint::FcPatternCreate, FcFontSet, FcFontSetAdd};
+
+#[no_mangle]
+/// Externally called in fcfontations.c as the file scanner function
+/// similar to the job that FreeType performs.
+///
+/// # Safety
+/// * At this point, the font file path is not dereferenced.
+/// * In this initial sanity check mock call, only one empty pattern
+///   is added to the FontSet, which is null checked, which is sound.
+pub unsafe extern "C" fn add_patterns_to_fontset(
+    _: *const libc::c_char,
+    font_set: *mut FcFontSet,
+) -> libc::c_int {
+    let empty_pattern = FcPatternCreate();
+    if !font_set.is_null() {
+        FcFontSetAdd(
+            font_set,
+            empty_pattern as *mut fc_fontations_bindgen::FcPattern,
+        )
+    } else {
+        0
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use crate::add_patterns_to_fontset;
+    use fc_fontations_bindgen::{FcFontSetCreate, FcFontSetDestroy};
+
+    #[test]
+    fn basic_pattern_construction() {
+        unsafe {
+            let font_set = FcFontSetCreate();
+            assert!(add_patterns_to_fontset(std::ptr::null(), font_set) == 1);
+            FcFontSetDestroy(font_set);
+        }
+    }
+}
diff --git a/meson.build b/meson.build
index 0e9e99a..7d41f84 100644
--- a/meson.build
+++ b/meson.build
@@ -1,7 +1,7 @@
 project('fontconfig', 'c',
   version: '2.15.0',
-  meson_version : '>= 1.3.0',
-  default_options: [ 'buildtype=debugoptimized'],
+  meson_version : '>= 1.6.0',
+  default_options: [ 'buildtype=debugoptimized', ]
 )
 
 fs = import('fs')
@@ -73,6 +73,12 @@ if xmltype == ''
   xmltype = xml_dep.name()
 endif
 
+fontations = get_option('fontations')
+if (fontations.enabled())
+  conf.set('ENABLE_FONTATIONS', 1)
+  add_languages(['rust'], native: false, required : true)
+endif
+
 pkgmod = import('pkgconfig')
 python3 = import('python').find_installation()
 
@@ -484,6 +490,10 @@ subdir('fc-case')
 subdir('fc-lang')
 subdir('src')
 
+if get_option('fontations').enabled()
+  subdir('fc-fontations')
+endif
+
 if not get_option('tools').disabled()
   subdir('fc-cache')
   subdir('fc-cat')
@@ -549,6 +559,7 @@ summary({
   'Tools': not get_option('tools').disabled(),
   'iconv': found_iconv == 1,
   'XML backend': xmltype,
+  'Fontations support' : fontations
 }, section: 'General', bool_yn: true, list_sep: ', ')
 summary({
   'Hinting': preferred_hinting,
diff --git a/meson_options.txt b/meson_options.txt
index 49c6dad..d148621 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -16,6 +16,8 @@ option('cache-build', type : 'feature', value : 'enabled',
 option('iconv', type: 'feature', value: 'disabled')
 option('xml-backend', type: 'combo', choices: ['auto', 'expat', 'libxml2'], value: 'auto',
   description: 'Select xml backend to read config')
+option('fontations', type: 'feature', value: 'disabled',
+  description: 'Use Fontations (https://github.com/googlefonts/fontations) for indexing.')
 
 # Defaults
 option('default-hinting', type: 'combo', choices: ['none', 'slight', 'medium', 'full'], value: 'slight',
diff --git a/test/meson.build b/test/meson.build
index d547591..eff0b22 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -26,6 +26,7 @@ if host_machine.system() != 'windows'
   endif
 endif
 
+
 foreach test_data : tests
   fname = test_data[0]
   opts = test_data.length() > 1 ? test_data[1] : {}
@@ -43,6 +44,11 @@ foreach test_data : tests
   test(test_name, exe, timeout: 600)
 endforeach
 
+if get_option('fontations').enabled()
+  rust = import('rust')
+  rust.test('fc_fontations_tests', fc_fontations)
+endif
+
 fs = import('fs')
 
 if host_machine.system() != 'windows'


More information about the Fontconfig mailing list