Impl freetype use, bindgen for fontconfig

TODO: fontconfig
This commit is contained in:
Stephen Seo 2022-07-31 19:52:00 +09:00
parent ab604b34ee
commit 1d9342d8f5
6 changed files with 293 additions and 45 deletions

137
Cargo.lock generated
View file

@ -30,6 +30,15 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" 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]] [[package]]
name = "alsa" name = "alsa"
version = "0.6.0" version = "0.6.0"
@ -120,21 +129,26 @@ checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270"
[[package]] [[package]]
name = "bindgen" name = "bindgen"
version = "0.59.2" version = "0.53.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" checksum = "c72a978d268b1d70b0e963217e60fdabd9523a941457a6c42a7315d15c7e89e5"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cexpr", "cexpr",
"cfg-if 0.1.10",
"clang-sys", "clang-sys",
"clap",
"env_logger",
"lazy_static", "lazy_static",
"lazycell", "lazycell",
"log",
"peeking_take_while", "peeking_take_while",
"proc-macro2", "proc-macro2",
"quote", "quote",
"regex", "regex",
"rustc-hash", "rustc-hash",
"shlex", "shlex",
"which",
] ]
[[package]] [[package]]
@ -264,11 +278,11 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
[[package]] [[package]]
name = "cexpr" name = "cexpr"
version = "0.6.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
dependencies = [ dependencies = [
"nom", "nom 5.1.2",
] ]
[[package]] [[package]]
@ -294,13 +308,13 @@ dependencies = [
[[package]] [[package]]
name = "clang-sys" name = "clang-sys"
version = "1.3.3" version = "0.29.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b" checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a"
dependencies = [ dependencies = [
"glob", "glob",
"libc", "libc",
"libloading 0.7.3", "libloading 0.5.2",
] ]
[[package]] [[package]]
@ -380,12 +394,6 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "const-cstr"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3d0b5ff30645a68f35ece8cea4556ca14ef8a1651455f789a099a0513532a6"
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.6.4" version = "0.6.4"
@ -496,9 +504,9 @@ dependencies = [
[[package]] [[package]]
name = "coreaudio-sys" name = "coreaudio-sys"
version = "0.2.10" version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dff444d80630d7073077d38d40b4501fd518bd2b922c2a55edcc8b0f7be57e6" checksum = "17f73df0f29f4c3c374854f076c47dc018f19acaa63538880dba0937ad4fa8d7"
dependencies = [ dependencies = [
"bindgen", "bindgen",
] ]
@ -781,6 +789,19 @@ version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" 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]] [[package]]
name = "error-chain" name = "error-chain"
version = "0.12.4" version = "0.12.4"
@ -862,15 +883,6 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 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]] [[package]]
name = "foreign-types" name = "foreign-types"
version = "0.3.2" version = "0.3.2"
@ -1215,6 +1227,15 @@ version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549" 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]] [[package]]
name = "ident_case" name = "ident_case"
version = "1.0.1" version = "1.0.1"
@ -1385,6 +1406,16 @@ version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" 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]] [[package]]
name = "libloading" name = "libloading"
version = "0.6.7" version = "0.6.7"
@ -1639,7 +1670,7 @@ dependencies = [
name = "mpd_info_screen" name = "mpd_info_screen"
version = "0.2.20" version = "0.2.20"
dependencies = [ dependencies = [
"fontconfig", "bindgen",
"freetype", "freetype",
"ggez", "ggez",
"image 0.24.3", "image 0.24.3",
@ -1793,6 +1824,16 @@ dependencies = [
"memoffset", "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]] [[package]]
name = "nom" name = "nom"
version = "7.1.1" version = "7.1.1"
@ -2156,6 +2197,12 @@ dependencies = [
"unicase", "unicase",
] ]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.20" version = "1.0.20"
@ -2264,6 +2311,8 @@ version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [ dependencies = [
"aho-corasick",
"memchr",
"regex-syntax", "regex-syntax",
] ]
@ -2446,9 +2495,9 @@ dependencies = [
[[package]] [[package]]
name = "shlex" name = "shlex"
version = "1.1.0" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
[[package]] [[package]]
name = "sid" name = "sid"
@ -2660,6 +2709,15 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "textwrap" name = "textwrap"
version = "0.11.0" version = "0.11.0"
@ -2982,6 +3040,15 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
[[package]]
name = "which"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"
@ -3062,7 +3129,7 @@ version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7"
dependencies = [ dependencies = [
"nom", "nom 7.1.1",
] ]
[[package]] [[package]]
@ -3086,18 +3153,6 @@ version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" 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]] [[package]]
name = "zip" name = "zip"
version = "0.5.13" version = "0.5.13"

View file

@ -13,7 +13,9 @@ structopt = "0.3"
image = "0.24" image = "0.24"
ggez = "0.7" ggez = "0.7"
freetype = { version = "0.7", optional = true } freetype = { version = "0.7", optional = true }
fontconfig = { version = "0.5", optional = true }
[build-dependencies]
bindgen = { version = "0.53", optional = true }
[features] [features]
unicode_support = ["dep:freetype", "dep:fontconfig"] unicode_support = ["dep:freetype", "dep:bindgen"]

26
build.rs Normal file
View file

@ -0,0 +1,26 @@
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");
}

1
src/bindgen_wrapper.h Normal file
View file

@ -0,0 +1 @@
#include <fontconfig/fontconfig.h>

View file

@ -1 +1,9 @@
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"));
}
}

View file

@ -1 +1,157 @@
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))
}