From 6c9a65e63d8ef803b80a071e1623533849d53590 Mon Sep 17 00:00:00 2001 From: Andy Carlson <2yinyang2@gmail.com> Date: Tue, 25 Feb 2025 10:36:01 -0500 Subject: [PATCH 1/2] add fallible font methods to FontCollection --- src/font_collection.rs | 64 +++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/src/font_collection.rs b/src/font_collection.rs index 90b9121..3e4974f 100644 --- a/src/font_collection.rs +++ b/src/font_collection.rs @@ -10,6 +10,7 @@ use winapi::shared::minwindef::{BOOL, FALSE, TRUE}; use winapi::shared::winerror::S_OK; use winapi::um::dwrite::IDWriteFontCollectionLoader; use winapi::um::dwrite::{IDWriteFont, IDWriteFontCollection, IDWriteFontFamily}; +use winapi::um::winnt::HRESULT; use wio::com::ComPtr; use super::{DWriteFactory, Font, FontDescriptor, FontFace, FontFamily}; @@ -108,62 +109,87 @@ impl FontCollection { unsafe { (*self.native.get()).GetFontFamilyCount() } } + #[deprecated(note = "Use `font_family` instead.")] pub fn get_font_family(&self, index: u32) -> FontFamily { + self.font_family(index).unwrap() + } + + pub fn font_family(&self, index: u32) -> Result { + let mut family: *mut IDWriteFontFamily = ptr::null_mut(); unsafe { - let mut family: *mut IDWriteFontFamily = ptr::null_mut(); let hr = (*self.native.get()).GetFontFamily(index, &mut family); - assert!(hr == 0); - FontFamily::take(ComPtr::from_raw(family)) + if hr != S_OK { + return Err(hr); + } + Ok(FontFamily::take(ComPtr::from_raw(family))) } } - // Find a font matching the given font descriptor in this - // font collection. + #[deprecated(note = "Use `font_from_descriptor` instead.")] pub fn get_font_from_descriptor(&self, desc: &FontDescriptor) -> Option { - if let Some(family) = self.get_font_family_by_name(&desc.family_name) { - let font = family.get_first_matching_font(desc.weight, desc.stretch, desc.style); + self.font_from_descriptor(desc).unwrap() + } + + // Find a font matching the given font descriptor in this font collection. + pub fn font_from_descriptor(&self, desc: &FontDescriptor) -> Result, HRESULT> { + if let Some(family) = self.font_family_by_name(&desc.family_name)? { + let font = family.first_matching_font(desc.weight, desc.stretch, desc.style)?; // Exact matches only here if font.weight() == desc.weight && font.stretch() == desc.stretch && font.style() == desc.style { - return Some(font); + return Ok(Some(font)); } } - None + Ok(None) } + #[deprecated(note = "Use `font_from_face` instead.")] pub fn get_font_from_face(&self, face: &FontFace) -> Option { + self.font_from_face(face).ok() + } + + pub fn font_from_face(&self, face: &FontFace) -> Result { + let mut font: *mut IDWriteFont = ptr::null_mut(); unsafe { - let mut font: *mut IDWriteFont = ptr::null_mut(); let hr = (*self.native.get()).GetFontFromFontFace(face.as_ptr(), &mut font); - if hr != 0 { - return None; + if hr != S_OK { + return Err(hr); } - Some(Font::take(ComPtr::from_raw(font))) + Ok(Font::take(ComPtr::from_raw(font))) } } + #[deprecated(note = "Use `font_family_by_name` instead.")] pub fn get_font_family_by_name(&self, family_name: &str) -> Option { + self.font_family_by_name(family_name).unwrap() + } + + pub fn font_family_by_name(&self, family_name: &str) -> Result, HRESULT> { + let mut index: u32 = 0; + let mut exists: BOOL = FALSE; unsafe { - let mut index: u32 = 0; - let mut exists: BOOL = FALSE; let hr = (*self.native.get()).FindFamilyName( family_name.to_wide_null().as_ptr(), &mut index, &mut exists, ); - assert!(hr == 0); + if hr != S_OK { + return Err(hr); + } if exists == FALSE { - return None; + return Ok(None); } let mut family: *mut IDWriteFontFamily = ptr::null_mut(); let hr = (*self.native.get()).GetFontFamily(index, &mut family); - assert!(hr == 0); + if hr != S_OK { + return Err(hr); + } - Some(FontFamily::take(ComPtr::from_raw(family))) + Ok(Some(FontFamily::take(ComPtr::from_raw(family)))) } } } From 0b653dc45b61dcf8a4875587fb9b0737521476f0 Mon Sep 17 00:00:00 2001 From: Andy Carlson <2yinyang2@gmail.com> Date: Sun, 23 Mar 2025 09:35:52 -0400 Subject: [PATCH 2/2] apply mrobinson patch --- src/font_collection.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/font_collection.rs b/src/font_collection.rs index 3e4974f..2154b28 100644 --- a/src/font_collection.rs +++ b/src/font_collection.rs @@ -114,6 +114,7 @@ impl FontCollection { self.font_family(index).unwrap() } + /// Returns the [`FontFamily`] at the given index. pub fn font_family(&self, index: u32) -> Result { let mut family: *mut IDWriteFontFamily = ptr::null_mut(); unsafe { @@ -130,7 +131,7 @@ impl FontCollection { self.font_from_descriptor(desc).unwrap() } - // Find a font matching the given font descriptor in this font collection. + /// Find a font matching the given font descriptor in this [`FontCollection`]. pub fn font_from_descriptor(&self, desc: &FontDescriptor) -> Result, HRESULT> { if let Some(family) = self.font_family_by_name(&desc.family_name)? { let font = family.first_matching_font(desc.weight, desc.stretch, desc.style)?; @@ -151,6 +152,7 @@ impl FontCollection { self.font_from_face(face).ok() } + /// Get a [`Font`] from the given [`FontFace`]. pub fn font_from_face(&self, face: &FontFace) -> Result { let mut font: *mut IDWriteFont = ptr::null_mut(); unsafe { @@ -167,6 +169,8 @@ impl FontCollection { self.font_family_by_name(family_name).unwrap() } + /// Find a [`FontFamily`] with the given name. Returns `None` if no family + /// with that name is found. pub fn font_family_by_name(&self, family_name: &str) -> Result, HRESULT> { let mut index: u32 = 0; let mut exists: BOOL = FALSE;