mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-01 12:24:16 +00:00
Remove yeslogic-fontconfig dependency
We need only 9 different functions from fontconfig and one data structure. We can do that interaction with libloading by hand and avoid causing issues like servo/font-kit#212
This commit is contained in:
parent
a259095353
commit
c81a3f7b64
4 changed files with 76 additions and 28 deletions
|
|
@ -95,7 +95,6 @@ rust-version = "1.66"
|
|||
[workspace.dependencies]
|
||||
resvg = { version= "0.34.0", default-features = false, features = ["text"] }
|
||||
fontdb = { version = "0.14.1", default-features = false }
|
||||
yeslogic-fontconfig-sys = { version = "3.2.0", features = ["dlopen"] }
|
||||
send_wrapper = { version = "0.6.0" }
|
||||
|
||||
[profile.release]
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ homepage = "https://slint.dev"
|
|||
path = "lib.rs"
|
||||
|
||||
[features]
|
||||
shared-fontdb = ["dep:fontdb", "dep:libc", "dep:yeslogic-fontconfig-sys", "derive_more", "cfg-if"]
|
||||
shared-fontdb = ["dep:fontdb", "dep:libloading", "derive_more", "cfg-if"]
|
||||
|
||||
[dependencies]
|
||||
fontdb = { workspace = true, optional = true }
|
||||
|
|
@ -24,8 +24,7 @@ derive_more = { version = "0.99.5", optional = true }
|
|||
cfg-if = { version = "1", 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 }
|
||||
yeslogic-fontconfig-sys = { workspace = true, optional = true }
|
||||
libloading = { version = "0.8.0", optional = true }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
fontdb = { workspace = true, optional = true, default-features = true, features = ["fontconfig", "memmap"] }
|
||||
|
|
|
|||
|
|
@ -3,31 +3,86 @@
|
|||
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
use fontconfig_sys as ffi;
|
||||
use core::ffi::{c_char, c_int, c_uchar, c_void};
|
||||
|
||||
use ffi::statics::LIB;
|
||||
const FC_MATCH_PATTERN: c_int = 0;
|
||||
const FC_RESULT_MATCH: c_int = 0;
|
||||
|
||||
#[repr(C)]
|
||||
struct FcFontSet {
|
||||
nfont: c_int,
|
||||
sfont: c_int,
|
||||
fonts: *mut *mut c_void,
|
||||
}
|
||||
|
||||
// This is duplicated in the slint-compiler's glyph embedding code
|
||||
pub fn find_families(requested_family: &str) -> Vec<String> {
|
||||
unsafe {
|
||||
let config = (LIB.FcInitLoadConfigAndFonts)();
|
||||
let fontconfig = libloading::Library::new("libfontconfig.so.1")
|
||||
.expect("Unable to dlopen libfontconfig.so.1");
|
||||
let fc_init_load_config_and_fonts: libloading::Symbol<
|
||||
unsafe extern "C" fn() -> *mut c_void,
|
||||
> = fontconfig
|
||||
.get(b"FcInitLoadConfigAndFonts")
|
||||
.expect("Unable to find FcInitLoadConfigAndFonts");
|
||||
let fc_name_parse: libloading::Symbol<unsafe extern "C" fn(*const c_uchar) -> *mut c_void> =
|
||||
fontconfig.get(b"FcNameParse").expect("Unable to find FcNameParse");
|
||||
let fc_config_substitute: libloading::Symbol<
|
||||
unsafe extern "C" fn(
|
||||
*mut c_void, // FcConfig *
|
||||
*mut c_void, // FcPattern *
|
||||
c_int, // FcMatchKind
|
||||
) -> c_int,
|
||||
> = fontconfig.get(b"FcConfigSubstitute").expect("Unable to find FcConfigSubstitute");
|
||||
let fc_default_substitute: libloading::Symbol<unsafe extern "C" fn(*mut c_void)> =
|
||||
fontconfig.get(b"FcDefaultSubstitute").expect("Unable to find FcDefaultSubstitute");
|
||||
let fc_font_sort: libloading::Symbol<
|
||||
unsafe extern "C" fn(
|
||||
*mut c_void, // FcConfig *
|
||||
*mut c_void, // FcPattern *
|
||||
c_int, // FcBool trim
|
||||
*mut *mut c_void, // FcCharSet **
|
||||
*mut c_int, // FcResult *
|
||||
) -> *mut FcFontSet,
|
||||
> = fontconfig.get(b"FcFontSort").expect("Unable to find FcFontSort");
|
||||
let fc_pattern_get_string: libloading::Symbol<
|
||||
unsafe extern "C" fn(
|
||||
*mut c_void, // FcPattern *
|
||||
*const c_char, // const char *object
|
||||
c_int, // int n
|
||||
*mut *mut c_uchar, // FcChar8 **s
|
||||
) -> c_int,
|
||||
> = fontconfig.get(b"FcPatternGetString").expect("Unable to find FcPatternGetString");
|
||||
let fc_font_set_destroy: libloading::Symbol<unsafe extern "C" fn(*mut FcFontSet)> =
|
||||
fontconfig.get(b"FcFontSetDestroy").expect("Unable to find FcFontSetDestroy");
|
||||
let fc_pattern_destroy: libloading::Symbol<
|
||||
unsafe extern "C" fn(
|
||||
*mut c_void, // FcPattern *
|
||||
),
|
||||
> = fontconfig.get(b"FcPatternDestroy").expect("Unable to find FcPatternDestroy");
|
||||
let fc_config_destroy: libloading::Symbol<
|
||||
unsafe extern "C" fn(
|
||||
*mut c_void, // FcConfig *
|
||||
),
|
||||
> = fontconfig.get(b"FcConfigDestroy").expect("Unable to find FcConfigDestroy");
|
||||
|
||||
let config = fc_init_load_config_and_fonts();
|
||||
let family_cstr = std::ffi::CString::new(requested_family).unwrap();
|
||||
let pattern = (LIB.FcNameParse)(family_cstr.as_ptr() as *mut libc::c_uchar);
|
||||
(LIB.FcConfigSubstitute)(std::ptr::null_mut(), pattern, ffi::FcMatchPattern);
|
||||
(LIB.FcDefaultSubstitute)(pattern);
|
||||
let mut sort_result = ffi::FcResultMatch;
|
||||
let result_set =
|
||||
(LIB.FcFontSort)(config, pattern, 1, std::ptr::null_mut(), &mut sort_result);
|
||||
let pattern = fc_name_parse(family_cstr.as_ptr() as *mut c_uchar);
|
||||
fc_config_substitute(std::ptr::null_mut(), pattern, FC_MATCH_PATTERN);
|
||||
fc_default_substitute(pattern);
|
||||
let mut sort_result = FC_RESULT_MATCH;
|
||||
let result_set = fc_font_sort(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 (LIB.FcPatternGetString)(
|
||||
if fc_pattern_get_string(
|
||||
*(*result_set).fonts.offset(idx as isize),
|
||||
b"family\0".as_ptr() as *const libc::c_char,
|
||||
b"family\0".as_ptr() as *const c_char,
|
||||
0,
|
||||
&mut raw_family_name,
|
||||
) != ffi::FcResultMatch
|
||||
) != FC_RESULT_MATCH
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -35,19 +90,18 @@ pub fn find_families(requested_family: &str) -> Vec<String> {
|
|||
if raw_family_name.is_null() {
|
||||
continue;
|
||||
}
|
||||
if let Some(family_name) =
|
||||
std::ffi::CStr::from_ptr(raw_family_name as *const libc::c_char)
|
||||
.to_str()
|
||||
.ok()
|
||||
.map(|raw_family_name| raw_family_name.to_owned())
|
||||
if let Some(family_name) = std::ffi::CStr::from_ptr(raw_family_name as *const c_char)
|
||||
.to_str()
|
||||
.ok()
|
||||
.map(|raw_family_name| raw_family_name.to_owned())
|
||||
{
|
||||
families.push(family_name)
|
||||
}
|
||||
}
|
||||
|
||||
(LIB.FcFontSetDestroy)(result_set);
|
||||
(LIB.FcPatternDestroy)(pattern);
|
||||
(LIB.FcConfigDestroy)(config);
|
||||
fc_font_set_destroy(result_set);
|
||||
fc_pattern_destroy(pattern);
|
||||
fc_config_destroy(config);
|
||||
families
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,10 +96,6 @@ fontdb = { workspace = true, optional = true, default-features = true, features
|
|||
rustybuzz = { version = "0.7.0", optional = true }
|
||||
fontdue = { version = "0.7.1", 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 }
|
||||
yeslogic-fontconfig-sys = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
slint = { path = "../../api/rs/slint", default-features = false, features = ["std", "compat-1-0"] }
|
||||
i-slint-backend-testing = { path="../backends/testing" }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue