merge with master

This commit is contained in:
Sebastian Köln 2019-06-25 11:36:04 +03:00
commit 21fffb29f7
25 changed files with 1471 additions and 50 deletions

1
.gitignore vendored
View File

@ -8,6 +8,7 @@ node_modules
/examples/c_canvas_minimal/build /examples/c_canvas_minimal/build
/shaders/build /shaders/build
/c/build /c/build
/examples/macos_app/Pathfinder\ Example.xcodeproj/project.xcworkspace/xcuserdata/*
# Editors # Editors
*.swp *.swp

View File

@ -13,7 +13,6 @@ members = [
"examples/canvas_moire", "examples/canvas_moire",
"examples/canvas_text", "examples/canvas_text",
"examples/lottie_basic", "examples/lottie_basic",
"examples/convert",
"examples/swf_basic", "examples/swf_basic",
"geometry", "geometry",
"gl", "gl",
@ -29,5 +28,6 @@ members = [
"ui", "ui",
"utils/area-lut", "utils/area-lut",
"utils/gamma-lut", "utils/gamma-lut",
"utils/svg-to-skia" "utils/svg-to-skia",
"utils/convert",
] ]

View File

@ -3,7 +3,7 @@
# Pathfinder 3 # Pathfinder 3
Pathfinder 3 is a fast, practical, GPU-based rasterizer for fonts and vector graphics using OpenGL Pathfinder 3 is a fast, practical, GPU-based rasterizer for fonts and vector graphics using OpenGL
and OpenGL ES 3.0+. 3.0+, OpenGL ES 3.0+, or Metal.
Please note that Pathfinder is under heavy development and is incomplete in various areas. Please note that Pathfinder is under heavy development and is incomplete in various areas.
@ -75,12 +75,6 @@ The SDL 2 library requires some additional manual installation steps. Follow the
[`rust-sdl2` installation instructions](https://github.com/Rust-SDL2/rust-sdl2#sdl20-development-libraries) to make sure the libraries are installed. Note that SDL2 is [`rust-sdl2` installation instructions](https://github.com/Rust-SDL2/rust-sdl2#sdl20-development-libraries) to make sure the libraries are installed. Note that SDL2 is
only required to run the demo; Pathfinder itself has no dependency on the library. only required to run the demo; Pathfinder itself has no dependency on the library.
On macOS, it is recommended that you force the use of the integrated GPU, as issues with Apple's
OpenGL drivers may limit performance on discrete GPUs. You can use
[gfxCardStatus.app](https://gfx.io/) for this. See the
[wiki](https://github.com/pcwalton/pathfinder/wiki/GPU-driver-compatibility) for more information
on GPU compatibility issues.
## Authors ## Authors
The primary author is Patrick Walton (@pcwalton), with contributions from the Servo development The primary author is Patrick Walton (@pcwalton), with contributions from the Servo development

View File

@ -2,18 +2,53 @@ 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`. */
#ifndef PF_PATHFINDER_H
#define PF_PATHFINDER_H
#ifdef __APPLE__
#include <QuartzCore/QuartzCore.h>
#endif
#ifdef __cplusplus
extern \"C\" { extern \"C\" {
#endif
"""
trailer = """\
#ifdef __cplusplus
}
#endif
#endif
""" """
trailer = "}"
include_guard = "PF_PATHFINDER_H"
include_version = true include_version = true
[parse] [parse]
parse_deps = true parse_deps = true
include = [ include = [
"font-kit",
"pathfinder_canvas", "pathfinder_canvas",
"pathfinder_content", "pathfinder_content",
"pathfinder_geometry", "pathfinder_geometry",
"pathfinder_gl", "pathfinder_gl",
"pathfinder_gpu",
"pathfinder_metal",
"pathfinder_renderer", "pathfinder_renderer",
] ]
[export.rename]
"BuildOptions" = "PFBuildOptionsPrivate"
"CanvasFontContext" = "PFCanvasFontContextPrivate"
"CanvasRenderingContext2D" = "PFCanvasRenderingContext2DPrivate"
"DestFramebuffer_GLDevice" = "PFDestFramebufferGLDevicePrivate"
"DestFramebuffer_MetalDevice" = "PFDestFramebufferMetalDevicePrivate"
"FillStyle" = "PFFillStylePrivate"
"GLDevice" = "PFGLDevicePrivate"
"Handle" = "FKHandlePrivate"
"MetalDevice" = "PFMetalDevicePrivate"
"Path2D" = "PFPath2DPrivate"
"RenderTransform" = "PFRenderTransformPrivate"
"Renderer_GLDevice" = "PFRendererGLDevicePrivate"
"Renderer_MetalDevice" = "PFRendererMetalDevicePrivate"
"ResourceLoaderWrapper" = "PFResourceLoaderWrapperPrivate"
"Scene" = "PFScenePrivate"
"SceneProxy" = "PFSceneProxyPrivate"

View File

@ -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,20 +183,18 @@ 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`
/// Consumes the font context. /// This function internally adds a reference to the font context. Therefore, if you created the
/// font context, you must release it yourself to avoid a leak.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFCanvasCreate(font_context: PFCanvasFontContextRef, pub unsafe extern "C" fn PFCanvasCreate(font_context: PFCanvasFontContextRef,
size: *const PFVector2F) size: *const PFVector2F)
-> PFCanvasRef { -> PFCanvasRef {
Box::into_raw(Box::new(CanvasRenderingContext2D::new(*Box::from_raw(font_context), Box::into_raw(Box::new(CanvasRenderingContext2D::new((*font_context).clone(),
(*size).to_rust()))) (*size).to_rust())))
} }
@ -188,17 +219,18 @@ pub unsafe extern "C" fn PFCanvasFontContextCreateWithFonts(fonts: *const FKHand
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFCanvasFontContextDestroy(font_context: PFCanvasFontContextRef) { pub unsafe extern "C" fn PFCanvasFontContextAddRef(font_context: PFCanvasFontContextRef)
drop(Box::from_raw(font_context))
}
#[no_mangle]
pub unsafe extern "C" fn PFCanvasFontContextClone(font_context: PFCanvasFontContextRef)
-> PFCanvasFontContextRef { -> PFCanvasFontContextRef {
Box::into_raw(Box::new((*font_context).clone())) Box::into_raw(Box::new((*font_context).clone()))
} }
/// Consumes the canvas. #[no_mangle]
pub unsafe extern "C" fn PFCanvasFontContextRelease(font_context: PFCanvasFontContextRef) {
drop(Box::from_raw(font_context))
}
/// This function takes ownership of the supplied canvas and will automatically destroy it when
/// the scene is destroyed.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFCanvasCreateScene(canvas: PFCanvasRef) -> PFSceneRef { pub unsafe extern "C" fn PFCanvasCreateScene(canvas: PFCanvasRef) -> PFSceneRef {
Box::into_raw(Box::new(Box::from_raw(canvas).into_scene())) Box::into_raw(Box::new(Box::from_raw(canvas).into_scene()))
@ -315,13 +347,15 @@ pub unsafe extern "C" fn PFCanvasSetStrokeStyle(canvas: PFCanvasRef,
(*canvas).set_stroke_style(*stroke_style) (*canvas).set_stroke_style(*stroke_style)
} }
/// Consumes the path. /// This function automatically destroys the path. If you wish to use the path again, clone it
/// first.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFCanvasFillPath(canvas: PFCanvasRef, path: PFPathRef) { pub unsafe extern "C" fn PFCanvasFillPath(canvas: PFCanvasRef, path: PFPathRef) {
(*canvas).fill_path(*Box::from_raw(path)) (*canvas).fill_path(*Box::from_raw(path))
} }
/// Consumes the path. /// This function automatically destroys the path. If you wish to use the path again, clone it
/// first.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFCanvasStrokePath(canvas: PFCanvasRef, path: PFPathRef) { pub unsafe extern "C" fn PFCanvasStrokePath(canvas: PFCanvasRef, path: PFPathRef) {
(*canvas).stroke_path(*Box::from_raw(path)) (*canvas).stroke_path(*Box::from_raw(path))
@ -421,7 +455,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 +469,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)))
} }
@ -461,7 +496,9 @@ pub unsafe extern "C" fn PFGLDestFramebufferDestroy(dest_framebuffer: PFGLDestFr
drop(Box::from_raw(dest_framebuffer)) drop(Box::from_raw(dest_framebuffer))
} }
/// Takes ownership of `device` and `dest_framebuffer`, but not `resources`. /// This function takes ownership of and automatically takes responsibility for destroying `device`
/// and `dest_framebuffer`. However, it does not take ownership of `resources`; therefore, if you
/// created the resource loader, you must destroy it yourself to avoid a memory leak.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn PFGLRendererCreate(device: PFGLDeviceRef, pub unsafe extern "C" fn PFGLRendererCreate(device: PFGLDeviceRef,
resources: PFResourceLoaderRef, resources: PFResourceLoaderRef,
@ -469,7 +506,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())))
} }
@ -498,7 +535,9 @@ pub unsafe extern "C" fn PFMetalDestFramebufferDestroy(dest_framebuffer:
drop(Box::from_raw(dest_framebuffer)) drop(Box::from_raw(dest_framebuffer))
} }
/// Takes ownership of `device` and `dest_framebuffer`, but not `resources`. /// This function takes ownership of and automatically takes responsibility for destroying `device`
/// and `dest_framebuffer`. However, it does not take ownership of `resources`; therefore, if you
/// created the resource loader, you must destroy it yourself to avoid a memory leak.
#[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 PFMetalRendererCreate(device: PFMetalDeviceRef, pub unsafe extern "C" fn PFMetalRendererCreate(device: PFMetalDeviceRef,
@ -507,7 +546,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())))
} }
@ -518,25 +557,33 @@ pub unsafe extern "C" fn PFMetalRendererDestroy(renderer: PFMetalRendererRef) {
drop(Box::from_raw(renderer)) drop(Box::from_raw(renderer))
} }
/// Returns a reference to the Metal device in the renderer.
///
/// This reference remains valid as long as the device is alive.
#[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 PFMetalRendererGetDevice(renderer: PFMetalRendererRef) -> PFMetalDeviceRef { pub unsafe extern "C" fn PFMetalRendererGetDevice(renderer: PFMetalRendererRef)
-> PFMetalDeviceRef {
&mut (*renderer).device &mut (*renderer).device
} }
/// This function does not take ownership of `renderer` or `build_options`. Therefore, if you
/// created the renderer and/or options, you must destroy them yourself to avoid a leak.
#[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, (*build_options).clone())
} }
/// This function does not take ownership of `renderer` or `build_options`. Therefore, if you
/// created the renderer and/or options, you must destroy them yourself to avoid a leak.
#[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, (*build_options).clone())
} }
// `metal` // `metal`
@ -554,8 +601,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 +736,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 +784,3 @@ impl PFRendererOptions {
} }
} }
} }
impl PFBuildOptions {
pub fn to_rust(&self) -> BuildOptions {
BuildOptions::default()
}
}

View File

@ -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.

View File

@ -0,0 +1,354 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
6A9A35B322C1E14700B86652 /* libpathfinder_c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A9A35B222C1E14700B86652 /* libpathfinder_c.a */; };
6AFD6FFA22BD780D00AC1ED3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AFD6FF922BD780D00AC1ED3 /* AppDelegate.m */; };
6AFD6FFC22BD781000AC1ED3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6AFD6FFB22BD781000AC1ED3 /* Assets.xcassets */; };
6AFD6FFF22BD781000AC1ED3 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6AFD6FFD22BD781000AC1ED3 /* MainMenu.xib */; };
6AFD700222BD781000AC1ED3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AFD700122BD781000AC1ED3 /* main.m */; };
6AFD700B22BD7B7A00AC1ED3 /* PathfinderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AFD700A22BD7B7A00AC1ED3 /* PathfinderView.m */; };
6AFD700F22BD930500AC1ED3 /* libharfbuzz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6AFD700E22BD930500AC1ED3 /* libharfbuzz.a */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
6A9A35B222C1E14700B86652 /* libpathfinder_c.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpathfinder_c.a; path = ../../../target/release/libpathfinder_c.a; sourceTree = "<group>"; };
6AFD6FF522BD780D00AC1ED3 /* Pathfinder Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Pathfinder Example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
6AFD6FF822BD780D00AC1ED3 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
6AFD6FF922BD780D00AC1ED3 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
6AFD6FFB22BD781000AC1ED3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
6AFD6FFE22BD781000AC1ED3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
6AFD700022BD781000AC1ED3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6AFD700122BD781000AC1ED3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
6AFD700322BD781000AC1ED3 /* Pathfinder_Example.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Pathfinder_Example.entitlements; sourceTree = "<group>"; };
6AFD700922BD7B7A00AC1ED3 /* PathfinderView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PathfinderView.h; sourceTree = "<group>"; };
6AFD700A22BD7B7A00AC1ED3 /* PathfinderView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PathfinderView.m; sourceTree = "<group>"; };
6AFD700E22BD930500AC1ED3 /* libharfbuzz.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libharfbuzz.a; path = ../../../../../../../usr/local/lib/libharfbuzz.a; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
6AFD6FF222BD780D00AC1ED3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6A9A35B322C1E14700B86652 /* libpathfinder_c.a in Frameworks */,
6AFD700F22BD930500AC1ED3 /* libharfbuzz.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
6AFD6FEC22BD780D00AC1ED3 = {
isa = PBXGroup;
children = (
6AFD6FF722BD780D00AC1ED3 /* Pathfinder Example */,
6AFD6FF622BD780D00AC1ED3 /* Products */,
);
sourceTree = "<group>";
};
6AFD6FF622BD780D00AC1ED3 /* Products */ = {
isa = PBXGroup;
children = (
6AFD6FF522BD780D00AC1ED3 /* Pathfinder Example.app */,
);
name = Products;
sourceTree = "<group>";
};
6AFD6FF722BD780D00AC1ED3 /* Pathfinder Example */ = {
isa = PBXGroup;
children = (
6AFD6FF822BD780D00AC1ED3 /* AppDelegate.h */,
6AFD6FF922BD780D00AC1ED3 /* AppDelegate.m */,
6AFD6FFB22BD781000AC1ED3 /* Assets.xcassets */,
6AFD6FFD22BD781000AC1ED3 /* MainMenu.xib */,
6AFD700022BD781000AC1ED3 /* Info.plist */,
6AFD700922BD7B7A00AC1ED3 /* PathfinderView.h */,
6AFD700A22BD7B7A00AC1ED3 /* PathfinderView.m */,
6AFD700122BD781000AC1ED3 /* main.m */,
6AFD700322BD781000AC1ED3 /* Pathfinder_Example.entitlements */,
6A9A35B222C1E14700B86652 /* libpathfinder_c.a */,
6AFD700E22BD930500AC1ED3 /* libharfbuzz.a */,
);
path = "Pathfinder Example";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
6AFD6FF422BD780D00AC1ED3 /* Pathfinder Example */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6AFD700622BD781000AC1ED3 /* Build configuration list for PBXNativeTarget "Pathfinder Example" */;
buildPhases = (
6AFD6FF122BD780D00AC1ED3 /* Sources */,
6AFD6FF222BD780D00AC1ED3 /* Frameworks */,
6AFD6FF322BD780D00AC1ED3 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "Pathfinder Example";
productName = "Pathfinder Example";
productReference = 6AFD6FF522BD780D00AC1ED3 /* Pathfinder Example.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
6AFD6FED22BD780D00AC1ED3 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "The Pathfinder Project Deelopers";
TargetAttributes = {
6AFD6FF422BD780D00AC1ED3 = {
CreatedOnToolsVersion = 10.2.1;
SystemCapabilities = {
com.apple.Sandbox = {
enabled = 0;
};
};
};
};
};
buildConfigurationList = 6AFD6FF022BD780D00AC1ED3 /* Build configuration list for PBXProject "Pathfinder Example" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 6AFD6FEC22BD780D00AC1ED3;
productRefGroup = 6AFD6FF622BD780D00AC1ED3 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
6AFD6FF422BD780D00AC1ED3 /* Pathfinder Example */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
6AFD6FF322BD780D00AC1ED3 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6AFD6FFC22BD781000AC1ED3 /* Assets.xcassets in Resources */,
6AFD6FFF22BD781000AC1ED3 /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
6AFD6FF122BD780D00AC1ED3 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6AFD700222BD781000AC1ED3 /* main.m in Sources */,
6AFD700B22BD7B7A00AC1ED3 /* PathfinderView.m in Sources */,
6AFD6FFA22BD780D00AC1ED3 /* AppDelegate.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
6AFD6FFD22BD781000AC1ED3 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
6AFD6FFE22BD781000AC1ED3 /* Base */,
);
name = MainMenu.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
6AFD700422BD781000AC1ED3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
6AFD700522BD781000AC1ED3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
};
name = Release;
};
6AFD700722BD781000AC1ED3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
FRAMEWORK_SEARCH_PATHS = "";
HEADER_SEARCH_PATHS = ../../c/build/include;
INFOPLIST_FILE = "Pathfinder Example/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
LIBRARY_SEARCH_PATHS = (
../../target/release,
/usr/local/lib,
);
PRODUCT_BUNDLE_IDENTIFIER = "graphics.pathfinder.Pathfinder-Example";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
6AFD700822BD781000AC1ED3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
FRAMEWORK_SEARCH_PATHS = "";
HEADER_SEARCH_PATHS = ../../c/build/include;
INFOPLIST_FILE = "Pathfinder Example/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
LIBRARY_SEARCH_PATHS = (
../../target/release,
/usr/local/lib,
);
PRODUCT_BUNDLE_IDENTIFIER = "graphics.pathfinder.Pathfinder-Example";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
6AFD6FF022BD780D00AC1ED3 /* Build configuration list for PBXProject "Pathfinder Example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6AFD700422BD781000AC1ED3 /* Debug */,
6AFD700522BD781000AC1ED3 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
6AFD700622BD781000AC1ED3 /* Build configuration list for PBXNativeTarget "Pathfinder Example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6AFD700722BD781000AC1ED3 /* Debug */,
6AFD700822BD781000AC1ED3 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 6AFD6FED22BD780D00AC1ED3 /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Pathfinder Example.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6AFD6FF422BD780D00AC1ED3"
BuildableName = "Pathfinder Example.app"
BlueprintName = "Pathfinder Example"
ReferencedContainer = "container:Pathfinder Example.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6AFD6FF422BD780D00AC1ED3"
BuildableName = "Pathfinder Example.app"
BlueprintName = "Pathfinder Example"
ReferencedContainer = "container:Pathfinder Example.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "YES"
customWorkingDirectory = "/Users/pcwalton/Source/pathfinder/examples/macos_app"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6AFD6FF422BD780D00AC1ED3"
BuildableName = "Pathfinder Example.app"
BlueprintName = "Pathfinder Example"
ReferencedContainer = "container:Pathfinder Example.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
<AdditionalOption
key = "NSZombieEnabled"
value = "YES"
isEnabled = "YES">
</AdditionalOption>
<AdditionalOption
key = "MallocScribble"
value = ""
isEnabled = "YES">
</AdditionalOption>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6AFD6FF422BD780D00AC1ED3"
BuildableName = "Pathfinder Example.app"
BlueprintName = "Pathfinder Example"
ReferencedContainer = "container:Pathfinder Example.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
scope = "0"
stopOnStyle = "0">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Pathfinder Example.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>6AFD6FF422BD780D00AC1ED3</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,15 @@
//
// AppDelegate.h
// Pathfinder Example
//
// Created by Patrick Walton on 6/21/19.
// Copyright © 2019 The Pathfinder Project Developers. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@end

View File

@ -0,0 +1,28 @@
//
// AppDelegate.m
// Pathfinder Example
//
// Created by Patrick Walton on 6/21/19.
// Copyright © 2019 The Pathfinder Project Developers. All rights reserved.
//
#import "AppDelegate.h"
@interface AppDelegate ()
@property (weak) IBOutlet NSWindow *window;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
@end

View File

@ -0,0 +1,58 @@
{
"images" : [
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,373 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate">
<connections>
<outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="Pathfinder Example" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Pathfinder Example" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About Pathfinder Example" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" enabled="NO" keyEquivalent="," id="BOF-NM-1cW"/>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide Pathfinder Example" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="-1" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit Pathfinder Example" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="5QF-Oa-p0T">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
<items>
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
<connections>
<action selector="undo:" target="-1" id="M6e-cu-g7V"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
<connections>
<action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
<connections>
<action selector="cut:" target="-1" id="YJe-68-I9s"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
<connections>
<action selector="copy:" target="-1" id="G1f-GL-Joy"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
<connections>
<action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
</connections>
</menuItem>
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
</connections>
</menuItem>
<menuItem title="Delete" id="pa3-QI-u2k">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
<connections>
<action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
<menuItem title="Find" id="4EN-yA-p0u">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Find" id="1b7-l0-nxx">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
<connections>
<action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
</connections>
</menuItem>
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
<connections>
<action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
<connections>
<action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
<connections>
<action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
<connections>
<action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
<items>
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
<connections>
<action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
</connections>
</menuItem>
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
<connections>
<action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
</connections>
</menuItem>
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
</connections>
</menuItem>
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Substitutions" id="9ic-FL-obx">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
<items>
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
</connections>
</menuItem>
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
</connections>
</menuItem>
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
</connections>
</menuItem>
<menuItem title="Smart Links" id="cwL-P1-jid">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
</connections>
</menuItem>
<menuItem title="Data Detectors" id="tRr-pd-1PS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
</connections>
</menuItem>
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Transformations" id="2oI-Rn-ZJC">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
<items>
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
</connections>
</menuItem>
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
</connections>
</menuItem>
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Speech" id="xrE-MZ-jX0">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
<items>
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
</connections>
</menuItem>
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="H8h-7b-M4v">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="View" id="HyV-fh-RgO">
<items>
<menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="toggleToolbarShown:" target="-1" id="BXY-wc-z0C"/>
</connections>
</menuItem>
<menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="runToolbarCustomizationPalette:" target="-1" id="pQI-g3-MTW"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="hB3-LF-h0Y"/>
<menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleSidebar:" target="-1" id="iwa-gc-5KM"/>
</connections>
</menuItem>
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleFullScreen:" target="-1" id="dU3-MA-1Rq"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
<connections>
<action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="R4o-n2-Eq4">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="wpr-3q-Mcd">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
<items>
<menuItem title="Pathfinder Example Help" keyEquivalent="?" id="FKE-Sm-Kum">
<connections>
<action selector="showHelp:" target="-1" id="y7X-2Q-9no"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<window title="Pathfinder Example" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<rect key="contentRect" x="335" y="390" width="640" height="480"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="640" height="480"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<customView id="naY-wz-xJX" customClass="PathfinderView">
<rect key="frame" x="0.0" y="0.0" width="640" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</customView>
</subviews>
</view>
</window>
</objects>
</document>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2019 The Pathfinder Project Developers. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@ -0,0 +1,30 @@
//
// PathfinderView.h
// Pathfinder Example
//
// Created by Patrick Walton on 6/21/19.
// Copyright © 2019 The Pathfinder Project Developers. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <Metal/Metal.h>
#include <pathfinder/pathfinder.h>
NS_ASSUME_NONNULL_BEGIN
@interface PathfinderView : NSView {
id<MTLDevice> mDevice;
PFMetalRendererRef mRenderer;
PFCanvasFontContextRef mFontContext;
PFBuildOptionsRef mBuildOptions;
CVDisplayLinkRef mDisplayLink;
int32_t mFrameNumber;
CGSize mLayerSize;
NSLock *mRenderLock;
}
- (void)_render;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,194 @@
//
// PathfinderView.m
// Pathfinder Example
//
// Created by Patrick Walton on 6/21/19.
// Copyright © 2019 The Pathfinder Project Developers. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>
#import "PathfinderView.h"
#import <Metal/Metal.h>
#include <math.h>
static CVReturn outputCallback(CVDisplayLinkRef displayLink,
const CVTimeStamp *now,
const CVTimeStamp *outputTime,
CVOptionFlags flagsIn,
CVOptionFlags *flagsOut,
void *userData) {
[(__bridge PathfinderView *)userData _render];
return kCVReturnSuccess;
}
static CATransform3D createPerspectiveMatrix(CGFloat fovY,
CGFloat aspect,
CGFloat zNear,
CGFloat zFar) {
CGFloat f = tan(1.0 / (fovY * 0.5));
CGFloat zDenom = 1.0 / (zNear - zFar);
CATransform3D transform = CATransform3DIdentity;
transform.m11 = f / aspect;
transform.m22 = f;
transform.m33 = (zFar + zNear) * zDenom;
transform.m34 = -1.0;
transform.m43 = 2.0 * zFar * zNear * zDenom;
return transform;
}
static PFTransform3DF pfTransformFromCATransform(const CATransform3D *transform) {
// Core Animation matrices are in column-major order, while Pathfinder matrices are in
// row-major order (at least in the latter's C API). So transpose here.
PFTransform3DF pfTransform;
pfTransform.m00 = (float)transform->m11;
pfTransform.m01 = (float)transform->m21;
pfTransform.m02 = (float)transform->m31;
pfTransform.m03 = (float)transform->m41;
pfTransform.m10 = (float)transform->m12;
pfTransform.m11 = (float)transform->m22;
pfTransform.m12 = (float)transform->m32;
pfTransform.m13 = (float)transform->m42;
pfTransform.m20 = (float)transform->m13;
pfTransform.m21 = (float)transform->m23;
pfTransform.m22 = (float)transform->m33;
pfTransform.m23 = (float)transform->m43;
pfTransform.m30 = (float)transform->m14;
pfTransform.m31 = (float)transform->m24;
pfTransform.m32 = (float)transform->m34;
pfTransform.m33 = (float)transform->m44;
return pfTransform;
}
@implementation PathfinderView
#define FONT_SIZE 256.0f
- (void)_render {
[mRenderLock lock];
CGSize size = mLayerSize;
PFCanvasRef canvas = PFCanvasCreate(mFontContext, &(PFVector2F){size.width, size.height});
PFFillStyleRef fillStyle =
PFFillStyleCreateColor(&(PFColorU){0, 0, 0, 255});
PFCanvasSetFillStyle(canvas, fillStyle);
PFCanvasSetFontSize(canvas, FONT_SIZE);
PFCanvasSetTextAlign(canvas, PF_TEXT_ALIGN_CENTER);
PFVector2F textOrigin;
textOrigin.x = 0.0;
textOrigin.y = FONT_SIZE * 0.25;
PFCanvasFillText(canvas, "Pathfinder", 0, &textOrigin);
PFCanvasFillRect(canvas, &(const PFRectF){0.0, 0.0, 1.0, 1.0});
PFFillStyleDestroy(fillStyle);
PFSceneRef scene = PFCanvasCreateScene(canvas);
PFSceneProxyRef sceneProxy = PFSceneProxyCreateFromSceneAndRayonExecutor(scene);
int32_t frame = mFrameNumber;
int32_t nT = frame % 240;
if (nT > 120)
nT = 240 - nT;
CATransform3D transform =
CATransform3DMakeTranslation(0.0, 0.0, -8.0 + (CGFloat)nT / 120.0 * 8.0);
transform = CATransform3DRotate(transform,
frame / 120.0 * M_PI * 2.0,
0.0,
1.0,
0.0);
transform = CATransform3DScale(transform, -2.0 / size.width, 2.0 / size.height, 1.0);
CGFloat aspect = size.width / size.height;
transform = CATransform3DConcat(transform,
createPerspectiveMatrix(M_PI * 0.25, aspect, 0.01, 10.0));
PFPerspective pfPerspective;
pfPerspective.transform = pfTransformFromCATransform(&transform);
pfPerspective.window_size.x = size.width;
pfPerspective.window_size.y = size.height;
PFBuildOptionsRef buildOptions = PFBuildOptionsCreate();
PFRenderTransformRef renderTransform = PFRenderTransformCreatePerspective(&pfPerspective);
PFBuildOptionsSetTransform(buildOptions, renderTransform);
PFSceneProxyBuildAndRenderMetal(sceneProxy, mRenderer, buildOptions);
PFMetalDevicePresentDrawable(PFMetalRendererGetDevice(mRenderer));
mFrameNumber++;
[mRenderLock unlock];
}
- (void)_checkCVResult:(CVReturn)result {
if (result != kCVReturnSuccess) {
@throw [NSException exceptionWithName:@"CoreVideoCallFailed"
reason:@"Core Video call failed"
userInfo:nil];
}
}
- (void)_initializeIfNecessary:(CAMetalLayer *)layer {
if (mDevice != nil)
return;
mFrameNumber = 0;
mDevice = MTLCreateSystemDefaultDevice();
[layer setDevice:mDevice];
[layer setContentsScale:[[self window] backingScaleFactor]];
mRenderLock = [[NSLock alloc] init];
mLayerSize = [self convertSizeToBacking:[layer bounds].size];
PFMetalDeviceRef device = PFMetalDeviceCreate(layer);
PFResourceLoaderRef resourceLoader = PFFilesystemResourceLoaderLocate();
PFMetalDestFramebufferRef destFramebuffer =
PFMetalDestFramebufferCreateFullWindow(&(PFVector2I){mLayerSize.width, mLayerSize.height});
PFRendererOptions rendererOptions;
rendererOptions.background_color = (PFColorF){1.0, 1.0, 1.0, 1.0};
rendererOptions.flags = PF_RENDERER_OPTIONS_FLAGS_HAS_BACKGROUND_COLOR;
mRenderer = PFMetalRendererCreate(device,
resourceLoader,
destFramebuffer,
&rendererOptions);
mFontContext = PFCanvasFontContextCreateWithSystemSource();
mBuildOptions = PFBuildOptionsCreate();
[self _checkCVResult:CVDisplayLinkCreateWithActiveCGDisplays(&mDisplayLink)];
[self _checkCVResult:CVDisplayLinkSetOutputCallback(mDisplayLink,
outputCallback,
(__bridge void *_Nullable)(self))];
[self _checkCVResult:CVDisplayLinkStart(mDisplayLink)];
}
- (CALayer *)makeBackingLayer {
return [[CAMetalLayer alloc] init];
}
- (BOOL)wantsLayer {
return YES;
}
- (BOOL)wantsUpdateLayer {
return YES;
}
- (NSViewLayerContentsRedrawPolicy)layerContentsRedrawPolicy {
return NSViewLayerContentsRedrawOnSetNeedsDisplay;
}
- (void)drawRect:(NSRect)dirtyRect {
[self _initializeIfNecessary:(CAMetalLayer *)[self layer]];
}
- (void)displayLayer:(CALayer *)layer {
[self _initializeIfNecessary:(CAMetalLayer *)layer];
}
- (void)awakeFromNib {
[self _initializeIfNecessary:(CAMetalLayer *)[self layer]];
}
@end

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

View File

@ -0,0 +1,13 @@
//
// main.m
// Pathfinder Example
//
// Created by Patrick Walton on 6/21/19.
// Copyright © 2019 The Pathfinder Project Developers. All rights reserved.
//
#import <Cocoa/Cocoa.h>
int main(int argc, const char * argv[]) {
return NSApplicationMain(argc, argv);
}

View File

@ -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 {