feat(macos): port Ghostty's macOS code paths (Metal, CoreText, Darwin)
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)
This commit is contained in:
1 parent
3c8fae1089
commit
452b782149
124 files changed
+14936
-1242
No files matched your search
@@ -0,0 +1,56 @@
|
||||
# macOS CoreText font backend (M1 / font)
|
||||
|
||||
Crate: `ghostty-font`. Compile-checked with
|
||||
`cargo check|clippy --target aarch64-apple-darwin|x86_64-apple-darwin -p ghostty-font --all-targets`
|
||||
(clean, `-D warnings`); never run on real macOS. Linux behaviour unchanged
|
||||
(`cargo test -p ghostty-font`: 203 pass / 3 ignored, clippy `-D warnings`, nightly fmt).
|
||||
|
||||
## Backend selection (`font/backend.zig`)
|
||||
`build.rs` emits cfgs from target + cargo features: `font_freetype`, `font_fontconfig`,
|
||||
`font_harfbuzz`, `font_coretext` (Apple), `font_coretext_face`, `font_coretext_shaper`, `font_noshape`.
|
||||
* Linux/other: fontconfig + FreeType + HarfBuzz (unchanged). wasm32: web_canvas (unchanged).
|
||||
* Apple targets, default `Backend::Coretext`: CoreText discovery/face/shaper; freetype-sys,
|
||||
harfbuzz-sys, fontconfig are NOT linked (freetype/harfbuzz are optional deps, `bundled`, apple only).
|
||||
* Cargo features (apple only): `coretext-freetype` (CT discovery, FreeType face, HarfBuzz shaper),
|
||||
`coretext-harfbuzz` (CT face + HarfBuzz via `hb_coretext_font_create`), `coretext-noshape`
|
||||
(no-op shaper). `backend::OPTIONS` follows the features. `face::DEFAULT_DPI` is 72 on macOS.
|
||||
|
||||
## Module map (Zig -> Rust, `crates/ghostty-font/src/`)
|
||||
| Zig | Rust |
|
||||
|---|---|
|
||||
| face/coretext.zig | `face/coretext.rs` (CTFont face, CoreGraphics bitmap rasterization, `ColorState`) + `face/coretext_math.rs` (pure math, tested on Linux) |
|
||||
| shaper/coretext.zig | `shaper/coretext.rs` (CTTypesetter/CTLine/CTRun, feature dicts, per-font attr-dict cache) + `shaper/coretext_cells.rs` (pure cluster/ligature logic, tested) + `shaper/cf_release.rs` |
|
||||
| discovery.zig CoreText + `toCoreTextDescriptor` | `discovery_coretext.rs` (`CoreText`, `Score`-based sorting, CJK / `CTFontCreateForString` fallbacks) |
|
||||
| DeferredFace.zig CoreText | `deferred_face_coretext.rs` (+ `coretext_freetype` file-path load) |
|
||||
| library.zig (noop for CT) | `library.rs` (empty library when no FreeType) |
|
||||
| SharedGridSet.zig Apple Emoji branch | `shared_grid_set.rs` (Apple Color Emoji via discovery on CT; embedded Noto emoji otherwise) |
|
||||
| (CF helpers of the `macos` package) | `coretext_util.rs` (`CfBox` Send+Sync wrapper, tables, glyph lookup, variation axes) |
|
||||
|
||||
API unification (so collection/grid/resolver stop naming `face::freetype::*`): `face::{Face, FaceError,
|
||||
RenderError, HbFont}`, `shape::{Shaper, ShapeError, ShapeRunError}`, `discovery::{Discover, NextError}`.
|
||||
`discover_fallback` now takes `&mut Collection` (CT needs `get_face`); no-op shaper gained `shape_run`,
|
||||
`ShapeError` and `new -> Result`.
|
||||
|
||||
## Tests
|
||||
Ported & platform-independent (run on Linux): metrics table priority (OS/2 typo vs hhea vs win),
|
||||
underline/strikethrough fallbacks, synthetic-bold width, glyph bearing/canvas layout (incl. sbix, thicken,
|
||||
bold), UTF-16/surrogate table, CoreText cell building incl. ligature/out-of-order-cluster/non-LTR heuristics,
|
||||
discovery `Score` ordering, style fuzzy/exact scoring, variation-axis bold/italic thresholds, backend
|
||||
capability predicates. macOS-only tests written but not runnable here (`#[cfg(font_coretext...)]`):
|
||||
face (Monaco ASCII, name, emoji, in-memory, variable, set variation, SVG table, glyphIndex colored vs text),
|
||||
discovery (coretext, codepoint, sorting), deferred face. The Zig CoreText shaper tests (23, need
|
||||
Terminal/RenderState + system fonts) are NOT ported; resolver/collection tests adjusted for CT
|
||||
(`Coretext doesn't support Noto's format`, text-emoji index 1).
|
||||
|
||||
## Caveats / TODO(integration)
|
||||
* Never executed on macOS: rasterization (CGBitmapContext flags, colour spaces), shaping and discovery are
|
||||
faithful ports but unverified at runtime.
|
||||
* `coretext-freetype` / `coretext-harfbuzz` cannot be cross-checked here: bundled harfbuzz with CoreText
|
||||
needs the macOS SDK headers (`ApplicationServices`). `coretext-noshape` and the default are checked.
|
||||
* `face_metrics` returns `Some(..)` for cap/ex/ascii height always (Zig returns plain values for CT).
|
||||
* CF release thread is local to the font crate (`shaper/cf_release.rs`, std thread + channel);
|
||||
switch to `ghostty_os::cf_release_thread` once that exists.
|
||||
* `Face::init` copies in-memory font data into a CFData (Zig used no-copy).
|
||||
* Renderer crate must use `ghostty_font::shape::{ShapeError, ShapeRunError}` instead of
|
||||
`shaper::harfbuzz::{ShapeError, ShapeRunError}` (generic.rs lines ~144-146) to build on macOS.
|
||||
* Cross-check env: `CC_<target>`/`AR_<target>` zig-cc wrappers (onig_sys C build); `GETTEXT_DIR` dummy.
|
||||
Reference in new issue
Block a user