Ports the macOS-specific Zig code behind cfg(target_os = "macos"): - renderer: a GraphicsApi trait with generic::Renderer<G>; Metal backend (all renderer/metal/* files, shaders.metal verbatim, runtime library compile, IOSurface layer, CVDisplayLink), shadertoy -> MSL via naga; OpenGL remains the backend elsewhere. - font: CoreText face, shaper and discovery with build.rs backend selection (coretext default; coretext-freetype / coretext-harfbuzz / coretext-noshape features), no fontconfig/freetype/harfbuzz on Apple. - input: KeymapDarwin via UCKeyTranslate, option-as-alt, mac keycodes. - os: macos, mach, cf_release_thread, NSProcessInfo args and macOS branches; config: macOS defaults, keybinds, Application Support paths. - termio/core: login(1) wrapping, openpty/execvpe, Darwin child exit handling, os_log logging. Compile-checked for aarch64/x86_64-apple-darwin (clippy -D warnings clean) using the cross setup in docs/rewrite/notes/macos-M1.md; cannot run here. The embedded runtime/C API (embedded.zig) is the next step. Also includes the cross-platform integration edits shared by the crash, verification, Windows and macOS work (Cargo target-gating, thread crash-context hooks, apprt-gtk surface/IME refactor, termio/os cfg gates), a cfg fix so ghostty-config builds on wasm32, and an allow for the intentional recursion in the crash overflow test. Test Plan: - cargo test --workspace (3224 passed) - cargo clippy --workspace --all-targets -- -D warnings - cargo check --target aarch64-apple-darwin -p ghostty-renderer (with the documented cross env)
88 lines
2.3 KiB
Rust
88 lines
2.3 KiB
Rust
//! A library represents the shared state that the underlying font
|
|
//! library implementation(s) require per-process. Port of `font/library.zig`.
|
|
//!
|
|
//! * FreeType backends: the `FT_Library` (plus a face-creation mutex).
|
|
//! * Backends without a library (CoreText, Canvas): an empty library
|
|
//! (Zig: `NoopLibrary`).
|
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
#[cfg(font_freetype)]
|
|
use crate::face::freetype::ft;
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum LibraryError {
|
|
#[cfg(font_freetype)]
|
|
#[error("freetype error {0}")]
|
|
Freetype(i32),
|
|
}
|
|
|
|
/// Shared font library state. Cheap to clone.
|
|
#[derive(Clone)]
|
|
pub struct Library {
|
|
#[cfg_attr(not(font_freetype), allow(dead_code))]
|
|
pub(crate) inner: Arc<LibraryInner>,
|
|
}
|
|
|
|
pub(crate) struct LibraryInner {
|
|
#[cfg(font_freetype)]
|
|
pub(crate) lib: ft::Lib,
|
|
|
|
/// Mutex to be held any time the library is
|
|
/// being used to create or destroy a face.
|
|
pub(crate) mutex: Mutex<()>,
|
|
}
|
|
|
|
impl Library {
|
|
#[cfg(font_freetype)]
|
|
pub fn init() -> Result<Library, LibraryError> {
|
|
let lib = ft::Lib::new().map_err(LibraryError::Freetype)?;
|
|
Ok(Library {
|
|
inner: Arc::new(LibraryInner {
|
|
lib,
|
|
mutex: Mutex::new(()),
|
|
}),
|
|
})
|
|
}
|
|
|
|
/// The CoreText backend has no per-process library state.
|
|
#[cfg(not(font_freetype))]
|
|
#[allow(clippy::unnecessary_wraps)]
|
|
pub fn init() -> Result<Library, LibraryError> {
|
|
Ok(Library {
|
|
inner: Arc::new(LibraryInner {
|
|
mutex: Mutex::new(()),
|
|
}),
|
|
})
|
|
}
|
|
|
|
/// Lock the library mutex (poisoning is ignored: the guarded state is
|
|
/// only the font library's own).
|
|
#[cfg_attr(not(font_freetype), allow(dead_code))]
|
|
pub(crate) fn lock(&self) -> std::sync::MutexGuard<'_, ()> {
|
|
self.inner
|
|
.mutex
|
|
.lock()
|
|
.unwrap_or_else(std::sync::PoisonError::into_inner)
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Debug for Library {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
f.write_str("Library")
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn init_and_clone() {
|
|
let lib = Library::init().unwrap();
|
|
let lib2 = lib.clone();
|
|
drop(lib);
|
|
drop(lib2.lock());
|
|
}
|
|
}
|