#![allow(unused_imports, non_snake_case, non_camel_case_types, unused_variables)]
use super::windows::*;
use super::*;
pub unsafe fn get_font_name_en(font: &mut ComPtr<IDWriteFont>) -> Option<String> {
let mut names: *mut IDWriteLocalizedStrings = ptr::null_mut();
if S_OK != font.GetFaceNames(&mut names) {
return None;
}
let mut names = ComPtr::from_raw(names);
get_locale_string_en(&mut names)
}
pub unsafe fn get_family_name_en(family: &mut ComPtr<IDWriteFontFamily>) -> Option<String> {
let mut names: *mut IDWriteLocalizedStrings = ptr::null_mut();
if S_OK != family.GetFamilyNames(&mut names) {
return None;
}
let mut names = ComPtr::from_raw(names);
get_locale_string_en(&mut names)
}
pub unsafe fn get_locale_string_en(strings: &mut ComPtr<IDWriteLocalizedStrings>) -> Option<String> {
thread_local! {
static EN_US_LOCALE: std::rc::Rc<Vec<wchar_t>> = std::rc::Rc::new(OsStr::new("en-us").to_wide_null());
}
let mut index: u32 = 0;
let mut exists: BOOL = FALSE;
let hr = strings.FindLocaleName((EN_US_LOCALE.with(|v| v.clone())).as_ptr(), &mut index, &mut exists);
if hr != S_OK || exists == FALSE {
index = 0;
}
get_locale_string(strings, index)
}
pub unsafe fn get_locale_string(strings: &mut ComPtr<IDWriteLocalizedStrings>, index: UINT32) -> Option<String> {
let mut buffer = [0u16; 1024];
let mut length: UINT32 = 0;
if S_OK != strings.GetStringLength(index, &mut length) {
return None;
}
if length + 1 > buffer.len() as _ {
return Default::default();
}
if S_OK != strings.GetString(index, buffer.as_mut_ptr(), length + 1) {
return None;
}
String::from_utf16(&buffer[..length as _]).ok()
}
pub unsafe fn font_file(font: &mut ComPtr<IDWriteFont>) -> Option<(u32, PathBuf)> {
let mut face: *mut IDWriteFontFace = ptr::null_mut();
if S_OK != font.CreateFontFace(&mut face) {
return None;
}
let Some(face) = ComPtr::try_from_raw(face) else { return None };
let mut num_files: UINT32 = 0;
if S_OK != face.GetFiles(&mut num_files, ptr::null_mut()) {
return None;
}
if num_files < 1 {
return None;
}
num_files = 1;
let mut file: *mut IDWriteFontFile = ptr::null_mut();
if S_OK != face.GetFiles(&mut num_files, &mut file) {
return None;
}
let path = font_file_path(&mut ComPtr::from_raw(file))?;
let index = face.GetIndex();
Some((index, path))
}
#[cfg(target_os = "windows")]
pub unsafe fn font_file_path(fontfile: &mut ComPtr<IDWriteFontFile>) -> Option<PathBuf> {
use std::os::windows::ffi::OsStringExt as _;
let mut loader: *mut IDWriteFontFileLoader = ptr::null_mut();
if S_OK != fontfile.GetLoader(&mut loader) {
return None;
}
let loader = ComPtr::try_from_raw(loader)?;
let mut ref_key: *const c_void = ptr::null();
let mut ref_size: UINT32 = 0;
if S_OK != fontfile.GetReferenceKey(&mut ref_key, &mut ref_size) {
return None;
}
let loader: ComPtr<IDWriteLocalFontFileLoader> = loader.cast().ok()?;
let mut path = [0u16; 1024];
let mut length: UINT32 = 0;
if S_OK != loader.GetFilePathLengthFromKey(ref_key, ref_size, &mut length) {
return None;
}
if length + 1 > path.len() as _ {
return None;
}
if S_OK != loader.GetFilePathFromKey(ref_key, ref_size, path.as_mut_ptr(), length + 1) {
return None;
}
let path = &path[..length as _];
Some(PathBuf::from(OsString::from_wide(&path)))
}
#[cfg(not(target_os = "windows"))]
pub unsafe fn font_file_path(fontfile: &mut ComPtr<IDWriteFontFile>) -> Option<PathBuf> {
None
}