Improve C bindings and canvas_text example

This commit is contained in:
Michael Pfaff 2024-06-18 18:01:18 -04:00
parent 30419d0766
commit e5912d7d70
3 changed files with 65 additions and 7 deletions

View File

@ -8,7 +8,7 @@ edition = "2018"
capi = []
[lib]
crate-type = ["staticlib"]
crate-type = ["staticlib", "cdylib"]
name = "pathfinder"
[dependencies]
@ -16,8 +16,13 @@ font-kit = "0.6"
foreign-types = "0.3"
gl = "0.14"
libc = "0.2"
simple_logger = "4.3"
usvg = "0.9"
[dependencies.log]
version = "0.4"
features = ["max_level_info"]
[dependencies.pathfinder_canvas]
features = ["pf-text"]
path = "../canvas"

View File

@ -27,6 +27,7 @@ use pathfinder_gpu::Device;
use pathfinder_resources::ResourceLoader;
use pathfinder_resources::fs::FilesystemResourceLoader;
use pathfinder_resources::embedded::EmbeddedResourceLoader;
use pathfinder_renderer::concurrent::executor::SequentialExecutor;
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererLevel};
@ -51,6 +52,11 @@ use metal::{self, CoreAnimationDrawableRef, DeviceRef as NativeMetalDeviceRef};
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
use pathfinder_metal::MetalDevice;
#[no_mangle]
pub extern "system" fn init_logging() {
simple_logger::init_with_env().unwrap();
}
// Constants
// `canvas`
@ -272,6 +278,13 @@ pub unsafe extern "C" fn PFCanvasCreateScene(canvas: PFCanvasRef) -> PFSceneRef
Box::into_raw(Box::new(Box::from_raw(canvas).into_canvas().into_scene()))
}
// Extensions
#[no_mangle]
pub unsafe extern "C" fn PFCanvasClear(canvas: PFCanvasRef) {
(*canvas).clear()
}
// Drawing rectangles
#[no_mangle]
@ -284,6 +297,11 @@ pub unsafe extern "C" fn PFCanvasStrokeRect(canvas: PFCanvasRef, rect: *const PF
(*canvas).stroke_rect((*rect).to_rust())
}
#[no_mangle]
pub unsafe extern "C" fn PFCanvasClearRect(canvas: PFCanvasRef, rect: *const PFRectF) {
(*canvas).clear_rect((*rect).to_rust())
}
// Drawing text
#[no_mangle]
@ -378,9 +396,13 @@ pub unsafe extern "C" fn PFCanvasSetLineDashOffset(canvas: PFCanvasRef, new_offs
pub unsafe extern "C" fn PFCanvasSetFontByPostScriptName(canvas: PFCanvasRef,
postscript_name: *const c_char,
postscript_name_len: usize) -> i32 {
match (*canvas).set_font(to_rust_string(&postscript_name, postscript_name_len)) {
let name = to_rust_string(&postscript_name, postscript_name_len);
match (*canvas).set_font(name) {
Ok(_) => 0,
Err(_) => 1
Err(e) => {
log::error!("Failed to set font to {:?}: {:?}", name, e);
1
}
}
}
@ -787,6 +809,15 @@ pub unsafe extern "C" fn PFSceneDestroy(scene: PFSceneRef) {
drop(Box::from_raw(scene))
}
#[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)))
}
#[no_mangle]
pub unsafe extern "C" fn PFSceneProxyCreateFromSceneAndRayonExecutor(scene: PFSceneRef,
level: PFRendererLevel)

View File

@ -25,6 +25,7 @@ use sdl2::keyboard::Keycode;
use sdl2::video::GLProfile;
use std::iter;
use std::sync::Arc;
use std::time::{Duration, Instant};
fn main() {
// Set up SDL2.
@ -34,7 +35,10 @@ fn main() {
// Make sure we have at least a GL 3.0 context. Pathfinder requires this.
let gl_attributes = video.gl_attr();
gl_attributes.set_context_profile(GLProfile::Core);
gl_attributes.set_context_version(3, 3);
gl_attributes.set_context_version(4, 1);
gl_attributes.set_context_flags()
.forward_compatible()
.set();
// Open a window.
let window_size = vec2i(640, 480);
@ -66,17 +70,33 @@ fn main() {
// Wait for a keypress.
let mut event_pump = sdl_context.event_pump().unwrap();
let mut n = 0;
let start = Instant::now();
let mut last_update = Instant::now();
let mut fps_buf = String::new();
loop {
match event_pump.wait_event() {
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => return,
Event::Window { win_event: WindowEvent::Exposed, .. } => {
match event_pump.poll_event() {
Some(Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. }) => return,
Some(Event::Window { win_event: WindowEvent::Exposed, .. }) | None => {
// Make a canvas.
let mut canvas = Canvas::new(window_size.to_f32()).get_context_2d(font_context.clone());
// Draw the text.
canvas.set_font("Overpass-Regular");
canvas.set_font_size(32.0);
let now = Instant::now();
let elapsed = now.duration_since(last_update);
if elapsed >= Duration::from_millis(500) {
last_update = now;
let fps = (n as f64) * ((Duration::from_secs(1).as_micros() as f64) / (elapsed.as_micros() as f64));
fps_buf.clear();
fps_buf.push_str("FPS: ");
use std::fmt::Write;
write!(fps_buf, "{fps:.2}").unwrap();
n = 0;
}
canvas.fill_text("Hello Pathfinder!", vec2f(32.0, 48.0));
canvas.fill_text(&fps_buf, vec2f(32.0, 96.0));
canvas.set_text_align(TextAlign::Right);
canvas.stroke_text("Goodbye Pathfinder!", vec2f(608.0, 464.0));
@ -86,6 +106,8 @@ fn main() {
RayonExecutor);
scene.build_and_render(&mut renderer, BuildOptions::default());
window.gl_swap_window();
n += 1;
},
_ => {}
}