diff --git a/Cargo.toml b/Cargo.toml index 1415a66..1e41c98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "font-kit" -version = "0.10.1" +version = "0.11.0" authors = ["Patrick Walton "] description = "A cross-platform font loading library" license = "MIT/Apache-2.0" @@ -14,7 +14,8 @@ edition = "2018" default = ["source"] loader-freetype = ["freetype"] loader-freetype-default = ["loader-freetype"] -source-fontconfig = ["servo-fontconfig"] +source-fontconfig = ["yeslogic-fontconfig-sys"] +source-fontconfig-dlopen = ["yeslogic-fontconfig-sys/dlopen"] source-fontconfig-default = ["source-fontconfig"] source = [] @@ -32,8 +33,8 @@ pathfinder_simd = "0.5.1" version = "0.7" optional = true -[dependencies.servo-fontconfig] -version = "0.5" +[dependencies.yeslogic-fontconfig-sys] +version = "3.0.0" optional = true [dev-dependencies] @@ -58,7 +59,7 @@ core-text = "19.1.0" freetype = "0.7" [target.'cfg(not(any(target_family = "windows", target_os = "macos", target_os = "ios", target_arch = "wasm32")))'.dependencies] -servo-fontconfig = "0.5" +yeslogic-fontconfig-sys = "3.0.0" [target.'cfg(not(any(target_arch = "wasm32", target_family = "windows", target_os = "android")))'.dependencies] dirs-next = "2.0" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..be57bdd --- /dev/null +++ b/build.rs @@ -0,0 +1,7 @@ +fn main() { + 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=\"source-fontconfig-dlopen\""); + } +} diff --git a/src/sources/fontconfig.rs b/src/sources/fontconfig.rs index b3a04ab..d6f48dd 100644 --- a/src/sources/fontconfig.rs +++ b/src/sources/fontconfig.rs @@ -244,7 +244,13 @@ impl Source for FontconfigSource { mod fc { #![allow(dead_code)] - use fontconfig::fontconfig as ffi; + use fontconfig_sys as ffi; + use fontconfig_sys::ffi_dispatch; + + #[cfg(feature = "source-fontconfig-dlopen")] + use ffi::statics::LIB; + #[cfg(not(feature = "source-fontconfig-dlopen"))] + use ffi::*; use std::ffi::{CStr, CString}; use std::os::raw::{c_char, c_uchar}; @@ -308,7 +314,7 @@ mod fc { pub fn new() -> Self { unsafe { Config { - d: ffi::FcInitLoadConfigAndFonts(), + d: ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcInitLoadConfigAndFonts,), } } } @@ -317,7 +323,7 @@ mod fc { impl Drop for Config { fn drop(&mut self) { unsafe { - ffi::FcConfigDestroy(self.d); + ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcConfigDestroy, self.d); } } } @@ -337,23 +343,23 @@ mod fc { // FcPatternCreate pub fn new() -> Self { - unsafe { Pattern::from_ptr(ffi::FcPatternCreate()) } + unsafe { Pattern::from_ptr(ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcPatternCreate,)) } } // FcNameParse pub fn from_name(name: &str) -> Self { let c_name = CString::new(name).unwrap(); - unsafe { Pattern::from_ptr(ffi::FcNameParse(c_name.as_ptr() as *mut c_uchar)) } + unsafe { Pattern::from_ptr(ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcNameParse, c_name.as_ptr() as *mut c_uchar)) } } // FcPatternAddString pub fn push_string(&mut self, object: Object, value: String) { unsafe { let c_string = CString::new(value).unwrap(); - ffi::FcPatternAddString( + ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcPatternAddString, self.d, object.as_ptr(), - c_string.as_ptr() as *const c_uchar, + c_string.as_ptr() as *const c_uchar ); // We have to keep this string, because `FcPattern` has a pointer to it now. @@ -364,21 +370,21 @@ mod fc { // FcConfigSubstitute pub fn config_substitute(&mut self, match_kind: MatchKind) { unsafe { - ffi::FcConfigSubstitute(ptr::null_mut(), self.d, match_kind.to_u32()); + ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcConfigSubstitute, ptr::null_mut(), self.d, match_kind.to_u32()); } } // FcDefaultSubstitute pub fn default_substitute(&mut self) { unsafe { - ffi::FcDefaultSubstitute(self.d); + ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcDefaultSubstitute, self.d); } } // FcFontSort pub fn sorted(&self, config: &Config) -> Result { let mut res = ffi::FcResultMatch; - let d = unsafe { ffi::FcFontSort(config.d, self.d, 1, ptr::null_mut(), &mut res) }; + let d = unsafe { ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcFontSort, config.d, self.d, 1, ptr::null_mut(), &mut res) }; match res { ffi::FcResultMatch => Ok(FontSet { d, idx: 0 }), @@ -391,7 +397,7 @@ mod fc { // FcFontList pub fn list(&self, config: &Config, set: ObjectSet) -> Result { - let d = unsafe { ffi::FcFontList(config.d, self.d, set.d) }; + let d = unsafe { ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcFontList, config.d, self.d, set.d) }; if !d.is_null() { Ok(FontSet { d, idx: 0 }) } else { @@ -403,7 +409,7 @@ mod fc { impl Drop for Pattern { #[inline] fn drop(&mut self) { - unsafe { ffi::FcPatternDestroy(self.d) } + unsafe { ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcPatternDestroy, self.d) } } } @@ -417,7 +423,7 @@ mod fc { pub fn get_string(&self, object: Object) -> Option { unsafe { let mut string = ptr::null_mut(); - let res = ffi::FcPatternGetString(self.d, object.as_ptr(), 0, &mut string); + let res = ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcPatternGetString, self.d, object.as_ptr(), 0, &mut string); if res != ffi::FcResultMatch { return None; } @@ -437,7 +443,7 @@ mod fc { pub fn get_integer(&self, object: Object) -> Option { unsafe { let mut integer = 0; - let res = ffi::FcPatternGetInteger(self.d, object.as_ptr(), 0, &mut integer); + let res = ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcPatternGetInteger, self.d, object.as_ptr(), 0, &mut integer); if res != ffi::FcResultMatch { return None; } @@ -484,7 +490,7 @@ mod fc { impl Drop for FontSet { fn drop(&mut self) { - unsafe { ffi::FcFontSetDestroy(self.d) } + unsafe { ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcFontSetDestroy, self.d) } } } @@ -497,7 +503,7 @@ mod fc { pub fn new() -> Self { unsafe { ObjectSet { - d: ffi::FcObjectSetCreate(), + d: ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcObjectSetCreate,), } } } @@ -507,14 +513,14 @@ mod fc { unsafe { // Returns `false` if the property name cannot be inserted // into the set (due to allocation failure). - assert_eq!(ffi::FcObjectSetAdd(self.d, object.as_ptr()), 1); + assert_eq!(ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcObjectSetAdd, self.d, object.as_ptr()), 1); } } } impl Drop for ObjectSet { fn drop(&mut self) { - unsafe { ffi::FcObjectSetDestroy(self.d) } + unsafe { ffi_dispatch!(feature="source-fontconfig-dlopen", LIB, FcObjectSetDestroy, self.d) } } } }