diff --git a/c/Cargo.toml b/c/Cargo.toml index 2d0ba52e..69f7f4b4 100644 --- a/c/Cargo.toml +++ b/c/Cargo.toml @@ -4,9 +4,6 @@ version = "0.1.0" authors = ["Patrick Walton "] edition = "2018" -[features] -capi = [] - [lib] crate-type = ["staticlib", "cdylib"] name = "pathfinder" diff --git a/c/src/lib.rs b/c/src/lib.rs index 94461f46..efc9e3cc 100644 --- a/c/src/lib.rs +++ b/c/src/lib.rs @@ -10,6 +10,7 @@ //! C bindings to Pathfinder. +use font_kit::font::Font; use font_kit::handle::Handle; use gl; use pathfinder_canvas::{Canvas, CanvasFontContext, CanvasRenderingContext2D, FillStyle, LineJoin}; @@ -40,7 +41,7 @@ use pathfinder_svg::SVGScene; use std::ffi::CString; use std::os::raw::{c_char, c_void}; use std::path::PathBuf; -use std::ptr; +use std::ptr::{self, NonNull}; use std::slice; use std::str; use usvg::{Options, Tree}; @@ -108,6 +109,7 @@ pub type FKHandleRef = *mut Handle; pub type PFCanvasRef = *mut CanvasRenderingContext2D; pub type PFPathRef = *mut Path2D; pub type PFCanvasFontContextRef = *mut CanvasFontContext; +pub type FKFontRef = NonNull; pub type PFFillStyleRef = *mut FillStyle; pub type PFLineCap = u8; pub type PFLineJoin = u8; @@ -324,9 +326,8 @@ pub unsafe extern "C" fn PFCanvasStrokeText(canvas: PFCanvasRef, pub unsafe extern "C" fn PFCanvasMeasureText(canvas: PFCanvasRef, string: *const c_char, string_len: usize, - out_text_metrics: *mut PFTextMetrics) { - debug_assert!(!out_text_metrics.is_null()); - *out_text_metrics = (*canvas).measure_text(to_rust_string(&string, string_len)).to_c() + out_text_metrics: NonNull) { + out_text_metrics.write((*canvas).measure_text(to_rust_string(&string, string_len)).to_c()) } #[no_mangle] @@ -393,14 +394,30 @@ pub unsafe extern "C" fn PFCanvasSetLineDashOffset(canvas: PFCanvasRef, new_offs } #[no_mangle] -pub unsafe extern "C" fn PFCanvasSetFontByPostScriptName(canvas: PFCanvasRef, +pub unsafe extern "C" fn PFCanvasFontContextGetFontByPostScriptName(context: PFCanvasFontContextRef, postscript_name: *const c_char, - postscript_name_len: usize) -> i32 { + postscript_name_len: usize) -> Option { let name = to_rust_string(&postscript_name, postscript_name_len); - match (*canvas).set_font(name) { + match (*context).get_font_by_postscript_name(name) { + Ok(font) => NonNull::new(Box::into_raw(Box::new(font))), + Err(e) => { + log::error!("Failed to get font {:?}: {:?}", name, e); + None + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn FKFontDestroy(font: FKFontRef) { + drop(Box::from_raw(font.as_ptr())) +} + +#[no_mangle] +pub unsafe extern "C" fn PFCanvasSetFont(canvas: PFCanvasRef, font: FKFontRef) -> i32 { + match (*canvas).set_font(font.as_ref().clone()) { Ok(_) => 0, Err(e) => { - log::error!("Failed to set font to {:?}: {:?}", name, e); + log::error!("Failed to set font: {:?}", e); 1 } } @@ -646,6 +663,33 @@ pub unsafe extern "C" fn PFGLRendererGetDevice(renderer: PFGLRendererRef) -> PFG (*renderer).device_mut() } +#[no_mangle] +pub unsafe extern "C" fn PFGLRendererSetViewport(renderer: PFGLRendererRef, new_viewport: PFRectI) -> i32 { + match (*renderer).options_mut().dest { + DestFramebuffer::Default { ref mut viewport, .. } => { + *viewport = new_viewport.to_rust(); + 0 + } + DestFramebuffer::Other(_) => 1, + } +} + +#[no_mangle] +pub unsafe extern "C" fn PFGLRendererSetWindowSize(renderer: PFGLRendererRef, new_window_size: PFVector2I) -> i32 { + match (*renderer).options_mut().dest { + DestFramebuffer::Default { ref mut window_size, .. } => { + *window_size = new_window_size.to_rust(); + 0 + } + DestFramebuffer::Other(_) => 1, + } +} + +#[no_mangle] +pub unsafe extern "C" fn PFGLRendererDestFramebufferSizeChanged(renderer: PFGLRendererRef) { + (*renderer).dest_framebuffer_size_changed() +} + #[cfg(all(target_os = "macos", not(feature = "pf-gl")))] #[no_mangle] pub unsafe extern "C" fn PFMetalDestFramebufferCreateFullWindow(window_size: *const PFVector2I) @@ -810,21 +854,18 @@ pub unsafe extern "C" fn PFSceneDestroy(scene: PFSceneRef) { } #[no_mangle] -pub unsafe extern "C" fn PFSceneProxyCreateFromSceneAndSequentialExecutor(scene: PFSceneRef, - level: PFRendererLevel) - -> PFSceneProxyRef { - Box::into_raw(Box::new(SceneProxy::from_scene(*Box::from_raw(scene), - to_rust_renderer_level(level), - SequentialExecutor))) +pub unsafe extern "C" fn PFSceneProxyCreateWithSequentialExecutor(level: PFRendererLevel) -> PFSceneProxyRef { + Box::into_raw(Box::new(SceneProxy::new(to_rust_renderer_level(level), SequentialExecutor))) } #[no_mangle] -pub unsafe extern "C" fn PFSceneProxyCreateFromSceneAndRayonExecutor(scene: PFSceneRef, - level: PFRendererLevel) - -> PFSceneProxyRef { - Box::into_raw(Box::new(SceneProxy::from_scene(*Box::from_raw(scene), - to_rust_renderer_level(level), - RayonExecutor))) +pub unsafe extern "C" fn PFSceneProxyCreateWithRayonExecutor(level: PFRendererLevel) -> PFSceneProxyRef { + Box::into_raw(Box::new(SceneProxy::new(to_rust_renderer_level(level), RayonExecutor))) +} + +#[no_mangle] +pub unsafe extern "C" fn PFSceneProxyReplaceScene(scene_proxy: PFSceneProxyRef, scene: PFSceneRef) { + (*scene_proxy).replace_scene(*Box::from_raw(scene)) } #[no_mangle] diff --git a/canvas/src/text.rs b/canvas/src/text.rs index 1f59cbc6..c4ceaf7f 100644 --- a/canvas/src/text.rs +++ b/canvas/src/text.rs @@ -154,13 +154,7 @@ pub trait ToTextLayout { impl ToTextLayout for str { fn layout(&self, state: CanvasState) -> Cow { - let skribo_layout = Rc::new(skribo::layout(&TextStyle { size: state.0.font_size }, - &state.0.font_collection, - self)); - Cow::Owned(TextMetrics::new(skribo_layout, - state.0.font_size, - state.0.text_align, - state.0.text_baseline)) + Cow::Owned(TextMetrics::layout(self, &state.0.font_collection, state.0.font_size, state.0.text_align, state.0.text_baseline)) } } @@ -233,7 +227,7 @@ impl CanvasFontContext { CanvasFontContext::new(Arc::new(MemSource::from_fonts(fonts).unwrap())) } - fn get_font_by_postscript_name(&self, postscript_name: &str) -> Result { + pub fn get_font_by_postscript_name(&self, postscript_name: &str) -> Result { let this = self.0.borrow(); if let Some(cached_font) = this.font_context.get_cached_font(postscript_name) { return Ok((*cached_font).clone()); @@ -322,6 +316,13 @@ impl TextMetrics { } } + pub fn layout(string: &str, font_collection: &FontCollection, font_size: f32, text_align: TextAlign, text_baseline: TextBaseline) -> TextMetrics { + let skribo_layout = Rc::new(skribo::layout(&TextStyle { size: font_size }, + font_collection, + string)); + TextMetrics::new(skribo_layout, font_size, text_align, text_baseline) + } + pub fn text_x_offset(&self) -> f32 { if self.text_x_offset.get().is_none() { self.text_x_offset.set(Some(match self.align {