aboutsummaryrefslogtreecommitdiff
path: root/src/list_fonts.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/list_fonts.rs')
-rw-r--r--src/list_fonts.rs186
1 files changed, 0 insertions, 186 deletions
diff --git a/src/list_fonts.rs b/src/list_fonts.rs
deleted file mode 100644
index f171f57e..00000000
--- a/src/list_fonts.rs
+++ /dev/null
@@ -1,186 +0,0 @@
-use std::collections::HashMap;
-use std::ffi::{CStr, CString};
-use std::fmt;
-use std::path::PathBuf;
-use std::ptr;
-use std::str::from_utf8;
-
-use libc::{c_char, c_int};
-
-use fontconfig::fontconfig::{FcConfigGetCurrent, FcConfigGetFonts, FcSetSystem};
-use fontconfig::fontconfig::{FcPatternGetString, FcPatternCreate, FcPatternAddString};
-use fontconfig::fontconfig::{FcPatternGetInteger};
-use fontconfig::fontconfig::{FcObjectSetCreate, FcObjectSetAdd};
-use fontconfig::fontconfig::{FcResultMatch, FcFontSetList};
-use fontconfig::fontconfig::{FcChar8};
-use fontconfig::fontconfig::{FcFontSetDestroy, FcPatternDestroy, FcObjectSetDestroy};
-
-unsafe fn fc_char8_to_string(fc_str: *mut FcChar8) -> String {
- from_utf8(CStr::from_ptr(fc_str as *const c_char).to_bytes()).unwrap().to_owned()
-}
-
-fn list_families() -> Vec<String> {
- let mut families = Vec::new();
- unsafe {
- // https://www.freedesktop.org/software/fontconfig/fontconfig-devel/fcconfiggetcurrent.html
- let config = FcConfigGetCurrent(); // *mut FcConfig
-
- // https://www.freedesktop.org/software/fontconfig/fontconfig-devel/fcconfiggetfonts.html
- let font_set = FcConfigGetFonts(config, FcSetSystem); // *mut FcFontSet
-
- let nfont = (*font_set).nfont as isize;
- for i in 0..nfont {
- let font = (*font_set).fonts.offset(i); // *mut FcPattern
- let id = 0 as c_int;
- let mut family: *mut FcChar8 = ptr::null_mut();
- let mut format: *mut FcChar8 = ptr::null_mut();
-
- let result = FcPatternGetString(*font,
- b"fontformat\0".as_ptr() as *mut c_char,
- id,
- &mut format);
-
- if result != FcResultMatch {
- continue;
- }
-
- let format = fc_char8_to_string(format);
-
- if format != "TrueType" && format != "CFF" {
- continue
- }
-
- let mut id = 0;
- while FcPatternGetString(*font, b"family\0".as_ptr() as *mut c_char, id, &mut family) == FcResultMatch {
- let safe_family = fc_char8_to_string(family);
- id += 1;
- families.push(safe_family);
- }
- }
- }
-
- families.sort();
- families.dedup();
- families
-}
-
-#[derive(Debug)]
-pub struct Variant {
- style: String,
- file: PathBuf,
- index: isize,
-}
-
-impl Variant {
- #[inline]
- pub fn path(&self) -> &::std::path::Path {
- self.file.as_path()
- }
-
- #[inline]
- pub fn index(&self) -> isize {
- self.index
- }
-}
-
-#[derive(Debug)]
-pub struct Family {
- name: String,
- variants: HashMap<String, Variant>,
-}
-
-impl fmt::Display for Family {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(write!(f, "{}: ", self.name));
- for (k, _v) in &self.variants {
- try!(write!(f, "{}, ", k));
- }
-
- Ok(())
- }
-}
-
-impl Family {
- #[inline]
- pub fn variants(&self) -> &HashMap<String, Variant> {
- &self.variants
- }
-}
-
-static FILE: &'static [u8] = b"file\0";
-static FAMILY: &'static [u8] = b"family\0";
-static INDEX: &'static [u8] = b"index\0";
-static STYLE: &'static [u8] = b"style\0";
-
-pub fn get_family_info(family: String) -> Family {
-
- let mut members = Vec::new();
-
- unsafe {
- let config = FcConfigGetCurrent(); // *mut FcConfig
- let mut font_set = FcConfigGetFonts(config, FcSetSystem); // *mut FcFontSet
-
- let pattern = FcPatternCreate();
- let family_name = CString::new(&family[..]).unwrap();
- let family_name = family_name.as_ptr();
-
- // Add family name to pattern. Use this for searching.
- FcPatternAddString(pattern, FAMILY.as_ptr() as *mut c_char, family_name as *mut FcChar8);
-
- // Request filename, style, and index for each variant in family
- let object_set = FcObjectSetCreate(); // *mut FcObjectSet
- FcObjectSetAdd(object_set, FILE.as_ptr() as *mut c_char);
- FcObjectSetAdd(object_set, INDEX.as_ptr() as *mut c_char);
- FcObjectSetAdd(object_set, STYLE.as_ptr() as *mut c_char);
-
- let variants = FcFontSetList(config, &mut font_set, 1 /* nsets */, pattern, object_set);
- let num_variant = (*variants).nfont as isize;
-
- for i in 0..num_variant {
- let font = (*variants).fonts.offset(i);
- let mut file: *mut FcChar8 = ptr::null_mut();
- assert_eq!(FcPatternGetString(*font, FILE.as_ptr() as *mut c_char, 0, &mut file),
- FcResultMatch);
- let file = fc_char8_to_string(file);
-
- let mut style: *mut FcChar8 = ptr::null_mut();
- assert_eq!(FcPatternGetString(*font, STYLE.as_ptr() as *mut c_char, 0, &mut style),
- FcResultMatch);
- let style = fc_char8_to_string(style);
-
- let mut index = 0 as c_int;
- assert_eq!(FcPatternGetInteger(*font, INDEX.as_ptr() as *mut c_char, 0, &mut index),
- FcResultMatch);
-
- members.push(Variant {
- style: style,
- file: PathBuf::from(file),
- index: index as isize,
- });
- }
-
- FcFontSetDestroy(variants);
- FcPatternDestroy(pattern);
- FcObjectSetDestroy(object_set);
- }
-
- Family {
- name: family,
- variants: members.into_iter().map(|v| (v.style.clone(), v)).collect()
- }
-}
-
-pub fn get_font_families() -> HashMap<String, Family> {
- list_families().into_iter()
- .map(|family| (family.clone(), get_family_info(family)))
- .collect()
-}
-
-#[cfg(test)]
-mod tests {
- #[test]
- fn get_font_families() {
- let families = super::get_font_families();
- assert!(!families.is_empty());
- }
-}