Add transform support to the C API, and fix build problems
This commit is contained in:
parent
82171088c5
commit
a8d20cb37f
|
@ -2,18 +2,28 @@ language = "C"
|
|||
header = """\
|
||||
/* Generated code. Do not edit; instead run `cargo build` in `pathfinder_c`. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern \"C\" {
|
||||
#endif
|
||||
"""
|
||||
trailer = """\
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
"""
|
||||
trailer = "}"
|
||||
include_guard = "PF_PATHFINDER_H"
|
||||
include_version = true
|
||||
|
||||
[parse]
|
||||
parse_deps = true
|
||||
include = [
|
||||
"font-kit",
|
||||
"metal",
|
||||
"pathfinder_canvas",
|
||||
"pathfinder_content",
|
||||
"pathfinder_geometry",
|
||||
"pathfinder_gl",
|
||||
"pathfinder_gpu",
|
||||
"pathfinder_metal",
|
||||
"pathfinder_renderer",
|
||||
]
|
||||
|
|
155
c/src/lib.rs
155
c/src/lib.rs
|
@ -19,6 +19,8 @@ use pathfinder_content::color::{ColorF, ColorU};
|
|||
use pathfinder_content::outline::ArcDirection;
|
||||
use pathfinder_content::stroke::LineCap;
|
||||
use pathfinder_geometry::rect::{RectF, RectI};
|
||||
use pathfinder_geometry::transform2d::{Matrix2x2F, Transform2DF};
|
||||
use pathfinder_geometry::transform3d::{Perspective, Transform3DF};
|
||||
use pathfinder_geometry::vector::{Vector2F, Vector2I};
|
||||
use pathfinder_gl::{GLDevice, GLVersion};
|
||||
use pathfinder_gpu::resources::{FilesystemResourceLoader, ResourceLoader};
|
||||
|
@ -26,7 +28,7 @@ use pathfinder_renderer::concurrent::rayon::RayonExecutor;
|
|||
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
|
||||
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
||||
use pathfinder_renderer::gpu::renderer::Renderer;
|
||||
use pathfinder_renderer::options::BuildOptions;
|
||||
use pathfinder_renderer::options::{BuildOptions, RenderTransform};
|
||||
use pathfinder_renderer::scene::Scene;
|
||||
use pathfinder_simd::default::F32x4;
|
||||
use std::ffi::CString;
|
||||
|
@ -60,6 +62,11 @@ pub const PF_TEXT_ALIGN_RIGHT: u8 = 2;
|
|||
pub const PF_ARC_DIRECTION_CW: u8 = 0;
|
||||
pub const PF_ARC_DIRECTION_CCW: u8 = 1;
|
||||
|
||||
// `gl`
|
||||
|
||||
pub const PF_GL_VERSION_GL3: u8 = 0;
|
||||
pub const PF_GL_VERSION_GLES3: u8 = 1;
|
||||
|
||||
// `renderer`
|
||||
|
||||
pub const PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR: u8 = 0x1;
|
||||
|
@ -120,10 +127,35 @@ pub struct PFRectI {
|
|||
pub origin: PFVector2I,
|
||||
pub lower_right: PFVector2I,
|
||||
}
|
||||
/// Row-major order.
|
||||
#[repr(C)]
|
||||
pub struct PFMatrix2x2F {
|
||||
pub m00: f32, pub m01: f32,
|
||||
pub m10: f32, pub m11: f32,
|
||||
}
|
||||
/// Row-major order.
|
||||
#[repr(C)]
|
||||
pub struct PFTransform2DF {
|
||||
pub matrix: PFMatrix2x2F,
|
||||
pub vector: PFVector2F,
|
||||
}
|
||||
/// Row-major order.
|
||||
#[repr(C)]
|
||||
pub struct PFTransform3DF {
|
||||
pub m00: f32, pub m01: f32, pub m02: f32, pub m03: f32,
|
||||
pub m10: f32, pub m11: f32, pub m12: f32, pub m13: f32,
|
||||
pub m20: f32, pub m21: f32, pub m22: f32, pub m23: f32,
|
||||
pub m30: f32, pub m31: f32, pub m32: f32, pub m33: f32,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct PFPerspective {
|
||||
pub transform: PFTransform3DF,
|
||||
pub window_size: PFVector2I,
|
||||
}
|
||||
|
||||
// `gl`
|
||||
pub type PFGLDeviceRef = *mut GLDevice;
|
||||
pub type PFGLVersion = GLVersion;
|
||||
pub type PFGLVersion = u8;
|
||||
pub type PFGLFunctionLoader = extern "C" fn(name: *const c_char, userdata: *mut c_void)
|
||||
-> *const c_void;
|
||||
// `gpu`
|
||||
|
@ -135,7 +167,8 @@ pub type PFMetalDestFramebufferRef = *mut DestFramebuffer<MetalDevice>;
|
|||
pub type PFMetalRendererRef = *mut Renderer<MetalDevice>;
|
||||
// FIXME(pcwalton): Double-boxing is unfortunate. Remove this when `std::raw::TraitObject` is
|
||||
// stable?
|
||||
pub type PFResourceLoaderRef = *mut Box<dyn ResourceLoader>;
|
||||
pub type PFResourceLoaderRef = *mut ResourceLoaderWrapper;
|
||||
pub struct ResourceLoaderWrapper(Box<dyn ResourceLoader>);
|
||||
|
||||
// `metal`
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
|
@ -150,11 +183,8 @@ pub struct PFRendererOptions {
|
|||
pub flags: PFRendererOptionsFlags,
|
||||
}
|
||||
pub type PFRendererOptionsFlags = u8;
|
||||
// TODO(pcwalton)
|
||||
#[repr(C)]
|
||||
pub struct PFBuildOptions {
|
||||
pub placeholder: u32,
|
||||
}
|
||||
pub type PFBuildOptionsRef = *mut BuildOptions;
|
||||
pub type PFRenderTransformRef = *mut RenderTransform;
|
||||
|
||||
// `canvas`
|
||||
|
||||
|
@ -421,7 +451,7 @@ pub unsafe extern "C" fn PFFillStyleDestroy(fill_style: PFFillStyleRef) {
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFFilesystemResourceLoaderLocate() -> PFResourceLoaderRef {
|
||||
let loader = Box::new(FilesystemResourceLoader::locate());
|
||||
Box::into_raw(Box::new(loader as Box<dyn ResourceLoader>))
|
||||
Box::into_raw(Box::new(ResourceLoaderWrapper(loader as Box<dyn ResourceLoader>)))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -435,6 +465,7 @@ pub unsafe extern "C" fn PFGLLoadWith(loader: PFGLFunctionLoader, userdata: *mut
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFGLDeviceCreate(version: PFGLVersion, default_framebuffer: u32)
|
||||
-> PFGLDeviceRef {
|
||||
let version = match version { PF_GL_VERSION_GLES3 => GLVersion::GLES3, _ => GLVersion::GL3 };
|
||||
Box::into_raw(Box::new(GLDevice::new(version, default_framebuffer)))
|
||||
}
|
||||
|
||||
|
@ -469,7 +500,7 @@ pub unsafe extern "C" fn PFGLRendererCreate(device: PFGLDeviceRef,
|
|||
options: *const PFRendererOptions)
|
||||
-> PFGLRendererRef {
|
||||
Box::into_raw(Box::new(Renderer::new(*Box::from_raw(device),
|
||||
&**resources,
|
||||
&*((*resources).0),
|
||||
*Box::from_raw(dest_framebuffer),
|
||||
(*options).to_rust())))
|
||||
}
|
||||
|
@ -507,7 +538,7 @@ pub unsafe extern "C" fn PFMetalRendererCreate(device: PFMetalDeviceRef,
|
|||
options: *const PFRendererOptions)
|
||||
-> PFMetalRendererRef {
|
||||
Box::into_raw(Box::new(Renderer::new(*Box::from_raw(device),
|
||||
&**resources,
|
||||
&*((*resources).0),
|
||||
*Box::from_raw(dest_framebuffer),
|
||||
(*options).to_rust())))
|
||||
}
|
||||
|
@ -524,19 +555,21 @@ pub unsafe extern "C" fn PFMetalRendererGetDevice(renderer: PFMetalRendererRef)
|
|||
&mut (*renderer).device
|
||||
}
|
||||
|
||||
// Consumes `build_options`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFSceneProxyBuildAndRenderGL(scene_proxy: PFSceneProxyRef,
|
||||
renderer: PFGLRendererRef,
|
||||
build_options: *const PFBuildOptions) {
|
||||
(*scene_proxy).build_and_render(&mut *renderer, (*build_options).to_rust())
|
||||
build_options: PFBuildOptionsRef) {
|
||||
(*scene_proxy).build_and_render(&mut *renderer, *Box::from_raw(build_options))
|
||||
}
|
||||
|
||||
// Consumes `build_options`.
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFSceneProxyBuildAndRenderMetal(scene_proxy: PFSceneProxyRef,
|
||||
renderer: PFMetalRendererRef,
|
||||
build_options: *const PFBuildOptions) {
|
||||
(*scene_proxy).build_and_render(&mut *renderer, (*build_options).to_rust())
|
||||
build_options: PFBuildOptionsRef) {
|
||||
(*scene_proxy).build_and_render(&mut *renderer, *Box::from_raw(build_options))
|
||||
}
|
||||
|
||||
// `metal`
|
||||
|
@ -554,8 +587,60 @@ pub unsafe extern "C" fn PFMetalDeviceDestroy(device: PFMetalDeviceRef) {
|
|||
drop(Box::from_raw(device))
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFMetalDevicePresentDrawable(device: PFMetalDeviceRef) {
|
||||
(*device).present_drawable()
|
||||
}
|
||||
|
||||
// `renderer`
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFRenderTransformCreate2D(transform: *const PFTransform2DF)
|
||||
-> PFRenderTransformRef {
|
||||
Box::into_raw(Box::new(RenderTransform::Transform2D((*transform).to_rust())))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFRenderTransformCreatePerspective(perspective: *const PFPerspective)
|
||||
-> PFRenderTransformRef {
|
||||
Box::into_raw(Box::new(RenderTransform::Perspective((*perspective).to_rust())))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFRenderTransformDestroy(transform: PFRenderTransformRef) {
|
||||
drop(Box::from_raw(transform))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFBuildOptionsCreate() -> PFBuildOptionsRef {
|
||||
Box::into_raw(Box::new(BuildOptions::default()))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFBuildOptionsDestroy(options: PFBuildOptionsRef) {
|
||||
drop(Box::from_raw(options))
|
||||
}
|
||||
|
||||
/// Consumes the transform.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFBuildOptionsSetTransform(options: PFBuildOptionsRef,
|
||||
transform: PFRenderTransformRef) {
|
||||
(*options).transform = *Box::from_raw(transform)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFBuildOptionsSetDilation(options: PFBuildOptionsRef,
|
||||
dilation: *const PFVector2F) {
|
||||
(*options).dilation = (*dilation).to_rust()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFBuildOptionsSetSubpixelAAEnabled(options: PFBuildOptionsRef,
|
||||
subpixel_aa_enabled: bool) {
|
||||
(*options).subpixel_aa_enabled = subpixel_aa_enabled
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn PFSceneDestroy(scene: PFSceneRef) {
|
||||
drop(Box::from_raw(scene))
|
||||
|
@ -637,6 +722,40 @@ impl PFVector2I {
|
|||
}
|
||||
}
|
||||
|
||||
impl PFMatrix2x2F {
|
||||
#[inline]
|
||||
pub fn to_rust(&self) -> Matrix2x2F {
|
||||
Matrix2x2F::row_major(self.m00, self.m01, self.m10, self.m11)
|
||||
}
|
||||
}
|
||||
|
||||
impl PFTransform2DF {
|
||||
#[inline]
|
||||
pub fn to_rust(&self) -> Transform2DF {
|
||||
Transform2DF { matrix: self.matrix.to_rust(), vector: self.vector.to_rust() }
|
||||
}
|
||||
}
|
||||
|
||||
impl PFTransform3DF {
|
||||
#[inline]
|
||||
pub fn to_rust(&self) -> Transform3DF {
|
||||
Transform3DF::row_major(self.m00, self.m01, self.m02, self.m03,
|
||||
self.m10, self.m11, self.m12, self.m13,
|
||||
self.m20, self.m21, self.m22, self.m23,
|
||||
self.m30, self.m31, self.m32, self.m33)
|
||||
}
|
||||
}
|
||||
|
||||
impl PFPerspective {
|
||||
#[inline]
|
||||
pub fn to_rust(&self) -> Perspective {
|
||||
Perspective {
|
||||
transform: self.transform.to_rust(),
|
||||
window_size: self.window_size.to_rust(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers for `renderer`
|
||||
|
||||
impl PFRendererOptions {
|
||||
|
@ -651,9 +770,3 @@ impl PFRendererOptions {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PFBuildOptions {
|
||||
pub fn to_rust(&self) -> BuildOptions {
|
||||
BuildOptions::default()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ int main(int argc, const char **argv) {
|
|||
// Render the canvas to screen.
|
||||
PFSceneRef scene = PFCanvasCreateScene(canvas);
|
||||
PFSceneProxyRef scene_proxy = PFSceneProxyCreateFromSceneAndRayonExecutor(scene);
|
||||
PFSceneProxyBuildAndRenderGL(scene_proxy, renderer, &(PFBuildOptions){0});
|
||||
PFSceneProxyBuildAndRenderGL(scene_proxy, renderer, PFBuildOptionsCreate());
|
||||
SDL_GL_SwapWindow(window);
|
||||
|
||||
// Wait for a keypress.
|
||||
|
|
|
@ -116,8 +116,8 @@ impl Sub<Matrix2x2F> for Matrix2x2F {
|
|||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct Transform2DF {
|
||||
// Row-major order.
|
||||
matrix: Matrix2x2F,
|
||||
vector: Vector2F,
|
||||
pub matrix: Matrix2x2F,
|
||||
pub vector: Vector2F,
|
||||
}
|
||||
|
||||
impl Default for Transform2DF {
|
||||
|
|
Loading…
Reference in New Issue