use crate::{sys, ObjectSet, ObjectSetRef, Pattern, PatternRef};
use std::marker::PhantomData;
use std::ptr::NonNull;
use std::slice;
#[derive(Copy, Clone)]
pub struct FontSetRef<'a>(NonNull<sys::FcFontSet>, PhantomData<&'a sys::FcFontSet>);
impl<'a> FontSetRef<'a> {
fn as_ptr(self) -> *mut sys::FcFontSet {
self.0.as_ptr()
}
pub fn fonts(self) -> &'a [PatternRef<'a>] {
let ptr = unsafe { (*self.as_ptr()).fonts.cast() };
let len = unsafe { (*self.as_ptr()).nfont } as usize;
if len == 0 {
&[]
} else {
unsafe { slice::from_raw_parts(ptr, len) }
}
}
}
pub struct FontSet(NonNull<sys::FcFontSet>);
impl FontSet {
pub fn all() -> FontSet {
FontSet::new(
Pattern::from_name(c"").unwrap().as_ref(),
ObjectSet::all().as_ref(),
)
}
pub fn new(pattern: PatternRef<'_>, objects: ObjectSetRef<'_>) -> FontSet {
super::init();
let ptr = unsafe {
sys::FcFontList(
sys::FcConfigGetCurrent(),
pattern.as_ptr(),
objects.as_ptr(),
)
};
FontSet(NonNull::new(ptr).unwrap())
}
pub fn as_ref(&self) -> FontSetRef<'_> {
FontSetRef(self.0, PhantomData)
}
}
impl Drop for FontSet {
fn drop(&mut self) {
unsafe { sys::FcFontSetDestroy(self.0.as_ptr()) }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_font_set() {
let all = FontSet::all();
let fs = all.as_ref();
assert!(!fs.fonts().is_empty());
}
}