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 = """\
|
header = """\
|
||||||
/* Generated code. Do not edit; instead run `cargo build` in `pathfinder_c`. */
|
/* Generated code. Do not edit; instead run `cargo build` in `pathfinder_c`. */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
extern \"C\" {
|
extern \"C\" {
|
||||||
|
#endif
|
||||||
|
"""
|
||||||
|
trailer = """\
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
"""
|
"""
|
||||||
trailer = "}"
|
|
||||||
include_guard = "PF_PATHFINDER_H"
|
include_guard = "PF_PATHFINDER_H"
|
||||||
include_version = true
|
include_version = true
|
||||||
|
|
||||||
[parse]
|
[parse]
|
||||||
parse_deps = true
|
parse_deps = true
|
||||||
include = [
|
include = [
|
||||||
|
"font-kit",
|
||||||
|
"metal",
|
||||||
"pathfinder_canvas",
|
"pathfinder_canvas",
|
||||||
"pathfinder_content",
|
"pathfinder_content",
|
||||||
"pathfinder_geometry",
|
"pathfinder_geometry",
|
||||||
"pathfinder_gl",
|
"pathfinder_gl",
|
||||||
|
"pathfinder_gpu",
|
||||||
|
"pathfinder_metal",
|
||||||
"pathfinder_renderer",
|
"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::outline::ArcDirection;
|
||||||
use pathfinder_content::stroke::LineCap;
|
use pathfinder_content::stroke::LineCap;
|
||||||
use pathfinder_geometry::rect::{RectF, RectI};
|
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_geometry::vector::{Vector2F, Vector2I};
|
||||||
use pathfinder_gl::{GLDevice, GLVersion};
|
use pathfinder_gl::{GLDevice, GLVersion};
|
||||||
use pathfinder_gpu::resources::{FilesystemResourceLoader, ResourceLoader};
|
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::concurrent::scene_proxy::SceneProxy;
|
||||||
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
||||||
use pathfinder_renderer::gpu::renderer::Renderer;
|
use pathfinder_renderer::gpu::renderer::Renderer;
|
||||||
use pathfinder_renderer::options::BuildOptions;
|
use pathfinder_renderer::options::{BuildOptions, RenderTransform};
|
||||||
use pathfinder_renderer::scene::Scene;
|
use pathfinder_renderer::scene::Scene;
|
||||||
use pathfinder_simd::default::F32x4;
|
use pathfinder_simd::default::F32x4;
|
||||||
use std::ffi::CString;
|
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_CW: u8 = 0;
|
||||||
pub const PF_ARC_DIRECTION_CCW: u8 = 1;
|
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`
|
// `renderer`
|
||||||
|
|
||||||
pub const PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR: u8 = 0x1;
|
pub const PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR: u8 = 0x1;
|
||||||
|
@ -120,10 +127,35 @@ pub struct PFRectI {
|
||||||
pub origin: PFVector2I,
|
pub origin: PFVector2I,
|
||||||
pub lower_right: 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`
|
// `gl`
|
||||||
pub type PFGLDeviceRef = *mut GLDevice;
|
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)
|
pub type PFGLFunctionLoader = extern "C" fn(name: *const c_char, userdata: *mut c_void)
|
||||||
-> *const c_void;
|
-> *const c_void;
|
||||||
// `gpu`
|
// `gpu`
|
||||||
|
@ -135,7 +167,8 @@ pub type PFMetalDestFramebufferRef = *mut DestFramebuffer<MetalDevice>;
|
||||||
pub type PFMetalRendererRef = *mut Renderer<MetalDevice>;
|
pub type PFMetalRendererRef = *mut Renderer<MetalDevice>;
|
||||||
// FIXME(pcwalton): Double-boxing is unfortunate. Remove this when `std::raw::TraitObject` is
|
// FIXME(pcwalton): Double-boxing is unfortunate. Remove this when `std::raw::TraitObject` is
|
||||||
// stable?
|
// stable?
|
||||||
pub type PFResourceLoaderRef = *mut Box<dyn ResourceLoader>;
|
pub type PFResourceLoaderRef = *mut ResourceLoaderWrapper;
|
||||||
|
pub struct ResourceLoaderWrapper(Box<dyn ResourceLoader>);
|
||||||
|
|
||||||
// `metal`
|
// `metal`
|
||||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||||
|
@ -150,11 +183,8 @@ pub struct PFRendererOptions {
|
||||||
pub flags: PFRendererOptionsFlags,
|
pub flags: PFRendererOptionsFlags,
|
||||||
}
|
}
|
||||||
pub type PFRendererOptionsFlags = u8;
|
pub type PFRendererOptionsFlags = u8;
|
||||||
// TODO(pcwalton)
|
pub type PFBuildOptionsRef = *mut BuildOptions;
|
||||||
#[repr(C)]
|
pub type PFRenderTransformRef = *mut RenderTransform;
|
||||||
pub struct PFBuildOptions {
|
|
||||||
pub placeholder: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
// `canvas`
|
// `canvas`
|
||||||
|
|
||||||
|
@ -421,7 +451,7 @@ pub unsafe extern "C" fn PFFillStyleDestroy(fill_style: PFFillStyleRef) {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn PFFilesystemResourceLoaderLocate() -> PFResourceLoaderRef {
|
pub unsafe extern "C" fn PFFilesystemResourceLoaderLocate() -> PFResourceLoaderRef {
|
||||||
let loader = Box::new(FilesystemResourceLoader::locate());
|
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]
|
#[no_mangle]
|
||||||
|
@ -435,6 +465,7 @@ pub unsafe extern "C" fn PFGLLoadWith(loader: PFGLFunctionLoader, userdata: *mut
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn PFGLDeviceCreate(version: PFGLVersion, default_framebuffer: u32)
|
pub unsafe extern "C" fn PFGLDeviceCreate(version: PFGLVersion, default_framebuffer: u32)
|
||||||
-> PFGLDeviceRef {
|
-> PFGLDeviceRef {
|
||||||
|
let version = match version { PF_GL_VERSION_GLES3 => GLVersion::GLES3, _ => GLVersion::GL3 };
|
||||||
Box::into_raw(Box::new(GLDevice::new(version, default_framebuffer)))
|
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)
|
options: *const PFRendererOptions)
|
||||||
-> PFGLRendererRef {
|
-> PFGLRendererRef {
|
||||||
Box::into_raw(Box::new(Renderer::new(*Box::from_raw(device),
|
Box::into_raw(Box::new(Renderer::new(*Box::from_raw(device),
|
||||||
&**resources,
|
&*((*resources).0),
|
||||||
*Box::from_raw(dest_framebuffer),
|
*Box::from_raw(dest_framebuffer),
|
||||||
(*options).to_rust())))
|
(*options).to_rust())))
|
||||||
}
|
}
|
||||||
|
@ -507,7 +538,7 @@ pub unsafe extern "C" fn PFMetalRendererCreate(device: PFMetalDeviceRef,
|
||||||
options: *const PFRendererOptions)
|
options: *const PFRendererOptions)
|
||||||
-> PFMetalRendererRef {
|
-> PFMetalRendererRef {
|
||||||
Box::into_raw(Box::new(Renderer::new(*Box::from_raw(device),
|
Box::into_raw(Box::new(Renderer::new(*Box::from_raw(device),
|
||||||
&**resources,
|
&*((*resources).0),
|
||||||
*Box::from_raw(dest_framebuffer),
|
*Box::from_raw(dest_framebuffer),
|
||||||
(*options).to_rust())))
|
(*options).to_rust())))
|
||||||
}
|
}
|
||||||
|
@ -524,19 +555,21 @@ pub unsafe extern "C" fn PFMetalRendererGetDevice(renderer: PFMetalRendererRef)
|
||||||
&mut (*renderer).device
|
&mut (*renderer).device
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Consumes `build_options`.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn PFSceneProxyBuildAndRenderGL(scene_proxy: PFSceneProxyRef,
|
pub unsafe extern "C" fn PFSceneProxyBuildAndRenderGL(scene_proxy: PFSceneProxyRef,
|
||||||
renderer: PFGLRendererRef,
|
renderer: PFGLRendererRef,
|
||||||
build_options: *const PFBuildOptions) {
|
build_options: PFBuildOptionsRef) {
|
||||||
(*scene_proxy).build_and_render(&mut *renderer, (*build_options).to_rust())
|
(*scene_proxy).build_and_render(&mut *renderer, *Box::from_raw(build_options))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Consumes `build_options`.
|
||||||
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
#[cfg(all(target_os = "macos", not(feature = "pf-gl")))]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn PFSceneProxyBuildAndRenderMetal(scene_proxy: PFSceneProxyRef,
|
pub unsafe extern "C" fn PFSceneProxyBuildAndRenderMetal(scene_proxy: PFSceneProxyRef,
|
||||||
renderer: PFMetalRendererRef,
|
renderer: PFMetalRendererRef,
|
||||||
build_options: *const PFBuildOptions) {
|
build_options: PFBuildOptionsRef) {
|
||||||
(*scene_proxy).build_and_render(&mut *renderer, (*build_options).to_rust())
|
(*scene_proxy).build_and_render(&mut *renderer, *Box::from_raw(build_options))
|
||||||
}
|
}
|
||||||
|
|
||||||
// `metal`
|
// `metal`
|
||||||
|
@ -554,8 +587,60 @@ pub unsafe extern "C" fn PFMetalDeviceDestroy(device: PFMetalDeviceRef) {
|
||||||
drop(Box::from_raw(device))
|
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`
|
// `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]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn PFSceneDestroy(scene: PFSceneRef) {
|
pub unsafe extern "C" fn PFSceneDestroy(scene: PFSceneRef) {
|
||||||
drop(Box::from_raw(scene))
|
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`
|
// Helpers for `renderer`
|
||||||
|
|
||||||
impl PFRendererOptions {
|
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.
|
// Render the canvas to screen.
|
||||||
PFSceneRef scene = PFCanvasCreateScene(canvas);
|
PFSceneRef scene = PFCanvasCreateScene(canvas);
|
||||||
PFSceneProxyRef scene_proxy = PFSceneProxyCreateFromSceneAndRayonExecutor(scene);
|
PFSceneProxyRef scene_proxy = PFSceneProxyCreateFromSceneAndRayonExecutor(scene);
|
||||||
PFSceneProxyBuildAndRenderGL(scene_proxy, renderer, &(PFBuildOptions){0});
|
PFSceneProxyBuildAndRenderGL(scene_proxy, renderer, PFBuildOptionsCreate());
|
||||||
SDL_GL_SwapWindow(window);
|
SDL_GL_SwapWindow(window);
|
||||||
|
|
||||||
// Wait for a keypress.
|
// Wait for a keypress.
|
||||||
|
|
|
@ -116,8 +116,8 @@ impl Sub<Matrix2x2F> for Matrix2x2F {
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub struct Transform2DF {
|
pub struct Transform2DF {
|
||||||
// Row-major order.
|
// Row-major order.
|
||||||
matrix: Matrix2x2F,
|
pub matrix: Matrix2x2F,
|
||||||
vector: Vector2F,
|
pub vector: Vector2F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Transform2DF {
|
impl Default for Transform2DF {
|
||||||
|
|
Loading…
Reference in New Issue