source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
+[[package]]
+name = "aho-corasick"
+version = "0.7.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "alsa"
version = "0.6.0"
[[package]]
name = "bindgen"
-version = "0.59.2"
+version = "0.53.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8"
+checksum = "c72a978d268b1d70b0e963217e60fdabd9523a941457a6c42a7315d15c7e89e5"
dependencies = [
"bitflags",
"cexpr",
+ "cfg-if 0.1.10",
"clang-sys",
+ "clap",
+ "env_logger",
"lazy_static",
"lazycell",
+ "log",
"peeking_take_while",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
+ "which",
]
[[package]]
[[package]]
name = "cexpr"
-version = "0.6.0"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
+checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
dependencies = [
- "nom",
+ "nom 5.1.2",
]
[[package]]
[[package]]
name = "clang-sys"
-version = "1.3.3"
+version = "0.29.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b"
+checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a"
dependencies = [
"glob",
"libc",
- "libloading 0.7.3",
+ "libloading 0.5.2",
]
[[package]]
"memchr",
]
-[[package]]
-name = "const-cstr"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed3d0b5ff30645a68f35ece8cea4556ca14ef8a1651455f789a099a0513532a6"
-
[[package]]
name = "core-foundation"
version = "0.6.4"
[[package]]
name = "coreaudio-sys"
-version = "0.2.10"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3dff444d80630d7073077d38d40b4501fd518bd2b922c2a55edcc8b0f7be57e6"
+checksum = "17f73df0f29f4c3c374854f076c47dc018f19acaa63538880dba0937ad4fa8d7"
dependencies = [
"bindgen",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
+[[package]]
+name = "env_logger"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
+dependencies = [
+ "atty",
+ "humantime",
+ "log",
+ "regex",
+ "termcolor",
+]
+
[[package]]
name = "error-chain"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
-[[package]]
-name = "fontconfig"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a25320ad784a9578ada0b395dd7dcd2321109404bbb341ec27e64b01a1e49b47"
-dependencies = [
- "yeslogic-fontconfig-sys",
-]
-
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549"
+[[package]]
+name = "humantime"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
+dependencies = [
+ "quick-error",
+]
+
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+[[package]]
+name = "libloading"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
+dependencies = [
+ "cc",
+ "winapi",
+]
+
[[package]]
name = "libloading"
version = "0.6.7"
name = "mpd_info_screen"
version = "0.2.20"
dependencies = [
- "fontconfig",
+ "bindgen",
"freetype",
"ggez",
"image 0.24.3",
"memoffset",
]
+[[package]]
+name = "nom"
+version = "5.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
+dependencies = [
+ "memchr",
+ "version_check",
+]
+
[[package]]
name = "nom"
version = "7.1.1"
"unicase",
]
+[[package]]
+name = "quick-error"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+
[[package]]
name = "quote"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
+ "aho-corasick",
+ "memchr",
"regex-syntax",
]
[[package]]
name = "shlex"
-version = "1.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
+checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
[[package]]
name = "sid"
"winapi",
]
+[[package]]
+name = "termcolor"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
+dependencies = [
+ "winapi-util",
+]
+
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
+[[package]]
+name = "which"
+version = "3.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7"
dependencies = [
- "nom",
+ "nom 7.1.1",
]
[[package]]
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
-[[package]]
-name = "yeslogic-fontconfig-sys"
-version = "3.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2bbd69036d397ebbff671b1b8e4d918610c181c5a16073b96f984a38d08c386"
-dependencies = [
- "const-cstr",
- "dlib 0.5.0",
- "once_cell",
- "pkg-config",
-]
-
[[package]]
name = "zip"
version = "0.5.13"
image = "0.24"
ggez = "0.7"
freetype = { version = "0.7", optional = true }
-fontconfig = { version = "0.5", optional = true }
+
+[build-dependencies]
+bindgen = { version = "0.53", optional = true }
[features]
-unicode_support = ["dep:freetype", "dep:fontconfig"]
+unicode_support = ["dep:freetype", "dep:bindgen"]
--- /dev/null
+use std::env;
+use std::path::PathBuf;
+
+use bindgen;
+
+#[cfg(not(feature = "unicode_support"))]
+fn main() {
+}
+
+#[cfg(feature = "unicode_support")]
+fn main() {
+ println!("cargo:rustc-link-search=/usr/lib");
+ println!("cargo:rustc-link-lib=fontconfig");
+ println!("cargo:rerun-if-changed=src/bindgen_wrapper.h");
+
+ let bindings = bindgen::Builder::default()
+ .header("src/bindgen_wrapper.h")
+ .parse_callbacks(Box::new(bindgen::CargoCallbacks))
+ .generate()
+ .expect("Unable to generate bindings");
+
+ let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
+ bindings
+ .write_to_file(out_path.join("unicode_support_bindings.rs"))
+ .expect("Couldn't write bindings");
+}
--- /dev/null
+#include <fontconfig/fontconfig.h>
-use fontconfig;
+mod ffi {
+ mod bindgen {
+ #![allow(non_upper_case_globals)]
+ #![allow(non_camel_case_types)]
+ #![allow(non_snake_case)]
+
+ include!(concat!(env!("OUT_DIR"), "/unicode_support_bindings.rs"));
+ }
+}
-use freetype;
+use std::path::Path;
+
+mod ffi {
+ use freetype::freetype::{
+ FT_Done_Face, FT_Done_Library, FT_Face, FT_FaceRec_, FT_Get_Char_Index, FT_Init_FreeType,
+ FT_Library, FT_ModuleRec_, FT_Open_Args, FT_Open_Face, FT_Parameter_, FT_StreamRec_,
+ FT_OPEN_PATHNAME,
+ };
+ use std::ffi::CString;
+ use std::path::Path;
+
+ pub struct FTLibrary {
+ library: FT_Library,
+ }
+
+ impl Drop for FTLibrary {
+ fn drop(&mut self) {
+ if !self.library.is_null() {
+ unsafe {
+ FT_Done_Library(self.library);
+ }
+ }
+ }
+ }
+
+ impl FTLibrary {
+ pub fn new() -> Option<FTLibrary> {
+ unsafe {
+ let mut library_ptr: FT_Library = 0 as FT_Library;
+ if FT_Init_FreeType(&mut library_ptr) != 0 {
+ Some(FTLibrary {
+ library: library_ptr,
+ })
+ } else {
+ None
+ }
+ }
+ }
+
+ pub fn get(&self) -> FT_Library {
+ self.library
+ }
+ }
+
+ pub struct FTOpenArgs {
+ args: FT_Open_Args,
+ pathname: Option<CString>,
+ }
+
+ impl FTOpenArgs {
+ pub fn new_with_path(path: &Path) -> Self {
+ unsafe {
+ let cstring: CString = CString::from_vec_unchecked(
+ path.as_os_str().to_str().unwrap().as_bytes().to_vec(),
+ );
+ let mut args = FT_Open_Args {
+ flags: FT_OPEN_PATHNAME,
+ memory_base: 0 as *const u8,
+ memory_size: 0,
+ pathname: cstring.as_ptr() as *mut i8,
+ stream: 0 as *mut FT_StreamRec_,
+ driver: 0 as *mut FT_ModuleRec_,
+ num_params: 0,
+ params: 0 as *mut FT_Parameter_,
+ };
+
+ FTOpenArgs {
+ args,
+ pathname: Some(cstring),
+ }
+ }
+ }
+
+ pub fn get_args(&self) -> FT_Open_Args {
+ self.args
+ }
+
+ pub fn get_ptr(&mut self) -> *mut FT_Open_Args {
+ &mut self.args as *mut FT_Open_Args
+ }
+ }
+
+ pub struct FTFaces {
+ faces: Vec<FT_Face>,
+ }
+
+ impl Drop for FTFaces {
+ fn drop(&mut self) {
+ for face in &self.faces {
+ unsafe {
+ FT_Done_Face(*face);
+ }
+ }
+ }
+ }
+
+ impl FTFaces {
+ pub fn new(library: &FTLibrary, args: &mut FTOpenArgs) -> Result<FTFaces, ()> {
+ let mut faces = FTFaces { faces: Vec::new() };
+ unsafe {
+ let count;
+ let mut face: FT_Face = 0 as FT_Face;
+ // first get number of faces
+ let mut result = FT_Open_Face(
+ library.get(),
+ args.get_ptr(),
+ -1,
+ &mut face as *mut *mut FT_FaceRec_,
+ );
+ if result != 0 {
+ FT_Done_Face(face);
+ return Err(());
+ }
+ count = (*face).num_faces;
+
+ for i in 0..count {
+ result = FT_Open_Face(
+ library.get(),
+ args.get_ptr(),
+ i,
+ &mut face as *mut *mut FT_FaceRec_,
+ );
+ if result != 0 {
+ FT_Done_Face(face);
+ return Err(());
+ }
+ faces.faces.push(face);
+ }
+ }
+
+ Ok(faces)
+ }
+
+ pub fn has_char(&self, c: char) -> bool {
+ let char_value: u64 = c as u64;
+
+ for face in &self.faces {
+ unsafe {
+ let result = FT_Get_Char_Index(*face, char_value);
+ if result != 0 {
+ return true;
+ }
+ }
+ }
+
+ false
+ }
+ }
+}
+
+pub fn font_has_char(c: char, font_path: &Path) -> Result<bool, ()> {
+ let library = ffi::FTLibrary::new().ok_or(())?;
+ let mut args = ffi::FTOpenArgs::new_with_path(font_path);
+ let faces = ffi::FTFaces::new(&library, &mut args)?;
+
+ Ok(faces.has_char(c))
+}