mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-13 17:25:27 +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]
|
[workspace.dependencies]
|
||||||
resvg = { version= "0.34.0", default-features = false, features = ["text"] }
|
resvg = { version= "0.34.0", default-features = false, features = ["text"] }
|
||||||
fontdb = { version = "0.14.1", default-features = false }
|
fontdb = { version = "0.14.1", default-features = false }
|
||||||
yeslogic-fontconfig-sys = { version = "3.2.0", features = ["dlopen"] }
|
|
||||||
send_wrapper = { version = "0.6.0" }
|
send_wrapper = { version = "0.6.0" }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ homepage = "https://slint.dev"
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
|
|
||||||
[features]
|
[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]
|
[dependencies]
|
||||||
fontdb = { workspace = true, optional = true }
|
fontdb = { workspace = true, optional = true }
|
||||||
|
|
@ -24,8 +24,7 @@ derive_more = { version = "0.99.5", optional = true }
|
||||||
cfg-if = { version = "1", 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]
|
[target.'cfg(not(any(target_family = "windows", target_os = "macos", target_os = "ios", target_arch = "wasm32")))'.dependencies]
|
||||||
libc = { version = "0.2", optional = true }
|
libloading = { version = "0.8.0", optional = true }
|
||||||
yeslogic-fontconfig-sys = { workspace = true, optional = true }
|
|
||||||
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
fontdb = { workspace = true, optional = true, default-features = true, features = ["fontconfig", "memmap"] }
|
fontdb = { workspace = true, optional = true, default-features = true, features = ["fontconfig", "memmap"] }
|
||||||
|
|
|
||||||
|
|
@ -3,31 +3,86 @@
|
||||||
|
|
||||||
#![allow(unsafe_code)]
|
#![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
|
// This is duplicated in the slint-compiler's glyph embedding code
|
||||||
pub fn find_families(requested_family: &str) -> Vec<String> {
|
pub fn find_families(requested_family: &str) -> Vec<String> {
|
||||||
unsafe {
|
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 family_cstr = std::ffi::CString::new(requested_family).unwrap();
|
||||||
let pattern = (LIB.FcNameParse)(family_cstr.as_ptr() as *mut libc::c_uchar);
|
let pattern = fc_name_parse(family_cstr.as_ptr() as *mut c_uchar);
|
||||||
(LIB.FcConfigSubstitute)(std::ptr::null_mut(), pattern, ffi::FcMatchPattern);
|
fc_config_substitute(std::ptr::null_mut(), pattern, FC_MATCH_PATTERN);
|
||||||
(LIB.FcDefaultSubstitute)(pattern);
|
fc_default_substitute(pattern);
|
||||||
let mut sort_result = ffi::FcResultMatch;
|
let mut sort_result = FC_RESULT_MATCH;
|
||||||
let result_set =
|
let result_set = fc_font_sort(config, pattern, 1, std::ptr::null_mut(), &mut sort_result);
|
||||||
(LIB.FcFontSort)(config, pattern, 1, std::ptr::null_mut(), &mut sort_result);
|
|
||||||
|
|
||||||
let mut families = Vec::new();
|
let mut families = Vec::new();
|
||||||
for idx in 0..(*result_set).nfont {
|
for idx in 0..(*result_set).nfont {
|
||||||
let mut raw_family_name = std::ptr::null_mut();
|
let mut raw_family_name = std::ptr::null_mut();
|
||||||
if (LIB.FcPatternGetString)(
|
if fc_pattern_get_string(
|
||||||
*(*result_set).fonts.offset(idx as isize),
|
*(*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,
|
0,
|
||||||
&mut raw_family_name,
|
&mut raw_family_name,
|
||||||
) != ffi::FcResultMatch
|
) != FC_RESULT_MATCH
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -35,8 +90,7 @@ pub fn find_families(requested_family: &str) -> Vec<String> {
|
||||||
if raw_family_name.is_null() {
|
if raw_family_name.is_null() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(family_name) =
|
if let Some(family_name) = std::ffi::CStr::from_ptr(raw_family_name as *const c_char)
|
||||||
std::ffi::CStr::from_ptr(raw_family_name as *const libc::c_char)
|
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok()
|
.ok()
|
||||||
.map(|raw_family_name| raw_family_name.to_owned())
|
.map(|raw_family_name| raw_family_name.to_owned())
|
||||||
|
|
@ -45,9 +99,9 @@ pub fn find_families(requested_family: &str) -> Vec<String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(LIB.FcFontSetDestroy)(result_set);
|
fc_font_set_destroy(result_set);
|
||||||
(LIB.FcPatternDestroy)(pattern);
|
fc_pattern_destroy(pattern);
|
||||||
(LIB.FcConfigDestroy)(config);
|
fc_config_destroy(config);
|
||||||
families
|
families
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,10 +96,6 @@ fontdb = { workspace = true, optional = true, default-features = true, features
|
||||||
rustybuzz = { version = "0.7.0", optional = true }
|
rustybuzz = { version = "0.7.0", optional = true }
|
||||||
fontdue = { version = "0.7.1", 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]
|
[dev-dependencies]
|
||||||
slint = { path = "../../api/rs/slint", default-features = false, features = ["std", "compat-1-0"] }
|
slint = { path = "../../api/rs/slint", default-features = false, features = ["std", "compat-1-0"] }
|
||||||
i-slint-backend-testing = { path="../backends/testing" }
|
i-slint-backend-testing = { path="../backends/testing" }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue