Skip to content

Commit 30419d0

Browse files
authored
Fix #553 (#555)
* use a Result for font functions that can fail * derive Debug for FontError and add data to the variants
1 parent dc6034f commit 30419d0

File tree

2 files changed

+35
-24
lines changed

2 files changed

+35
-24
lines changed

c/src/lib.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,11 @@ pub unsafe extern "C" fn PFCanvasSetLineDashOffset(canvas: PFCanvasRef, new_offs
377377
#[no_mangle]
378378
pub unsafe extern "C" fn PFCanvasSetFontByPostScriptName(canvas: PFCanvasRef,
379379
postscript_name: *const c_char,
380-
postscript_name_len: usize) {
381-
(*canvas).set_font(to_rust_string(&postscript_name, postscript_name_len))
380+
postscript_name_len: usize) -> i32 {
381+
match (*canvas).set_font(to_rust_string(&postscript_name, postscript_name_len)) {
382+
Ok(_) => 0,
383+
Err(_) => 1
384+
}
382385
}
383386

384387
#[no_mangle]

canvas/src/text.rs

+30-22
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use crate::{CanvasRenderingContext2D, State, TextAlign, TextBaseline};
1212
use font_kit::canvas::RasterizationOptions;
13+
use font_kit::error::{FontLoadingError, SelectionError};
1314
use font_kit::family_name::FamilyName;
1415
use font_kit::handle::Handle;
1516
use font_kit::hinting::HintingOptions;
@@ -103,9 +104,10 @@ impl CanvasRenderingContext2D {
103104
}
104105

105106
#[inline]
106-
pub fn set_font<FC>(&mut self, font_collection: FC) where FC: IntoFontCollection {
107-
let font_collection = font_collection.into_font_collection(&self.canvas_font_context);
107+
pub fn set_font<FC>(&mut self, font_collection: FC) -> Result<(), FontError> where FC: IntoFontCollection {
108+
let font_collection = font_collection.into_font_collection(&self.canvas_font_context)?;
108109
self.current_state.font_collection = font_collection;
110+
Ok(())
109111
}
110112

111113
#[inline]
@@ -188,6 +190,13 @@ impl ToTextLayout for TextMetrics {
188190
#[derive(Clone)]
189191
pub struct CanvasFontContext(pub(crate) Rc<RefCell<CanvasFontContextData>>);
190192

193+
/// The reason a font could not be loaded
194+
#[derive(Debug)]
195+
pub enum FontError {
196+
NotFound(SelectionError),
197+
LoadError(FontLoadingError),
198+
}
199+
191200
pub(super) struct CanvasFontContextData {
192201
pub(super) font_context: FontContext<Font>,
193202
#[allow(dead_code)]
@@ -224,16 +233,15 @@ impl CanvasFontContext {
224233
CanvasFontContext::new(Arc::new(MemSource::from_fonts(fonts).unwrap()))
225234
}
226235

227-
fn get_font_by_postscript_name(&self, postscript_name: &str) -> Font {
236+
fn get_font_by_postscript_name(&self, postscript_name: &str) -> Result<Font, FontError> {
228237
let this = self.0.borrow();
229238
if let Some(cached_font) = this.font_context.get_cached_font(postscript_name) {
230-
return (*cached_font).clone();
239+
return Ok((*cached_font).clone());
231240
}
232241
this.font_source
233242
.select_by_postscript_name(postscript_name)
234-
.expect("Couldn't find a font with that PostScript name!")
235-
.load()
236-
.expect("Failed to load the font!")
243+
.map_err(FontError::NotFound)?
244+
.load().map_err(FontError::LoadError)
237245
}
238246
}
239247

@@ -523,46 +531,46 @@ impl VerticalMetrics {
523531
/// Various things that can be conveniently converted into font collections for use with
524532
/// `CanvasRenderingContext2D::set_font()`.
525533
pub trait IntoFontCollection {
526-
fn into_font_collection(self, font_context: &CanvasFontContext) -> Arc<FontCollection>;
534+
fn into_font_collection(self, font_context: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError>;
527535
}
528536

529537
impl IntoFontCollection for Arc<FontCollection> {
530538
#[inline]
531-
fn into_font_collection(self, _: &CanvasFontContext) -> Arc<FontCollection> {
532-
self
539+
fn into_font_collection(self, _: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
540+
Ok(self)
533541
}
534542
}
535543

536544
impl IntoFontCollection for FontFamily {
537545
#[inline]
538-
fn into_font_collection(self, _: &CanvasFontContext) -> Arc<FontCollection> {
546+
fn into_font_collection(self, _: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
539547
let mut font_collection = FontCollection::new();
540548
font_collection.add_family(self);
541-
Arc::new(font_collection)
549+
Ok(Arc::new(font_collection))
542550
}
543551
}
544552

545553
impl IntoFontCollection for Vec<FontFamily> {
546554
#[inline]
547-
fn into_font_collection(self, _: &CanvasFontContext) -> Arc<FontCollection> {
555+
fn into_font_collection(self, _: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
548556
let mut font_collection = FontCollection::new();
549557
for family in self {
550558
font_collection.add_family(family);
551559
}
552-
Arc::new(font_collection)
560+
Ok(Arc::new(font_collection))
553561
}
554562
}
555563

556564
impl IntoFontCollection for Font {
557565
#[inline]
558-
fn into_font_collection(self, context: &CanvasFontContext) -> Arc<FontCollection> {
559-
FontFamily::new_from_font(self).into_font_collection(context)
566+
fn into_font_collection(self, context: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
567+
Ok(FontFamily::new_from_font(self).into_font_collection(context)?)
560568
}
561569
}
562570

563571
impl<'a> IntoFontCollection for &'a [Font] {
564572
#[inline]
565-
fn into_font_collection(self, context: &CanvasFontContext) -> Arc<FontCollection> {
573+
fn into_font_collection(self, context: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
566574
let mut family = FontFamily::new();
567575
for font in self {
568576
family.add_font(FontRef::new((*font).clone()))
@@ -573,19 +581,19 @@ impl<'a> IntoFontCollection for &'a [Font] {
573581

574582
impl<'a> IntoFontCollection for &'a str {
575583
#[inline]
576-
fn into_font_collection(self, context: &CanvasFontContext) -> Arc<FontCollection> {
577-
context.get_font_by_postscript_name(self).into_font_collection(context)
584+
fn into_font_collection(self, context: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
585+
context.get_font_by_postscript_name(self)?.into_font_collection(context)
578586
}
579587
}
580588

581589
impl<'a, 'b> IntoFontCollection for &'a [&'b str] {
582590
#[inline]
583-
fn into_font_collection(self, context: &CanvasFontContext) -> Arc<FontCollection> {
591+
fn into_font_collection(self, context: &CanvasFontContext) -> Result<Arc<FontCollection>, FontError> {
584592
let mut font_collection = FontCollection::new();
585593
for postscript_name in self {
586-
let font = context.get_font_by_postscript_name(postscript_name);
594+
let font = context.get_font_by_postscript_name(postscript_name)?;
587595
font_collection.add_family(FontFamily::new_from_font(font));
588596
}
589-
Arc::new(font_collection)
597+
Ok(Arc::new(font_collection))
590598
}
591599
}

0 commit comments

Comments
 (0)