* use a Result for font functions that can fail

* derive Debug for FontError and add data to the variants
This commit is contained in:
Sebastian 2024-03-10 15:08:16 +00:00 committed by GitHub
parent dc6034f666
commit 30419d0766
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 24 deletions

View File

@ -377,8 +377,11 @@ pub unsafe extern "C" fn PFCanvasSetLineDashOffset(canvas: PFCanvasRef, new_offs
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFCanvasSetFontByPostScriptName(canvas: PFCanvasRef, pub unsafe extern "C" fn PFCanvasSetFontByPostScriptName(canvas: PFCanvasRef,
postscript_name: *const c_char, postscript_name: *const c_char,
postscript_name_len: usize) { postscript_name_len: usize) -> i32 {
(*canvas).set_font(to_rust_string(&postscript_name, postscript_name_len)) match (*canvas).set_font(to_rust_string(&postscript_name, postscript_name_len)) {
Ok(_) => 0,
Err(_) => 1
}
} }
#[no_mangle] #[no_mangle]

View File

@ -10,6 +10,7 @@
use crate::{CanvasRenderingContext2D, State, TextAlign, TextBaseline}; use crate::{CanvasRenderingContext2D, State, TextAlign, TextBaseline};
use font_kit::canvas::RasterizationOptions; use font_kit::canvas::RasterizationOptions;
use font_kit::error::{FontLoadingError, SelectionError};
use font_kit::family_name::FamilyName; use font_kit::family_name::FamilyName;
use font_kit::handle::Handle; use font_kit::handle::Handle;
use font_kit::hinting::HintingOptions; use font_kit::hinting::HintingOptions;
@ -103,9 +104,10 @@ impl CanvasRenderingContext2D {
} }
#[inline] #[inline]
pub fn set_font<FC>(&mut self, font_collection: FC) where FC: IntoFontCollection { pub fn set_font<FC>(&mut self, font_collection: FC) -> Result<(), FontError> where FC: IntoFontCollection {
let font_collection = font_collection.into_font_collection(&self.canvas_font_context); let font_collection = font_collection.into_font_collection(&self.canvas_font_context)?;
self.current_state.font_collection = font_collection; self.current_state.font_collection = font_collection;
Ok(())
} }
#[inline] #[inline]
@ -188,6 +190,13 @@ impl ToTextLayout for TextMetrics {
#[derive(Clone)] #[derive(Clone)]
pub struct CanvasFontContext(pub(crate) Rc<RefCell<CanvasFontContextData>>); pub struct CanvasFontContext(pub(crate) Rc<RefCell<CanvasFontContextData>>);
/// The reason a font could not be loaded
#[derive(Debug)]
pub enum FontError {
NotFound(SelectionError),
LoadError(FontLoadingError),
}
pub(super) struct CanvasFontContextData { pub(super) struct CanvasFontContextData {
pub(super) font_context: FontContext<Font>, pub(super) font_context: FontContext<Font>,
#[allow(dead_code)] #[allow(dead_code)]
@ -224,16 +233,15 @@ impl CanvasFontContext {
CanvasFontContext::new(Arc::new(MemSource::from_fonts(fonts).unwrap())) CanvasFontContext::new(Arc::new(MemSource::from_fonts(fonts).unwrap()))
} }
fn get_font_by_postscript_name(&self, postscript_name: &str) -> Font { fn get_font_by_postscript_name(&self, postscript_name: &str) -> Result<Font, FontError> {
let this = self.0.borrow(); let this = self.0.borrow();
if let Some(cached_font) = this.font_context.get_cached_font(postscript_name) { if let Some(cached_font) = this.font_context.get_cached_font(postscript_name) {
return (*cached_font).clone(); return Ok((*cached_font).clone());
} }
this.font_source this.font_source
.select_by_postscript_name(postscript_name) .select_by_postscript_name(postscript_name)
.expect("Couldn't find a font with that PostScript name!") .map_err(FontError::NotFound)?
.load() .load().map_err(FontError::LoadError)
.expect("Failed to load the font!")
} }
} }
@ -523,46 +531,46 @@ impl VerticalMetrics {
/// Various things that can be conveniently converted into font collections for use with /// Various things that can be conveniently converted into font collections for use with
/// `CanvasRenderingContext2D::set_font()`. /// `CanvasRenderingContext2D::set_font()`.
pub trait IntoFontCollection { pub trait IntoFontCollection {
fn into_font_collection(self, font_context: &CanvasFontContext) -> Arc<FontCollection>; fn into_font_collection(self, font_context: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError>;
} }
impl IntoFontCollection for Arc<FontCollection> { impl IntoFontCollection for Arc<FontCollection> {
#[inline] #[inline]
fn into_font_collection(self, _: &CanvasFontContext) -> Arc<FontCollection> { fn into_font_collection(self, _: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
self Ok(self)
} }
} }
impl IntoFontCollection for FontFamily { impl IntoFontCollection for FontFamily {
#[inline] #[inline]
fn into_font_collection(self, _: &CanvasFontContext) -> Arc<FontCollection> { fn into_font_collection(self, _: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
let mut font_collection = FontCollection::new(); let mut font_collection = FontCollection::new();
font_collection.add_family(self); font_collection.add_family(self);
Arc::new(font_collection) Ok(Arc::new(font_collection))
} }
} }
impl IntoFontCollection for Vec<FontFamily> { impl IntoFontCollection for Vec<FontFamily> {
#[inline] #[inline]
fn into_font_collection(self, _: &CanvasFontContext) -> Arc<FontCollection> { fn into_font_collection(self, _: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
let mut font_collection = FontCollection::new(); let mut font_collection = FontCollection::new();
for family in self { for family in self {
font_collection.add_family(family); font_collection.add_family(family);
} }
Arc::new(font_collection) Ok(Arc::new(font_collection))
} }
} }
impl IntoFontCollection for Font { impl IntoFontCollection for Font {
#[inline] #[inline]
fn into_font_collection(self, context: &CanvasFontContext) -> Arc<FontCollection> { fn into_font_collection(self, context: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
FontFamily::new_from_font(self).into_font_collection(context) Ok(FontFamily::new_from_font(self).into_font_collection(context)?)
} }
} }
impl<'a> IntoFontCollection for &'a [Font] { impl<'a> IntoFontCollection for &'a [Font] {
#[inline] #[inline]
fn into_font_collection(self, context: &CanvasFontContext) -> Arc<FontCollection> { fn into_font_collection(self, context: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
let mut family = FontFamily::new(); let mut family = FontFamily::new();
for font in self { for font in self {
family.add_font(FontRef::new((*font).clone())) family.add_font(FontRef::new((*font).clone()))
@ -573,19 +581,19 @@ impl<'a> IntoFontCollection for &'a [Font] {
impl<'a> IntoFontCollection for &'a str { impl<'a> IntoFontCollection for &'a str {
#[inline] #[inline]
fn into_font_collection(self, context: &CanvasFontContext) -> Arc<FontCollection> { fn into_font_collection(self, context: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
context.get_font_by_postscript_name(self).into_font_collection(context) context.get_font_by_postscript_name(self)?.into_font_collection(context)
} }
} }
impl<'a, 'b> IntoFontCollection for &'a [&'b str] { impl<'a, 'b> IntoFontCollection for &'a [&'b str] {
#[inline] #[inline]
fn into_font_collection(self, context: &CanvasFontContext) -> Arc<FontCollection> { fn into_font_collection(self, context: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
let mut font_collection = FontCollection::new(); let mut font_collection = FontCollection::new();
for postscript_name in self { for postscript_name in self {
let font = context.get_font_by_postscript_name(postscript_name); let font = context.get_font_by_postscript_name(postscript_name)?;
font_collection.add_family(FontFamily::new_from_font(font)); font_collection.add_family(FontFamily::new_from_font(font));
} }
Arc::new(font_collection) Ok(Arc::new(font_collection))
} }
} }