diff --git a/examples/plotter/Cargo.toml b/examples/plotter/Cargo.toml index 7314f9d99b8..20bb7a7d41c 100644 --- a/examples/plotter/Cargo.toml +++ b/examples/plotter/Cargo.toml @@ -15,7 +15,7 @@ name = "plotter" [dependencies] slint = { path = "../../api/rs/slint" } -plotters = { version = "0.3.1", default-features = false, features = ["bitmap_backend", "surface_series"] } +plotters = { version = "0.3.4", default-features = false, features = ["bitmap_backend", "surface_series"] } [build-dependencies] slint-build = { path = "../../api/rs/build" } diff --git a/internal/backends/winit/Cargo.toml b/internal/backends/winit/Cargo.toml index afe7c3ba813..c6bdea5e9fb 100644 --- a/internal/backends/winit/Cargo.toml +++ b/internal/backends/winit/Cargo.toml @@ -20,7 +20,7 @@ path = "lib.rs" [features] wayland = ["winit/wayland", "glutin/wayland", "copypasta/wayland"] x11 = ["winit/x11", "glutin/x11", "copypasta/x11"] -renderer-winit-femtovg = ["femtovg", "fontdb", "libc", "servo-fontconfig", "winapi", "dwrote", "imgref", "unicode-script", "ttf-parser", "rgb"] +renderer-winit-femtovg = ["femtovg", "fontdb", "libc", "yeslogic-fontconfig-sys", "winapi", "dwrote", "imgref", "unicode-script", "ttf-parser", "rgb"] renderer-winit-skia = ["skia-safe", "glow", "unicode-segmentation", "metal", "objc", "core-graphics-types", "foreign-types", "wio", "winapi/d3d12", "winapi/dxgi", "winapi/dxgi1_2", "winapi/dxgi1_3", "winapi/dxgi1_4", "winapi/d3d12sdklayers", "winapi/synchapi"] renderer-winit-skia-opengl = ["skia-safe/gl", "glow", "unicode-segmentation"] renderer-winit-software = ["femtovg", "imgref", "rgb"] @@ -77,9 +77,7 @@ wio = { version = "0.2.2", optional = true } [target.'cfg(not(any(target_family = "windows", target_os = "macos", target_os = "ios", target_arch = "wasm32")))'.dependencies] libc = { version = "0.2", optional = true } -# Require font-config from the system on Linux. Issue #88 indicates that the copy provided by servo-fontconfig may be incompatible -# with distros at times. -servo-fontconfig = { version = "0.5", optional = true, features = [ "force_system_lib" ] } +yeslogic-fontconfig-sys = { version = "3.2", optional = true } [target.'cfg(target_os = "macos")'.dependencies] # For GL rendering diff --git a/internal/backends/winit/build.rs b/internal/backends/winit/build.rs index a313401e307..b1fcd08a272 100644 --- a/internal/backends/winit/build.rs +++ b/internal/backends/winit/build.rs @@ -11,4 +11,10 @@ fn main() { skia_backend_metal: { all(target_os = "macos", not(feature = "renderer-winit-skia-opengl")) }, skia_backend_d3d: { all(target_family = "windows", not(feature = "renderer-winit-skia-opengl")) }, } + + println!("cargo:rerun-if-env-changed=RUST_FONTCONFIG_DLOPEN"); + let dlopen = std::env::var("RUST_FONTCONFIG_DLOPEN").is_ok(); + if dlopen { + println!("cargo:rustc-cfg=feature=\"fontconfig-dlopen\""); + } } diff --git a/internal/backends/winit/renderer/femtovg/fonts/fontconfig.rs b/internal/backends/winit/renderer/femtovg/fonts/fontconfig.rs index f2bb1e8d985..9b95ea1fdd4 100644 --- a/internal/backends/winit/renderer/femtovg/fonts/fontconfig.rs +++ b/internal/backends/winit/renderer/femtovg/fonts/fontconfig.rs @@ -1,29 +1,58 @@ // Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial -use fontconfig::fontconfig; +use fontconfig_sys as ffi; +use fontconfig_sys::ffi_dispatch; + +#[cfg(feature = "fontconfig-dlopen")] +use ffi::statics::LIB; +#[cfg(not(feature = "fontconfig-dlopen"))] +use ffi::*; // This is duplicated in the slint-compiler's glyph embedding code pub fn find_families(requested_family: &str) -> Vec { unsafe { - let config = fontconfig::FcInitLoadConfigAndFonts(); + let config = ffi_dispatch!(feature = "fontconfig-dlopen", LIB, FcInitLoadConfigAndFonts,); let family_cstr = std::ffi::CString::new(requested_family).unwrap(); - let pattern = fontconfig::FcNameParse(family_cstr.as_ptr() as *mut libc::c_uchar); - fontconfig::FcConfigSubstitute(std::ptr::null_mut(), pattern, fontconfig::FcMatchPattern); - fontconfig::FcDefaultSubstitute(pattern); - let mut sort_result = fontconfig::FcResultMatch; - let result_set = - fontconfig::FcFontSort(config, pattern, 1, std::ptr::null_mut(), &mut sort_result); + let pattern = ffi_dispatch!( + feature = "fontconfig-dlopen", + LIB, + FcNameParse, + family_cstr.as_ptr() as *mut libc::c_uchar + ); + ffi_dispatch!( + feature = "fontconfig-dlopen", + LIB, + FcConfigSubstitute, + std::ptr::null_mut(), + pattern, + ffi::FcMatchPattern + ); + ffi_dispatch!(feature = "fontconfig-dlopen", LIB, FcDefaultSubstitute, pattern); + let mut sort_result = ffi::FcResultMatch; + let result_set = ffi_dispatch!( + feature = "fontconfig-dlopen", + LIB, + FcFontSort, + config, + pattern, + 1, + std::ptr::null_mut(), + &mut sort_result + ); let mut families = Vec::new(); for idx in 0..(*result_set).nfont { let mut raw_family_name = std::ptr::null_mut(); - if fontconfig::FcPatternGetString( + if ffi_dispatch!( + feature = "fontconfig-dlopen", + LIB, + FcPatternGetString, *(*result_set).fonts.offset(idx as isize), b"family\0".as_ptr() as *const libc::c_char, 0, - &mut raw_family_name, - ) != fontconfig::FcResultMatch + &mut raw_family_name + ) != ffi::FcResultMatch { continue; } @@ -41,9 +70,9 @@ pub fn find_families(requested_family: &str) -> Vec { } } - fontconfig::FcFontSetDestroy(result_set); - fontconfig::FcPatternDestroy(pattern); - fontconfig::FcConfigDestroy(config); + ffi_dispatch!(feature = "fontconfig-dlopen", LIB, FcFontSetDestroy, result_set); + ffi_dispatch!(feature = "fontconfig-dlopen", LIB, FcPatternDestroy, pattern); + ffi_dispatch!(feature = "fontconfig-dlopen", LIB, FcConfigDestroy, config); families } } diff --git a/internal/compiler/Cargo.toml b/internal/compiler/Cargo.toml index 6f98cbfc579..09580c4cbb9 100644 --- a/internal/compiler/Cargo.toml +++ b/internal/compiler/Cargo.toml @@ -61,9 +61,7 @@ usvg = "0.23" [target.'cfg(not(any(target_family = "windows", target_os = "macos", target_os = "ios", target_arch = "wasm32")))'.dependencies] libc = { version = "0.2" } -# Require font-config from the system on Linux. Issue #88 indicates that the copy provided by servo-fontconfig may be incompatible -# with distros at times. -servo-fontconfig = { version = "0.5", features = [ "force_system_lib" ] } +yeslogic-fontconfig-sys = "3.2.0" [dev-dependencies] i-slint-parser-test-macro = { path = "./parser-test-macro" } diff --git a/internal/compiler/build.rs b/internal/compiler/build.rs index 7027b3d27f2..2f45fd4ba20 100644 --- a/internal/compiler/build.rs +++ b/internal/compiler/build.rs @@ -6,6 +6,12 @@ use std::io::Write; use std::path::{Path, PathBuf}; fn main() -> std::io::Result<()> { + println!("cargo:rerun-if-env-changed=RUST_FONTCONFIG_DLOPEN"); + let dlopen = std::env::var("RUST_FONTCONFIG_DLOPEN").is_ok(); + if dlopen { + println!("cargo:rustc-cfg=feature=\"fontconfig-dlopen\""); + } + let mut library_dir = PathBuf::from(std::env::var_os("CARGO_MANIFEST_DIR").unwrap()); library_dir.push("widgets"); diff --git a/internal/compiler/passes/embed_glyphs/fontconfig.rs b/internal/compiler/passes/embed_glyphs/fontconfig.rs index b29e14c9cfe..a149687affb 100644 --- a/internal/compiler/passes/embed_glyphs/fontconfig.rs +++ b/internal/compiler/passes/embed_glyphs/fontconfig.rs @@ -1,30 +1,59 @@ // Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial -use fontconfig::fontconfig; +use fontconfig_sys as ffi; +use fontconfig_sys::ffi_dispatch; -// This is duplicated from the GL backend +#[cfg(feature = "fontconfig-dlopen")] +use ffi::statics::LIB; +#[cfg(not(feature = "fontconfig-dlopen"))] +use ffi::*; + +// This is duplicated in the slint-compiler's glyph embedding code pub fn find_families(requested_family: &str) -> Vec { #[allow(unsafe_code)] unsafe { - let config = fontconfig::FcInitLoadConfigAndFonts(); + let config = ffi_dispatch!(feature = "fontconfig-dlopen", LIB, FcInitLoadConfigAndFonts,); let family_cstr = std::ffi::CString::new(requested_family).unwrap(); - let pattern = fontconfig::FcNameParse(family_cstr.as_ptr() as *mut libc::c_uchar); - fontconfig::FcConfigSubstitute(std::ptr::null_mut(), pattern, fontconfig::FcMatchPattern); - fontconfig::FcDefaultSubstitute(pattern); - let mut sort_result = fontconfig::FcResultMatch; - let result_set = - fontconfig::FcFontSort(config, pattern, 1, std::ptr::null_mut(), &mut sort_result); + let pattern = ffi_dispatch!( + feature = "fontconfig-dlopen", + LIB, + FcNameParse, + family_cstr.as_ptr() as *mut libc::c_uchar + ); + ffi_dispatch!( + feature = "fontconfig-dlopen", + LIB, + FcConfigSubstitute, + std::ptr::null_mut(), + pattern, + ffi::FcMatchPattern + ); + ffi_dispatch!(feature = "fontconfig-dlopen", LIB, FcDefaultSubstitute, pattern); + let mut sort_result = ffi::FcResultMatch; + let result_set = ffi_dispatch!( + feature = "fontconfig-dlopen", + LIB, + FcFontSort, + config, + pattern, + 1, + std::ptr::null_mut(), + &mut sort_result + ); let mut families = Vec::new(); for idx in 0..(*result_set).nfont { let mut raw_family_name = std::ptr::null_mut(); - if fontconfig::FcPatternGetString( + if ffi_dispatch!( + feature = "fontconfig-dlopen", + LIB, + FcPatternGetString, *(*result_set).fonts.offset(idx as isize), b"family\0".as_ptr() as *const libc::c_char, 0, - &mut raw_family_name, - ) != fontconfig::FcResultMatch + &mut raw_family_name + ) != ffi::FcResultMatch { continue; } @@ -42,9 +71,9 @@ pub fn find_families(requested_family: &str) -> Vec { } } - fontconfig::FcFontSetDestroy(result_set); - fontconfig::FcPatternDestroy(pattern); - fontconfig::FcConfigDestroy(config); + ffi_dispatch!(feature = "fontconfig-dlopen", LIB, FcFontSetDestroy, result_set); + ffi_dispatch!(feature = "fontconfig-dlopen", LIB, FcPatternDestroy, pattern); + ffi_dispatch!(feature = "fontconfig-dlopen", LIB, FcConfigDestroy, config); families } }